blob: e81cd8f60984be2d2e0af469644d7b9014158923 [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 }
Matteo Scandolo66fbaf52021-03-24 14:13:38 -0700433 // if the connection drops we should retry to establish a new one for a little bit
434 // for now set to 2 Minutes
435 reconnectBackoff := backoff.NewExponentialBackOff()
436 reconnectBackoff.MaxElapsedTime = dh.openOLT.ReconnectTimeout
437 reconnectOperation := func() error {
438 logger.Debugw(ctx, "attempting-reconnection-to-device",
439 log.Fields{"err": err,
440 "device-id": dh.device.Id})
441 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
442 return err
443 }
444 return nil
445 }
446 if err = backoff.Retry(reconnectOperation, reconnectBackoff); err != nil {
447 logger.Errorw(ctx, "cannot-reconnect-to-device-backoff-expired",
448 log.Fields{"err": err,
449 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700450 return err
451 }
Matteo Scandolo66fbaf52021-03-24 14:13:38 -0700452
Girish Gowdra3f974912020-03-23 20:35:18 -0700453 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400454 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530455 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400456 // Reset backoff if we have a successful receive
457 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400458 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700459 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000460 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530461 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530462 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400463 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400464 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400465 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700466 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700467 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700468 // Close the send stream
469 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700470
Girish Gowdra3f974912020-03-23 20:35:18 -0700471 return nil
472}
473
474func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700475 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700476 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
477 if err != nil {
478 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
479 }
480 if indications == nil {
481 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
482 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700483 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700484 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400485}
486
487// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
488func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
489 switch indication.Data.(type) {
490 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
491 return true
492
493 default:
494 return false
495 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700496}
497
David K. Bainbridge794735f2020-02-11 21:01:37 -0800498func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700499 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000500 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530501 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700502 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530503 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700504 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000505 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000506 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530507 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000508 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800509 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000510 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800511 }
512 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700513}
514
David K. Bainbridge794735f2020-02-11 21:01:37 -0800515// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530516func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700517 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700518 switch indication.Data.(type) {
519 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000520 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
521 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700522 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 -0800523 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400524 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800525 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700526 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000527 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
528 defer span.Finish()
529
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700530 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800531 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000532 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400533 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800534 }
535 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000536 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700537 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000538 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
539 defer span.Finish()
540
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700541 intfOperInd := indication.GetIntfOperInd()
542 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800543 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000544 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400545 _ = 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 -0800546 }
547 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400548 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
549 logger.Warn(ctx, err)
550 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700551 } else if intfOperInd.GetType() == "pon" {
552 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
553 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800554 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000555 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400556 _ = 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 -0800557 }
558 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000559 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700560 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000561 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530562 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530563 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700564 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000565 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
566 defer span.Finish()
567
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700568 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000569 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800570 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800571 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700572 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000573 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
574 defer span.Finish()
575
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700576 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000577 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800578 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800579 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700580 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000581 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
582 defer span.Finish()
583
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700584 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000585 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 -0800586 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000587 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400588 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800589 }
590 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700591 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000592 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
593 defer span.Finish()
594
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700595 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000596 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700597 "intf-type": pktInd.IntfId,
598 "intf-id": pktInd.IntfId,
599 "gem-port-id": pktInd.GemportId,
600 "port-no": pktInd.PortNo,
601 "device-id": dh.device.Id,
602 })
603
604 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000605 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700606 "intf-type": pktInd.IntfId,
607 "intf-id": pktInd.IntfId,
608 "gem-port-id": pktInd.GemportId,
609 "port-no": pktInd.PortNo,
610 "packet": hex.EncodeToString(pktInd.Pkt),
611 "device-id": dh.device.Id,
612 })
613 }
614
David K. Bainbridge794735f2020-02-11 21:01:37 -0800615 go func() {
616 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400617 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800618 }
619 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700620 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000621 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
622 defer span.Finish()
623
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700624 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700625 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700626 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000627 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
628 defer span.Finish()
629
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700630 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000631 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700632 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000633 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
634 defer span.Finish()
635
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700636 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000637 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
638 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700639 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530640}
641
642// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530643func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530644 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000645 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530646
Girish Gowdru0c588b22019-04-23 23:24:56 -0400647 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530648 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400649 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000650 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400651 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000652
653 //Clear olt communication failure event
654 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
655 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700656 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000657 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
658
Gamze Abakac2c32a62021-03-11 11:44:18 +0000659 //check adapter and agent reconcile status
660 //reboot olt if needed (olt disconnection case)
661 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
662 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
663 log.Fields{
664 "device-id": dh.device.Id,
665 "adapter-status": dh.adapterPreviouslyConnected,
666 "agent-status": dh.agentPreviouslyConnected,
667 })
668 _ = dh.RebootDevice(ctx, dh.device)
669 }
670
Girish Gowdru0c588b22019-04-23 23:24:56 -0400671 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530672}
673
674// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530675func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000676 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400677
npujarec5762e2020-01-01 14:08:48 +0530678 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400679 if err != nil || device == nil {
680 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000681 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400682 }
683
684 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400685
686 //Update the device oper state and connection status
687 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800688 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400689 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800690 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400691
David K. Bainbridge794735f2020-02-11 21:01:37 -0800692 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000693 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400694 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400695
696 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530697 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400698 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000699 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400700 }
701 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400702 // Update onu state as down in onu adapter
703 onuInd := oop.OnuIndication{}
704 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800705 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300706 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800707 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400708 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300709 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800710 "onu-indicator": onuInd,
711 "device-type": onuDevice.Type,
712 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700713 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800714 } else {
715 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 -0700716 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400717 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800718 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700719 /* Discovered ONUs entries need to be cleared , since after OLT
720 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530721 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800722 dh.lockDevice.Unlock()
723
Neha Sharma96b7bf22020-06-15 10:37:32 +0000724 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700725 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530726}
727
728// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530729func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400730 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000731
732 // if the connection is already available, close the previous connection (olt reboot case)
733 if dh.clientCon != nil {
734 if err = dh.clientCon.Close(); err != nil {
735 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
736 } else {
737 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
738 }
739 }
740
741 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000742 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
743 grpc.WithInsecure(),
744 grpc.WithBlock(),
745 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000746 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000747 )),
748 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000749 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000750 )))
751
752 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530753 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530754 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000755 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400756 }
757 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530758}
759
760// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530761func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400762 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530763 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400764 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530765}
766
767// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530768func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530769 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000770 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400771
772 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530773 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
774 if err != nil || device == nil {
775 /*TODO: needs to handle error scenarios */
776 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
777 }
778 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000779 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400780
781 cloned := proto.Clone(device).(*voltha.Device)
782 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
783 cloned.OperStatus = voltha.OperStatus_UNKNOWN
784 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530785 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
786 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 -0400787 }
788
Chaitrashree G S44124192019-08-07 20:21:36 -0400789 // 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 +0530790 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400791 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530792 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400793 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400794 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
795 // all the modules initialized and ready to handle incoming ONUs.
796
Thomas Lee S985938d2020-05-04 11:40:41 +0530797 err = dh.initializeDeviceHandlerModules(ctx)
798 if err != nil {
799 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 -0400800 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400801
802 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800803 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530804 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400805 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800806 }
807 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700808
809 go startHeartbeatCheck(ctx, dh)
810
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400811 return nil
812 }
813
Neha Sharma8f4e4322020-08-06 10:51:53 +0000814 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400815 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400816 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400817 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400818 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400819 dh.populateActivePorts(ctx, ports)
820 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
821 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400822 }
823
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400824 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530825 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 -0400826 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530827
cuilin20187b2a8c32019-03-26 19:52:28 -0700828 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800829 go func() {
830 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400831 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800832 }
833 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000834 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000835
836 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000837 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000838 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700839
840 go startHeartbeatCheck(ctx, dh)
841
cuilin20187b2a8c32019-03-26 19:52:28 -0700842 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530843}
844
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400845func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000846 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400847
848 if err != nil {
849 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
850 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700851 dh.totalPonPorts = deviceInfo.GetPonPorts()
Gamze Abakac2c32a62021-03-11 11:44:18 +0000852 dh.agentPreviouslyConnected = deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700853
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400854 // Instantiate resource manager
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800855 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 -0400856 return olterrors.ErrResourceManagerInstantiating
857 }
858
Girish Gowdra9602eb42020-09-09 15:50:39 -0700859 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400860
Girish Gowdra9602eb42020-09-09 15:50:39 -0700861 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
862 for i := range dh.flowMgr {
863 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700864 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700865 return olterrors.ErrResourceManagerInstantiating
866 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400867 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700868
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400869 /* TODO: Instantiate Alarm , stats , BW managers */
870 /* Instantiating Event Manager to handle Alarms and KPIs */
871 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
872
873 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000874 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400875
876 return nil
877
878}
879
Neha Sharma96b7bf22020-06-15 10:37:32 +0000880func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400881 var err error
882 var deviceInfo *oop.DeviceInfo
883
Neha Sharma8f4e4322020-08-06 10:51:53 +0000884 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400885
886 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000887 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400888 }
889 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000890 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400891 }
892
Neha Sharma96b7bf22020-06-15 10:37:32 +0000893 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400894 dh.device.Root = true
895 dh.device.Vendor = deviceInfo.Vendor
896 dh.device.Model = deviceInfo.Model
897 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
898 dh.device.HardwareVersion = deviceInfo.HardwareVersion
899 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
900
901 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000902 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400903 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000904 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400905 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000906 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400907 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000908 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400909 dh.device.MacAddress = genmac
910 } else {
911 dh.device.MacAddress = deviceInfo.DeviceId
912 }
913
914 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000915 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000916 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400917 }
918
919 return deviceInfo, nil
920}
921
Neha Sharma96b7bf22020-06-15 10:37:32 +0000922func startCollector(ctx context.Context, dh *DeviceHandler) {
923 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530924 for {
925 select {
926 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000927 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530928 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000929 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700930
Neha Sharma8f4e4322020-08-06 10:51:53 +0000931 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400932 if err != nil {
933 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
934 continue
935 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530936 for _, port := range ports {
937 // NNI Stats
938 if port.Type == voltha.Port_ETHERNET_NNI {
939 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
940 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000941 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000942 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000943 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530944 }
945 // PON Stats
946 if port.Type == voltha.Port_PON_OLT {
947 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
948 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
949 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000950 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000951 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530952 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000953 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000954
955 //ONU & Gem Stats
956 onuGemInfo := dh.flowMgr[intfID].onuGemInfo
957 if len(onuGemInfo) != 0 {
958 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfo)
959 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500960 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530961 }
962 }
963 }
964}
965
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700966//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530967func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400968 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000969 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530970 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530971
972 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400973 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
974 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530975 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530976}
977
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700978//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530979func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700980 return &ic.SwitchCapability{
981 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530982 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700983 HwDesc: "open_pon",
984 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700985 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700986 },
987 SwitchFeatures: &of.OfpSwitchFeatures{
988 NBuffers: 256,
989 NTables: 2,
990 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
991 of.OfpCapabilities_OFPC_TABLE_STATS |
992 of.OfpCapabilities_OFPC_PORT_STATS |
993 of.OfpCapabilities_OFPC_GROUP_STATS),
994 },
995 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530996}
997
Neha Sharma96b7bf22020-06-15 10:37:32 +0000998func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
999 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 -07001000 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001001 var deviceID string
1002 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -07001003
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001004 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001005 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001006 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 -07001007 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1008 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001009
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001010 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301011
1012 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1013
Neha Sharma96b7bf22020-06-15 10:37:32 +00001014 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 -07001015 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001016 kwargs := make(map[string]interface{})
1017 kwargs["onu_id"] = omciInd.OnuId
1018 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001019
Neha Sharma8f4e4322020-08-06 10:51:53 +00001020 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001021 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301022 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001023 "intf-id": omciInd.IntfId,
1024 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001025 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001026 deviceType = onuDevice.Type
1027 deviceID = onuDevice.Id
1028 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1029 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301030 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001031 } else {
1032 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001033 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 +05301034 deviceType = onuInCache.(*OnuDevice).deviceType
1035 deviceID = onuInCache.(*OnuDevice).deviceID
1036 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001037 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001038
1039 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001040 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001041 ic.InterAdapterMessageType_OMCI_REQUEST, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001042 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301043 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001044 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001045 "destination": deviceType,
1046 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001047 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001048 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001049 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301050}
1051
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001052//ProcessInterAdapterMessage sends the proxied messages to the target device
1053// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1054// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001055func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1056 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001057 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001058 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -07001059 fromTopic := msg.Header.FromTopic
1060 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001061 toDeviceID := msg.Header.ToDeviceId
1062 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001063
Neha Sharma96b7bf22020-06-15 10:37:32 +00001064 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 -07001065
1066 msgBody := msg.GetBody()
1067
1068 omciMsg := &ic.InterAdapterOmciMessage{}
1069 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001070 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001071 }
1072
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001073 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001074 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001075 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301076 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001077 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001078 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001079 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001080 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1081 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301082 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001083 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001084 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001085 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001086 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001087 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1088 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301089 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001090 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001091 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001092 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001093 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001094 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001095 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001096 }
1097 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301098}
1099
Neha Sharma96b7bf22020-06-15 10:37:32 +00001100func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001101 var intfID uint32
1102 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001103 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001104 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001105 intfID = onuDevice.ProxyAddress.GetChannelId()
1106 onuID = onuDevice.ProxyAddress.GetOnuId()
1107 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001108 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001109 intfID = omciMsg.GetProxyAddress().GetChannelId()
1110 onuID = omciMsg.GetProxyAddress().GetOnuId()
1111 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001112 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001113 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001114 logger.Debugw(ctx, "onu-not-reachable--cannot-send-omci", log.Fields{"intf-id": intfID, "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001115
Thomas Lee S94109f12020-03-03 16:39:29 +05301116 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001117 "intf-id": intfID,
1118 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001119 }
1120
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001121 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1122 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001123 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001124 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1125 hex.Encode(hexPkt, omciMsg.Message)
1126 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1127
1128 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1129 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1130 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001131 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001132 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001133
Neha Sharma8f4e4322020-08-06 10:51:53 +00001134 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001135 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301136 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001137 "intf-id": intfID,
1138 "onu-id": onuID,
1139 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001140 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001141 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001142}
1143
David K. Bainbridge794735f2020-02-11 21:01:37 -08001144func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301145 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001146 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001147 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001148 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001149 // TODO: need resource manager
1150 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301151 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301152 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001153 st, _ := status.FromError(err)
1154 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001155 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1156
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001157 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301158 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001159 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001160 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001161 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001162 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001163 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001164}
1165
Mahir Gunyelb0046752021-02-26 13:51:05 -08001166func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001167 channelID := onuDiscInd.GetIntfId()
1168 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001169
Mahir Gunyelb0046752021-02-26 13:51:05 -08001170 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001171 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301172
cuilin20187b2a8c32019-03-26 19:52:28 -07001173 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001174 if sn != "" {
1175 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001176 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001177 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001178 }
1179
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301180 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001181 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001182 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301183
1184 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1185 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1186 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1187 OnuLosRaise event sent for it */
1188 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1189 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1190 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001191 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301192 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1193 "currentIntfId": onuDiscInd.GetIntfId()})
1194 // TODO:: Should we need to ignore raising OnuLosClear event
1195 // when onu connected to different PON?
1196 }
1197 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1198 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1199 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001200 go func() {
1201 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1202 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1203 }
1204 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301205 }
1206 return true
1207 })
1208
Neha Sharma96b7bf22020-06-15 10:37:32 +00001209 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001210 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001211 }
1212
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001213 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001214
1215 // check the ONU is already know to the OLT
1216 // NOTE the second time the ONU is discovered this should return a device
1217 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1218
1219 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001220 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 -08001221 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001222 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 -08001223 switch e.Code() {
1224 case codes.Internal:
1225 // this probably means NOT FOUND, so just create a new device
1226 onuDevice = nil
1227 case codes.DeadlineExceeded:
1228 // if the call times out, cleanup and exit
1229 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001230 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001231 }
1232 }
1233 }
1234
1235 if onuDevice == nil {
1236 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001237 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001238 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001239 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301240 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001241
Neha Sharma96b7bf22020-06-15 10:37:32 +00001242 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001243
1244 if err != nil {
1245 // if we can't create an ID in resource manager,
1246 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001247 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001248 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001249 "pon-intf-id": ponintfid,
1250 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001251 }
1252
Neha Sharma8f4e4322020-08-06 10:51:53 +00001253 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001254 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001255 dh.discOnus.Delete(sn)
1256 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 +05301257 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001258 "pon-intf-id": ponintfid,
1259 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001260 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001261 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 -04001262 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1263 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001264 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301265 log.Fields{"onuDevice": onuDevice,
1266 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001267 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301268 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001269 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001270
1271 // we can now use the existing ONU Id
1272 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001273 //Insert the ONU into cache to use in OnuIndication.
1274 //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 +00001275 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001276 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301277 "intfId": onuDiscInd.GetIntfId(),
1278 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001279 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001280
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301281 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301282 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001283 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301284 log.Fields{"onu": onuDev,
1285 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001286
Kent Hagermane6ff1012020-07-14 15:07:53 -04001287 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301288 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001289 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001290 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001291 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001292 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001293 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301294 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001295 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001296 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001297 }
1298 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001299}
1300
Mahir Gunyelb0046752021-02-26 13:51:05 -08001301func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001302
1303 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001304 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001305 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001306 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001307 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001308 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301309 log.Fields{"onuId": onuInd.OnuId,
1310 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301311 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001312 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001313 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301314
David K. Bainbridge794735f2020-02-11 21:01:37 -08001315 errFields := log.Fields{"device-id": dh.device.Id}
1316
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301317 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1318
Mahir Gunyele77977b2019-06-27 05:36:22 -07001319 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1320 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001321 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001322 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001323 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001324 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1325 if serialNumber != "" {
1326 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001327 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001328 } else {
1329 kwargs["onu_id"] = onuInd.OnuId
1330 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001331 errFields["onu-id"] = onuInd.OnuId
1332 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001333 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001334 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001335 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001336
David K. Bainbridge794735f2020-02-11 21:01:37 -08001337 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001338 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001339 }
1340
David K. Bainbridge794735f2020-02-11 21:01:37 -08001341 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001342 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001343 "previousIntfId": onuDevice.ParentPortNo,
1344 "currentIntfId": ponPort})
1345 }
1346
1347 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001348 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301349 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1350 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301351 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001352 }
1353 if !foundInCache {
1354 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1355
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301356 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 -08001357
1358 }
kesavand7cf3a052020-08-28 12:49:18 +05301359 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001360 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
kesavand7cf3a052020-08-28 12:49:18 +05301361 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1362 }
1363 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001364 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001365 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001366 }
1367 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001368}
1369
Neha Sharma96b7bf22020-06-15 10:37:32 +00001370func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001371 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 -07001372 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1373 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1374 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1375 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001376 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001377 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1378 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001379 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001380 onuInd.OperState = "down"
1381 }
1382 }
1383
David K. Bainbridge794735f2020-02-11 21:01:37 -08001384 switch onuInd.OperState {
1385 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001386 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 -07001387 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301388 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001389 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001390 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301391 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001392 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001393 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001394 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001395 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001396 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001397 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001398 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 -04001399 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301400 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001401 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001402 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301403 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001404 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001405 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001406 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001407 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001408 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001409 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001410 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001411 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001412 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001413}
1414
cuilin20187b2a8c32019-03-26 19:52:28 -07001415func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1416 if serialNum != nil {
1417 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001418 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001419 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001420}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001421func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1422 decodedStr, err := hex.DecodeString(serialNum[4:])
1423 if err != nil {
1424 return nil, err
1425 }
1426 return &oop.SerialNumber{
1427 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001428 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001429 }, nil
1430}
cuilin20187b2a8c32019-03-26 19:52:28 -07001431
1432func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001433 if len(vendorSpecific) > 3 {
1434 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1435 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1436 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1437 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1438 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1439 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1440 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1441 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1442 return tmp
1443 }
1444 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001445}
1446
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001447//UpdateFlowsBulk upates the bulk flow
1448func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301449 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001450}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001451
1452//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001453func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1454 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301455 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001456 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301457 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001458 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001459 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001460 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001461 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001462 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001463 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001464 "intf-id": parentPort,
1465 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001466 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001467 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 -08001468 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301469}
1470
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001471// SendPacketInToCore sends packet-in to core
1472// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1473// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001474func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001475 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001476 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001477 "port": logicalPort,
1478 "packet": hex.EncodeToString(packetPayload),
1479 "device-id": dh.device.Id,
1480 })
1481 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001482 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 +05301483 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001484 "source": "adapter",
1485 "destination": "core",
1486 "device-id": dh.device.Id,
1487 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001488 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001489 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001490 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001491 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001492 "packet": hex.EncodeToString(packetPayload),
1493 "device-id": dh.device.Id,
1494 })
1495 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001496 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001497}
1498
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001499// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001500func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001501 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001502
1503 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1504 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001505 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001506 }
1507
Kent Hagermane6ff1012020-07-14 15:07:53 -04001508 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001509 metrics := dh.metrics.GetSubscriberMetrics()
1510 for _, m := range pmConfigs.Metrics {
1511 metrics[m.Name].Enabled = m.Enabled
1512
1513 }
1514 }
1515}
1516
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001517//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301518func (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 +00001519 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 +01001520
Girish Gowdra491a9c62021-01-06 16:43:07 -08001521 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001522 var errorsList []error
1523
Girish Gowdru0c588b22019-04-23 23:24:56 -04001524 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001525 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001526 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001527
Neha Sharma96b7bf22020-06-15 10:37:32 +00001528 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301529 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001530 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301531 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001532 if flow_utils.HasGroup(flow) {
1533 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1534 } else {
1535 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1536 }
Girish Gowdracefae192020-03-19 18:14:10 -07001537 if err != nil {
1538 errorsList = append(errorsList, err)
1539 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001540 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301541
1542 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001543 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001544 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301545 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001546 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301547 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001548 if flow_utils.HasGroup(flow) {
1549 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1550 } else {
1551 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1552 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001553 if err != nil {
1554 errorsList = append(errorsList, err)
1555 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301556 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001557 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001558
Girish Gowdracefae192020-03-19 18:14:10 -07001559 // 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 +00001560 if groups != nil {
1561 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001562 // err = dh.groupMgr.AddGroup(ctx, group)
1563 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001564 if err != nil {
1565 errorsList = append(errorsList, err)
1566 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001567 }
1568 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001569 // err = dh.groupMgr.ModifyGroup(ctx, group)
1570 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001571 if err != nil {
1572 errorsList = append(errorsList, err)
1573 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001574 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001575 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001576 // err = dh.groupMgr.DeleteGroup(ctx, group)
1577 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001578 if err != nil {
1579 errorsList = append(errorsList, err)
1580 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001581 }
1582 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001583 if len(errorsList) > 0 {
1584 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1585 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001586 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001587 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301588}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001589
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001590//DisableDevice disables the given device
1591//It marks the following for the given device:
1592//Device-Handler Admin-State : down
1593//Device Port-State: UNKNOWN
1594//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001596 /* On device disable ,admin state update has to be done prior sending request to agent since
1597 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001598 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001599 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001600 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001601 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001602 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001603 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001604 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001605 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001606 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001607 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301608
1609 dh.discOnus = sync.Map{}
1610 dh.onus = sync.Map{}
1611
Thomas Lee S85f37312020-04-03 17:06:12 +05301612 //stopping the stats collector
1613 dh.stopCollector <- true
1614
Neha Sharma96b7bf22020-06-15 10:37:32 +00001615 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001616 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301617 //Update device Admin state
1618 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001619 // 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 +00001620 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 -04001621 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001622 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001623 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001624 return nil
1625}
1626
Neha Sharma96b7bf22020-06-15 10:37:32 +00001627func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001628 // Update onu state as unreachable in onu adapter
1629 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301630 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001631 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001632 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001633 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001634 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 -04001635 }
1636 if onuDevices != nil {
1637 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001638 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001639 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001640 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001641 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001642 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001643 }
1644
1645 }
1646 }
1647
1648}
1649
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001650//ReenableDevice re-enables the olt device after disable
1651//It marks the following for the given device:
1652//Device-Handler Admin-State : up
1653//Device Port-State: ACTIVE
1654//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001655func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001656 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301657 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001658 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301659 }
1660 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001661 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001662
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001663 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001664
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001665 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1666 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001667 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001668 }
1669 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001670 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001671 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001672 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001673 device.OperStatus = voltha.OperStatus_ACTIVE
1674 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001675
Neha Sharma8f4e4322020-08-06 10:51:53 +00001676 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 +05301677 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001678 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001679 "connect-status": device.ConnectStatus,
1680 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001681 }
kesavand39e0aa32020-01-28 20:58:50 -05001682
Neha Sharma96b7bf22020-06-15 10:37:32 +00001683 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001684
1685 return nil
1686}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001687
npujarec5762e2020-01-01 14:08:48 +05301688func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001689 var uniID uint32
1690 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301691 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001692 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001693 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001694 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001695 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001696 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001697 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001698 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301699 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001700 for _, tpID := range tpIDList {
Girish Gowdraa482f272021-03-24 23:04:19 -07001701 if err = dh.resourceMgr.RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001702 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001703 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001704 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa482f272021-03-24 23:04:19 -07001705 if err = dh.resourceMgr.RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001706 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001707 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001708 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301709 }
npujarec5762e2020-01-01 14:08:48 +05301710 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1711 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001712 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301713 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001714 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001715 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001716 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 +00001717 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001718 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1719 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1720 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001721 }
1722 return nil
1723}
1724
npujarec5762e2020-01-01 14:08:48 +05301725func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001726 nniUniID := -1
1727 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301728
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001729 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301730 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001731 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001732 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301733 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301734 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001735 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001736 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001737 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301738 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301739 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001740 _ = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, nniIntfID, -1, -1)
1741
Devmalya Paul495b94a2019-08-27 19:42:00 -04001742 }
npujarec5762e2020-01-01 14:08:48 +05301743 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001744 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301745 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001746
David K. Bainbridge794735f2020-02-11 21:01:37 -08001747 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001748}
1749
1750// 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 +05301751func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001752 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001753 /* Clear the KV store data associated with the all the UNI ports
1754 This clears up flow data and also resource map data for various
1755 other pon resources like alloc_id and gemport_id
1756 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001757 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001758 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001759 // Stop the Stats collector
1760 dh.stopCollector <- true
1761 // stop the heartbeat check routine
1762 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301763 dh.lockDevice.RLock()
1764 // Stop the read indication only if it the routine is active
1765 if dh.isReadIndicationRoutineActive {
1766 dh.stopIndications <- true
1767 }
1768 dh.lockDevice.RUnlock()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001769 //Reset the state
1770 if dh.Client != nil {
1771 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301772 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001773 }
1774 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08001775 dh.removeOnuIndicationChannels(ctx)
Girish Gowdrab1caa442020-10-19 12:24:39 -07001776 // There is no need to update the core about operation status and connection status of the OLT.
1777 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1778 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1779 // because the device does not exist in DB.
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001780 return nil
1781}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001782func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001783
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001784 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301785 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001786 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301787 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301788 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301789 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001790 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001791 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001792 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301793 }
1794 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301795 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001796 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301797 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001798 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301799 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301800 // Clear flowids for gem cache.
1801 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301802 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301803 }
1804 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301805 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301806 }
npujarec5762e2020-01-01 14:08:48 +05301807 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301808 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301809 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301810 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001811 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001812 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001813 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001814 /* Clear the flows from KV store associated with NNI port.
1815 There are mostly trap rules from NNI port (like LLDP)
1816 */
npujarec5762e2020-01-01 14:08:48 +05301817 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001818 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001819 }
A R Karthick1f85b802019-10-11 05:06:05 +00001820
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001821 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001822 go func() {
1823 if err := dh.resourceMgr.Delete(ctx); err != nil {
1824 logger.Debug(ctx, err)
1825 }
1826 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001827 }
A R Karthick1f85b802019-10-11 05:06:05 +00001828
Devmalya Paul495b94a2019-08-27 19:42:00 -04001829 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301830 dh.onus.Range(func(key interface{}, value interface{}) bool {
1831 dh.onus.Delete(key)
1832 return true
1833 })
1834
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001835 /*Delete discovered ONU map for the device*/
1836 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1837 dh.discOnus.Delete(key)
1838 return true
1839 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001840}
1841
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001842//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001843func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001844 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301845 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001846 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001847 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001848 return nil
1849}
1850
David K. Bainbridge794735f2020-02-11 21:01:37 -08001851func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001852 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001853 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001854 "packet-indication": *packetIn,
1855 "device-id": dh.device.Id,
1856 "packet": hex.EncodeToString(packetIn.Pkt),
1857 })
1858 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001859 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001860 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001861 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001862 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001863 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001864 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001865 "logical-port-num": logicalPortNum,
1866 "device-id": dh.device.Id,
1867 "packet": hex.EncodeToString(packetIn.Pkt),
1868 })
1869 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001870
Neha Sharma8f4e4322020-08-06 10:51:53 +00001871 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 +05301872 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001873 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301874 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001875 "device-id": dh.device.Id,
1876 "packet": hex.EncodeToString(packetIn.Pkt),
1877 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001878 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001879
Matteo Scandolo92186242020-06-12 10:54:18 -07001880 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001881 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001882 "packet": hex.EncodeToString(packetIn.Pkt),
1883 "device-id": dh.device.Id,
1884 })
1885 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001886 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001887}
1888
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001889// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301890func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001891 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001892 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001893 "device-id": dh.device.Id,
1894 "egress-port-no": egressPortNo,
1895 "pkt-length": len(packet.Data),
1896 "packet": hex.EncodeToString(packet.Data),
1897 })
1898 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001899
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001900 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001901 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001902 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1903 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301904 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1905 // Do not packet-out lldp packets on uni port.
1906 // ONOS has no clue about uni/nni ports, it just packets out on all
1907 // available ports on the Logical Switch. It should not be interested
1908 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001909 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001910 "device-id": dh.device.Id,
1911 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301912 return nil
1913 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001914 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1915 if innerEthType == 0x8100 {
1916 // q-in-q 802.1ad or 802.1q double tagged packet.
1917 // slice out the outer tag.
1918 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001919 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001920 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001921 "packet-data": hex.EncodeToString(packet.Data),
1922 "device-id": dh.device.Id,
1923 })
1924 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001925 }
1926 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001927 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1928 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001929 uniID := UniIDFromPortNum(uint32(egressPortNo))
1930
Girish Gowdra9602eb42020-09-09 15:50:39 -07001931 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001932 if err != nil {
1933 // In this case the openolt agent will receive the gemPortID as 0.
1934 // The agent tries to retrieve the gemPortID in this case.
1935 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001936 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001937 "intf-id": intfID,
1938 "onu-id": onuID,
1939 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001940 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301941 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001942 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001943 }
1944
1945 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001946 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001947 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001948 "egress-port-no": egressPortNo,
1949 "intf-id": intfID,
1950 "onu-id": onuID,
1951 "uni-id": uniID,
1952 "gem-port-id": gemPortID,
1953 "packet": hex.EncodeToString(packet.Data),
1954 "device-id": dh.device.Id,
1955 })
1956 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001957
npujarec5762e2020-01-01 14:08:48 +05301958 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301959 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001960 "source": "adapter",
1961 "destination": "onu",
1962 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001963 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001964 "oni-id": onuID,
1965 "uni-id": uniID,
1966 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001967 "packet": hex.EncodeToString(packet.Data),
1968 "device-id": dh.device.Id,
1969 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001970 }
1971 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001972 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001973 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001974 return olterrors.NewErrInvalidValue(log.Fields{
1975 "egress-nni-port": egressPortNo,
1976 "device-id": dh.device.Id,
1977 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001978 }
1979 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001980
Matteo Scandolo92186242020-06-12 10:54:18 -07001981 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001982 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001983 "uplink-pkt": uplinkPkt,
1984 "packet": hex.EncodeToString(packet.Data),
1985 "device-id": dh.device.Id,
1986 })
1987 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001988
npujarec5762e2020-01-01 14:08:48 +05301989 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001990 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1991 "packet": hex.EncodeToString(packet.Data),
1992 "device-id": dh.device.Id,
1993 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001994 }
1995 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001996 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301997 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001998 "egressPortType": egressPortType,
1999 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05302000 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08002001 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04002002 }
2003 return nil
2004}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07002005
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07002006func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
2007 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07002008}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302009
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002010func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00002011
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302012 // start the heartbeat check towards the OLT.
2013 var timerCheck *time.Timer
2014
2015 for {
2016 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
2017 select {
2018 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00002019 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002020 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002021 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302022 if timerCheck == nil {
2023 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002024 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302025 }
2026 } else {
2027 if timerCheck != nil {
2028 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002029 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302030 }
2031 timerCheck = nil
2032 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002033 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05302034 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302035 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302036 }
2037 cancel()
2038 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00002039 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302040 return
2041 }
2042 }
2043}
2044
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002045func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2046 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2047 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002048 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2049 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2050 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2051 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2052 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002053 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002054 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2055 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002056 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302057
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002058 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2059 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002060 _ = 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 -04002061 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002062 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002063 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002064 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002065
2066 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002067 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002068 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2069 device.OperStatus = voltha.OperStatus_UNKNOWN
2070 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2071
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002072 go dh.cleanupDeviceResources(ctx)
2073
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002074 dh.lockDevice.RLock()
2075 // Stop the read indication only if it the routine is active
2076 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2077 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2078 // on next execution of the readIndication routine.
2079 if dh.isReadIndicationRoutineActive {
2080 dh.stopIndications <- true
2081 }
2082 dh.lockDevice.RUnlock()
2083
Gamze Abakac2c32a62021-03-11 11:44:18 +00002084 //reset adapter reconcile flag
2085 dh.adapterPreviouslyConnected = false
2086
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002087 dh.transitionMap.Handle(ctx, DeviceInit)
2088
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302089 }
2090}
kesavand39e0aa32020-01-28 20:58:50 -05002091
2092// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002093func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2094 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2095 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002096}
2097
2098// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002099func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2100 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2101 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002102}
2103
kdarapu1afeceb2020-02-12 01:38:09 -05002104//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 +00002105func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2106 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002107 if port.GetType() == voltha.Port_ETHERNET_NNI {
2108 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002109 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302110 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302111 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002112 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002113 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002114 }
2115 // fetch interfaceid from PortNo
2116 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2117 ponIntf := &oop.Interface{IntfId: ponID}
2118 var operStatus voltha.OperStatus_Types
2119 if enablePort {
2120 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302121 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002122
2123 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302124 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002125 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002126 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002127 }
2128 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002129 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002130 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002131 } else {
2132 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302133 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002134 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302135 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002136 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002137 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002138 }
2139 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002140 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002141 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002142 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302143 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 +05302144 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302145 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002146 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002147 }
2148 return nil
2149}
2150
kdarapu1afeceb2020-02-12 01:38:09 -05002151//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002152func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002153 // Disable the port and update the oper_port_status to core
2154 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002155 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002156 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002157 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302158 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302159 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002160 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002161 }
2162 }
2163 }
2164 return nil
2165}
2166
2167//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002168func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2169 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2170 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002171 if port.Type == voltha.Port_ETHERNET_NNI {
2172 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002173 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002174 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002175 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002176 }
2177 }
2178 if port.Type == voltha.Port_PON_OLT {
2179 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002180 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002181 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002182 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002183 }
2184 }
2185 }
2186}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002187
2188// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002189func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002190 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002191 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2192 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002193
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002194 var sn *oop.SerialNumber
2195 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002196 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302197 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002198 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302199 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002200 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002201 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002202
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002203 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Neha Sharma8f4e4322020-08-06 10:51:53 +00002204 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302205 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302206 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002207 "onu-id": onuID}, err).Log()
2208 }
2209 //clear PON resources associated with ONU
2210 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002211 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002212 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002213 "device-id": dh.device.Id,
2214 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002215 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002216 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002217 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002218 "device-id": dh.device.Id,
2219 "intf-id": intfID,
2220 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002221 } else {
2222 for i, onu := range onuGemData {
Girish Gowdraa0870562021-03-11 14:30:14 -08002223 if onu.OnuID == onuID && onu.SerialNumber == onuSn {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002224 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002225 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002226 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302227 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002228 "onu-device": onu,
2229 "error": err})
2230 }
2231 // Clear flowids for gem cache.
2232 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002233 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002234 }
2235 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002236 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002237 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002238 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002239 "intf-id": intfID,
2240 "onu-device": onu,
2241 "onu-gem": onuGemData,
2242 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002243 //Not returning error on cleanup.
2244 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002245 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002246 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002247 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002248 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002249 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002250 }
2251 }
2252 dh.onus.Delete(onuKey)
Girish Gowdraa0870562021-03-11 14:30:14 -08002253 dh.discOnus.Delete(onuSn)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002254 return nil
2255}
Girish Gowdracefae192020-03-19 18:14:10 -07002256
2257func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002258 for _, field := range flow_utils.GetOfbFields(flow) {
2259 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002260 return field.GetPort()
2261 }
2262 }
2263 return InvalidPort
2264}
2265
2266func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002267 for _, action := range flow_utils.GetActions(flow) {
2268 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002269 if out := action.GetOutput(); out != nil {
2270 return out.GetPort()
2271 }
2272 }
2273 }
2274 return InvalidPort
2275}
2276
Girish Gowdracefae192020-03-19 18:14:10 -07002277func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2278 inPort := getInPortFromFlow(flow)
2279 outPort := getOutPortFromFlow(flow)
2280
2281 if inPort == InvalidPort || outPort == InvalidPort {
2282 return inPort, outPort
2283 }
2284
2285 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2286 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2287 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002288 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002289 return uniPort, outPort
2290 }
2291 }
2292 } else {
2293 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2294 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002295 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002296 return inPort, uniPort
2297 }
2298 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2299 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002300 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002301 return uniPort, outPort
2302 }
2303 }
2304 }
2305
2306 return InvalidPort, InvalidPort
2307}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002308
2309func extractOmciTransactionID(omciPkt []byte) uint16 {
2310 if len(omciPkt) > 3 {
2311 d := omciPkt[0:2]
2312 transid := binary.BigEndian.Uint16(d)
2313 return transid
2314 }
2315 return 0
2316}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002317
2318// StoreOnuDevice stores the onu parameters to the local cache.
2319func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2320 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2321 dh.onus.Store(onuKey, onuDevice)
2322}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002323
Neha Sharma8f4e4322020-08-06 10:51:53 +00002324func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002325 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002326 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002327 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002328 resp := new(voltha.ReturnValues)
2329 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002330 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002331 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002332 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2333 return nil, err
2334 }
2335 ID = device.ProxyAddress.GetOnuId()
2336 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2337 valueparam.Onu = &Onu
2338 valueparam.Value = value
2339
2340 // This API is unsupported until agent patch is added
2341 resp.Unsupported = uint32(value)
2342 _ = ctx
2343
2344 // Uncomment this code once agent changes are complete and tests
2345 /*
2346 resp, err = dh.Client.GetValue(ctx, valueparam)
2347 if err != nil {
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002348 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002349 return nil, err
2350 }
2351 */
2352
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002353 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 -08002354 return resp, nil
2355}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002356
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002357func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002358 // Default to PON0
2359 var intfID uint32
2360 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002361 if inPort != InvalidPort && outPort != InvalidPort {
2362 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2363 }
2364 return intfID
2365}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002366
Mahir Gunyelb0046752021-02-26 13:51:05 -08002367func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2368 dh.perPonOnuIndicationChannelLock.Lock()
2369 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2370 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002371 return ch.indicationChannel
2372 }
2373 channels := onuIndicationChannels{
2374 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002375 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002376 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002377 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002378 stopChannel: make(chan struct{}),
2379 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002380 dh.perPonOnuIndicationChannel[intfID] = channels
2381 dh.perPonOnuIndicationChannelLock.Unlock()
2382 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002383 return channels.indicationChannel
2384
2385}
2386
Mahir Gunyelb0046752021-02-26 13:51:05 -08002387func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2388 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2389 dh.perPonOnuIndicationChannelLock.Lock()
2390 defer dh.perPonOnuIndicationChannelLock.Unlock()
2391 for _, v := range dh.perPonOnuIndicationChannel {
2392 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002393 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002394 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002395}
2396
Mahir Gunyelb0046752021-02-26 13:51:05 -08002397func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2398 ind := onuIndicationMsg{
2399 ctx: ctx,
2400 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002401 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002402 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002403 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002404 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002405}
2406
Mahir Gunyelb0046752021-02-26 13:51:05 -08002407func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002408 for {
2409 select {
2410 // process one indication per onu, before proceeding to the next one
2411 case onuInd := <-onuChannels.indicationChannel:
2412 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002413 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002414 switch onuInd.indication.Data.(type) {
2415 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002416 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002417 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2418 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002419 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002420 }
2421 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002422 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002423 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2424 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002425 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002426 }
2427 }
2428 case <-onuChannels.stopChannel:
2429 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2430 close(onuChannels.indicationChannel)
2431 return
2432 }
2433 }
2434}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002435
2436// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2437// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2438func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2439 // Step1 : Fill McastFlowOrGroupControlBlock
2440 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2441 // Step3 : Wait on response channel for response
2442 // Step4 : Return error value
2443 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2444 errChan := make(chan error)
2445 var groupID uint32
2446 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2447 ctx: ctx,
2448 flowOrGroupAction: action,
2449 flow: flow,
2450 group: group,
2451 errChan: &errChan,
2452 }
2453 if flow != nil {
2454 groupID = flow_utils.GetGroup(flow)
2455 } else if group != nil {
2456 groupID = group.Desc.GroupId
2457 } else {
2458 return errors.New("flow-and-group-both-nil")
2459 }
2460 // Derive the appropriate go routine to handle the request by a simple module operation.
2461 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2462 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2463 // Wait for handler to return error value
2464 err := <-errChan
2465 logger.Debugw(ctx, "process-flow-or-group--received-resp", log.Fields{"flow": flow, "group": group, "action": action, "err": err})
2466 return err
2467}
2468
2469// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
2470func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock) {
2471 for {
2472 // block on the channel to receive an incoming mcast flow/group
2473 // process the flow completely before proceeding to handle the next flow
2474 mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel
2475 if mcastFlowOrGroupCb.flow != nil {
2476 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2477 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2478 log.Fields{"device-id": dh.device.Id,
2479 "flowToAdd": mcastFlowOrGroupCb.flow})
2480 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2481 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2482 // Pass the return value over the return channel
2483 *mcastFlowOrGroupCb.errChan <- err
2484 } else { // flow remove
2485 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2486 log.Fields{"device-id": dh.device.Id,
2487 "flowToRemove": mcastFlowOrGroupCb.flow})
2488 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2489 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2490 // Pass the return value over the return channel
2491 *mcastFlowOrGroupCb.errChan <- err
2492 }
2493 } else { // mcast group
2494 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2495 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2496 log.Fields{"device-id": dh.device.Id,
2497 "groupToAdd": mcastFlowOrGroupCb.group})
2498 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2499 // Pass the return value over the return channel
2500 *mcastFlowOrGroupCb.errChan <- err
2501 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2502 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2503 log.Fields{"device-id": dh.device.Id,
2504 "groupToModify": mcastFlowOrGroupCb.group})
2505 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2506 // Pass the return value over the return channel
2507 *mcastFlowOrGroupCb.errChan <- err
2508 } else { // group remove
2509 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2510 log.Fields{"device-id": dh.device.Id,
2511 "groupToRemove": mcastFlowOrGroupCb.group})
2512 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2513 // Pass the return value over the return channel
2514 *mcastFlowOrGroupCb.errChan <- err
2515 }
2516 }
2517 }
2518}
kesavand62126212021-01-12 04:56:06 -05002519
2520func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2521
2522 singleValResp := extension.SingleGetValueResponse{
2523 Response: &extension.GetValueResponse{
2524 Response: &extension.GetValueResponse_PortCoutners{
2525 PortCoutners: &extension.GetOltPortCountersResponse{},
2526 },
2527 },
2528 }
2529
2530 errResp := func(status extension.GetValueResponse_Status,
2531 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2532 return &extension.SingleGetValueResponse{
2533 Response: &extension.GetValueResponse{
2534 Status: status,
2535 ErrReason: reason,
2536 },
2537 }
2538 }
2539
2540 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2541 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2542 //send error response
2543 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2544 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2545 }
2546 statIndChn := make(chan bool, 1)
2547 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2548 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2549 //request openOlt agent to send the the port statistics indication
2550
2551 go func() {
2552 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2553 if err != nil {
2554 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2555 }
2556 }()
2557 select {
2558 case <-statIndChn:
2559 //indication received for ports stats
2560 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2561 case <-time.After(oltPortInfoTimeout * time.Second):
2562 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2563 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2564 case <-ctx.Done():
2565 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2566 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2567 }
2568 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2569 //get nni stats
2570 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2571 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2572 cmnni := dh.portStats.collectNNIMetrics(intfID)
2573 if cmnni == nil {
2574 //TODO define the error reason
2575 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2576 }
2577 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2578 return &singleValResp
2579
2580 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2581 // get pon stats
2582 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2583 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2584 cmpon := dh.portStats.collectPONMetrics(intfID)
2585 if cmpon == nil {
2586 //TODO define the error reason
2587 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2588 }
2589 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2590 return &singleValResp
2591 }
2592 }
2593 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2594}