blob: 96d67b7070b971beb8e885be11a5a76025361022 [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 Gowdraa09aeab2020-09-14 16:30:52 -070038 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080039 "github.com/opencord/voltha-lib-go/v4/pkg/config"
Himani Chawlacd407802020-12-10 12:08:59 +053040 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
Girish Gowdra491a9c62021-01-06 16:43:07 -080041 flow_utils "github.com/opencord/voltha-lib-go/v4/pkg/flows"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070042 "github.com/opencord/voltha-lib-go/v4/pkg/log"
43 "github.com/opencord/voltha-lib-go/v4/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
manikkaraj kbf256be2019-03-25 00:13:48 +053085 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053086
Girish Gowdra3ab6d212020-03-24 17:33:15 -070087 discOnus sync.Map
88 onus sync.Map
89 portStats *OpenOltStatisticsMgr
90 metrics *pmmetrics.PmMetrics
91 stopCollector chan bool
92 stopHeartbeatCheck chan bool
93 activePorts sync.Map
94 stopIndications chan bool
95 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070096
Mahir Gunyelb0046752021-02-26 13:51:05 -080097 totalPonPorts uint32
98 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
99 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800100
101 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
102 // A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
103 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
Gamze Abakac2c32a62021-03-11 11:44:18 +0000104
105 adapterPreviouslyConnected bool
106 agentPreviouslyConnected bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700107}
108
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700109//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700110type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700111 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700112 deviceType string
113 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700114 onuID uint32
115 intfID uint32
116 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530117 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400118 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700119}
120
Mahir Gunyelb0046752021-02-26 13:51:05 -0800121type onuIndicationMsg struct {
122 ctx context.Context
123 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800124}
125
126type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800127 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800128 stopChannel chan struct{}
129}
130
Girish Gowdra491a9c62021-01-06 16:43:07 -0800131//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
132//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
133//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
134//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
135type McastFlowOrGroupControlBlock struct {
136 ctx context.Context // Flow/group handler context
137 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
138 flow *voltha.OfpFlowStats // Flow message (can be nil or valid flow)
139 group *voltha.OfpGroupEntry // Group message (can be nil or valid group)
140 errChan *chan error // channel to report the mcast Flow/group handling error
141}
142
Naga Manjunath7615e552019-10-11 22:35:47 +0530143var pmNames = []string{
144 "rx_bytes",
145 "rx_packets",
146 "rx_mcast_packets",
147 "rx_bcast_packets",
148 "tx_bytes",
149 "tx_packets",
150 "tx_mcast_packets",
151 "tx_bcast_packets",
152}
153
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700154//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530155func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700156 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700157 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700158 device.deviceType = deviceTp
159 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700160 device.onuID = onuID
161 device.intfID = intfID
162 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530163 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700164 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530165}
166
167//NewDeviceHandler creates a new device handler
Himani Chawlacd407802020-12-10 12:08:59 +0530168func 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 -0700169 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800170 dh.cm = cm
cuilin20187b2a8c32019-03-26 19:52:28 -0700171 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400172 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400173 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700174 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700175 dh.device = cloned
176 dh.openOLT = adapter
177 dh.exitChannel = make(chan int, 1)
178 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530179 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530180 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530181 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 -0500182 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400183 dh.stopIndications = make(chan bool, 1)
Mahir Gunyelb0046752021-02-26 13:51:05 -0800184 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800185 // Create a slice of buffered channels for handling concurrent mcast flow/group.
186 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
187 for i := range dh.incomingMcastFlowOrGroup {
188 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
189 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
190 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
191 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
192 // for incoming mcast flow/group to be processed serially.
193 go dh.mcastFlowOrGroupChannelHandlerRoutine(dh.incomingMcastFlowOrGroup[i])
194 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700195 //TODO initialize the support classes.
196 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530197}
198
199// start save the device to the data model
200func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700201 dh.lockDevice.Lock()
202 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000203 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700204 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000205 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530206}
207
208// stop stops the device dh. Not much to do for now
209func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700210 dh.lockDevice.Lock()
211 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000212 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700213 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000214 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530215}
216
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400217func macifyIP(ip net.IP) string {
218 if len(ip) > 0 {
219 oct1 := strconv.FormatInt(int64(ip[12]), 16)
220 oct2 := strconv.FormatInt(int64(ip[13]), 16)
221 oct3 := strconv.FormatInt(int64(ip[14]), 16)
222 oct4 := strconv.FormatInt(int64(ip[15]), 16)
223 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
224 }
225 return ""
226}
227
Neha Sharma96b7bf22020-06-15 10:37:32 +0000228func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400229 var genmac string
230 var addr net.IP
231 var ips []string
232 var err error
233
Neha Sharma96b7bf22020-06-15 10:37:32 +0000234 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400235
236 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000237 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400238
239 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000240 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400241 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000242 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400243 }
244 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000245 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530246 log.Fields{"host": ips[0],
247 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400248 return genmac, nil
249 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000250 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400251 }
252
253 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000254 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530255 log.Fields{"host": host,
256 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400257 return genmac, nil
258}
259
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530260func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700261 slist := strings.Split(mac, ":")
262 result := make([]uint32, len(slist))
263 var err error
264 var tmp int64
265 for index, val := range slist {
266 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
267 return []uint32{1, 2, 3, 4, 5, 6}
268 }
269 result[index] = uint32(tmp)
270 }
271 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530272}
273
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700274//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 -0800275func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530276
David K. Bainbridge794735f2020-02-11 21:01:37 -0800277 switch portType {
278 case voltha.Port_ETHERNET_NNI:
279 return fmt.Sprintf("nni-%d", portNum), nil
280 case voltha.Port_PON_OLT:
281 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700282 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800283
Girish Kumarf26e4882020-03-05 06:49:10 +0000284 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530285}
286
Neha Sharma96b7bf22020-06-15 10:37:32 +0000287func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000288 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700289 if state == "up" {
290 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500291 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500292 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700293 } else {
294 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500295 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700296 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700297 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400298 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800299 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000300 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400301 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500302
Neha Sharma8f4e4322020-08-06 10:51:53 +0000303 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 +0000304 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000305 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 -0400306 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
307 "device-id": dh.device.Id,
308 "port-type": portType,
309 "port-number": portNum,
310 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500311 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400312 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500313 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400314 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700315 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400316 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700317 PortNo: portNum,
318 Label: label,
319 Type: portType,
320 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700321 OfpPort: &of.OfpPort{
322 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
323 Config: 0,
324 State: uint32(of.OfpPortState_OFPPS_LIVE),
325 Curr: capacity,
326 Advertised: capacity,
327 Peer: capacity,
328 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
329 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
330 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700331 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000332 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700333 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000334 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000335 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800336 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000337 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400338 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000339 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530340 return nil
341}
342
Kent Hagermane6ff1012020-07-14 15:07:53 -0400343func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000344 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530345 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400346 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
347 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530348 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800349 dh.lockDevice.Lock()
350 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530351 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530352}
353
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700354// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530355// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800356func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000357 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700358 defer func() {
359 dh.lockDevice.Lock()
360 dh.isReadIndicationRoutineActive = false
361 dh.lockDevice.Unlock()
362 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700363 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700364 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700365 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700366 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400367
David Bainbridgef5879ca2019-12-13 21:17:54 +0000368 // Create an exponential backoff around re-enabling indications. The
369 // maximum elapsed time for the back off is set to 0 so that we will
370 // continue to retry. The max interval defaults to 1m, but is set
371 // here for code clarity
372 indicationBackoff := backoff.NewExponentialBackOff()
373 indicationBackoff.MaxElapsedTime = 0
374 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700375
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700376 dh.lockDevice.Lock()
377 dh.isReadIndicationRoutineActive = true
378 dh.lockDevice.Unlock()
379
Girish Gowdra3f974912020-03-23 20:35:18 -0700380Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700381 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400382 select {
383 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000384 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700385 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400386 default:
387 indication, err := indications.Recv()
388 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000389 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530390 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530391 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400392 // Use an exponential back off to prevent getting into a tight loop
393 duration := indicationBackoff.NextBackOff()
394 if duration == backoff.Stop {
395 // If we reach a maximum then warn and reset the backoff
396 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000397 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530398 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530399 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400400 indicationBackoff.Reset()
401 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700402
403 // On failure process a backoff timer while watching for stopIndications
404 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700405 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700406 select {
407 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000408 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700409 if !backoffTimer.Stop() {
410 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700411 }
412 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700413 case <-backoffTimer.C:
414 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700415 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700416 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
417 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400418 }
419 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000420 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530421 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000422 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530423 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530424 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700425 // Close the stream, and re-initialize it
426 if err = indications.CloseSend(); err != nil {
427 // Ok to ignore here, because we landed here due to a problem on the stream
428 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000429 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530430 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530431 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700432 }
433 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
434 return err
435 }
436 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400437 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530438 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400439 // Reset backoff if we have a successful receive
440 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400441 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700442 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000443 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530444 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530445 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400446 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400447 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400448 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700449 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700450 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700451 // Close the send stream
452 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700453
Girish Gowdra3f974912020-03-23 20:35:18 -0700454 return nil
455}
456
457func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700458 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700459 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
460 if err != nil {
461 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
462 }
463 if indications == nil {
464 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
465 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700466 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700467 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400468}
469
470// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
471func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
472 switch indication.Data.(type) {
473 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
474 return true
475
476 default:
477 return false
478 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700479}
480
David K. Bainbridge794735f2020-02-11 21:01:37 -0800481func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700482 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000483 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530484 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700485 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530486 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700487 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000488 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000489 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530490 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000491 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800492 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000493 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800494 }
495 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700496}
497
David K. Bainbridge794735f2020-02-11 21:01:37 -0800498// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530499func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700500 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700501 switch indication.Data.(type) {
502 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000503 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
504 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700505 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 -0800506 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400507 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800508 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700509 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000510 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
511 defer span.Finish()
512
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700513 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800514 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000515 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400516 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800517 }
518 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000519 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700520 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000521 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
522 defer span.Finish()
523
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700524 intfOperInd := indication.GetIntfOperInd()
525 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800526 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000527 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400528 _ = 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 -0800529 }
530 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400531 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
532 logger.Warn(ctx, err)
533 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700534 } else if intfOperInd.GetType() == "pon" {
535 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
536 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800537 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000538 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400539 _ = 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 -0800540 }
541 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000542 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700543 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000544 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530545 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530546 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700547 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000548 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
549 defer span.Finish()
550
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700551 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800553 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800554 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700555 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000556 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
557 defer span.Finish()
558
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700559 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000560 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800561 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800562 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700563 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000564 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
565 defer span.Finish()
566
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700567 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000568 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 -0800569 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000570 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400571 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800572 }
573 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700574 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000575 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
576 defer span.Finish()
577
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700578 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000579 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700580 "intf-type": pktInd.IntfId,
581 "intf-id": pktInd.IntfId,
582 "gem-port-id": pktInd.GemportId,
583 "port-no": pktInd.PortNo,
584 "device-id": dh.device.Id,
585 })
586
587 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000588 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700589 "intf-type": pktInd.IntfId,
590 "intf-id": pktInd.IntfId,
591 "gem-port-id": pktInd.GemportId,
592 "port-no": pktInd.PortNo,
593 "packet": hex.EncodeToString(pktInd.Pkt),
594 "device-id": dh.device.Id,
595 })
596 }
597
David K. Bainbridge794735f2020-02-11 21:01:37 -0800598 go func() {
599 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400600 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800601 }
602 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700603 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000604 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
605 defer span.Finish()
606
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700607 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700608 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700609 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000610 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
611 defer span.Finish()
612
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700613 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000614 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700615 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000616 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
617 defer span.Finish()
618
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700619 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000620 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
621 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700622 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530623}
624
625// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530626func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530627 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000628 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530629
Girish Gowdru0c588b22019-04-23 23:24:56 -0400630 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530631 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400632 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000633 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400634 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000635
636 //Clear olt communication failure event
637 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
638 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700639 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000640 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
641
Gamze Abakac2c32a62021-03-11 11:44:18 +0000642 //check adapter and agent reconcile status
643 //reboot olt if needed (olt disconnection case)
644 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
645 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
646 log.Fields{
647 "device-id": dh.device.Id,
648 "adapter-status": dh.adapterPreviouslyConnected,
649 "agent-status": dh.agentPreviouslyConnected,
650 })
651 _ = dh.RebootDevice(ctx, dh.device)
652 }
653
Girish Gowdru0c588b22019-04-23 23:24:56 -0400654 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530655}
656
657// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530658func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000659 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400660
npujarec5762e2020-01-01 14:08:48 +0530661 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400662 if err != nil || device == nil {
663 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000664 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400665 }
666
667 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400668
669 //Update the device oper state and connection status
670 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800671 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400672 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800673 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400674
David K. Bainbridge794735f2020-02-11 21:01:37 -0800675 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000676 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400677 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400678
679 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530680 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400681 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000682 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400683 }
684 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400685 // Update onu state as down in onu adapter
686 onuInd := oop.OnuIndication{}
687 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800688 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300689 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800690 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400691 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300692 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800693 "onu-indicator": onuInd,
694 "device-type": onuDevice.Type,
695 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700696 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800697 } else {
698 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 -0700699 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400700 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800701 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700702 /* Discovered ONUs entries need to be cleared , since after OLT
703 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530704 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800705 dh.lockDevice.Unlock()
706
Neha Sharma96b7bf22020-06-15 10:37:32 +0000707 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700708 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530709}
710
711// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530712func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400713 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000714 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
715 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
716 grpc.WithInsecure(),
717 grpc.WithBlock(),
718 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000719 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000720 )),
721 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000722 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000723 )))
724
725 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530726 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530727 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000728 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400729 }
730 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530731}
732
733// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530734func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400735 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530736 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400737 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530738}
739
740// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530741func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530742 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000743 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400744
745 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530746 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
747 if err != nil || device == nil {
748 /*TODO: needs to handle error scenarios */
749 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
750 }
751 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000752 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400753
754 cloned := proto.Clone(device).(*voltha.Device)
755 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
756 cloned.OperStatus = voltha.OperStatus_UNKNOWN
757 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530758 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
759 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 -0400760 }
761
Chaitrashree G S44124192019-08-07 20:21:36 -0400762 // 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 +0530763 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400764 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530765 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400766 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400767 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
768 // all the modules initialized and ready to handle incoming ONUs.
769
Thomas Lee S985938d2020-05-04 11:40:41 +0530770 err = dh.initializeDeviceHandlerModules(ctx)
771 if err != nil {
772 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 -0400773 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400774
775 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800776 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530777 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400778 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800779 }
780 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700781
782 go startHeartbeatCheck(ctx, dh)
783
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400784 return nil
785 }
786
Neha Sharma8f4e4322020-08-06 10:51:53 +0000787 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400788 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400789 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400790 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400791 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400792 dh.populateActivePorts(ctx, ports)
793 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
794 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400795 }
796
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400797 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530798 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 -0400799 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530800
cuilin20187b2a8c32019-03-26 19:52:28 -0700801 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800802 go func() {
803 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400804 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800805 }
806 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000807 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000808
809 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000810 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000811 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700812
813 go startHeartbeatCheck(ctx, dh)
814
cuilin20187b2a8c32019-03-26 19:52:28 -0700815 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530816}
817
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400818func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000819 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400820
821 if err != nil {
822 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
823 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700824 dh.totalPonPorts = deviceInfo.GetPonPorts()
Gamze Abakac2c32a62021-03-11 11:44:18 +0000825 dh.agentPreviouslyConnected = deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700826
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400827 // Instantiate resource manager
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800828 if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr == nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400829 return olterrors.ErrResourceManagerInstantiating
830 }
831
Girish Gowdra9602eb42020-09-09 15:50:39 -0700832 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400833
Girish Gowdra9602eb42020-09-09 15:50:39 -0700834 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
835 for i := range dh.flowMgr {
836 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700837 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700838 return olterrors.ErrResourceManagerInstantiating
839 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400840 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700841
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400842 /* TODO: Instantiate Alarm , stats , BW managers */
843 /* Instantiating Event Manager to handle Alarms and KPIs */
844 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
845
846 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000847 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400848
849 return nil
850
851}
852
Neha Sharma96b7bf22020-06-15 10:37:32 +0000853func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400854 var err error
855 var deviceInfo *oop.DeviceInfo
856
Neha Sharma8f4e4322020-08-06 10:51:53 +0000857 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400858
859 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000860 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400861 }
862 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000863 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400864 }
865
Neha Sharma96b7bf22020-06-15 10:37:32 +0000866 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400867 dh.device.Root = true
868 dh.device.Vendor = deviceInfo.Vendor
869 dh.device.Model = deviceInfo.Model
870 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
871 dh.device.HardwareVersion = deviceInfo.HardwareVersion
872 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
873
874 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000875 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400876 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000877 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400878 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000879 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400880 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000881 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400882 dh.device.MacAddress = genmac
883 } else {
884 dh.device.MacAddress = deviceInfo.DeviceId
885 }
886
887 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000888 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000889 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400890 }
891
892 return deviceInfo, nil
893}
894
Neha Sharma96b7bf22020-06-15 10:37:32 +0000895func startCollector(ctx context.Context, dh *DeviceHandler) {
896 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530897 for {
898 select {
899 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000900 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530901 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000902 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700903
Neha Sharma8f4e4322020-08-06 10:51:53 +0000904 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400905 if err != nil {
906 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
907 continue
908 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530909 for _, port := range ports {
910 // NNI Stats
911 if port.Type == voltha.Port_ETHERNET_NNI {
912 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
913 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000914 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000915 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000916 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530917 }
918 // PON Stats
919 if port.Type == voltha.Port_PON_OLT {
920 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
921 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
922 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000923 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000924 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530925 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000926 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000927
928 //ONU & Gem Stats
929 onuGemInfo := dh.flowMgr[intfID].onuGemInfo
930 if len(onuGemInfo) != 0 {
931 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfo)
932 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500933 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530934 }
935 }
936 }
937}
938
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700939//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530940func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400941 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000942 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530943 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530944
945 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400946 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
947 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530948 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530949}
950
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700951//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530952func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700953 return &ic.SwitchCapability{
954 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530955 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700956 HwDesc: "open_pon",
957 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700958 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700959 },
960 SwitchFeatures: &of.OfpSwitchFeatures{
961 NBuffers: 256,
962 NTables: 2,
963 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
964 of.OfpCapabilities_OFPC_TABLE_STATS |
965 of.OfpCapabilities_OFPC_PORT_STATS |
966 of.OfpCapabilities_OFPC_GROUP_STATS),
967 },
968 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530969}
970
Neha Sharma96b7bf22020-06-15 10:37:32 +0000971func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
972 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 -0700973 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700974 var deviceID string
975 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700976
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400977 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700978 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000979 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 -0700980 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
981 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400982
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700983 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530984
985 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
986
Neha Sharma96b7bf22020-06-15 10:37:32 +0000987 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 -0700988 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700989 kwargs := make(map[string]interface{})
990 kwargs["onu_id"] = omciInd.OnuId
991 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700992
Neha Sharma8f4e4322020-08-06 10:51:53 +0000993 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700994 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530995 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700996 "intf-id": omciInd.IntfId,
997 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700998 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700999 deviceType = onuDevice.Type
1000 deviceID = onuDevice.Id
1001 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1002 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301003 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001004 } else {
1005 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001006 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 +05301007 deviceType = onuInCache.(*OnuDevice).deviceType
1008 deviceID = onuInCache.(*OnuDevice).deviceID
1009 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001010 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001011
1012 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001013 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001014 ic.InterAdapterMessageType_OMCI_REQUEST, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001015 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301016 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001017 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001018 "destination": deviceType,
1019 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001020 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001021 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001022 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301023}
1024
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001025//ProcessInterAdapterMessage sends the proxied messages to the target device
1026// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1027// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001028func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1029 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001030 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001031 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -07001032 fromTopic := msg.Header.FromTopic
1033 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001034 toDeviceID := msg.Header.ToDeviceId
1035 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001036
Neha Sharma96b7bf22020-06-15 10:37:32 +00001037 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 -07001038
1039 msgBody := msg.GetBody()
1040
1041 omciMsg := &ic.InterAdapterOmciMessage{}
1042 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001043 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001044 }
1045
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001046 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001047 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001048 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301049 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001050 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001051 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001052 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001053 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1054 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301055 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001056 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001057 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001058 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001059 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001060 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1061 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301062 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001063 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001064 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001065 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001066 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001067 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001068 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001069 }
1070 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301071}
1072
Neha Sharma96b7bf22020-06-15 10:37:32 +00001073func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001074 var intfID uint32
1075 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001076 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001077 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001078 intfID = onuDevice.ProxyAddress.GetChannelId()
1079 onuID = onuDevice.ProxyAddress.GetOnuId()
1080 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001081 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001082 intfID = omciMsg.GetProxyAddress().GetChannelId()
1083 onuID = omciMsg.GetProxyAddress().GetOnuId()
1084 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001085 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001086 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001087 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 -08001088
Thomas Lee S94109f12020-03-03 16:39:29 +05301089 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001090 "intf-id": intfID,
1091 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001092 }
1093
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001094 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1095 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001096 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001097 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1098 hex.Encode(hexPkt, omciMsg.Message)
1099 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1100
1101 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1102 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1103 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001104 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001105 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001106
Neha Sharma8f4e4322020-08-06 10:51:53 +00001107 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001108 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301109 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001110 "intf-id": intfID,
1111 "onu-id": onuID,
1112 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001113 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001114 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001115}
1116
David K. Bainbridge794735f2020-02-11 21:01:37 -08001117func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301118 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001119 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001120 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001121 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001122 // TODO: need resource manager
1123 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301124 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301125 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001126 st, _ := status.FromError(err)
1127 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001128 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1129
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001130 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301131 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001132 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001133 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001134 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001135 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001136 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001137}
1138
Mahir Gunyelb0046752021-02-26 13:51:05 -08001139func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001140 channelID := onuDiscInd.GetIntfId()
1141 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001142
Mahir Gunyelb0046752021-02-26 13:51:05 -08001143 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001144 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301145
cuilin20187b2a8c32019-03-26 19:52:28 -07001146 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001147 if sn != "" {
1148 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001149 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001150 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001151 }
1152
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301153 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001154 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001155 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301156
1157 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1158 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1159 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1160 OnuLosRaise event sent for it */
1161 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1162 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1163 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001164 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301165 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1166 "currentIntfId": onuDiscInd.GetIntfId()})
1167 // TODO:: Should we need to ignore raising OnuLosClear event
1168 // when onu connected to different PON?
1169 }
1170 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1171 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1172 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001173 go func() {
1174 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1175 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1176 }
1177 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301178 }
1179 return true
1180 })
1181
Neha Sharma96b7bf22020-06-15 10:37:32 +00001182 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001183 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001184 }
1185
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001186 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001187
1188 // check the ONU is already know to the OLT
1189 // NOTE the second time the ONU is discovered this should return a device
1190 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1191
1192 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001193 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 -08001194 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001195 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 -08001196 switch e.Code() {
1197 case codes.Internal:
1198 // this probably means NOT FOUND, so just create a new device
1199 onuDevice = nil
1200 case codes.DeadlineExceeded:
1201 // if the call times out, cleanup and exit
1202 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001203 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001204 }
1205 }
1206 }
1207
1208 if onuDevice == nil {
1209 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001210 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001211 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001212 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301213 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001214
Neha Sharma96b7bf22020-06-15 10:37:32 +00001215 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001216
1217 if err != nil {
1218 // if we can't create an ID in resource manager,
1219 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001220 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001221 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001222 "pon-intf-id": ponintfid,
1223 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001224 }
1225
Neha Sharma8f4e4322020-08-06 10:51:53 +00001226 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001227 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001228 dh.discOnus.Delete(sn)
1229 dh.resourceMgr.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 +05301230 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001231 "pon-intf-id": ponintfid,
1232 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001233 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001234 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().Unix()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001235 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1236 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001237 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301238 log.Fields{"onuDevice": onuDevice,
1239 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001240 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301241 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001242 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001243
1244 // we can now use the existing ONU Id
1245 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001246 //Insert the ONU into cache to use in OnuIndication.
1247 //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 +00001248 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001249 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301250 "intfId": onuDiscInd.GetIntfId(),
1251 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001252 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001253
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301254 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301255 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001256 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301257 log.Fields{"onu": onuDev,
1258 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001259
Kent Hagermane6ff1012020-07-14 15:07:53 -04001260 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301261 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001262 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001263 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001264 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001265 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001266 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301267 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001268 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001269 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001270 }
1271 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001272}
1273
Mahir Gunyelb0046752021-02-26 13:51:05 -08001274func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001275
1276 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001277 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001278 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001279 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001280 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001281 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301282 log.Fields{"onuId": onuInd.OnuId,
1283 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301284 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001285 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001286 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301287
David K. Bainbridge794735f2020-02-11 21:01:37 -08001288 errFields := log.Fields{"device-id": dh.device.Id}
1289
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301290 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1291
Mahir Gunyele77977b2019-06-27 05:36:22 -07001292 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1293 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001294 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001295 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001296 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001297 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1298 if serialNumber != "" {
1299 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001300 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001301 } else {
1302 kwargs["onu_id"] = onuInd.OnuId
1303 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001304 errFields["onu-id"] = onuInd.OnuId
1305 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001306 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001307 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001308 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001309
David K. Bainbridge794735f2020-02-11 21:01:37 -08001310 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001311 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001312 }
1313
David K. Bainbridge794735f2020-02-11 21:01:37 -08001314 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001315 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001316 "previousIntfId": onuDevice.ParentPortNo,
1317 "currentIntfId": ponPort})
1318 }
1319
1320 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001321 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301322 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1323 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301324 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001325 }
1326 if !foundInCache {
1327 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1328
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301329 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 -08001330
1331 }
kesavand7cf3a052020-08-28 12:49:18 +05301332 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001333 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
kesavand7cf3a052020-08-28 12:49:18 +05301334 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1335 }
1336 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001337 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001338 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001339 }
1340 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001341}
1342
Neha Sharma96b7bf22020-06-15 10:37:32 +00001343func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001344 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 -07001345 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1346 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1347 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1348 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001349 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001350 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1351 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001352 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001353 onuInd.OperState = "down"
1354 }
1355 }
1356
David K. Bainbridge794735f2020-02-11 21:01:37 -08001357 switch onuInd.OperState {
1358 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001359 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 -07001360 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301361 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001362 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001363 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301364 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001365 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001366 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001367 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001368 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001369 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001370 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001371 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 -04001372 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301373 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001374 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001375 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301376 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001377 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001378 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001379 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001380 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001381 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001382 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001383 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001384 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001385 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001386}
1387
cuilin20187b2a8c32019-03-26 19:52:28 -07001388func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1389 if serialNum != nil {
1390 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001391 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001392 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001393}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001394func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1395 decodedStr, err := hex.DecodeString(serialNum[4:])
1396 if err != nil {
1397 return nil, err
1398 }
1399 return &oop.SerialNumber{
1400 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001401 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001402 }, nil
1403}
cuilin20187b2a8c32019-03-26 19:52:28 -07001404
1405func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001406 if len(vendorSpecific) > 3 {
1407 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1408 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1409 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1410 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1411 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1412 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1413 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1414 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1415 return tmp
1416 }
1417 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001418}
1419
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001420//UpdateFlowsBulk upates the bulk flow
1421func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301422 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001423}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001424
1425//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001426func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1427 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301428 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001429 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301430 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001431 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001432 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001433 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001434 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001435 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001436 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001437 "intf-id": parentPort,
1438 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001439 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001440 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 -08001441 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301442}
1443
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001444// SendPacketInToCore sends packet-in to core
1445// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1446// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001447func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001448 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001449 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001450 "port": logicalPort,
1451 "packet": hex.EncodeToString(packetPayload),
1452 "device-id": dh.device.Id,
1453 })
1454 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001455 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 +05301456 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001457 "source": "adapter",
1458 "destination": "core",
1459 "device-id": dh.device.Id,
1460 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001461 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001462 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001463 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001464 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001465 "packet": hex.EncodeToString(packetPayload),
1466 "device-id": dh.device.Id,
1467 })
1468 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001469 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001470}
1471
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001472// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001473func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001474 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001475
1476 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1477 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001478 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001479 }
1480
Kent Hagermane6ff1012020-07-14 15:07:53 -04001481 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001482 metrics := dh.metrics.GetSubscriberMetrics()
1483 for _, m := range pmConfigs.Metrics {
1484 metrics[m.Name].Enabled = m.Enabled
1485
1486 }
1487 }
1488}
1489
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001490//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301491func (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 +00001492 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 +01001493
Girish Gowdra491a9c62021-01-06 16:43:07 -08001494 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001495 var errorsList []error
1496
Girish Gowdru0c588b22019-04-23 23:24:56 -04001497 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001498 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001499 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001500
Neha Sharma96b7bf22020-06-15 10:37:32 +00001501 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301502 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001503 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301504 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001505 if flow_utils.HasGroup(flow) {
1506 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1507 } else {
1508 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1509 }
Girish Gowdracefae192020-03-19 18:14:10 -07001510 if err != nil {
1511 errorsList = append(errorsList, err)
1512 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001513 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301514
1515 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001516 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001517 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301518 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001519 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301520 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001521 if flow_utils.HasGroup(flow) {
1522 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1523 } else {
1524 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1525 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001526 if err != nil {
1527 errorsList = append(errorsList, err)
1528 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301529 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001530 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001531
Girish Gowdracefae192020-03-19 18:14:10 -07001532 // 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 +00001533 if groups != nil {
1534 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001535 // err = dh.groupMgr.AddGroup(ctx, group)
1536 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001537 if err != nil {
1538 errorsList = append(errorsList, err)
1539 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001540 }
1541 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001542 // err = dh.groupMgr.ModifyGroup(ctx, group)
1543 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001544 if err != nil {
1545 errorsList = append(errorsList, err)
1546 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001547 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001548 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001549 // err = dh.groupMgr.DeleteGroup(ctx, group)
1550 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001551 if err != nil {
1552 errorsList = append(errorsList, err)
1553 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001554 }
1555 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001556 if len(errorsList) > 0 {
1557 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1558 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001559 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001560 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301561}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001562
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001563//DisableDevice disables the given device
1564//It marks the following for the given device:
1565//Device-Handler Admin-State : down
1566//Device Port-State: UNKNOWN
1567//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001568func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001569 /* On device disable ,admin state update has to be done prior sending request to agent since
1570 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001571 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001572 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001573 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001574 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001575 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001576 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001577 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001578 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001579 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001580 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301581
1582 dh.discOnus = sync.Map{}
1583 dh.onus = sync.Map{}
1584
Thomas Lee S85f37312020-04-03 17:06:12 +05301585 //stopping the stats collector
1586 dh.stopCollector <- true
1587
Neha Sharma96b7bf22020-06-15 10:37:32 +00001588 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001589 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301590 //Update device Admin state
1591 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001592 // 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 +00001593 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 -04001594 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001595 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001596 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001597 return nil
1598}
1599
Neha Sharma96b7bf22020-06-15 10:37:32 +00001600func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001601 // Update onu state as unreachable in onu adapter
1602 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301603 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001604 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001605 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001606 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "error": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001608 }
1609 if onuDevices != nil {
1610 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001611 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001612 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001613 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001614 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001615 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001616 }
1617
1618 }
1619 }
1620
1621}
1622
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001623//ReenableDevice re-enables the olt device after disable
1624//It marks the following for the given device:
1625//Device-Handler Admin-State : up
1626//Device Port-State: ACTIVE
1627//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001628func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001629 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301630 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001631 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301632 }
1633 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001634 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001635
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001636 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001637
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001638 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1639 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001640 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001641 }
1642 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001643 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001644 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001645 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001646 device.OperStatus = voltha.OperStatus_ACTIVE
1647 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001648
Neha Sharma8f4e4322020-08-06 10:51:53 +00001649 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 +05301650 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001651 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001652 "connect-status": device.ConnectStatus,
1653 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001654 }
kesavand39e0aa32020-01-28 20:58:50 -05001655
Neha Sharma96b7bf22020-06-15 10:37:32 +00001656 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001657
1658 return nil
1659}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001660
npujarec5762e2020-01-01 14:08:48 +05301661func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001662 var uniID uint32
1663 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301664 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001665 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001666 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001667 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001668 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001669 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001670 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301672 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001673 for _, tpID := range tpIDList {
Girish Gowdraa482f272021-03-24 23:04:19 -07001674 if err = dh.resourceMgr.RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001675 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001676 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001677 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa482f272021-03-24 23:04:19 -07001678 if err = dh.resourceMgr.RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001679 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001680 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001681 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301682 }
npujarec5762e2020-01-01 14:08:48 +05301683 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1684 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001685 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301686 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001687 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001688 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001689 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 +00001690 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001691 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1692 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1693 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001694 }
1695 return nil
1696}
1697
npujarec5762e2020-01-01 14:08:48 +05301698func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001699 nniUniID := -1
1700 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301701
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001702 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301703 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001704 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001705 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301706 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301707 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001708 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001709 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001710 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301711 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301712 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001713 _ = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, nniIntfID, -1, -1)
1714
Devmalya Paul495b94a2019-08-27 19:42:00 -04001715 }
npujarec5762e2020-01-01 14:08:48 +05301716 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001717 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301718 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001719
David K. Bainbridge794735f2020-02-11 21:01:37 -08001720 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001721}
1722
1723// 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 +05301724func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001725 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001726 /* Clear the KV store data associated with the all the UNI ports
1727 This clears up flow data and also resource map data for various
1728 other pon resources like alloc_id and gemport_id
1729 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001730 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001731 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001732 // Stop the Stats collector
1733 dh.stopCollector <- true
1734 // stop the heartbeat check routine
1735 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301736 dh.lockDevice.RLock()
1737 // Stop the read indication only if it the routine is active
1738 if dh.isReadIndicationRoutineActive {
1739 dh.stopIndications <- true
1740 }
1741 dh.lockDevice.RUnlock()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001742 //Reset the state
1743 if dh.Client != nil {
1744 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301745 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001746 }
1747 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08001748 dh.removeOnuIndicationChannels(ctx)
Girish Gowdrab1caa442020-10-19 12:24:39 -07001749 // There is no need to update the core about operation status and connection status of the OLT.
1750 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1751 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1752 // because the device does not exist in DB.
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001753 return nil
1754}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001755func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001756
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001757 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301758 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001759 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301760 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301761 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301762 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001763 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001764 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001765 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301766 }
1767 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301768 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001769 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301770 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001771 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301772 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301773 // Clear flowids for gem cache.
1774 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301775 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301776 }
1777 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301778 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301779 }
npujarec5762e2020-01-01 14:08:48 +05301780 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301781 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301782 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301783 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001784 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001785 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001786 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001787 /* Clear the flows from KV store associated with NNI port.
1788 There are mostly trap rules from NNI port (like LLDP)
1789 */
npujarec5762e2020-01-01 14:08:48 +05301790 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001791 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001792 }
A R Karthick1f85b802019-10-11 05:06:05 +00001793
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001794 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001795 go func() {
1796 if err := dh.resourceMgr.Delete(ctx); err != nil {
1797 logger.Debug(ctx, err)
1798 }
1799 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001800 }
A R Karthick1f85b802019-10-11 05:06:05 +00001801
Devmalya Paul495b94a2019-08-27 19:42:00 -04001802 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301803 dh.onus.Range(func(key interface{}, value interface{}) bool {
1804 dh.onus.Delete(key)
1805 return true
1806 })
1807
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001808 /*Delete discovered ONU map for the device*/
1809 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1810 dh.discOnus.Delete(key)
1811 return true
1812 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001813}
1814
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001815//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001816func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001817 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301818 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001819 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001820 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001821 return nil
1822}
1823
David K. Bainbridge794735f2020-02-11 21:01:37 -08001824func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001825 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001826 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001827 "packet-indication": *packetIn,
1828 "device-id": dh.device.Id,
1829 "packet": hex.EncodeToString(packetIn.Pkt),
1830 })
1831 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001832 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001833 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001834 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001835 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001836 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001837 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001838 "logical-port-num": logicalPortNum,
1839 "device-id": dh.device.Id,
1840 "packet": hex.EncodeToString(packetIn.Pkt),
1841 })
1842 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001843
Neha Sharma8f4e4322020-08-06 10:51:53 +00001844 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 +05301845 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001846 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301847 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001848 "device-id": dh.device.Id,
1849 "packet": hex.EncodeToString(packetIn.Pkt),
1850 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001851 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001852
Matteo Scandolo92186242020-06-12 10:54:18 -07001853 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001854 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001855 "packet": hex.EncodeToString(packetIn.Pkt),
1856 "device-id": dh.device.Id,
1857 })
1858 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001859 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001860}
1861
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001862// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301863func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001864 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001865 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001866 "device-id": dh.device.Id,
1867 "egress-port-no": egressPortNo,
1868 "pkt-length": len(packet.Data),
1869 "packet": hex.EncodeToString(packet.Data),
1870 })
1871 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001872
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001873 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001874 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001875 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1876 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301877 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1878 // Do not packet-out lldp packets on uni port.
1879 // ONOS has no clue about uni/nni ports, it just packets out on all
1880 // available ports on the Logical Switch. It should not be interested
1881 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001882 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001883 "device-id": dh.device.Id,
1884 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301885 return nil
1886 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001887 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1888 if innerEthType == 0x8100 {
1889 // q-in-q 802.1ad or 802.1q double tagged packet.
1890 // slice out the outer tag.
1891 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001892 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001893 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001894 "packet-data": hex.EncodeToString(packet.Data),
1895 "device-id": dh.device.Id,
1896 })
1897 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001898 }
1899 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001900 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1901 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001902 uniID := UniIDFromPortNum(uint32(egressPortNo))
1903
Girish Gowdra9602eb42020-09-09 15:50:39 -07001904 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001905 if err != nil {
1906 // In this case the openolt agent will receive the gemPortID as 0.
1907 // The agent tries to retrieve the gemPortID in this case.
1908 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001909 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001910 "intf-id": intfID,
1911 "onu-id": onuID,
1912 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001913 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301914 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001915 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001916 }
1917
1918 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001919 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001920 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001921 "egress-port-no": egressPortNo,
1922 "intf-id": intfID,
1923 "onu-id": onuID,
1924 "uni-id": uniID,
1925 "gem-port-id": gemPortID,
1926 "packet": hex.EncodeToString(packet.Data),
1927 "device-id": dh.device.Id,
1928 })
1929 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001930
npujarec5762e2020-01-01 14:08:48 +05301931 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301932 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001933 "source": "adapter",
1934 "destination": "onu",
1935 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001936 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001937 "oni-id": onuID,
1938 "uni-id": uniID,
1939 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001940 "packet": hex.EncodeToString(packet.Data),
1941 "device-id": dh.device.Id,
1942 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001943 }
1944 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001945 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001946 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001947 return olterrors.NewErrInvalidValue(log.Fields{
1948 "egress-nni-port": egressPortNo,
1949 "device-id": dh.device.Id,
1950 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001951 }
1952 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001953
Matteo Scandolo92186242020-06-12 10:54:18 -07001954 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001955 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001956 "uplink-pkt": uplinkPkt,
1957 "packet": hex.EncodeToString(packet.Data),
1958 "device-id": dh.device.Id,
1959 })
1960 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001961
npujarec5762e2020-01-01 14:08:48 +05301962 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001963 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1964 "packet": hex.EncodeToString(packet.Data),
1965 "device-id": dh.device.Id,
1966 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001967 }
1968 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001969 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301970 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001971 "egressPortType": egressPortType,
1972 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301973 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001974 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001975 }
1976 return nil
1977}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001978
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001979func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1980 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001981}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301982
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001983func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001984
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301985 // start the heartbeat check towards the OLT.
1986 var timerCheck *time.Timer
1987
1988 for {
1989 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1990 select {
1991 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001992 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001993 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001994 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301995 if timerCheck == nil {
1996 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001997 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301998 }
1999 } else {
2000 if timerCheck != nil {
2001 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002002 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302003 }
2004 timerCheck = nil
2005 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002006 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05302007 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302008 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302009 }
2010 cancel()
2011 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00002012 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302013 return
2014 }
2015 }
2016}
2017
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002018func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2019 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2020 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002021 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2022 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2023 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2024 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2025 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002026 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002027 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2028 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002029 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302030
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002031 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2032 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002033 _ = 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 -04002034 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002035 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002036 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002037 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002038
2039 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002040 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002041 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2042 device.OperStatus = voltha.OperStatus_UNKNOWN
2043 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2044
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002045 go dh.cleanupDeviceResources(ctx)
2046
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002047 dh.lockDevice.RLock()
2048 // Stop the read indication only if it the routine is active
2049 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2050 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2051 // on next execution of the readIndication routine.
2052 if dh.isReadIndicationRoutineActive {
2053 dh.stopIndications <- true
2054 }
2055 dh.lockDevice.RUnlock()
2056
Gamze Abakac2c32a62021-03-11 11:44:18 +00002057 //reset adapter reconcile flag
2058 dh.adapterPreviouslyConnected = false
2059
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002060 dh.transitionMap.Handle(ctx, DeviceInit)
2061
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302062 }
2063}
kesavand39e0aa32020-01-28 20:58:50 -05002064
2065// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002066func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2067 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2068 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002069}
2070
2071// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002072func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2073 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2074 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002075}
2076
kdarapu1afeceb2020-02-12 01:38:09 -05002077//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 +00002078func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2079 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002080 if port.GetType() == voltha.Port_ETHERNET_NNI {
2081 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002082 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302083 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302084 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002085 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002086 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002087 }
2088 // fetch interfaceid from PortNo
2089 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2090 ponIntf := &oop.Interface{IntfId: ponID}
2091 var operStatus voltha.OperStatus_Types
2092 if enablePort {
2093 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302094 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002095
2096 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302097 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002098 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002099 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002100 }
2101 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002102 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002103 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002104 } else {
2105 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302106 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002107 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302108 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002109 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002110 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002111 }
2112 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002113 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002114 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002115 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302116 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 +05302117 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302118 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002119 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002120 }
2121 return nil
2122}
2123
kdarapu1afeceb2020-02-12 01:38:09 -05002124//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002125func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002126 // Disable the port and update the oper_port_status to core
2127 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002128 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002129 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002130 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302131 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302132 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002133 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002134 }
2135 }
2136 }
2137 return nil
2138}
2139
2140//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002141func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2142 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2143 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002144 if port.Type == voltha.Port_ETHERNET_NNI {
2145 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002146 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002147 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002148 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002149 }
2150 }
2151 if port.Type == voltha.Port_PON_OLT {
2152 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002153 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002154 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002155 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002156 }
2157 }
2158 }
2159}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002160
2161// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002162func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002163 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002164 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2165 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002166
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002167 var sn *oop.SerialNumber
2168 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002169 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302170 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002171 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302172 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002173 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002174 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002175
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002176 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Neha Sharma8f4e4322020-08-06 10:51:53 +00002177 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302178 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302179 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002180 "onu-id": onuID}, err).Log()
2181 }
2182 //clear PON resources associated with ONU
2183 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002184 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002185 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002186 "device-id": dh.device.Id,
2187 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002188 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002189 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002190 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002191 "device-id": dh.device.Id,
2192 "intf-id": intfID,
2193 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002194 } else {
2195 for i, onu := range onuGemData {
Girish Gowdraa0870562021-03-11 14:30:14 -08002196 if onu.OnuID == onuID && onu.SerialNumber == onuSn {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002197 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002198 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002199 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302200 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002201 "onu-device": onu,
2202 "error": err})
2203 }
2204 // Clear flowids for gem cache.
2205 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002206 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002207 }
2208 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002209 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002210 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002211 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002212 "intf-id": intfID,
2213 "onu-device": onu,
2214 "onu-gem": onuGemData,
2215 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002216 //Not returning error on cleanup.
2217 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002218 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002219 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002220 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002221 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002222 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002223 }
2224 }
2225 dh.onus.Delete(onuKey)
Girish Gowdraa0870562021-03-11 14:30:14 -08002226 dh.discOnus.Delete(onuSn)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002227 return nil
2228}
Girish Gowdracefae192020-03-19 18:14:10 -07002229
2230func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002231 for _, field := range flow_utils.GetOfbFields(flow) {
2232 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002233 return field.GetPort()
2234 }
2235 }
2236 return InvalidPort
2237}
2238
2239func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002240 for _, action := range flow_utils.GetActions(flow) {
2241 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002242 if out := action.GetOutput(); out != nil {
2243 return out.GetPort()
2244 }
2245 }
2246 }
2247 return InvalidPort
2248}
2249
Girish Gowdracefae192020-03-19 18:14:10 -07002250func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2251 inPort := getInPortFromFlow(flow)
2252 outPort := getOutPortFromFlow(flow)
2253
2254 if inPort == InvalidPort || outPort == InvalidPort {
2255 return inPort, outPort
2256 }
2257
2258 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2259 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2260 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002261 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002262 return uniPort, outPort
2263 }
2264 }
2265 } else {
2266 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2267 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002268 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002269 return inPort, uniPort
2270 }
2271 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2272 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002273 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002274 return uniPort, outPort
2275 }
2276 }
2277 }
2278
2279 return InvalidPort, InvalidPort
2280}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002281
2282func extractOmciTransactionID(omciPkt []byte) uint16 {
2283 if len(omciPkt) > 3 {
2284 d := omciPkt[0:2]
2285 transid := binary.BigEndian.Uint16(d)
2286 return transid
2287 }
2288 return 0
2289}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002290
2291// StoreOnuDevice stores the onu parameters to the local cache.
2292func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2293 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2294 dh.onus.Store(onuKey, onuDevice)
2295}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002296
Neha Sharma8f4e4322020-08-06 10:51:53 +00002297func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002298 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002299 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002300 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002301 resp := new(voltha.ReturnValues)
2302 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002303 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002304 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002305 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2306 return nil, err
2307 }
2308 ID = device.ProxyAddress.GetOnuId()
2309 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2310 valueparam.Onu = &Onu
2311 valueparam.Value = value
2312
2313 // This API is unsupported until agent patch is added
2314 resp.Unsupported = uint32(value)
2315 _ = ctx
2316
2317 // Uncomment this code once agent changes are complete and tests
2318 /*
2319 resp, err = dh.Client.GetValue(ctx, valueparam)
2320 if err != nil {
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002321 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002322 return nil, err
2323 }
2324 */
2325
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002326 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 -08002327 return resp, nil
2328}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002329
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002330func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002331 // Default to PON0
2332 var intfID uint32
2333 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002334 if inPort != InvalidPort && outPort != InvalidPort {
2335 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2336 }
2337 return intfID
2338}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002339
Mahir Gunyelb0046752021-02-26 13:51:05 -08002340func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2341 dh.perPonOnuIndicationChannelLock.Lock()
2342 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2343 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002344 return ch.indicationChannel
2345 }
2346 channels := onuIndicationChannels{
2347 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002348 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002349 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002350 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002351 stopChannel: make(chan struct{}),
2352 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002353 dh.perPonOnuIndicationChannel[intfID] = channels
2354 dh.perPonOnuIndicationChannelLock.Unlock()
2355 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002356 return channels.indicationChannel
2357
2358}
2359
Mahir Gunyelb0046752021-02-26 13:51:05 -08002360func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2361 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2362 dh.perPonOnuIndicationChannelLock.Lock()
2363 defer dh.perPonOnuIndicationChannelLock.Unlock()
2364 for _, v := range dh.perPonOnuIndicationChannel {
2365 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002366 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002367 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002368}
2369
Mahir Gunyelb0046752021-02-26 13:51:05 -08002370func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2371 ind := onuIndicationMsg{
2372 ctx: ctx,
2373 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002374 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002375 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002376 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002377 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002378}
2379
Mahir Gunyelb0046752021-02-26 13:51:05 -08002380func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002381 for {
2382 select {
2383 // process one indication per onu, before proceeding to the next one
2384 case onuInd := <-onuChannels.indicationChannel:
2385 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002386 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002387 switch onuInd.indication.Data.(type) {
2388 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002389 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002390 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2391 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002392 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002393 }
2394 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002395 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002396 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2397 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002398 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002399 }
2400 }
2401 case <-onuChannels.stopChannel:
2402 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2403 close(onuChannels.indicationChannel)
2404 return
2405 }
2406 }
2407}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002408
2409// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2410// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2411func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2412 // Step1 : Fill McastFlowOrGroupControlBlock
2413 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2414 // Step3 : Wait on response channel for response
2415 // Step4 : Return error value
2416 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2417 errChan := make(chan error)
2418 var groupID uint32
2419 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2420 ctx: ctx,
2421 flowOrGroupAction: action,
2422 flow: flow,
2423 group: group,
2424 errChan: &errChan,
2425 }
2426 if flow != nil {
2427 groupID = flow_utils.GetGroup(flow)
2428 } else if group != nil {
2429 groupID = group.Desc.GroupId
2430 } else {
2431 return errors.New("flow-and-group-both-nil")
2432 }
2433 // Derive the appropriate go routine to handle the request by a simple module operation.
2434 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2435 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2436 // Wait for handler to return error value
2437 err := <-errChan
2438 logger.Debugw(ctx, "process-flow-or-group--received-resp", log.Fields{"flow": flow, "group": group, "action": action, "err": err})
2439 return err
2440}
2441
2442// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
2443func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock) {
2444 for {
2445 // block on the channel to receive an incoming mcast flow/group
2446 // process the flow completely before proceeding to handle the next flow
2447 mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel
2448 if mcastFlowOrGroupCb.flow != nil {
2449 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2450 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2451 log.Fields{"device-id": dh.device.Id,
2452 "flowToAdd": mcastFlowOrGroupCb.flow})
2453 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2454 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2455 // Pass the return value over the return channel
2456 *mcastFlowOrGroupCb.errChan <- err
2457 } else { // flow remove
2458 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2459 log.Fields{"device-id": dh.device.Id,
2460 "flowToRemove": mcastFlowOrGroupCb.flow})
2461 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2462 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2463 // Pass the return value over the return channel
2464 *mcastFlowOrGroupCb.errChan <- err
2465 }
2466 } else { // mcast group
2467 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2468 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2469 log.Fields{"device-id": dh.device.Id,
2470 "groupToAdd": mcastFlowOrGroupCb.group})
2471 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2472 // Pass the return value over the return channel
2473 *mcastFlowOrGroupCb.errChan <- err
2474 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2475 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2476 log.Fields{"device-id": dh.device.Id,
2477 "groupToModify": mcastFlowOrGroupCb.group})
2478 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2479 // Pass the return value over the return channel
2480 *mcastFlowOrGroupCb.errChan <- err
2481 } else { // group remove
2482 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2483 log.Fields{"device-id": dh.device.Id,
2484 "groupToRemove": mcastFlowOrGroupCb.group})
2485 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2486 // Pass the return value over the return channel
2487 *mcastFlowOrGroupCb.errChan <- err
2488 }
2489 }
2490 }
2491}
kesavand62126212021-01-12 04:56:06 -05002492
2493func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2494
2495 singleValResp := extension.SingleGetValueResponse{
2496 Response: &extension.GetValueResponse{
2497 Response: &extension.GetValueResponse_PortCoutners{
2498 PortCoutners: &extension.GetOltPortCountersResponse{},
2499 },
2500 },
2501 }
2502
2503 errResp := func(status extension.GetValueResponse_Status,
2504 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2505 return &extension.SingleGetValueResponse{
2506 Response: &extension.GetValueResponse{
2507 Status: status,
2508 ErrReason: reason,
2509 },
2510 }
2511 }
2512
2513 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2514 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2515 //send error response
2516 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2517 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2518 }
2519 statIndChn := make(chan bool, 1)
2520 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2521 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2522 //request openOlt agent to send the the port statistics indication
2523
2524 go func() {
2525 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2526 if err != nil {
2527 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2528 }
2529 }()
2530 select {
2531 case <-statIndChn:
2532 //indication received for ports stats
2533 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2534 case <-time.After(oltPortInfoTimeout * time.Second):
2535 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2536 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2537 case <-ctx.Done():
2538 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2539 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2540 }
2541 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2542 //get nni stats
2543 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2544 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2545 cmnni := dh.portStats.collectNNIMetrics(intfID)
2546 if cmnni == nil {
2547 //TODO define the error reason
2548 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2549 }
2550 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2551 return &singleValResp
2552
2553 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2554 // get pon stats
2555 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2556 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2557 cmpon := dh.portStats.collectPONMetrics(intfID)
2558 if cmpon == nil {
2559 //TODO define the error reason
2560 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2561 }
2562 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2563 return &singleValResp
2564 }
2565 }
2566 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2567}