blob: 0dfb781c750b57f1a28f57c718058fb81d8839cd [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"
cuilin20187b2a8c32019-03-26 19:52:28 -070024 "fmt"
25 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040026 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070027 "strconv"
28 "strings"
29 "sync"
30 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053031
Matteo Scandolo945e4012019-12-12 14:16:11 -080032 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070033 "github.com/gogo/protobuf/proto"
34 "github.com/golang/protobuf/ptypes"
Girish Kumar93e91742020-07-27 16:43:19 +000035 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
36 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
Esin Karamanccb714b2019-11-29 15:02:06 +000037 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
Kent Hagermanf1db18b2020-07-08 13:38:15 -040038 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
Esin Karamanccb714b2019-11-29 15:02:06 +000039 "github.com/opencord/voltha-lib-go/v3/pkg/log"
40 "github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics"
Thomas Lee S94109f12020-03-03 16:39:29 +053041 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080042 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Esin Karamanccb714b2019-11-29 15:02:06 +000043 "github.com/opencord/voltha-protos/v3/go/common"
44 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
45 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
46 oop "github.com/opencord/voltha-protos/v3/go/openolt"
47 "github.com/opencord/voltha-protos/v3/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070048 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040049 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040050 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053051)
52
salmansiddiqui7ac62132019-08-22 03:58:50 +000053// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040054const (
salmansiddiqui7ac62132019-08-22 03:58:50 +000055 MaxRetry = 10
56 MaxTimeOutInMs = 500
Girish Gowdracefae192020-03-19 18:14:10 -070057 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040058)
59
Girish Gowdracefae192020-03-19 18:14:10 -070060// pendingFlowRemoveDataKey is key to pendingFlowRemoveDataPerSubscriber map
61type pendingFlowRemoveDataKey struct {
62 intfID uint32
63 onuID uint32
64 uniID uint32
65}
66
67// pendingFlowRemoveData is value stored in pendingFlowRemoveDataPerSubscriber map
68// This holds the number of pending flow removes and also a signal channel to
69// to indicate the receiver when all flow removes are handled
70type pendingFlowRemoveData struct {
71 pendingFlowRemoveCount uint32
72 allFlowsRemoved chan struct{}
73}
74
Phaneendra Manda4c62c802019-03-06 21:37:49 +053075//DeviceHandler will interact with the OLT device.
76type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070077 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053078 coreProxy adapterif.CoreProxy
79 AdapterProxy adapterif.AdapterProxy
80 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070081 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070082 exitChannel chan int
83 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053084 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070085 transitionMap *TransitionMap
86 clientCon *grpc.ClientConn
manikkaraj kbf256be2019-03-25 00:13:48 +053087 flowMgr *OpenOltFlowMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040088 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053089 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053090
Girish Gowdra3ab6d212020-03-24 17:33:15 -070091 discOnus sync.Map
92 onus sync.Map
93 portStats *OpenOltStatisticsMgr
94 metrics *pmmetrics.PmMetrics
95 stopCollector chan bool
96 stopHeartbeatCheck chan bool
97 activePorts sync.Map
98 stopIndications chan bool
99 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -0700100
101 // pendingFlowRemoveDataPerSubscriber map is used to maintain the context on a per
102 // subscriber basis for the number of pending flow removes. This data is used
103 // to process all the flow removes for a subscriber before handling flow adds.
104 // Interleaving flow delete and flow add processing has known to cause PON resource
105 // management contentions on a per subscriber bases, so we need ensure ordering.
106 pendingFlowRemoveDataPerSubscriber map[pendingFlowRemoveDataKey]pendingFlowRemoveData
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
Naga Manjunath7615e552019-10-11 22:35:47 +0530121var pmNames = []string{
122 "rx_bytes",
123 "rx_packets",
124 "rx_mcast_packets",
125 "rx_bcast_packets",
126 "tx_bytes",
127 "tx_packets",
128 "tx_mcast_packets",
129 "tx_bcast_packets",
130}
131
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700132//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530133func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700134 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700135 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700136 device.deviceType = deviceTp
137 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700138 device.onuID = onuID
139 device.intfID = intfID
140 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530141 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700142 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530143}
144
145//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530146func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700147 var dh DeviceHandler
148 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400149 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400150 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700151 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700152 dh.device = cloned
153 dh.openOLT = adapter
154 dh.exitChannel = make(chan int, 1)
155 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530156 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530157 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530158 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 -0500159 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400160 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700161 dh.pendingFlowRemoveDataPerSubscriber = make(map[pendingFlowRemoveDataKey]pendingFlowRemoveData)
162
cuilin20187b2a8c32019-03-26 19:52:28 -0700163 //TODO initialize the support classes.
164 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530165}
166
167// start save the device to the data model
168func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700169 dh.lockDevice.Lock()
170 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000171 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700172 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000173 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530174}
175
176// stop stops the device dh. Not much to do for now
177func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700178 dh.lockDevice.Lock()
179 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000180 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700181 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000182 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530183}
184
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400185func macifyIP(ip net.IP) string {
186 if len(ip) > 0 {
187 oct1 := strconv.FormatInt(int64(ip[12]), 16)
188 oct2 := strconv.FormatInt(int64(ip[13]), 16)
189 oct3 := strconv.FormatInt(int64(ip[14]), 16)
190 oct4 := strconv.FormatInt(int64(ip[15]), 16)
191 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
192 }
193 return ""
194}
195
Neha Sharma96b7bf22020-06-15 10:37:32 +0000196func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400197 var genmac string
198 var addr net.IP
199 var ips []string
200 var err error
201
Neha Sharma96b7bf22020-06-15 10:37:32 +0000202 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400203
204 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000205 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400206
207 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000208 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400209 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000210 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400211 }
212 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000213 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530214 log.Fields{"host": ips[0],
215 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400216 return genmac, nil
217 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000218 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400219 }
220
221 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000222 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530223 log.Fields{"host": host,
224 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400225 return genmac, nil
226}
227
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530228func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700229 slist := strings.Split(mac, ":")
230 result := make([]uint32, len(slist))
231 var err error
232 var tmp int64
233 for index, val := range slist {
234 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
235 return []uint32{1, 2, 3, 4, 5, 6}
236 }
237 result[index] = uint32(tmp)
238 }
239 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530240}
241
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700242//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 -0800243func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530244
David K. Bainbridge794735f2020-02-11 21:01:37 -0800245 switch portType {
246 case voltha.Port_ETHERNET_NNI:
247 return fmt.Sprintf("nni-%d", portNum), nil
248 case voltha.Port_PON_OLT:
249 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700250 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800251
Girish Kumarf26e4882020-03-05 06:49:10 +0000252 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530253}
254
Neha Sharma96b7bf22020-06-15 10:37:32 +0000255func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000256 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700257 if state == "up" {
258 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500259 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500260 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700261 } else {
262 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500263 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700264 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700265 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400266 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800267 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000268 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400269 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500270
Neha Sharma8f4e4322020-08-06 10:51:53 +0000271 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 +0000272 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000273 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 -0400274 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
275 "device-id": dh.device.Id,
276 "port-type": portType,
277 "port-number": portNum,
278 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500279 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400280 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500281 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400282 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700283 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400284 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700285 PortNo: portNum,
286 Label: label,
287 Type: portType,
288 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700289 OfpPort: &of.OfpPort{
290 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
291 Config: 0,
292 State: uint32(of.OfpPortState_OFPPS_LIVE),
293 Curr: capacity,
294 Advertised: capacity,
295 Peer: capacity,
296 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
297 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
298 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700299 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000300 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700301 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000302 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000303 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800304 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000305 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400306 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000307 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530308 return nil
309}
310
Kent Hagermane6ff1012020-07-14 15:07:53 -0400311func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530312 dh.lockDevice.Lock()
313 defer dh.lockDevice.Unlock()
Neha Sharma8f4e4322020-08-06 10:51:53 +0000314 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530315 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400316 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
317 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530318 }
319 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530320}
321
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700322// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530323// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800324func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000325 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700326 defer func() {
327 dh.lockDevice.Lock()
328 dh.isReadIndicationRoutineActive = false
329 dh.lockDevice.Unlock()
330 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700331 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700332 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700333 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700334 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400335 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530336 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400337 if err != nil || device == nil {
338 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000339 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400340 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400341
David Bainbridgef5879ca2019-12-13 21:17:54 +0000342 // Create an exponential backoff around re-enabling indications. The
343 // maximum elapsed time for the back off is set to 0 so that we will
344 // continue to retry. The max interval defaults to 1m, but is set
345 // here for code clarity
346 indicationBackoff := backoff.NewExponentialBackOff()
347 indicationBackoff.MaxElapsedTime = 0
348 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700349
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700350 dh.lockDevice.Lock()
351 dh.isReadIndicationRoutineActive = true
352 dh.lockDevice.Unlock()
353
Girish Gowdra3f974912020-03-23 20:35:18 -0700354Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700355 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400356 select {
357 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000358 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700359 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400360 default:
361 indication, err := indications.Recv()
362 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000363 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530364 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530365 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400366 // Use an exponential back off to prevent getting into a tight loop
367 duration := indicationBackoff.NextBackOff()
368 if duration == backoff.Stop {
369 // If we reach a maximum then warn and reset the backoff
370 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000371 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530372 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530373 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400374 indicationBackoff.Reset()
375 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700376
377 // On failure process a backoff timer while watching for stopIndications
378 // events
379 backoff := time.NewTimer(indicationBackoff.NextBackOff())
380 select {
381 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000382 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700383 if !backoff.Stop() {
384 <-backoff.C
385 }
386 break Loop
387 case <-backoff.C:
388 // backoff expired continue
389 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700390 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
391 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400392 }
393 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000394 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530395 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000396 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530397 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530398 "device-id": dh.device.Id})
399 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000400 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700401 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400402 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700403 // Close the stream, and re-initialize it
404 if err = indications.CloseSend(); err != nil {
405 // Ok to ignore here, because we landed here due to a problem on the stream
406 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000407 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530408 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530409 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700410 }
411 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
412 return err
413 }
414 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400415 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530416 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400417 // Reset backoff if we have a successful receive
418 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400419 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530420 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000421 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530422 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530423 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400424 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400425 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400426 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700427 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700428 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700429 // Close the send stream
430 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700431
Girish Gowdra3f974912020-03-23 20:35:18 -0700432 return nil
433}
434
435func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
436
437 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
438 if err != nil {
439 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
440 }
441 if indications == nil {
442 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
443 }
444
445 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400446}
447
448// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
449func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
450 switch indication.Data.(type) {
451 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
452 return true
453
454 default:
455 return false
456 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700457}
458
David K. Bainbridge794735f2020-02-11 21:01:37 -0800459func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000460 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000461 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530462 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700463 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530464 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700465 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000466 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000467 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530468 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000469 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800470 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000471 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800472 }
473 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700474}
475
David K. Bainbridge794735f2020-02-11 21:01:37 -0800476// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530477func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400478 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700479 switch indication.Data.(type) {
480 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000481 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
482 defer span.Finish()
483
David K. Bainbridge794735f2020-02-11 21:01:37 -0800484 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400485 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800486 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700487 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000488 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
489 defer span.Finish()
490
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700491 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800492 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000493 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400494 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800495 }
496 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000497 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700498 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000499 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
500 defer span.Finish()
501
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700502 intfOperInd := indication.GetIntfOperInd()
503 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800504 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000505 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400506 _ = 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 -0800507 }
508 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400509 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
510 logger.Warn(ctx, err)
511 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700512 } else if intfOperInd.GetType() == "pon" {
513 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
514 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800515 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000516 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400517 _ = 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 -0800518 }
519 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000520 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700521 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530523 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530524 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700525 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000526 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
527 defer span.Finish()
528
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700529 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000530 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700531 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800532 go func() {
533 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400534 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu-discovery", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800535 }
536 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700537 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000538 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
539 defer span.Finish()
540
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700541 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000542 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800543 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000544 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400545 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800546 }
547 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700548 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000549 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
550 defer span.Finish()
551
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700552 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000553 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 -0800554 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000555 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400556 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800557 }
558 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700559 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000560 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
561 defer span.Finish()
562
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700563 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000564 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700565 "intf-type": pktInd.IntfId,
566 "intf-id": pktInd.IntfId,
567 "gem-port-id": pktInd.GemportId,
568 "port-no": pktInd.PortNo,
569 "device-id": dh.device.Id,
570 })
571
572 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000573 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700574 "intf-type": pktInd.IntfId,
575 "intf-id": pktInd.IntfId,
576 "gem-port-id": pktInd.GemportId,
577 "port-no": pktInd.PortNo,
578 "packet": hex.EncodeToString(pktInd.Pkt),
579 "device-id": dh.device.Id,
580 })
581 }
582
David K. Bainbridge794735f2020-02-11 21:01:37 -0800583 go func() {
584 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400585 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800586 }
587 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700588 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000589 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
590 defer span.Finish()
591
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700592 portStats := indication.GetPortStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000593 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.resourceMgr.DevInfo.GetPonPorts())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700594 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000595 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
596 defer span.Finish()
597
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700598 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000599 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700600 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000601 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
602 defer span.Finish()
603
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700604 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000605 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
606 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700607 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530608}
609
610// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530611func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530612 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000613 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530614
Girish Gowdru0c588b22019-04-23 23:24:56 -0400615 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530616 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400617 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000618 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400619 }
620 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530621}
622
623// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530624func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700625 dh.lockDevice.Lock()
626 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000627 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400628
npujarec5762e2020-01-01 14:08:48 +0530629 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400630 if err != nil || device == nil {
631 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000632 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400633 }
634
635 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400636
637 //Update the device oper state and connection status
638 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400639 dh.device = cloned
640
David K. Bainbridge794735f2020-02-11 21:01:37 -0800641 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000642 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400643 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400644
645 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530646 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400647 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000648 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400649 }
650 for _, onuDevice := range onuDevices.Items {
651
652 // Update onu state as down in onu adapter
653 onuInd := oop.OnuIndication{}
654 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800655 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700656 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800657 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400658 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800659 "source": "openolt",
660 "onu-indicator": onuInd,
661 "device-type": onuDevice.Type,
662 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700663 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700664 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400665 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700666 /* Discovered ONUs entries need to be cleared , since after OLT
667 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530668 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000669 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700670 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530671}
672
673// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530674func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400675 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000676 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
677 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
678 grpc.WithInsecure(),
679 grpc.WithBlock(),
680 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000681 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000682 )),
683 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000684 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000685 )))
686
687 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530688 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530689 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000690 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400691 }
692 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530693}
694
695// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530696func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400697 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530698 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400699 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530700}
701
702// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530703func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530704 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000705 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400706
707 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530708 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
709 if err != nil || device == nil {
710 /*TODO: needs to handle error scenarios */
711 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
712 }
713 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000714 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400715
716 cloned := proto.Clone(device).(*voltha.Device)
717 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
718 cloned.OperStatus = voltha.OperStatus_UNKNOWN
719 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530720 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
721 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 -0400722 }
723
Chaitrashree G S44124192019-08-07 20:21:36 -0400724 // 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 +0530725 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400726 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530727 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400728 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400729 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
730 // all the modules initialized and ready to handle incoming ONUs.
731
Thomas Lee S985938d2020-05-04 11:40:41 +0530732 err = dh.initializeDeviceHandlerModules(ctx)
733 if err != nil {
734 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 -0400735 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400736
737 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800738 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530739 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400740 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800741 }
742 }()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400743 return nil
744 }
745
Neha Sharma8f4e4322020-08-06 10:51:53 +0000746 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400747 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400748 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400749 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400750 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400751 dh.populateActivePorts(ctx, ports)
752 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
753 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400754 }
755
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400756 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530757 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 -0400758 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530759
cuilin20187b2a8c32019-03-26 19:52:28 -0700760 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800761 go func() {
762 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400763 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800764 }
765 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000766 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000767
768 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000769 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000770 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700771 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530772}
773
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400774func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000775 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400776
777 if err != nil {
778 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
779 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400780 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000781 if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, deviceInfo); dh.resourceMgr == nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400782 return olterrors.ErrResourceManagerInstantiating
783 }
784
785 // Instantiate flow manager
786 if dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr); dh.flowMgr == nil {
787 return olterrors.ErrResourceManagerInstantiating
788
789 }
790 /* TODO: Instantiate Alarm , stats , BW managers */
791 /* Instantiating Event Manager to handle Alarms and KPIs */
792 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
793
794 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000795 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400796
797 return nil
798
799}
800
Neha Sharma96b7bf22020-06-15 10:37:32 +0000801func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400802 var err error
803 var deviceInfo *oop.DeviceInfo
804
Neha Sharma8f4e4322020-08-06 10:51:53 +0000805 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400806
807 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000808 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400809 }
810 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000811 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400812 }
813
Neha Sharma96b7bf22020-06-15 10:37:32 +0000814 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400815 dh.device.Root = true
816 dh.device.Vendor = deviceInfo.Vendor
817 dh.device.Model = deviceInfo.Model
818 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
819 dh.device.HardwareVersion = deviceInfo.HardwareVersion
820 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
821
822 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000823 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400824 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000825 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400826 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000827 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400828 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000829 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400830 dh.device.MacAddress = genmac
831 } else {
832 dh.device.MacAddress = deviceInfo.DeviceId
833 }
834
835 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000836 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000837 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400838 }
839
840 return deviceInfo, nil
841}
842
Neha Sharma96b7bf22020-06-15 10:37:32 +0000843func startCollector(ctx context.Context, dh *DeviceHandler) {
844 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530845 for {
846 select {
847 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000848 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530849 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000850 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700851
Neha Sharma8f4e4322020-08-06 10:51:53 +0000852 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400853 if err != nil {
854 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
855 continue
856 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530857 for _, port := range ports {
858 // NNI Stats
859 if port.Type == voltha.Port_ETHERNET_NNI {
860 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
861 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000862 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
863 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
864 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530865 }
866 // PON Stats
867 if port.Type == voltha.Port_PON_OLT {
868 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
869 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
870 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000871 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
872 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530873 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000874 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500875 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530876 }
877 }
878 }
879}
880
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700881//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530882func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400883 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000884 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530885 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530886
887 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400888 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
889 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530890 }
891
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400892 go startHeartbeatCheck(ctx, dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530893}
894
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700895//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530896func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700897 return &ic.SwitchCapability{
898 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530899 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700900 HwDesc: "open_pon",
901 SwDesc: "open_pon",
902 SerialNum: dh.device.SerialNumber,
903 },
904 SwitchFeatures: &of.OfpSwitchFeatures{
905 NBuffers: 256,
906 NTables: 2,
907 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
908 of.OfpCapabilities_OFPC_TABLE_STATS |
909 of.OfpCapabilities_OFPC_PORT_STATS |
910 of.OfpCapabilities_OFPC_GROUP_STATS),
911 },
912 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530913}
914
Neha Sharma96b7bf22020-06-15 10:37:32 +0000915func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
916 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 -0700917 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700918 var deviceID string
919 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700920
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400921 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700922 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000923 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 -0700924 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
925 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400926
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700927 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530928
929 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
930
Neha Sharma96b7bf22020-06-15 10:37:32 +0000931 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 -0700932 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700933 kwargs := make(map[string]interface{})
934 kwargs["onu_id"] = omciInd.OnuId
935 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700936
Neha Sharma8f4e4322020-08-06 10:51:53 +0000937 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700938 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530939 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700940 "intf-id": omciInd.IntfId,
941 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700942 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700943 deviceType = onuDevice.Type
944 deviceID = onuDevice.Id
945 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
946 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530947 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700948 } else {
949 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000950 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 +0530951 deviceType = onuInCache.(*OnuDevice).deviceType
952 deviceID = onuInCache.(*OnuDevice).deviceID
953 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700954 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700955
956 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +0000957 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530958 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800959 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530960 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530961 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800962 "destination": deviceType,
963 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000964 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700965 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800966 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530967}
968
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700969//ProcessInterAdapterMessage sends the proxied messages to the target device
970// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
971// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000972func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
973 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700974 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700975 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700976 fromTopic := msg.Header.FromTopic
977 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700978 toDeviceID := msg.Header.ToDeviceId
979 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700980
Neha Sharma96b7bf22020-06-15 10:37:32 +0000981 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 -0700982
983 msgBody := msg.GetBody()
984
985 omciMsg := &ic.InterAdapterOmciMessage{}
986 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000987 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700988 }
989
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700990 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000991 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700992 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530993 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800994 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000995 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700996 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000997 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
998 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530999 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001000 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001001 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001002 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001003 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001004 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1005 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301006 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001007 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001008 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001009 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001010 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001011 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001012 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001013 }
1014 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301015}
1016
Neha Sharma96b7bf22020-06-15 10:37:32 +00001017func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001018 var intfID uint32
1019 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001020 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001021 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001022 intfID = onuDevice.ProxyAddress.GetChannelId()
1023 onuID = onuDevice.ProxyAddress.GetOnuId()
1024 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001025 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001026 intfID = omciMsg.GetProxyAddress().GetChannelId()
1027 onuID = omciMsg.GetProxyAddress().GetOnuId()
1028 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001029 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001030 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001031 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 -08001032
Thomas Lee S94109f12020-03-03 16:39:29 +05301033 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001034 "intf-id": intfID,
1035 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001036 }
1037
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001038 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1039 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001040 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001041 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1042 hex.Encode(hexPkt, omciMsg.Message)
1043 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1044
1045 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1046 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1047 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001048 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001049 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001050
Neha Sharma8f4e4322020-08-06 10:51:53 +00001051 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001052 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301053 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001054 "intf-id": intfID,
1055 "onu-id": onuID,
1056 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001057 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001058 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001059}
1060
David K. Bainbridge794735f2020-02-11 21:01:37 -08001061func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301062 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})
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001063 if err := dh.flowMgr.UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001064 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001065 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001066 // TODO: need resource manager
1067 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301068 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301069 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001070 st, _ := status.FromError(err)
1071 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001072 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1073
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001074 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301075 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001076 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001077 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001078 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001079 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001080 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001081}
1082
David K. Bainbridge794735f2020-02-11 21:01:37 -08001083func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001084 channelID := onuDiscInd.GetIntfId()
1085 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001086
Neha Sharma96b7bf22020-06-15 10:37:32 +00001087 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301088
cuilin20187b2a8c32019-03-26 19:52:28 -07001089 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001090 if sn != "" {
1091 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001092 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001093 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001094 }
1095
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301096 var alarmInd oop.OnuAlarmIndication
1097 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001098 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301099
1100 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1101 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1102 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1103 OnuLosRaise event sent for it */
1104 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1105 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1106 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001107 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301108 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1109 "currentIntfId": onuDiscInd.GetIntfId()})
1110 // TODO:: Should we need to ignore raising OnuLosClear event
1111 // when onu connected to different PON?
1112 }
1113 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1114 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1115 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001116 go func() {
1117 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1118 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1119 }
1120 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301121 }
1122 return true
1123 })
1124
Neha Sharma96b7bf22020-06-15 10:37:32 +00001125 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001126 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001127 }
1128
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001129 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001130
1131 // check the ONU is already know to the OLT
1132 // NOTE the second time the ONU is discovered this should return a device
1133 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1134
1135 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001136 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 -08001137 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001138 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 -08001139 switch e.Code() {
1140 case codes.Internal:
1141 // this probably means NOT FOUND, so just create a new device
1142 onuDevice = nil
1143 case codes.DeadlineExceeded:
1144 // if the call times out, cleanup and exit
1145 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001146 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001147 }
1148 }
1149 }
1150
1151 if onuDevice == nil {
1152 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001153 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001154 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001155 ponintfid := onuDiscInd.GetIntfId()
1156 dh.lockDevice.Lock()
npujarec5762e2020-01-01 14:08:48 +05301157 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Matt Jeanneret53539512019-07-20 14:47:02 -04001158 dh.lockDevice.Unlock()
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001159
Neha Sharma96b7bf22020-06-15 10:37:32 +00001160 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001161
1162 if err != nil {
1163 // if we can't create an ID in resource manager,
1164 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001165 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001166 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001167 "pon-intf-id": ponintfid,
1168 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001169 }
1170
Neha Sharma8f4e4322020-08-06 10:51:53 +00001171 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001172 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001173 dh.discOnus.Delete(sn)
1174 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 +05301175 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001176 "pon-intf-id": ponintfid,
1177 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001178 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001179 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1180 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1181 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001182 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301183 log.Fields{"onuDevice": onuDevice,
1184 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001185 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301186 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001187 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001188
1189 // we can now use the existing ONU Id
1190 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001191 //Insert the ONU into cache to use in OnuIndication.
1192 //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 +00001193 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001194 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301195 "intfId": onuDiscInd.GetIntfId(),
1196 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001197 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001198
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301199 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301200 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001201 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301202 log.Fields{"onu": onuDev,
1203 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001204
Kent Hagermane6ff1012020-07-14 15:07:53 -04001205 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301206 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001207 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001208 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001209 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001210 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001211 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301212 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001213 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001214 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001215 }
1216 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001217}
1218
Neha Sharma96b7bf22020-06-15 10:37:32 +00001219func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001220 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1221
1222 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001223 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001224 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001225 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001226 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001227 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301228 log.Fields{"onuId": onuInd.OnuId,
1229 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301230 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001231 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301232
David K. Bainbridge794735f2020-02-11 21:01:37 -08001233 errFields := log.Fields{"device-id": dh.device.Id}
1234
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301235 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1236
Mahir Gunyele77977b2019-06-27 05:36:22 -07001237 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1238 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001239 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001240 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001241 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001242 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1243 if serialNumber != "" {
1244 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001245 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001246 } else {
1247 kwargs["onu_id"] = onuInd.OnuId
1248 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001249 errFields["onu-id"] = onuInd.OnuId
1250 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001251 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001252 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001253 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001254
David K. Bainbridge794735f2020-02-11 21:01:37 -08001255 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001256 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001257 }
1258
David K. Bainbridge794735f2020-02-11 21:01:37 -08001259 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001260 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001261 "previousIntfId": onuDevice.ParentPortNo,
1262 "currentIntfId": ponPort})
1263 }
1264
1265 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001266 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301267 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1268 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301269 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001270 }
1271 if !foundInCache {
1272 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1273
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301274 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 -08001275
1276 }
kesavand7cf3a052020-08-28 12:49:18 +05301277 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1278 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1279 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1280 }
1281 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001282 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001283 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001284 }
1285 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001286}
1287
Neha Sharma96b7bf22020-06-15 10:37:32 +00001288func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001289 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 -07001290 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1291 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1292 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1293 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001294 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001295 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1296 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001297 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001298 onuInd.OperState = "down"
1299 }
1300 }
1301
David K. Bainbridge794735f2020-02-11 21:01:37 -08001302 switch onuInd.OperState {
1303 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001304 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 -07001305 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301306 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001307 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1308 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301309 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001310 "onu-indicator": onuInd,
1311 "source": "openolt",
1312 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001313 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001314 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001315 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001316 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 -04001317 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301318 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001319 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1320 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301321 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001322 "onu-indicator": onuInd,
1323 "source": "openolt",
1324 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001325 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001326 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001327 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001328 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001329 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001330 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001331}
1332
cuilin20187b2a8c32019-03-26 19:52:28 -07001333func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1334 if serialNum != nil {
1335 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001336 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001337 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001338}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001339func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1340 decodedStr, err := hex.DecodeString(serialNum[4:])
1341 if err != nil {
1342 return nil, err
1343 }
1344 return &oop.SerialNumber{
1345 VendorId: []byte(serialNum[:4]),
1346 VendorSpecific: []byte(decodedStr),
1347 }, nil
1348}
cuilin20187b2a8c32019-03-26 19:52:28 -07001349
1350func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1351 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001352 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001353 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1354 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1355 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1356 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1357 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1358 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1359 return tmp
1360}
1361
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001362//UpdateFlowsBulk upates the bulk flow
1363func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301364 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001365}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001366
1367//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001368func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1369 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301370 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001371 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301372 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001373 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001374 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001375 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001376 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001377 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001378 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001379 "intf-id": parentPort,
1380 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001381 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001382 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 -08001383 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301384}
1385
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001386// SendPacketInToCore sends packet-in to core
1387// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1388// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001389func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001390 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001391 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001392 "port": logicalPort,
1393 "packet": hex.EncodeToString(packetPayload),
1394 "device-id": dh.device.Id,
1395 })
1396 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001397 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 +05301398 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001399 "source": "adapter",
1400 "destination": "core",
1401 "device-id": dh.device.Id,
1402 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001403 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001404 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001405 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001406 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001407 "packet": hex.EncodeToString(packetPayload),
1408 "device-id": dh.device.Id,
1409 })
1410 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001411 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001412}
1413
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001414// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001415func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001416 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001417
1418 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1419 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001420 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001421 }
1422
Kent Hagermane6ff1012020-07-14 15:07:53 -04001423 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001424 metrics := dh.metrics.GetSubscriberMetrics()
1425 for _, m := range pmConfigs.Metrics {
1426 metrics[m.Name].Enabled = m.Enabled
1427
1428 }
1429 }
1430}
1431
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001432//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301433func (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 +00001434 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 +01001435
1436 var errorsList []error
1437
Girish Gowdru0c588b22019-04-23 23:24:56 -04001438 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001439 for _, flow := range flows.ToRemove.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001440 dh.incrementActiveFlowRemoveCount(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001441
Neha Sharma96b7bf22020-06-15 10:37:32 +00001442 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301443 log.Fields{"device-id": device.Id,
1444 "flowToRemove": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001445 err := dh.flowMgr.RemoveFlow(ctx, flow)
1446 if err != nil {
1447 errorsList = append(errorsList, err)
1448 }
1449
Neha Sharma96b7bf22020-06-15 10:37:32 +00001450 dh.decrementActiveFlowRemoveCount(ctx, flow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001451 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301452
1453 for _, flow := range flows.ToAdd.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001454 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301455 log.Fields{"device-id": device.Id,
1456 "flowToAdd": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001457 // If there are active Flow Remove in progress for a given subscriber, wait until it completes
Neha Sharma96b7bf22020-06-15 10:37:32 +00001458 dh.waitForFlowRemoveToFinish(ctx, flow)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001459 err := dh.flowMgr.AddFlow(ctx, flow, flowMetadata)
1460 if err != nil {
1461 errorsList = append(errorsList, err)
1462 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301463 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001464 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001465
Girish Gowdracefae192020-03-19 18:14:10 -07001466 // 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 +00001467 if groups != nil {
1468 for _, group := range groups.ToAdd.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001469 err := dh.flowMgr.AddGroup(ctx, group)
1470 if err != nil {
1471 errorsList = append(errorsList, err)
1472 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001473 }
1474 for _, group := range groups.ToUpdate.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001475 err := dh.flowMgr.ModifyGroup(ctx, group)
1476 if err != nil {
1477 errorsList = append(errorsList, err)
1478 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001479 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001480 for _, group := range groups.ToRemove.Items {
1481 err := dh.flowMgr.DeleteGroup(ctx, group)
1482 if err != nil {
1483 errorsList = append(errorsList, err)
1484 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001485 }
1486 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001487 if len(errorsList) > 0 {
1488 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1489 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001490 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001491 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301492}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001493
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001494//DisableDevice disables the given device
1495//It marks the following for the given device:
1496//Device-Handler Admin-State : down
1497//Device Port-State: UNKNOWN
1498//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001499func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001500 /* On device disable ,admin state update has to be done prior sending request to agent since
1501 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001502 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001503 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001504 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001505 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001506 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001507 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001508 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001509 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001510 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001511 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301512
1513 dh.discOnus = sync.Map{}
1514 dh.onus = sync.Map{}
1515
Thomas Lee S85f37312020-04-03 17:06:12 +05301516 //stopping the stats collector
1517 dh.stopCollector <- true
1518
Neha Sharma96b7bf22020-06-15 10:37:32 +00001519 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001520 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301521 //Update device Admin state
1522 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001523 // 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 +00001524 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 -04001525 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001526 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001527 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001528 return nil
1529}
1530
Neha Sharma96b7bf22020-06-15 10:37:32 +00001531func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001532 // Update onu state as unreachable in onu adapter
1533 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301534 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001535 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001536 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001537 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001538 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 -04001539 }
1540 if onuDevices != nil {
1541 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001542 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001543 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1544 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001545 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301546 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001547 }
1548
1549 }
1550 }
1551
1552}
1553
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001554//ReenableDevice re-enables the olt device after disable
1555//It marks the following for the given device:
1556//Device-Handler Admin-State : up
1557//Device Port-State: ACTIVE
1558//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001559func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001560 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301561 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001562 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301563 }
1564 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001565 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001566
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001567 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001568
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001569 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1570 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001571 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001572 }
1573 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001574 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001575 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001576 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001577 device.OperStatus = voltha.OperStatus_ACTIVE
1578 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001579
Neha Sharma8f4e4322020-08-06 10:51:53 +00001580 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 +05301581 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001582 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001583 "connect-status": device.ConnectStatus,
1584 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001585 }
kesavand39e0aa32020-01-28 20:58:50 -05001586
Neha Sharma96b7bf22020-06-15 10:37:32 +00001587 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001588
1589 return nil
1590}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001591
npujarec5762e2020-01-01 14:08:48 +05301592func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001593 var uniID uint32
1594 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301595 for _, port := range onu.UniPorts {
1596 uniID = UniIDFromPortNum(uint32(port))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001597 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001598 /* Delete tech-profile instance from the KV store */
npujarec5762e2020-01-01 14:08:48 +05301599 if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001600 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001601 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001602 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301603 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001604 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301605 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001606 }
npujarec5762e2020-01-01 14:08:48 +05301607 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001608 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301609 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001610 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001611 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001612 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301613 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001614 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001615 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001616 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301617 }
npujarec5762e2020-01-01 14:08:48 +05301618 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1619 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001620 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301621 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001622 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Esin Karaman7fb80c22020-07-16 14:23:33 +00001623 if err = dh.resourceMgr.DelGemPortPktInOfAllServices(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001624 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 +00001625 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001626 }
1627 return nil
1628}
1629
npujarec5762e2020-01-01 14:08:48 +05301630func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001631 nniUniID := -1
1632 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301633
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001634 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301635 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001636 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001637 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301638 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301639 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001640 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001641 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001642 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301643 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301644 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001645 logger.Debugw(ctx, "current-flow-ids-for-nni", log.Fields{"flow-ids": flowIDs})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301646 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301647 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301648 }
npujarec5762e2020-01-01 14:08:48 +05301649 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001650 }
npujarec5762e2020-01-01 14:08:48 +05301651 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001652 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301653 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001654 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001655}
1656
1657// 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 +05301658func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001659 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001660 /* Clear the KV store data associated with the all the UNI ports
1661 This clears up flow data and also resource map data for various
1662 other pon resources like alloc_id and gemport_id
1663 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001664 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001665 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001666 // Stop the Stats collector
1667 dh.stopCollector <- true
1668 // stop the heartbeat check routine
1669 dh.stopHeartbeatCheck <- true
1670 //Reset the state
1671 if dh.Client != nil {
1672 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301673 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001674 }
1675 }
1676 cloned := proto.Clone(device).(*voltha.Device)
1677 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1678 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1679 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1680 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1681 "device-id": device.Id,
1682 "connect-status": cloned.ConnectStatus,
1683 "oper-status": cloned.OperStatus}, err).Log()
1684 }
1685 return nil
1686}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001687func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001688
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001689 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301690 noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
1691 var ponPort uint32
1692 for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
1693 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301694 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301695 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001696 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001697 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001698 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301699 }
1700 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301701 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001702 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301703 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001704 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301705 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301706 // Clear flowids for gem cache.
1707 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301708 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301709 }
1710 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301711 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301712 }
npujarec5762e2020-01-01 14:08:48 +05301713 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301714 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301715 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301716 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001717 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001718 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001719 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001720 /* Clear the flows from KV store associated with NNI port.
1721 There are mostly trap rules from NNI port (like LLDP)
1722 */
npujarec5762e2020-01-01 14:08:48 +05301723 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001724 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001725 }
A R Karthick1f85b802019-10-11 05:06:05 +00001726
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001727 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001728 go func() {
1729 if err := dh.resourceMgr.Delete(ctx); err != nil {
1730 logger.Debug(ctx, err)
1731 }
1732 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001733 }
A R Karthick1f85b802019-10-11 05:06:05 +00001734
Devmalya Paul495b94a2019-08-27 19:42:00 -04001735 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301736 dh.onus.Range(func(key interface{}, value interface{}) bool {
1737 dh.onus.Delete(key)
1738 return true
1739 })
1740
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001741 /*Delete discovered ONU map for the device*/
1742 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1743 dh.discOnus.Delete(key)
1744 return true
1745 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001746}
1747
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001748//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001749func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001750 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301751 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001752 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001753 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001754 return nil
1755}
1756
David K. Bainbridge794735f2020-02-11 21:01:37 -08001757func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001758 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001759 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001760 "packet-indication": *packetIn,
1761 "device-id": dh.device.Id,
1762 "packet": hex.EncodeToString(packetIn.Pkt),
1763 })
1764 }
npujarec5762e2020-01-01 14:08:48 +05301765 logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001766 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001767 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001768 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001769 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001770 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001771 "logical-port-num": logicalPortNum,
1772 "device-id": dh.device.Id,
1773 "packet": hex.EncodeToString(packetIn.Pkt),
1774 })
1775 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001776
Neha Sharma8f4e4322020-08-06 10:51:53 +00001777 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 +05301778 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001779 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301780 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001781 "device-id": dh.device.Id,
1782 "packet": hex.EncodeToString(packetIn.Pkt),
1783 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001784 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001785
Matteo Scandolo92186242020-06-12 10:54:18 -07001786 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001787 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001788 "packet": hex.EncodeToString(packetIn.Pkt),
1789 "device-id": dh.device.Id,
1790 })
1791 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001792 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001793}
1794
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001795// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301796func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001797 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001798 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001799 "device-id": dh.device.Id,
1800 "egress-port-no": egressPortNo,
1801 "pkt-length": len(packet.Data),
1802 "packet": hex.EncodeToString(packet.Data),
1803 })
1804 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001805
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001806 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001807 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001808 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1809 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301810 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1811 // Do not packet-out lldp packets on uni port.
1812 // ONOS has no clue about uni/nni ports, it just packets out on all
1813 // available ports on the Logical Switch. It should not be interested
1814 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001815 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001816 "device-id": dh.device.Id,
1817 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301818 return nil
1819 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001820 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1821 if innerEthType == 0x8100 {
1822 // q-in-q 802.1ad or 802.1q double tagged packet.
1823 // slice out the outer tag.
1824 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001825 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001826 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001827 "packet-data": hex.EncodeToString(packet.Data),
1828 "device-id": dh.device.Id,
1829 })
1830 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001831 }
1832 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001833 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1834 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001835 uniID := UniIDFromPortNum(uint32(egressPortNo))
1836
Esin Karaman7fb80c22020-07-16 14:23:33 +00001837 gemPortID, err := dh.flowMgr.GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001838 if err != nil {
1839 // In this case the openolt agent will receive the gemPortID as 0.
1840 // The agent tries to retrieve the gemPortID in this case.
1841 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001842 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001843 "intf-id": intfID,
1844 "onu-id": onuID,
1845 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001846 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301847 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001848 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001849 }
1850
1851 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001852
Matteo Scandolo92186242020-06-12 10:54:18 -07001853 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001854 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001855 "egress-port-no": egressPortNo,
1856 "intf-id": intfID,
1857 "onu-id": onuID,
1858 "uni-id": uniID,
1859 "gem-port-id": gemPortID,
1860 "packet": hex.EncodeToString(packet.Data),
1861 "device-id": dh.device.Id,
1862 })
1863 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001864
npujarec5762e2020-01-01 14:08:48 +05301865 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301866 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001867 "source": "adapter",
1868 "destination": "onu",
1869 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001870 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001871 "oni-id": onuID,
1872 "uni-id": uniID,
1873 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001874 "packet": hex.EncodeToString(packet.Data),
1875 "device-id": dh.device.Id,
1876 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001877 }
1878 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001879 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001880 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001881 return olterrors.NewErrInvalidValue(log.Fields{
1882 "egress-nni-port": egressPortNo,
1883 "device-id": dh.device.Id,
1884 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001885 }
1886 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001887
Matteo Scandolo92186242020-06-12 10:54:18 -07001888 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001889 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001890 "uplink-pkt": uplinkPkt,
1891 "packet": hex.EncodeToString(packet.Data),
1892 "device-id": dh.device.Id,
1893 })
1894 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001895
npujarec5762e2020-01-01 14:08:48 +05301896 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001897 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1898 "packet": hex.EncodeToString(packet.Data),
1899 "device-id": dh.device.Id,
1900 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001901 }
1902 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001903 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301904 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001905 "egressPortType": egressPortType,
1906 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301907 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001908 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001909 }
1910 return nil
1911}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001912
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001913func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1914 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001915}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301916
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001917func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001918
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301919 // start the heartbeat check towards the OLT.
1920 var timerCheck *time.Timer
1921
1922 for {
1923 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1924 select {
1925 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001926 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001927 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001928 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301929 if timerCheck == nil {
1930 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001931 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301932 }
1933 } else {
1934 if timerCheck != nil {
1935 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001936 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301937 }
1938 timerCheck = nil
1939 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001940 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301941 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301942 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301943 }
1944 cancel()
1945 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001946 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301947 return
1948 }
1949 }
1950}
1951
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001952func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1953 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1954 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001955 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001956 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301957
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001958 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1959 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001960 _ = 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 -04001961 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001962 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001963 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001964 }
1965 go dh.cleanupDeviceResources(ctx)
1966
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001967 dh.lockDevice.RLock()
1968 // Stop the read indication only if it the routine is active
1969 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1970 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1971 // on next execution of the readIndication routine.
1972 if dh.isReadIndicationRoutineActive {
1973 dh.stopIndications <- true
1974 }
1975 dh.lockDevice.RUnlock()
1976
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001977 dh.transitionMap.Handle(ctx, DeviceInit)
1978
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301979 }
1980}
kesavand39e0aa32020-01-28 20:58:50 -05001981
1982// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001983func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1984 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1985 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001986}
1987
1988// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001989func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1990 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1991 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001992}
1993
kdarapu1afeceb2020-02-12 01:38:09 -05001994//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 +00001995func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1996 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001997 if port.GetType() == voltha.Port_ETHERNET_NNI {
1998 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001999 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302000 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302001 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002002 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002003 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002004 }
2005 // fetch interfaceid from PortNo
2006 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2007 ponIntf := &oop.Interface{IntfId: ponID}
2008 var operStatus voltha.OperStatus_Types
2009 if enablePort {
2010 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302011 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002012
2013 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302014 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002015 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002016 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002017 }
2018 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002019 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002020 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002021 } else {
2022 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302023 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002024 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302025 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002026 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002027 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002028 }
2029 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002030 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002031 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002032 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302033 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 +05302034 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302035 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002036 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002037 }
2038 return nil
2039}
2040
kdarapu1afeceb2020-02-12 01:38:09 -05002041//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002042func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002043 // Disable the port and update the oper_port_status to core
2044 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002045 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002046 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002047 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302048 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302049 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002050 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002051 }
2052 }
2053 }
2054 return nil
2055}
2056
2057//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002058func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2059 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2060 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002061 if port.Type == voltha.Port_ETHERNET_NNI {
2062 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002063 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002064 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002065 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002066 }
2067 }
2068 if port.Type == voltha.Port_PON_OLT {
2069 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002070 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002071 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002072 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002073 }
2074 }
2075 }
2076}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002077
2078// ChildDeviceLost deletes ONU and clears pon resources related to it.
2079func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
divyadesai3af43e12020-08-18 07:10:54 +00002080 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002081 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2082 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002083 onuDevice, ok := dh.onus.Load(onuKey)
2084 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302085 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002086 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002087 "device-id": dh.device.Id,
2088 "onu-id": onuID,
2089 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002090 }
2091 var sn *oop.SerialNumber
2092 var err error
2093 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302094 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002095 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302096 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002097 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2098 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002099
2100 for uniID := 0; uniID < MaxUnisPerOnu; uniID++ {
2101 var flowRemoveData pendingFlowRemoveData
2102 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uint32(uniID)}
2103 dh.lockDevice.RLock()
2104 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
2105 dh.lockDevice.RUnlock()
2106 continue
2107 }
2108 dh.lockDevice.RUnlock()
2109
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002110 logger.Debugw(ctx, "wait-for-flow-remove-complete-before-processing-child-device-lost",
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002111 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2112 // Wait for all flow removes to finish first
2113 <-flowRemoveData.allFlowsRemoved
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002114 logger.Debugw(ctx, "flow-removes-complete-for-subscriber",
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002115 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2116 }
2117
2118 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Neha Sharma8f4e4322020-08-06 10:51:53 +00002119 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302120 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302121 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002122 "onu-id": onuID}, err).Log()
2123 }
2124 //clear PON resources associated with ONU
2125 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002126 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002127 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002128 "device-id": dh.device.Id,
2129 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002130 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002131 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002132 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002133 "device-id": dh.device.Id,
2134 "intf-id": intfID,
2135 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002136 } else {
2137 for i, onu := range onuGemData {
2138 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002139 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002140 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002141 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302142 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002143 "onu-device": onu,
2144 "error": err})
2145 }
2146 // Clear flowids for gem cache.
2147 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002148 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002149 }
2150 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002151 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002152 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002153 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002154 "intf-id": intfID,
2155 "onu-device": onu,
2156 "onu-gem": onuGemData,
2157 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002158 //Not returning error on cleanup.
2159 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002160 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002161 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002162 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002163 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002164 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002165 }
2166 }
2167 dh.onus.Delete(onuKey)
2168 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2169 return nil
2170}
Girish Gowdracefae192020-03-19 18:14:10 -07002171
2172func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2173 for _, field := range flows.GetOfbFields(flow) {
2174 if field.Type == flows.IN_PORT {
2175 return field.GetPort()
2176 }
2177 }
2178 return InvalidPort
2179}
2180
2181func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2182 for _, action := range flows.GetActions(flow) {
2183 if action.Type == flows.OUTPUT {
2184 if out := action.GetOutput(); out != nil {
2185 return out.GetPort()
2186 }
2187 }
2188 }
2189 return InvalidPort
2190}
2191
Neha Sharma96b7bf22020-06-15 10:37:32 +00002192func (dh *DeviceHandler) incrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002193 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002194 logger.Debugw(ctx, "increment-flow-remove-count-for-inPort-out-port", log.Fields{"inPort": inPort, "out-port": outPort})
Girish Gowdracefae192020-03-19 18:14:10 -07002195 if inPort != InvalidPort && outPort != InvalidPort {
2196 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2197 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002198 logger.Debugw(ctx, "increment-flow-remove-count-for-subscriber", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002199
2200 dh.lockDevice.Lock()
2201 defer dh.lockDevice.Unlock()
2202 flowRemoveData, ok := dh.pendingFlowRemoveDataPerSubscriber[key]
2203 if !ok {
2204 flowRemoveData = pendingFlowRemoveData{
2205 pendingFlowRemoveCount: 0,
2206 allFlowsRemoved: make(chan struct{}),
2207 }
2208 }
2209 flowRemoveData.pendingFlowRemoveCount++
2210 dh.pendingFlowRemoveDataPerSubscriber[key] = flowRemoveData
2211
Neha Sharma96b7bf22020-06-15 10:37:32 +00002212 logger.Debugw(ctx, "current-flow-remove-count–increment",
Matteo Scandolo92186242020-06-12 10:54:18 -07002213 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002214 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2215 }
2216}
2217
Neha Sharma96b7bf22020-06-15 10:37:32 +00002218func (dh *DeviceHandler) decrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002219 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002220 logger.Debugw(ctx, "decrement-flow-remove-count-for-inPort-out-port", log.Fields{"inPort": inPort, "out-port": outPort})
Girish Gowdracefae192020-03-19 18:14:10 -07002221 if inPort != InvalidPort && outPort != InvalidPort {
2222 _, intfID, onuID, uniID := ExtractAccessFromFlow(uint32(inPort), uint32(outPort))
2223 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002224 logger.Debugw(ctx, "decrement-flow-remove-count-for-subscriber", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002225
2226 dh.lockDevice.Lock()
2227 defer dh.lockDevice.Unlock()
2228 if val, ok := dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002229 logger.Fatalf(ctx, "flow-remove-key-not-found", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002230 } else {
2231 if val.pendingFlowRemoveCount > 0 {
2232 val.pendingFlowRemoveCount--
2233 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002234 logger.Debugw(ctx, "current-flow-remove-count-after-decrement",
Matteo Scandolo92186242020-06-12 10:54:18 -07002235 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002236 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2237 // If all flow removes have finished, then close the channel to signal the receiver
2238 // to go ahead with flow adds.
2239 if val.pendingFlowRemoveCount == 0 {
2240 close(val.allFlowsRemoved)
2241 delete(dh.pendingFlowRemoveDataPerSubscriber, key)
2242 return
2243 }
2244 dh.pendingFlowRemoveDataPerSubscriber[key] = val
2245 }
2246 }
2247}
2248
Neha Sharma96b7bf22020-06-15 10:37:32 +00002249func (dh *DeviceHandler) waitForFlowRemoveToFinish(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002250 var flowRemoveData pendingFlowRemoveData
2251 var ok bool
2252 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002253 logger.Debugw(ctx, "wait-for-flow-remove-to-finish-for-inPort-out-port", log.Fields{"inPort": inPort, "out-port": outPort})
Girish Gowdracefae192020-03-19 18:14:10 -07002254 if inPort != InvalidPort && outPort != InvalidPort {
2255 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2256 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002257 logger.Debugw(ctx, "wait-for-flow-remove-to-finish-for-subscriber", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002258
2259 dh.lockDevice.RLock()
2260 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002261 logger.Debugw(ctx, "no-pending-flow-to-remove", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002262 dh.lockDevice.RUnlock()
2263 return
2264 }
2265 dh.lockDevice.RUnlock()
2266
2267 // Wait for all flow removes to finish first
2268 <-flowRemoveData.allFlowsRemoved
2269
Neha Sharma96b7bf22020-06-15 10:37:32 +00002270 logger.Debugw(ctx, "all-flows-cleared--handling-flow-add-now", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002271 }
2272}
2273
2274func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2275 inPort := getInPortFromFlow(flow)
2276 outPort := getOutPortFromFlow(flow)
2277
2278 if inPort == InvalidPort || outPort == InvalidPort {
2279 return inPort, outPort
2280 }
2281
2282 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2283 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2284 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2285 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2286 return uniPort, outPort
2287 }
2288 }
2289 } else {
2290 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2291 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2292 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2293 return inPort, uniPort
2294 }
2295 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2296 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2297 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2298 return uniPort, outPort
2299 }
2300 }
2301 }
2302
2303 return InvalidPort, InvalidPort
2304}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002305
2306func extractOmciTransactionID(omciPkt []byte) uint16 {
2307 if len(omciPkt) > 3 {
2308 d := omciPkt[0:2]
2309 transid := binary.BigEndian.Uint16(d)
2310 return transid
2311 }
2312 return 0
2313}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002314
2315// StoreOnuDevice stores the onu parameters to the local cache.
2316func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2317 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2318 dh.onus.Store(onuKey, onuDevice)
2319}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002320
Neha Sharma8f4e4322020-08-06 10:51:53 +00002321func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002322 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002323 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002324 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002325 resp := new(voltha.ReturnValues)
2326 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002327 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002328 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002329 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2330 return nil, err
2331 }
2332 ID = device.ProxyAddress.GetOnuId()
2333 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2334 valueparam.Onu = &Onu
2335 valueparam.Value = value
2336
2337 // This API is unsupported until agent patch is added
2338 resp.Unsupported = uint32(value)
2339 _ = ctx
2340
2341 // Uncomment this code once agent changes are complete and tests
2342 /*
2343 resp, err = dh.Client.GetValue(ctx, valueparam)
2344 if err != nil {
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002345 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002346 return nil, err
2347 }
2348 */
2349
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002350 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 -08002351 return resp, nil
2352}