blob: 10bdd0996b19092f477d037feb202a8b168dc0f4 [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
ssiddiqui04386ee2021-08-23 21:58:25 +0530219func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
220 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
221 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
222 if pooledIntfID == intfID {
223 return resourceRanges.GetTechnology()
224 }
225 }
226 }
227 return ""
228}
229
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400230func macifyIP(ip net.IP) string {
231 if len(ip) > 0 {
232 oct1 := strconv.FormatInt(int64(ip[12]), 16)
233 oct2 := strconv.FormatInt(int64(ip[13]), 16)
234 oct3 := strconv.FormatInt(int64(ip[14]), 16)
235 oct4 := strconv.FormatInt(int64(ip[15]), 16)
236 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
237 }
238 return ""
239}
240
Neha Sharma96b7bf22020-06-15 10:37:32 +0000241func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400242 var genmac string
243 var addr net.IP
244 var ips []string
245 var err error
246
Neha Sharma96b7bf22020-06-15 10:37:32 +0000247 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400248
249 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000250 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400251
252 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000253 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400254 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000255 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400256 }
257 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000258 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530259 log.Fields{"host": ips[0],
260 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400261 return genmac, nil
262 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000263 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400264 }
265
266 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000267 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530268 log.Fields{"host": host,
269 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400270 return genmac, nil
271}
272
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530273func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700274 slist := strings.Split(mac, ":")
275 result := make([]uint32, len(slist))
276 var err error
277 var tmp int64
278 for index, val := range slist {
279 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
280 return []uint32{1, 2, 3, 4, 5, 6}
281 }
282 result[index] = uint32(tmp)
283 }
284 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530285}
286
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700287//GetportLabel returns the label for the NNI and the PON port based on port number and port type
David K. Bainbridge794735f2020-02-11 21:01:37 -0800288func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530289
David K. Bainbridge794735f2020-02-11 21:01:37 -0800290 switch portType {
291 case voltha.Port_ETHERNET_NNI:
292 return fmt.Sprintf("nni-%d", portNum), nil
293 case voltha.Port_PON_OLT:
294 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700295 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800296
Girish Kumarf26e4882020-03-05 06:49:10 +0000297 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530298}
299
Neha Sharma96b7bf22020-06-15 10:37:32 +0000300func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000301 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700302 if state == "up" {
303 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500304 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500305 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700306 } else {
307 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500308 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700309 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700310 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400311 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800312 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000313 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400314 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500315
Neha Sharma8f4e4322020-08-06 10:51:53 +0000316 if port, err := dh.coreProxy.GetDevicePort(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portNum); err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000317 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000318 if err := dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portType, portNum, operStatus); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400319 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
320 "device-id": dh.device.Id,
321 "port-type": portType,
322 "port-number": portNum,
323 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500324 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400325 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500326 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400327 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700328 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400329 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700330 PortNo: portNum,
331 Label: label,
332 Type: portType,
333 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700334 OfpPort: &of.OfpPort{
335 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
336 Config: 0,
337 State: uint32(of.OfpPortState_OFPPS_LIVE),
338 Curr: capacity,
339 Advertised: capacity,
340 Peer: capacity,
341 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
342 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
343 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700344 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000345 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700346 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000347 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000348 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800349 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000350 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400351 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000352 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530353 return nil
354}
355
Kent Hagermane6ff1012020-07-14 15:07:53 -0400356func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000357 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530358 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400359 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
360 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530361 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800362 dh.lockDevice.Lock()
363 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530364 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530365}
366
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700367// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530368// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800369func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000370 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700371 defer func() {
372 dh.lockDevice.Lock()
373 dh.isReadIndicationRoutineActive = false
374 dh.lockDevice.Unlock()
375 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700376 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700377 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700378 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700379 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400380
David Bainbridgef5879ca2019-12-13 21:17:54 +0000381 // Create an exponential backoff around re-enabling indications. The
382 // maximum elapsed time for the back off is set to 0 so that we will
383 // continue to retry. The max interval defaults to 1m, but is set
384 // here for code clarity
385 indicationBackoff := backoff.NewExponentialBackOff()
386 indicationBackoff.MaxElapsedTime = 0
387 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700388
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700389 dh.lockDevice.Lock()
390 dh.isReadIndicationRoutineActive = true
391 dh.lockDevice.Unlock()
392
Girish Gowdra3f974912020-03-23 20:35:18 -0700393Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700394 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400395 select {
396 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000397 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700398 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400399 default:
400 indication, err := indications.Recv()
401 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000402 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530403 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530404 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400405 // Use an exponential back off to prevent getting into a tight loop
406 duration := indicationBackoff.NextBackOff()
407 if duration == backoff.Stop {
408 // If we reach a maximum then warn and reset the backoff
409 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000410 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530411 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530412 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400413 indicationBackoff.Reset()
414 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700415
416 // On failure process a backoff timer while watching for stopIndications
417 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700418 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700419 select {
420 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000421 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700422 if !backoffTimer.Stop() {
423 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700424 }
425 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700426 case <-backoffTimer.C:
427 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700428 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700429 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
430 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400431 }
432 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000433 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530434 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000435 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530436 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530437 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700438 // Close the stream, and re-initialize it
439 if err = indications.CloseSend(); err != nil {
440 // Ok to ignore here, because we landed here due to a problem on the stream
441 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000442 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530443 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530444 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700445 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000446 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700447 return err
448 }
449 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400450 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530451 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400452 // Reset backoff if we have a successful receive
453 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400454 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700455 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000456 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530457 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530458 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400459 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400460 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400461 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700462 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700463 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700464 // Close the send stream
465 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700466
Girish Gowdra3f974912020-03-23 20:35:18 -0700467 return nil
468}
469
470func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700471 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700472 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
473 if err != nil {
474 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
475 }
476 if indications == nil {
477 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
478 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700479 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700480 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400481}
482
483// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
484func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
485 switch indication.Data.(type) {
486 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
487 return true
488
489 default:
490 return false
491 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700492}
493
David K. Bainbridge794735f2020-02-11 21:01:37 -0800494func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700495 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000496 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530497 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700498 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530499 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700500 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000501 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000502 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530503 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000504 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800505 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000506 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800507 }
508 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700509}
510
David K. Bainbridge794735f2020-02-11 21:01:37 -0800511// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530512func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700513 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700514 switch indication.Data.(type) {
515 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000516 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
517 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700518 logger.Infow(ctx, "received olt indication", log.Fields{"device-id": dh.device.Id, "olt-ind": indication.GetOltInd()})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800519 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400520 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800521 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700522 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000523 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
524 defer span.Finish()
525
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700526 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800527 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000528 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400529 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800530 }
531 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000532 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700533 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000534 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
535 defer span.Finish()
536
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700537 intfOperInd := indication.GetIntfOperInd()
538 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800539 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000540 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400541 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-nni", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800542 }
543 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700544 } else if intfOperInd.GetType() == "pon" {
545 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
546 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800547 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000548 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400549 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-pon", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800550 }
551 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700553 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000554 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530555 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530556 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700557 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000558 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
559 defer span.Finish()
560
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700561 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000562 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800563 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800564 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700565 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000566 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
567 defer span.Finish()
568
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700569 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000570 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800571 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800572 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000574 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
575 defer span.Finish()
576
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000578 logger.Debugw(ctx, "received-omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800579 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000580 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400581 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800582 }
583 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700584 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000585 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
586 defer span.Finish()
587
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700588 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000589 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700590 "intf-type": pktInd.IntfId,
591 "intf-id": pktInd.IntfId,
592 "gem-port-id": pktInd.GemportId,
593 "port-no": pktInd.PortNo,
594 "device-id": dh.device.Id,
595 })
596
597 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000598 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700599 "intf-type": pktInd.IntfId,
600 "intf-id": pktInd.IntfId,
601 "gem-port-id": pktInd.GemportId,
602 "port-no": pktInd.PortNo,
603 "packet": hex.EncodeToString(pktInd.Pkt),
604 "device-id": dh.device.Id,
605 })
606 }
607
David K. Bainbridge794735f2020-02-11 21:01:37 -0800608 go func() {
609 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400610 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800611 }
612 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700613 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000614 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
615 defer span.Finish()
616
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700617 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700618 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700619 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000620 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
621 defer span.Finish()
622
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700623 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000624 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700625 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000626 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
627 defer span.Finish()
628
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700629 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
631 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700632 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530633}
634
635// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530636func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530637 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000638 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530639
Girish Gowdru0c588b22019-04-23 23:24:56 -0400640 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530641 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400642 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000643 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400644 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000645
646 //Clear olt communication failure event
647 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
648 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700649 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000650 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
651
Gamze Abakac2c32a62021-03-11 11:44:18 +0000652 //check adapter and agent reconcile status
653 //reboot olt if needed (olt disconnection case)
654 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
655 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
656 log.Fields{
657 "device-id": dh.device.Id,
658 "adapter-status": dh.adapterPreviouslyConnected,
659 "agent-status": dh.agentPreviouslyConnected,
660 })
661 _ = dh.RebootDevice(ctx, dh.device)
662 }
663
Girish Gowdru0c588b22019-04-23 23:24:56 -0400664 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530665}
666
667// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530668func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000669 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400670
npujarec5762e2020-01-01 14:08:48 +0530671 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400672 if err != nil || device == nil {
673 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000674 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400675 }
676
677 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400678
679 //Update the device oper state and connection status
680 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800681 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400682 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800683 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400684
David K. Bainbridge794735f2020-02-11 21:01:37 -0800685 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000686 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400687 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400688
689 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530690 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400691 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000692 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400693 }
694 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400695 // Update onu state as down in onu adapter
696 onuInd := oop.OnuIndication{}
697 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800698 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300699 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800700 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400701 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300702 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800703 "onu-indicator": onuInd,
704 "device-type": onuDevice.Type,
705 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700706 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800707 } else {
708 logger.Debugw(ctx, "sending inter adapter down ind to onu success", log.Fields{"olt-device-id": device.Id, "onu-device-id": onuDevice.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700709 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400710 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800711 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700712 /* Discovered ONUs entries need to be cleared , since after OLT
713 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530714 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800715 dh.lockDevice.Unlock()
716
Neha Sharma96b7bf22020-06-15 10:37:32 +0000717 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700718 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530719}
720
721// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530722func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400723 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000724
725 // if the connection is already available, close the previous connection (olt reboot case)
726 if dh.clientCon != nil {
727 if err = dh.clientCon.Close(); err != nil {
728 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
729 } else {
730 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
731 }
732 }
733
734 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000735 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
736 grpc.WithInsecure(),
737 grpc.WithBlock(),
738 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000739 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000740 )),
741 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000742 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000743 )))
744
745 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530746 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530747 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000748 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400749 }
750 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530751}
752
753// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530754func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400755 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530756 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400757 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530758}
759
760// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530761func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530762 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000763 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400764
765 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530766 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
767 if err != nil || device == nil {
768 /*TODO: needs to handle error scenarios */
769 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
770 }
771 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000772 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400773
774 cloned := proto.Clone(device).(*voltha.Device)
775 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
776 cloned.OperStatus = voltha.OperStatus_UNKNOWN
777 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530778 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
779 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400780 }
781
Chaitrashree G S44124192019-08-07 20:21:36 -0400782 // Since the device was disabled before the OLT was rebooted, enforce the OLT to be Disabled after re-connection.
npujarec5762e2020-01-01 14:08:48 +0530783 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400784 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530785 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400786 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400787 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
788 // all the modules initialized and ready to handle incoming ONUs.
789
Thomas Lee S985938d2020-05-04 11:40:41 +0530790 err = dh.initializeDeviceHandlerModules(ctx)
791 if err != nil {
792 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400793 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400794
795 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800796 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530797 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400798 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800799 }
800 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700801
802 go startHeartbeatCheck(ctx, dh)
803
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400804 return nil
805 }
806
Neha Sharma8f4e4322020-08-06 10:51:53 +0000807 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400808 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400809 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400810 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400811 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400812 dh.populateActivePorts(ctx, ports)
813 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
814 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400815 }
816
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400817 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530818 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400819 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530820
cuilin20187b2a8c32019-03-26 19:52:28 -0700821 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800822 go func() {
823 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400824 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800825 }
826 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000827 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000828
829 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000830 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000831 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700832
833 go startHeartbeatCheck(ctx, dh)
834
cuilin20187b2a8c32019-03-26 19:52:28 -0700835 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530836}
837
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400838func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700839 var err error
840 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400841
842 if err != nil {
843 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
844 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700845 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
846 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700847
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700848 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700849 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700850 var i uint32
851 for i = 0; i < dh.totalPonPorts; i++ {
852 // Instantiate resource manager
853 if dh.resourceMgr[i] = rsrcMgr.NewResourceMgr(ctx, i, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, dh.deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700854 return olterrors.ErrResourceManagerInstantiating
855 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400856 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700857 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
858 // the KV store to manage mcast group data. Provide the first instance (0th index)
859 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
860 return olterrors.ErrGroupManagerInstantiating
861 }
862 for i = 0; i < dh.totalPonPorts; i++ {
863 // Instantiate flow manager
864 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
865 return olterrors.ErrFlowManagerInstantiating
866 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700867 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700868 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400869 /* TODO: Instantiate Alarm , stats , BW managers */
870 /* Instantiating Event Manager to handle Alarms and KPIs */
871 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
872
873 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000874 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400875
876 return nil
877
878}
879
Neha Sharma96b7bf22020-06-15 10:37:32 +0000880func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400881 var err error
882 var deviceInfo *oop.DeviceInfo
883
Neha Sharma8f4e4322020-08-06 10:51:53 +0000884 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400885
886 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000887 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400888 }
889 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000890 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400891 }
892
Neha Sharma96b7bf22020-06-15 10:37:32 +0000893 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400894 dh.device.Root = true
895 dh.device.Vendor = deviceInfo.Vendor
896 dh.device.Model = deviceInfo.Model
897 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
898 dh.device.HardwareVersion = deviceInfo.HardwareVersion
899 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
900
901 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000902 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400903 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000904 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400905 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000906 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400907 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000908 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400909 dh.device.MacAddress = genmac
910 } else {
911 dh.device.MacAddress = deviceInfo.DeviceId
912 }
913
914 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000915 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000916 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400917 }
918
919 return deviceInfo, nil
920}
921
Neha Sharma96b7bf22020-06-15 10:37:32 +0000922func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700923 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530924 for {
925 select {
926 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000927 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530928 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000929 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700930
Neha Sharma8f4e4322020-08-06 10:51:53 +0000931 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400932 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700933 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400934 continue
935 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530936 for _, port := range ports {
937 // NNI Stats
938 if port.Type == voltha.Port_ETHERNET_NNI {
939 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
940 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000941 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000942 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000943 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530944 }
945 // PON Stats
946 if port.Type == voltha.Port_PON_OLT {
947 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
948 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
949 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000950 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000951 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530952 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000953 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000954
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700955 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700956 if len(onuGemInfoLst) > 0 {
957 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000958 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500959 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530960 }
961 }
962 }
963}
964
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700965//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530966func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400967 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000968 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530969 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530970
971 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400972 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
973 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530974 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530975}
976
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700977//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530978func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700979 return &ic.SwitchCapability{
980 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530981 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700982 HwDesc: "open_pon",
983 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700984 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700985 },
986 SwitchFeatures: &of.OfpSwitchFeatures{
987 NBuffers: 256,
988 NTables: 2,
989 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
990 of.OfpCapabilities_OFPC_TABLE_STATS |
991 of.OfpCapabilities_OFPC_PORT_STATS |
992 of.OfpCapabilities_OFPC_GROUP_STATS),
993 },
994 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530995}
996
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700997// GetInterAdapterTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
998func (dh *DeviceHandler) GetInterAdapterTechProfileDownloadMessage(ctx context.Context, tpPath string, ponPortNum uint32, onuID uint32, uniID uint32) *ic.InterAdapterTechProfileDownloadMessage {
999 ifID, err := IntfIDFromPonPortNum(ctx, ponPortNum)
1000 if err != nil {
1001 return nil
1002 }
1003 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, tpPath, ifID, onuID, uniID)
1004}
1005
Neha Sharma96b7bf22020-06-15 10:37:32 +00001006func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
1007 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 -07001008 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001009 var deviceID string
1010 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -07001011
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001012 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001013 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001014 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 -07001015 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1016 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001017
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001018 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301019
1020 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1021
Neha Sharma96b7bf22020-06-15 10:37:32 +00001022 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 -07001023 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001024 kwargs := make(map[string]interface{})
1025 kwargs["onu_id"] = omciInd.OnuId
1026 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001027
Neha Sharma8f4e4322020-08-06 10:51:53 +00001028 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001029 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301030 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001031 "intf-id": omciInd.IntfId,
1032 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001033 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001034 deviceType = onuDevice.Type
1035 deviceID = onuDevice.Id
1036 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1037 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301038 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001039 } else {
1040 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001041 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 +05301042 deviceType = onuInCache.(*OnuDevice).deviceType
1043 deviceID = onuInCache.(*OnuDevice).deviceID
1044 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001045 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001046
1047 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001048 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001049 ic.InterAdapterMessageType_OMCI_RESPONSE, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001050 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301051 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001052 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001053 "destination": deviceType,
1054 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001055 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001056 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001057 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301058}
1059
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001060//ProcessInterAdapterMessage sends the proxied messages to the target device
1061// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1062// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001063func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1064 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001065 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001066 return dh.handleInterAdapterOmciMsg(ctx, msg)
1067 }
1068 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1069}
cuilin20187b2a8c32019-03-26 19:52:28 -07001070
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001071func (dh *DeviceHandler) handleInterAdapterOmciMsg(ctx context.Context, msg *ic.InterAdapterMessage) error {
1072 msgID := msg.Header.Id
1073 fromTopic := msg.Header.FromTopic
1074 toTopic := msg.Header.ToTopic
1075 toDeviceID := msg.Header.ToDeviceId
1076 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001077
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001078 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 -07001079
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001080 msgBody := msg.GetBody()
1081
1082 omciMsg := &ic.InterAdapterOmciMessage{}
1083 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
1084 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
1085 }
1086
1087 if omciMsg.GetProxyAddress() == nil {
1088 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
1089 if err != nil {
1090 return olterrors.NewErrNotFound("onu", log.Fields{
1091 "device-id": dh.device.Id,
1092 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001093 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001094 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 -07001095 if err := dh.sendProxiedOmciMessage(ctx, onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001096 return olterrors.NewErrCommunication("send-failed", log.Fields{
1097 "device-id": dh.device.Id,
1098 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001099 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001100 } else {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001101 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 -07001102 if err := dh.sendProxiedOmciMessage(ctx, nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001103 return olterrors.NewErrCommunication("send-failed", log.Fields{
1104 "device-id": dh.device.Id,
1105 "onu-device-id": toDeviceID}, err)
1106 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001107 }
1108 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301109}
1110
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001111func (dh *DeviceHandler) sendProxiedOmciMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001112 var intfID uint32
1113 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001114 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001115 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001116 intfID = onuDevice.ProxyAddress.GetChannelId()
1117 onuID = onuDevice.ProxyAddress.GetOnuId()
1118 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001119 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001120 intfID = omciMsg.GetProxyAddress().GetChannelId()
1121 onuID = omciMsg.GetProxyAddress().GetOnuId()
1122 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001123 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001124 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001125 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 -08001126
Thomas Lee S94109f12020-03-03 16:39:29 +05301127 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001128 "intf-id": intfID,
1129 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001130 }
1131
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001132 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1133 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001134 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001135 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1136 hex.Encode(hexPkt, omciMsg.Message)
1137 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1138
1139 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1140 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1141 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001142 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001143 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001144
Neha Sharma8f4e4322020-08-06 10:51:53 +00001145 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001146 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301147 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001148 "intf-id": intfID,
1149 "onu-id": onuID,
1150 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001151 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001152 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001153}
1154
David K. Bainbridge794735f2020-02-11 21:01:37 -08001155func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301156 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra197acc12021-08-16 10:59:45 -07001157 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001158 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001159 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001160 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301161 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301162 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001163 st, _ := status.FromError(err)
1164 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001165 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1166
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001167 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301168 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001169 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001170 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001171 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001172 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001173 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001174}
1175
Mahir Gunyelb0046752021-02-26 13:51:05 -08001176func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001177 channelID := onuDiscInd.GetIntfId()
1178 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001179
Mahir Gunyelb0046752021-02-26 13:51:05 -08001180 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001181 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301182
cuilin20187b2a8c32019-03-26 19:52:28 -07001183 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001184 if sn != "" {
1185 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001186 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001187 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001188 }
1189
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301190 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001191 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001192 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301193
1194 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1195 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1196 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1197 OnuLosRaise event sent for it */
1198 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1199 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1200 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001201 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301202 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1203 "currentIntfId": onuDiscInd.GetIntfId()})
1204 // TODO:: Should we need to ignore raising OnuLosClear event
1205 // when onu connected to different PON?
1206 }
1207 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1208 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1209 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001210 go func() {
1211 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001212 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001213 }
1214 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301215 }
1216 return true
1217 })
1218
Neha Sharma96b7bf22020-06-15 10:37:32 +00001219 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001221 }
1222
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001223 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001224
1225 // check the ONU is already know to the OLT
1226 // NOTE the second time the ONU is discovered this should return a device
1227 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1228
1229 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001230 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 -08001231 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001232 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 -08001233 switch e.Code() {
1234 case codes.Internal:
1235 // this probably means NOT FOUND, so just create a new device
1236 onuDevice = nil
1237 case codes.DeadlineExceeded:
1238 // if the call times out, cleanup and exit
1239 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001240 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001241 }
1242 }
1243 }
1244
1245 if onuDevice == nil {
1246 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001247 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001248 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001249 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001250 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001251
Neha Sharma96b7bf22020-06-15 10:37:32 +00001252 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001253
1254 if err != nil {
1255 // if we can't create an ID in resource manager,
1256 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001257 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001258 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001259 "pon-intf-id": ponintfid,
1260 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001261 }
1262
Neha Sharma8f4e4322020-08-06 10:51:53 +00001263 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001264 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001265 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001266 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 +05301267 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001268 "pon-intf-id": ponintfid,
1269 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001270 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001271 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 -07001272 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001273 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001274 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301275 log.Fields{"onuDevice": onuDevice,
1276 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001277 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301278 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001279 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001280
1281 // we can now use the existing ONU Id
1282 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001283 //Insert the ONU into cache to use in OnuIndication.
1284 //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 +00001285 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001286 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301287 "intfId": onuDiscInd.GetIntfId(),
1288 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001289 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001290
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301291 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301292 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001293 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301294 log.Fields{"onu": onuDev,
1295 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001296
Kent Hagermane6ff1012020-07-14 15:07:53 -04001297 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301298 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001299 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001300 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001301 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001302 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001303 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301304 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001305 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001306 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001307 }
1308 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001309}
1310
Mahir Gunyelb0046752021-02-26 13:51:05 -08001311func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001312
1313 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001314 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001315 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001316 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001317 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001318 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301319 log.Fields{"onuId": onuInd.OnuId,
1320 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301321 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001322 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001323 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301324
David K. Bainbridge794735f2020-02-11 21:01:37 -08001325 errFields := log.Fields{"device-id": dh.device.Id}
1326
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301327 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1328
Mahir Gunyele77977b2019-06-27 05:36:22 -07001329 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1330 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001331 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001332 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001333 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001334 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1335 if serialNumber != "" {
1336 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001337 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001338 } else {
1339 kwargs["onu_id"] = onuInd.OnuId
1340 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001341 errFields["onu-id"] = onuInd.OnuId
1342 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001343 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001344 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001345 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001346
David K. Bainbridge794735f2020-02-11 21:01:37 -08001347 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001348 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001349 }
1350
David K. Bainbridge794735f2020-02-11 21:01:37 -08001351 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001352 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001353 "previousIntfId": onuDevice.ParentPortNo,
1354 "currentIntfId": ponPort})
1355 }
1356
1357 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001358 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301359 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1360 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301361 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001362 }
1363 if !foundInCache {
1364 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1365
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301366 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 -08001367
1368 }
kesavand7cf3a052020-08-28 12:49:18 +05301369 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001370 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001371 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301372 }
1373 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001374 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001375 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001376 }
1377 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001378}
1379
Neha Sharma96b7bf22020-06-15 10:37:32 +00001380func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001381 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 -07001382 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1383 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1384 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1385 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001386 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001387 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1388 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001389 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001390 onuInd.OperState = "down"
1391 }
1392 }
1393
David K. Bainbridge794735f2020-02-11 21:01:37 -08001394 switch onuInd.OperState {
1395 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001396 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001397 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301398 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001399 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001400 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301401 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001402 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001403 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001404 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001405 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001406 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001407 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001408 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 -04001409 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301410 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001411 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001412 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301413 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001414 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001415 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001416 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001417 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001418 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001419 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001420 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001421 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001422 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001423}
1424
cuilin20187b2a8c32019-03-26 19:52:28 -07001425func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1426 if serialNum != nil {
1427 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001428 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001429 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001430}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001431func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1432 decodedStr, err := hex.DecodeString(serialNum[4:])
1433 if err != nil {
1434 return nil, err
1435 }
1436 return &oop.SerialNumber{
1437 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001438 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001439 }, nil
1440}
cuilin20187b2a8c32019-03-26 19:52:28 -07001441
1442func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001443 if len(vendorSpecific) > 3 {
1444 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1445 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1446 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1447 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1448 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1449 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1450 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1451 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1452 return tmp
1453 }
1454 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001455}
1456
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001457//UpdateFlowsBulk upates the bulk flow
1458func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301459 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001460}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001461
1462//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001463func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1464 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301465 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001466 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301467 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001468 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001469 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001470 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001471 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001472 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001473 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001474 "intf-id": parentPort,
1475 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001476 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001477 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 -08001478 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301479}
1480
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001481// SendPacketInToCore sends packet-in to core
1482// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1483// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001484func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001485 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001486 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001487 "port": logicalPort,
1488 "packet": hex.EncodeToString(packetPayload),
1489 "device-id": dh.device.Id,
1490 })
1491 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001492 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 +05301493 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001494 "source": "adapter",
1495 "destination": "core",
1496 "device-id": dh.device.Id,
1497 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001498 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001499 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001500 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001501 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001502 "packet": hex.EncodeToString(packetPayload),
1503 "device-id": dh.device.Id,
1504 })
1505 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001506 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001507}
1508
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001509// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001510func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001511 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001512
1513 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1514 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001515 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001516 }
1517
Kent Hagermane6ff1012020-07-14 15:07:53 -04001518 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001519 metrics := dh.metrics.GetSubscriberMetrics()
1520 for _, m := range pmConfigs.Metrics {
1521 metrics[m.Name].Enabled = m.Enabled
1522
1523 }
1524 }
1525}
1526
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001527//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301528func (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 +00001529 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 +01001530
Girish Gowdra491a9c62021-01-06 16:43:07 -08001531 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001532 var errorsList []error
1533
Girish Gowdru0c588b22019-04-23 23:24:56 -04001534 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001535 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001536 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001537
Neha Sharma96b7bf22020-06-15 10:37:32 +00001538 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301539 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001540 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301541 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001542 if flow_utils.HasGroup(flow) {
1543 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1544 } else {
1545 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1546 }
Girish Gowdracefae192020-03-19 18:14:10 -07001547 if err != nil {
1548 errorsList = append(errorsList, err)
1549 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001550 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301551
1552 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001553 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001554 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301555 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001556 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301557 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001558 if flow_utils.HasGroup(flow) {
1559 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1560 } else {
1561 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1562 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001563 if err != nil {
1564 errorsList = append(errorsList, err)
1565 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301566 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001567 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001568
Girish Gowdracefae192020-03-19 18:14:10 -07001569 // 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 +00001570 if groups != nil {
1571 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001572 // err = dh.groupMgr.AddGroup(ctx, group)
1573 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001574 if err != nil {
1575 errorsList = append(errorsList, err)
1576 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001577 }
1578 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001579 // err = dh.groupMgr.ModifyGroup(ctx, group)
1580 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001581 if err != nil {
1582 errorsList = append(errorsList, err)
1583 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001584 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001585 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001586 // err = dh.groupMgr.DeleteGroup(ctx, group)
1587 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001588 if err != nil {
1589 errorsList = append(errorsList, err)
1590 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001591 }
1592 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001593 if len(errorsList) > 0 {
1594 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1595 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001596 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001597 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301598}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001599
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001600//DisableDevice disables the given device
1601//It marks the following for the given device:
1602//Device-Handler Admin-State : down
1603//Device Port-State: UNKNOWN
1604//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001605func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001606 /* On device disable ,admin state update has to be done prior sending request to agent since
1607 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001608 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001609 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001610 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001611 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001612 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001613 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001614 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001615 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001616 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001617 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301618
1619 dh.discOnus = sync.Map{}
1620 dh.onus = sync.Map{}
1621
Thomas Lee S85f37312020-04-03 17:06:12 +05301622 //stopping the stats collector
1623 dh.stopCollector <- true
1624
Neha Sharma96b7bf22020-06-15 10:37:32 +00001625 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001626 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301627 //Update device Admin state
1628 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001629 // 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 +00001630 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 -04001631 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001632 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001633 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001634 return nil
1635}
1636
Neha Sharma96b7bf22020-06-15 10:37:32 +00001637func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001638 // Update onu state as unreachable in onu adapter
1639 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301640 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001641 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001642 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001643 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001644 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 -04001645 }
1646 if onuDevices != nil {
1647 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001648 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001649 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001650 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001651 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001652 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001653 }
1654
1655 }
1656 }
1657
1658}
1659
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001660//ReenableDevice re-enables the olt device after disable
1661//It marks the following for the given device:
1662//Device-Handler Admin-State : up
1663//Device Port-State: ACTIVE
1664//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001665func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001666 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301667 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001668 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301669 }
1670 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001672
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001673 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001674
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001675 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1676 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001677 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001678 }
1679 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001680 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001681 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001682 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001683 device.OperStatus = voltha.OperStatus_ACTIVE
1684 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001685
Neha Sharma8f4e4322020-08-06 10:51:53 +00001686 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 +05301687 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001688 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001689 "connect-status": device.ConnectStatus,
1690 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001691 }
kesavand39e0aa32020-01-28 20:58:50 -05001692
Neha Sharma96b7bf22020-06-15 10:37:32 +00001693 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001694
1695 return nil
1696}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001697
npujarec5762e2020-01-01 14:08:48 +05301698func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001699 var uniID uint32
1700 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301701 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001702 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001703 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001704 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001705 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001706 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001707 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001708 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001709 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001710 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001711 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001712 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001713 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001714 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001715 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001716 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001717 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001718 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301719 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001720 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1721 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001722 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301723 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001724 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001725 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001726 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 +00001727 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001728 }
1729 return nil
1730}
1731
Devmalya Paul495b94a2019-08-27 19:42:00 -04001732// 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 +05301733func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001734 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001735 /* Clear the KV store data associated with the all the UNI ports
1736 This clears up flow data and also resource map data for various
1737 other pon resources like alloc_id and gemport_id
1738 */
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001739 dh.cleanupDeviceResources(ctx)
1740 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 -04001741 // Stop the Stats collector
1742 dh.stopCollector <- true
1743 // stop the heartbeat check routine
1744 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301745 dh.lockDevice.RLock()
1746 // Stop the read indication only if it the routine is active
1747 if dh.isReadIndicationRoutineActive {
1748 dh.stopIndications <- true
1749 }
1750 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001751 dh.removeOnuIndicationChannels(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001752 //Reset the state
1753 if dh.Client != nil {
1754 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301755 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001756 }
1757 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001758 // There is no need to update the core about operation status and connection status of the OLT.
1759 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1760 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1761 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001762
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001763 return nil
1764}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001765func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001766
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001767 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301768 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001769 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001770 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001771 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001772 for i, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301773 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001774 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001775 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001776 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301777 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301778 // Clear flowids for gem cache.
1779 for _, gem := range onu.GemPorts {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001780 dh.resourceMgr[ponPort].DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301781 }
1782 onuID[0] = onu.OnuID
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001783 dh.resourceMgr[ponPort].FreeonuID(ctx, ponPort, onuID)
1784 err = dh.resourceMgr[ponPort].DelOnuGemInfo(ctx, ponPort, onu.OnuID)
1785 if err != nil {
1786 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
1787 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301788 }
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001789 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1790 logger.Debug(ctx, err)
1791 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001792 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001793 }
A R Karthick1f85b802019-10-11 05:06:05 +00001794
Devmalya Paul495b94a2019-08-27 19:42:00 -04001795 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301796 dh.onus.Range(func(key interface{}, value interface{}) bool {
1797 dh.onus.Delete(key)
1798 return true
1799 })
1800
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001801 /*Delete discovered ONU map for the device*/
1802 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1803 dh.discOnus.Delete(key)
1804 return true
1805 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001806}
1807
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001808//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001809func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001810 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301811 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001812 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001813 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001814 return nil
1815}
1816
David K. Bainbridge794735f2020-02-11 21:01:37 -08001817func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001818 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001819 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001820 "packet-indication": *packetIn,
1821 "device-id": dh.device.Id,
1822 "packet": hex.EncodeToString(packetIn.Pkt),
1823 })
1824 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001825 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001826 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001827 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001828 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001829 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001830 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001831 "logical-port-num": logicalPortNum,
1832 "device-id": dh.device.Id,
1833 "packet": hex.EncodeToString(packetIn.Pkt),
1834 })
1835 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001836
Neha Sharma8f4e4322020-08-06 10:51:53 +00001837 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 +05301838 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001839 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301840 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001841 "device-id": dh.device.Id,
1842 "packet": hex.EncodeToString(packetIn.Pkt),
1843 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001844 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001845
Matteo Scandolo92186242020-06-12 10:54:18 -07001846 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001847 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001848 "packet": hex.EncodeToString(packetIn.Pkt),
1849 "device-id": dh.device.Id,
1850 })
1851 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001852 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001853}
1854
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001855// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301856func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001857 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001858 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001859 "device-id": dh.device.Id,
1860 "egress-port-no": egressPortNo,
1861 "pkt-length": len(packet.Data),
1862 "packet": hex.EncodeToString(packet.Data),
1863 })
1864 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001865
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001866 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001867 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001868 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1869 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301870 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1871 // Do not packet-out lldp packets on uni port.
1872 // ONOS has no clue about uni/nni ports, it just packets out on all
1873 // available ports on the Logical Switch. It should not be interested
1874 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001875 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001876 "device-id": dh.device.Id,
1877 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301878 return nil
1879 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001880 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1881 if innerEthType == 0x8100 {
1882 // q-in-q 802.1ad or 802.1q double tagged packet.
1883 // slice out the outer tag.
1884 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001885 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001886 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001887 "packet-data": hex.EncodeToString(packet.Data),
1888 "device-id": dh.device.Id,
1889 })
1890 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001891 }
1892 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001893 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1894 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001895 uniID := UniIDFromPortNum(uint32(egressPortNo))
1896
Girish Gowdra9602eb42020-09-09 15:50:39 -07001897 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001898 if err != nil {
1899 // In this case the openolt agent will receive the gemPortID as 0.
1900 // The agent tries to retrieve the gemPortID in this case.
1901 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001902 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001903 "intf-id": intfID,
1904 "onu-id": onuID,
1905 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001906 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301907 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001908 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001909 }
1910
1911 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001912 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001913 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001914 "egress-port-no": egressPortNo,
1915 "intf-id": intfID,
1916 "onu-id": onuID,
1917 "uni-id": uniID,
1918 "gem-port-id": gemPortID,
1919 "packet": hex.EncodeToString(packet.Data),
1920 "device-id": dh.device.Id,
1921 })
1922 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001923
npujarec5762e2020-01-01 14:08:48 +05301924 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301925 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001926 "source": "adapter",
1927 "destination": "onu",
1928 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001929 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001930 "oni-id": onuID,
1931 "uni-id": uniID,
1932 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001933 "packet": hex.EncodeToString(packet.Data),
1934 "device-id": dh.device.Id,
1935 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001936 }
1937 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001938 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001939 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001940 return olterrors.NewErrInvalidValue(log.Fields{
1941 "egress-nni-port": egressPortNo,
1942 "device-id": dh.device.Id,
1943 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001944 }
1945 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001946
Matteo Scandolo92186242020-06-12 10:54:18 -07001947 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001948 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001949 "uplink-pkt": uplinkPkt,
1950 "packet": hex.EncodeToString(packet.Data),
1951 "device-id": dh.device.Id,
1952 })
1953 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001954
npujarec5762e2020-01-01 14:08:48 +05301955 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001956 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1957 "packet": hex.EncodeToString(packet.Data),
1958 "device-id": dh.device.Id,
1959 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001960 }
1961 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001962 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301963 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001964 "egressPortType": egressPortType,
1965 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301966 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001967 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001968 }
1969 return nil
1970}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001971
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001972func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1973 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001974}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301975
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001976func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001977
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301978 // start the heartbeat check towards the OLT.
1979 var timerCheck *time.Timer
1980
1981 for {
1982 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1983 select {
1984 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001985 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001986 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001987 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301988 if timerCheck == nil {
1989 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001990 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301991 }
1992 } else {
1993 if timerCheck != nil {
1994 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001995 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301996 }
1997 timerCheck = nil
1998 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001999 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05302000 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302001 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302002 }
2003 cancel()
2004 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002005 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302006 return
2007 }
2008 }
2009}
2010
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002011func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2012 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2013 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002014 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2015 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2016 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2017 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2018 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002019 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002020 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2021 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002022 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302023
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002024 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2025 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002026 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2027 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002028 _ = 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 -04002029 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002030 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002031 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002032 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002033
2034 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002035 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002036 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2037 device.OperStatus = voltha.OperStatus_UNKNOWN
2038 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2039
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002040 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002041 // Stop the Stats collector
2042 dh.stopCollector <- true
2043 // stop the heartbeat check routine
2044 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002045
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002046 dh.lockDevice.RLock()
2047 // Stop the read indication only if it the routine is active
2048 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2049 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2050 // on next execution of the readIndication routine.
2051 if dh.isReadIndicationRoutineActive {
2052 dh.stopIndications <- true
2053 }
2054 dh.lockDevice.RUnlock()
2055
Gamze Abakac2c32a62021-03-11 11:44:18 +00002056 //reset adapter reconcile flag
2057 dh.adapterPreviouslyConnected = false
2058
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002059 dh.transitionMap.Handle(ctx, DeviceInit)
2060
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302061 }
2062}
kesavand39e0aa32020-01-28 20:58:50 -05002063
2064// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002065func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2066 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2067 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002068}
2069
2070// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002071func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2072 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2073 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002074}
2075
kdarapu1afeceb2020-02-12 01:38:09 -05002076//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 +00002077func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2078 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002079 if port.GetType() == voltha.Port_ETHERNET_NNI {
2080 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002081 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302082 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302083 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002084 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002085 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002086 }
2087 // fetch interfaceid from PortNo
2088 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2089 ponIntf := &oop.Interface{IntfId: ponID}
2090 var operStatus voltha.OperStatus_Types
2091 if enablePort {
2092 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302093 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002094
2095 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302096 return olterrors.NewErrAdapter("pon-port-enable-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, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002102 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002103 } else {
2104 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302105 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002106 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302107 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002108 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002109 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002110 }
2111 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002112 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002113 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002114 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302115 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 +05302116 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302117 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002118 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002119 }
2120 return nil
2121}
2122
kdarapu1afeceb2020-02-12 01:38:09 -05002123//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002124func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002125 // Disable the port and update the oper_port_status to core
2126 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002127 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002128 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002129 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302130 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302131 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002132 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002133 }
2134 }
2135 }
2136 return nil
2137}
2138
2139//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002140func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2141 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2142 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002143 if port.Type == voltha.Port_ETHERNET_NNI {
2144 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002145 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002146 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002147 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002148 }
2149 }
2150 if port.Type == voltha.Port_PON_OLT {
2151 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002152 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002153 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002154 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002155 }
2156 }
2157 }
2158}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002159
2160// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002161func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002162 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002163 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2164 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002165
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002166 var sn *oop.SerialNumber
2167 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002168 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302169 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002170 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302171 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002172 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002173 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002174
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002175 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002176 //clear PON resources associated with ONU
2177 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2178 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2179 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2180 "device-id": dh.device.Id,
2181 "intf-id": intfID,
2182 "onuID": onuID,
2183 "err": err})
2184 } else {
2185 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2186 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2187 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2188 "device-id": dh.device.Id,
2189 "onu-device": onu,
2190 "err": err})
2191 }
2192 // Clear flowids for gem cache.
2193 for _, gem := range onuGem.GemPorts {
2194 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2195 }
Girish Gowdra197acc12021-08-16 10:59:45 -07002196 if err := dh.flowMgr[intfID].RemoveOnuInfoFromFlowMgrCacheAndKvStore(ctx, intfID, onuID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002197 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2198 "intf-id": intfID,
2199 "onu-device": onu,
2200 "onu-gem": onuGem,
2201 "err": err})
2202 //Not returning error on cleanup.
2203 }
2204 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
2205 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuGem.OnuID})
2206 }
2207 dh.onus.Delete(onuKey)
2208 dh.discOnus.Delete(onuSn)
2209
2210 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002211 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302212 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302213 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002214 "onu-id": onuID}, err).Log()
2215 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002216
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002217 return nil
2218}
Girish Gowdracefae192020-03-19 18:14:10 -07002219
2220func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002221 for _, field := range flow_utils.GetOfbFields(flow) {
2222 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002223 return field.GetPort()
2224 }
2225 }
2226 return InvalidPort
2227}
2228
2229func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002230 for _, action := range flow_utils.GetActions(flow) {
2231 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002232 if out := action.GetOutput(); out != nil {
2233 return out.GetPort()
2234 }
2235 }
2236 }
2237 return InvalidPort
2238}
2239
Girish Gowdracefae192020-03-19 18:14:10 -07002240func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2241 inPort := getInPortFromFlow(flow)
2242 outPort := getOutPortFromFlow(flow)
2243
2244 if inPort == InvalidPort || outPort == InvalidPort {
2245 return inPort, outPort
2246 }
2247
2248 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2249 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2250 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002251 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002252 return uniPort, outPort
2253 }
2254 }
2255 } else {
2256 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2257 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002258 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002259 return inPort, uniPort
2260 }
2261 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2262 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002263 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002264 return uniPort, outPort
2265 }
2266 }
2267 }
2268
2269 return InvalidPort, InvalidPort
2270}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002271
2272func extractOmciTransactionID(omciPkt []byte) uint16 {
2273 if len(omciPkt) > 3 {
2274 d := omciPkt[0:2]
2275 transid := binary.BigEndian.Uint16(d)
2276 return transid
2277 }
2278 return 0
2279}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002280
2281// StoreOnuDevice stores the onu parameters to the local cache.
2282func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2283 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2284 dh.onus.Store(onuKey, onuDevice)
2285}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002286
Neha Sharma8f4e4322020-08-06 10:51:53 +00002287func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002288 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002289 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002290 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002291 resp := new(voltha.ReturnValues)
2292 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002293 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002294 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002295 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2296 return nil, err
2297 }
2298 ID = device.ProxyAddress.GetOnuId()
2299 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2300 valueparam.Onu = &Onu
2301 valueparam.Value = value
2302
2303 // This API is unsupported until agent patch is added
2304 resp.Unsupported = uint32(value)
2305 _ = ctx
2306
2307 // Uncomment this code once agent changes are complete and tests
2308 /*
2309 resp, err = dh.Client.GetValue(ctx, valueparam)
2310 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002311 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002312 return nil, err
2313 }
2314 */
2315
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002316 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 -08002317 return resp, nil
2318}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002319
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002320func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002321 // Default to PON0
2322 var intfID uint32
2323 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002324 if inPort != InvalidPort && outPort != InvalidPort {
2325 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2326 }
2327 return intfID
2328}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002329
Mahir Gunyelb0046752021-02-26 13:51:05 -08002330func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2331 dh.perPonOnuIndicationChannelLock.Lock()
2332 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2333 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002334 return ch.indicationChannel
2335 }
2336 channels := onuIndicationChannels{
2337 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002338 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002339 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002340 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002341 stopChannel: make(chan struct{}),
2342 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002343 dh.perPonOnuIndicationChannel[intfID] = channels
2344 dh.perPonOnuIndicationChannelLock.Unlock()
2345 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002346 return channels.indicationChannel
2347
2348}
2349
Mahir Gunyelb0046752021-02-26 13:51:05 -08002350func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2351 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2352 dh.perPonOnuIndicationChannelLock.Lock()
2353 defer dh.perPonOnuIndicationChannelLock.Unlock()
2354 for _, v := range dh.perPonOnuIndicationChannel {
2355 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002356 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002357 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002358}
2359
Mahir Gunyelb0046752021-02-26 13:51:05 -08002360func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2361 ind := onuIndicationMsg{
2362 ctx: ctx,
2363 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002364 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002365 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002366 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002367 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002368}
2369
Mahir Gunyelb0046752021-02-26 13:51:05 -08002370func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002371 for {
2372 select {
2373 // process one indication per onu, before proceeding to the next one
2374 case onuInd := <-onuChannels.indicationChannel:
2375 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002376 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002377 switch onuInd.indication.Data.(type) {
2378 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002379 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002380 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2381 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002382 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002383 }
2384 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002385 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002386 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2387 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002388 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002389 }
2390 }
2391 case <-onuChannels.stopChannel:
2392 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2393 close(onuChannels.indicationChannel)
2394 return
2395 }
2396 }
2397}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002398
2399// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2400// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2401func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2402 // Step1 : Fill McastFlowOrGroupControlBlock
2403 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2404 // Step3 : Wait on response channel for response
2405 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002406 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002407 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2408 errChan := make(chan error)
2409 var groupID uint32
2410 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2411 ctx: ctx,
2412 flowOrGroupAction: action,
2413 flow: flow,
2414 group: group,
2415 errChan: &errChan,
2416 }
2417 if flow != nil {
2418 groupID = flow_utils.GetGroup(flow)
2419 } else if group != nil {
2420 groupID = group.Desc.GroupId
2421 } else {
2422 return errors.New("flow-and-group-both-nil")
2423 }
2424 // Derive the appropriate go routine to handle the request by a simple module operation.
2425 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2426 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2427 // Wait for handler to return error value
2428 err := <-errChan
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002429 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 -08002430 return err
2431}
2432
2433// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
2434func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock) {
2435 for {
2436 // block on the channel to receive an incoming mcast flow/group
2437 // process the flow completely before proceeding to handle the next flow
2438 mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel
2439 if mcastFlowOrGroupCb.flow != nil {
2440 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2441 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2442 log.Fields{"device-id": dh.device.Id,
2443 "flowToAdd": mcastFlowOrGroupCb.flow})
2444 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2445 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2446 // Pass the return value over the return channel
2447 *mcastFlowOrGroupCb.errChan <- err
2448 } else { // flow remove
2449 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2450 log.Fields{"device-id": dh.device.Id,
2451 "flowToRemove": mcastFlowOrGroupCb.flow})
2452 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2453 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2454 // Pass the return value over the return channel
2455 *mcastFlowOrGroupCb.errChan <- err
2456 }
2457 } else { // mcast group
2458 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2459 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2460 log.Fields{"device-id": dh.device.Id,
2461 "groupToAdd": mcastFlowOrGroupCb.group})
2462 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2463 // Pass the return value over the return channel
2464 *mcastFlowOrGroupCb.errChan <- err
2465 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2466 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2467 log.Fields{"device-id": dh.device.Id,
2468 "groupToModify": mcastFlowOrGroupCb.group})
2469 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2470 // Pass the return value over the return channel
2471 *mcastFlowOrGroupCb.errChan <- err
2472 } else { // group remove
2473 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2474 log.Fields{"device-id": dh.device.Id,
2475 "groupToRemove": mcastFlowOrGroupCb.group})
2476 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2477 // Pass the return value over the return channel
2478 *mcastFlowOrGroupCb.errChan <- err
2479 }
2480 }
2481 }
2482}
kesavand62126212021-01-12 04:56:06 -05002483
2484func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2485
2486 singleValResp := extension.SingleGetValueResponse{
2487 Response: &extension.GetValueResponse{
2488 Response: &extension.GetValueResponse_PortCoutners{
2489 PortCoutners: &extension.GetOltPortCountersResponse{},
2490 },
2491 },
2492 }
2493
2494 errResp := func(status extension.GetValueResponse_Status,
2495 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2496 return &extension.SingleGetValueResponse{
2497 Response: &extension.GetValueResponse{
2498 Status: status,
2499 ErrReason: reason,
2500 },
2501 }
2502 }
2503
2504 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2505 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2506 //send error response
2507 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2508 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2509 }
2510 statIndChn := make(chan bool, 1)
2511 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2512 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2513 //request openOlt agent to send the the port statistics indication
2514
2515 go func() {
2516 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2517 if err != nil {
2518 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2519 }
2520 }()
2521 select {
2522 case <-statIndChn:
2523 //indication received for ports stats
2524 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2525 case <-time.After(oltPortInfoTimeout * time.Second):
2526 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2527 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2528 case <-ctx.Done():
2529 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2530 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2531 }
2532 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2533 //get nni stats
2534 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2535 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2536 cmnni := dh.portStats.collectNNIMetrics(intfID)
2537 if cmnni == nil {
2538 //TODO define the error reason
2539 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2540 }
2541 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2542 return &singleValResp
2543
2544 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2545 // get pon stats
2546 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2547 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2548 cmpon := dh.portStats.collectPONMetrics(intfID)
2549 if cmpon == nil {
2550 //TODO define the error reason
2551 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2552 }
2553 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2554 return &singleValResp
2555 }
2556 }
2557 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2558}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302559
2560func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2561
2562 singleValResp := extension.SingleGetValueResponse{
2563 Response: &extension.GetValueResponse{
2564 Response: &extension.GetValueResponse_OnuPonCounters{
2565 OnuPonCounters: &extension.GetOnuCountersResponse{},
2566 },
2567 },
2568 }
2569
2570 errResp := func(status extension.GetValueResponse_Status,
2571 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2572 return &extension.SingleGetValueResponse{
2573 Response: &extension.GetValueResponse{
2574 Status: status,
2575 ErrReason: reason,
2576 },
2577 }
2578 }
2579 intfID := onuPonInfo.IntfId
2580 onuID := onuPonInfo.OnuId
2581 onuKey := dh.formOnuKey(intfID, onuID)
2582
2583 if _, ok := dh.onus.Load(onuKey); !ok {
2584 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2585 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2586 }
2587 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2588 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2589 if cmnni == nil {
2590 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2591 }
2592 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2593 return &singleValResp
2594
2595}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002596
2597func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2598
2599 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2600 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2601 if err != nil {
2602 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2603 return generateSingleGetValueErrorResponse(err)
2604 }
2605 return &extension.SingleGetValueResponse{
2606 Response: &extension.GetValueResponse{
2607 Status: extension.GetValueResponse_OK,
2608 Response: &extension.GetValueResponse_RxPower{
2609 RxPower: &extension.GetRxPowerResponse{
2610 IntfId: rxPowerRequest.IntfId,
2611 OnuId: rxPowerRequest.OnuId,
2612 Status: rxPower.Status,
2613 FailReason: rxPower.FailReason.String(),
2614 RxPower: rxPower.RxPowerMeanDbm,
2615 },
2616 },
2617 },
2618 }
2619}
2620
2621func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2622 errResp := func(status extension.GetValueResponse_Status,
2623 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2624 return &extension.SingleGetValueResponse{
2625 Response: &extension.GetValueResponse{
2626 Status: status,
2627 ErrReason: reason,
2628 },
2629 }
2630 }
2631
2632 if err != nil {
2633 if e, ok := status.FromError(err); ok {
2634 switch e.Code() {
2635 case codes.Internal:
2636 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2637 case codes.DeadlineExceeded:
2638 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2639 case codes.Unimplemented:
2640 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2641 case codes.NotFound:
2642 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2643 }
2644 }
2645 }
2646
2647 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2648}