blob: f735e27b1913bd08861a98bc5720871f309faab7 [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"
Girish Kumar93e91742020-07-27 16:43:19 +000048 "github.com/opentracing/opentracing-go"
cuilin20187b2a8c32019-03-26 19:52:28 -070049 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040050 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040051 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053052)
53
salmansiddiqui7ac62132019-08-22 03:58:50 +000054// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040055const (
salmansiddiqui7ac62132019-08-22 03:58:50 +000056 MaxRetry = 10
57 MaxTimeOutInMs = 500
Girish Gowdracefae192020-03-19 18:14:10 -070058 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040059)
60
Girish Gowdracefae192020-03-19 18:14:10 -070061// pendingFlowRemoveDataKey is key to pendingFlowRemoveDataPerSubscriber map
62type pendingFlowRemoveDataKey struct {
63 intfID uint32
64 onuID uint32
65 uniID uint32
66}
67
68// pendingFlowRemoveData is value stored in pendingFlowRemoveDataPerSubscriber map
69// This holds the number of pending flow removes and also a signal channel to
70// to indicate the receiver when all flow removes are handled
71type pendingFlowRemoveData struct {
72 pendingFlowRemoveCount uint32
73 allFlowsRemoved chan struct{}
74}
75
Phaneendra Manda4c62c802019-03-06 21:37:49 +053076//DeviceHandler will interact with the OLT device.
77type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070078 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053079 coreProxy adapterif.CoreProxy
80 AdapterProxy adapterif.AdapterProxy
81 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070082 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070083 exitChannel chan int
84 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053085 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070086 transitionMap *TransitionMap
87 clientCon *grpc.ClientConn
manikkaraj kbf256be2019-03-25 00:13:48 +053088 flowMgr *OpenOltFlowMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040089 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053090 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053091
Girish Gowdra3ab6d212020-03-24 17:33:15 -070092 discOnus sync.Map
93 onus sync.Map
94 portStats *OpenOltStatisticsMgr
95 metrics *pmmetrics.PmMetrics
96 stopCollector chan bool
97 stopHeartbeatCheck chan bool
98 activePorts sync.Map
99 stopIndications chan bool
100 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -0700101
102 // pendingFlowRemoveDataPerSubscriber map is used to maintain the context on a per
103 // subscriber basis for the number of pending flow removes. This data is used
104 // to process all the flow removes for a subscriber before handling flow adds.
105 // Interleaving flow delete and flow add processing has known to cause PON resource
106 // management contentions on a per subscriber bases, so we need ensure ordering.
107 pendingFlowRemoveDataPerSubscriber map[pendingFlowRemoveDataKey]pendingFlowRemoveData
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700108}
109
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700110//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700111type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700112 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700113 deviceType string
114 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700115 onuID uint32
116 intfID uint32
117 proxyDeviceID string
A R Karthick1f85b802019-10-11 05:06:05 +0000118 uniPorts map[uint32]struct{}
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530119 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400120 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700121}
122
Naga Manjunath7615e552019-10-11 22:35:47 +0530123var pmNames = []string{
124 "rx_bytes",
125 "rx_packets",
126 "rx_mcast_packets",
127 "rx_bcast_packets",
128 "tx_bytes",
129 "tx_packets",
130 "tx_mcast_packets",
131 "tx_bcast_packets",
132}
133
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700134//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530135func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700136 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700137 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700138 device.deviceType = deviceTp
139 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700140 device.onuID = onuID
141 device.intfID = intfID
142 device.proxyDeviceID = proxyDevID
A R Karthick1f85b802019-10-11 05:06:05 +0000143 device.uniPorts = make(map[uint32]struct{})
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530144 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700145 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530146}
147
148//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530149func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700150 var dh DeviceHandler
151 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400152 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400153 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700154 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700155 dh.device = cloned
156 dh.openOLT = adapter
157 dh.exitChannel = make(chan int, 1)
158 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530159 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530160 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530161 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 -0500162 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400163 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700164 dh.pendingFlowRemoveDataPerSubscriber = make(map[pendingFlowRemoveDataKey]pendingFlowRemoveData)
165
cuilin20187b2a8c32019-03-26 19:52:28 -0700166 //TODO initialize the support classes.
167 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530168}
169
170// start save the device to the data model
171func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700172 dh.lockDevice.Lock()
173 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000174 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700175 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000176 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530177}
178
179// stop stops the device dh. Not much to do for now
180func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700181 dh.lockDevice.Lock()
182 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000183 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700184 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000185 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530186}
187
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400188func macifyIP(ip net.IP) string {
189 if len(ip) > 0 {
190 oct1 := strconv.FormatInt(int64(ip[12]), 16)
191 oct2 := strconv.FormatInt(int64(ip[13]), 16)
192 oct3 := strconv.FormatInt(int64(ip[14]), 16)
193 oct4 := strconv.FormatInt(int64(ip[15]), 16)
194 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
195 }
196 return ""
197}
198
Neha Sharma96b7bf22020-06-15 10:37:32 +0000199func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400200 var genmac string
201 var addr net.IP
202 var ips []string
203 var err error
204
Neha Sharma96b7bf22020-06-15 10:37:32 +0000205 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400206
207 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000208 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400209
210 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000211 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400212 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000213 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400214 }
215 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000216 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530217 log.Fields{"host": ips[0],
218 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400219 return genmac, nil
220 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000221 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400222 }
223
224 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000225 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530226 log.Fields{"host": host,
227 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400228 return genmac, nil
229}
230
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530231func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700232 slist := strings.Split(mac, ":")
233 result := make([]uint32, len(slist))
234 var err error
235 var tmp int64
236 for index, val := range slist {
237 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
238 return []uint32{1, 2, 3, 4, 5, 6}
239 }
240 result[index] = uint32(tmp)
241 }
242 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530243}
244
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700245//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 -0800246func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530247
David K. Bainbridge794735f2020-02-11 21:01:37 -0800248 switch portType {
249 case voltha.Port_ETHERNET_NNI:
250 return fmt.Sprintf("nni-%d", portNum), nil
251 case voltha.Port_PON_OLT:
252 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700253 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800254
Girish Kumarf26e4882020-03-05 06:49:10 +0000255 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530256}
257
Neha Sharma96b7bf22020-06-15 10:37:32 +0000258func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000259 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700260 if state == "up" {
261 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500262 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500263 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700264 } else {
265 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500266 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700267 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700268 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400269 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800270 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000271 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400272 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500273
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400274 if port, err := dh.coreProxy.GetDevicePort(context.TODO(), dh.device.Id, portNum); err == nil && port.Type == portType {
275 log.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
276 if err := dh.coreProxy.PortStateUpdate(context.TODO(), dh.device.Id, portType, portNum, operStatus); err != nil {
277 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
278 "device-id": dh.device.Id,
279 "port-type": portType,
280 "port-number": portNum,
281 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500282 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400283 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500284 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400285 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700286 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400287 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700288 PortNo: portNum,
289 Label: label,
290 Type: portType,
291 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700292 OfpPort: &of.OfpPort{
293 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
294 Config: 0,
295 State: uint32(of.OfpPortState_OFPPS_LIVE),
296 Curr: capacity,
297 Advertised: capacity,
298 Peer: capacity,
299 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
300 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
301 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700302 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000303 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700304 // Synchronous call to update device - this method is run in its own go routine
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700305 if err := dh.coreProxy.PortCreated(context.TODO(), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000306 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800307 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000308 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400309 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000310 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530311 return nil
312}
313
Kent Hagermane6ff1012020-07-14 15:07:53 -0400314func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530315 dh.lockDevice.Lock()
316 defer dh.lockDevice.Unlock()
317 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
318 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400319 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
320 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530321 }
322 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530323}
324
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700325// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530326// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800327func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000328 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700329 defer func() {
330 dh.lockDevice.Lock()
331 dh.isReadIndicationRoutineActive = false
332 dh.lockDevice.Unlock()
333 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700334 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700335 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700336 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700337 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400338 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530339 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400340 if err != nil || device == nil {
341 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000342 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400343 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400344
David Bainbridgef5879ca2019-12-13 21:17:54 +0000345 // Create an exponential backoff around re-enabling indications. The
346 // maximum elapsed time for the back off is set to 0 so that we will
347 // continue to retry. The max interval defaults to 1m, but is set
348 // here for code clarity
349 indicationBackoff := backoff.NewExponentialBackOff()
350 indicationBackoff.MaxElapsedTime = 0
351 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700352
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700353 dh.lockDevice.Lock()
354 dh.isReadIndicationRoutineActive = true
355 dh.lockDevice.Unlock()
356
Girish Gowdra3f974912020-03-23 20:35:18 -0700357Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700358 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400359 select {
360 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000361 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700362 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400363 default:
364 indication, err := indications.Recv()
365 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000366 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530367 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530368 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400369 // Use an exponential back off to prevent getting into a tight loop
370 duration := indicationBackoff.NextBackOff()
371 if duration == backoff.Stop {
372 // If we reach a maximum then warn and reset the backoff
373 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000374 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530375 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530376 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400377 indicationBackoff.Reset()
378 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700379
380 // On failure process a backoff timer while watching for stopIndications
381 // events
382 backoff := time.NewTimer(indicationBackoff.NextBackOff())
383 select {
384 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000385 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700386 if !backoff.Stop() {
387 <-backoff.C
388 }
389 break Loop
390 case <-backoff.C:
391 // backoff expired continue
392 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700393 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
394 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400395 }
396 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000397 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530398 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000399 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530400 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530401 "device-id": dh.device.Id})
402 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000403 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700404 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400405 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700406 // Close the stream, and re-initialize it
407 if err = indications.CloseSend(); err != nil {
408 // Ok to ignore here, because we landed here due to a problem on the stream
409 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000410 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530411 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530412 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700413 }
414 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
415 return err
416 }
417 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400418 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530419 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400420 // Reset backoff if we have a successful receive
421 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400422 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530423 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000424 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530425 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530426 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400427 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400428 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400429 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700430 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700431 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700432 // Close the send stream
433 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700434
Girish Gowdra3f974912020-03-23 20:35:18 -0700435 return nil
436}
437
438func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
439
440 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
441 if err != nil {
442 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
443 }
444 if indications == nil {
445 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
446 }
447
448 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400449}
450
451// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
452func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
453 switch indication.Data.(type) {
454 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
455 return true
456
457 default:
458 return false
459 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700460}
461
David K. Bainbridge794735f2020-02-11 21:01:37 -0800462func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000463 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000464 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530465 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700466 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530467 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700468 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000469 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000470 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530471 return olterrors.NewErrAdapter("failed-indication", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530472 "device_id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800473 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000474 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800475 }
476 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700477}
478
David K. Bainbridge794735f2020-02-11 21:01:37 -0800479// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530480func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400481 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700482 switch indication.Data.(type) {
483 case *oop.Indication_OltInd:
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:
488 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800489 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000490 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400491 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800492 }
493 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000494 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700495 case *oop.Indication_IntfOperInd:
496 intfOperInd := indication.GetIntfOperInd()
497 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800498 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000499 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400500 _ = 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 -0800501 }
502 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400503 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
504 logger.Warn(ctx, err)
505 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700506 } else if intfOperInd.GetType() == "pon" {
507 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
508 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800509 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000510 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400511 _ = 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 -0800512 }
513 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000514 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700515 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000516 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530517 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530518 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700519 case *oop.Indication_OnuDiscInd:
520 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000521 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700522 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800523 go func() {
524 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400525 _ = 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 -0800526 }
527 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700528 case *oop.Indication_OnuInd:
529 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000530 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800531 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000532 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400533 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800534 }
535 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700536 case *oop.Indication_OmciInd:
537 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000538 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 -0800539 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000540 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400541 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800542 }
543 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700544 case *oop.Indication_PktInd:
545 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000546 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700547 "intf-type": pktInd.IntfId,
548 "intf-id": pktInd.IntfId,
549 "gem-port-id": pktInd.GemportId,
550 "port-no": pktInd.PortNo,
551 "device-id": dh.device.Id,
552 })
553
554 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000555 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700556 "intf-type": pktInd.IntfId,
557 "intf-id": pktInd.IntfId,
558 "gem-port-id": pktInd.GemportId,
559 "port-no": pktInd.PortNo,
560 "packet": hex.EncodeToString(pktInd.Pkt),
561 "device-id": dh.device.Id,
562 })
563 }
564
David K. Bainbridge794735f2020-02-11 21:01:37 -0800565 go func() {
566 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400567 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800568 }
569 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700570 case *oop.Indication_PortStats:
571 portStats := indication.GetPortStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000572 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.resourceMgr.DevInfo.GetPonPorts())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 case *oop.Indication_FlowStats:
574 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000575 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700576 case *oop.Indication_AlarmInd:
577 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000578 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
579 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700580 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530581}
582
583// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530584func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530585 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000586 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530587
Girish Gowdru0c588b22019-04-23 23:24:56 -0400588 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530589 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400590 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000591 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400592 }
593 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530594}
595
596// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530597func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700598 dh.lockDevice.Lock()
599 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000600 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400601
npujarec5762e2020-01-01 14:08:48 +0530602 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400603 if err != nil || device == nil {
604 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000605 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400606 }
607
608 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400609
610 //Update the device oper state and connection status
611 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400612 dh.device = cloned
613
David K. Bainbridge794735f2020-02-11 21:01:37 -0800614 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000615 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400616 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400617
618 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530619 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400620 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000621 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400622 }
623 for _, onuDevice := range onuDevices.Items {
624
625 // Update onu state as down in onu adapter
626 onuInd := oop.OnuIndication{}
627 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800628 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700629 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800630 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400631 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800632 "source": "openolt",
633 "onu-indicator": onuInd,
634 "device-type": onuDevice.Type,
635 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700636 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700637 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400638 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700639 /* Discovered ONUs entries need to be cleared , since after OLT
640 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530641 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000642 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700643 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530644}
645
646// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530647func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400648 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000649 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
650 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
651 grpc.WithInsecure(),
652 grpc.WithBlock(),
653 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
654 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(opentracing.GlobalTracer())),
655 )),
656 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
657 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(opentracing.GlobalTracer())),
658 )))
659
660 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530661 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530662 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000663 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400664 }
665 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530666}
667
668// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530669func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400670 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530671 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400672 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530673}
674
675// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530676func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530677 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000678 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400679
680 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530681 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
682 if err != nil || device == nil {
683 /*TODO: needs to handle error scenarios */
684 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
685 }
686 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000687 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400688
689 cloned := proto.Clone(device).(*voltha.Device)
690 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
691 cloned.OperStatus = voltha.OperStatus_UNKNOWN
692 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530693 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
694 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 -0400695 }
696
Chaitrashree G S44124192019-08-07 20:21:36 -0400697 // 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 +0530698 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400699 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530700 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400701 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400702 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
703 // all the modules initialized and ready to handle incoming ONUs.
704
Thomas Lee S985938d2020-05-04 11:40:41 +0530705 err = dh.initializeDeviceHandlerModules(ctx)
706 if err != nil {
707 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 -0400708 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400709
710 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800711 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530712 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400713 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800714 }
715 }()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400716 return nil
717 }
718
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400719 ports, err := dh.coreProxy.ListDevicePorts(context.TODO(), dh.device.Id)
720 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400721 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400722 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400723 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400724 dh.populateActivePorts(ctx, ports)
725 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
726 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400727 }
728
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400729 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530730 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 -0400731 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530732
cuilin20187b2a8c32019-03-26 19:52:28 -0700733 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800734 go func() {
735 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400736 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800737 }
738 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000739 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000740
741 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000742 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000743 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700744 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530745}
746
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400747func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000748 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400749
750 if err != nil {
751 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
752 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400753 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000754 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 -0400755 return olterrors.ErrResourceManagerInstantiating
756 }
757
758 // Instantiate flow manager
759 if dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr); dh.flowMgr == nil {
760 return olterrors.ErrResourceManagerInstantiating
761
762 }
763 /* TODO: Instantiate Alarm , stats , BW managers */
764 /* Instantiating Event Manager to handle Alarms and KPIs */
765 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
766
767 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000768 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400769
770 return nil
771
772}
773
Neha Sharma96b7bf22020-06-15 10:37:32 +0000774func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400775 var err error
776 var deviceInfo *oop.DeviceInfo
777
778 deviceInfo, err = dh.Client.GetDeviceInfo(context.Background(), new(oop.Empty))
779
780 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000781 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400782 }
783 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000784 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400785 }
786
Neha Sharma96b7bf22020-06-15 10:37:32 +0000787 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400788 dh.device.Root = true
789 dh.device.Vendor = deviceInfo.Vendor
790 dh.device.Model = deviceInfo.Model
791 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
792 dh.device.HardwareVersion = deviceInfo.HardwareVersion
793 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
794
795 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000796 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400797 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000798 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400799 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000800 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400801 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000802 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400803 dh.device.MacAddress = genmac
804 } else {
805 dh.device.MacAddress = deviceInfo.DeviceId
806 }
807
808 // Synchronous call to update device - this method is run in its own go routine
809 if err := dh.coreProxy.DeviceUpdate(context.TODO(), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000810 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400811 }
812
813 return deviceInfo, nil
814}
815
Neha Sharma96b7bf22020-06-15 10:37:32 +0000816func startCollector(ctx context.Context, dh *DeviceHandler) {
817 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530818 for {
819 select {
820 case <-dh.stopCollector:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000821 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"deviceID:": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530822 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000823 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700824
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400825 ports, err := dh.coreProxy.ListDevicePorts(context.Background(), dh.device.Id)
826 if err != nil {
827 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
828 continue
829 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530830 for _, port := range ports {
831 // NNI Stats
832 if port.Type == voltha.Port_ETHERNET_NNI {
833 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
834 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000835 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
836 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
837 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530838 }
839 // PON Stats
840 if port.Type == voltha.Port_PON_OLT {
841 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
842 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
843 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000844 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
845 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530846 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000847 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500848 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530849 }
850 }
851 }
852}
853
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700854//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530855func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400856 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000857 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530858 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530859
860 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400861 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
862 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530863 }
864
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400865 go startHeartbeatCheck(ctx, dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530866}
867
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700868//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530869func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700870 return &ic.SwitchCapability{
871 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530872 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700873 HwDesc: "open_pon",
874 SwDesc: "open_pon",
875 SerialNum: dh.device.SerialNumber,
876 },
877 SwitchFeatures: &of.OfpSwitchFeatures{
878 NBuffers: 256,
879 NTables: 2,
880 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
881 of.OfpCapabilities_OFPC_TABLE_STATS |
882 of.OfpCapabilities_OFPC_PORT_STATS |
883 of.OfpCapabilities_OFPC_GROUP_STATS),
884 },
885 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530886}
887
Neha Sharma96b7bf22020-06-15 10:37:32 +0000888func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
889 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 -0700890 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700891 var deviceID string
892 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700893
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400894 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700895 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000896 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 -0700897 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
898 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400899
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700900 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530901
902 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
903
Neha Sharma96b7bf22020-06-15 10:37:32 +0000904 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 -0700905 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700906 kwargs := make(map[string]interface{})
907 kwargs["onu_id"] = omciInd.OnuId
908 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700909
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700910 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
911 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530912 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700913 "intf-id": omciInd.IntfId,
914 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700915 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700916 deviceType = onuDevice.Type
917 deviceID = onuDevice.Id
918 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
919 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530920 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700921 } else {
922 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000923 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 +0530924 deviceType = onuInCache.(*OnuDevice).deviceType
925 deviceID = onuInCache.(*OnuDevice).deviceID
926 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700927 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700928
929 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
David K. Bainbridge794735f2020-02-11 21:01:37 -0800930 if err := dh.AdapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530931 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800932 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530933 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530934 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800935 "destination": deviceType,
936 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000937 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700938 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800939 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530940}
941
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700942//ProcessInterAdapterMessage sends the proxied messages to the target device
943// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
944// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000945func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
946 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700947 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700948 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700949 fromTopic := msg.Header.FromTopic
950 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700951 toDeviceID := msg.Header.ToDeviceId
952 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700953
Neha Sharma96b7bf22020-06-15 10:37:32 +0000954 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 -0700955
956 msgBody := msg.GetBody()
957
958 omciMsg := &ic.InterAdapterOmciMessage{}
959 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000960 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700961 }
962
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700963 if omciMsg.GetProxyAddress() == nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700964 onuDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, toDeviceID)
965 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530966 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800967 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000968 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700969 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000970 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
971 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530972 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800973 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000974 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800975 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700976 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000977 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
978 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530979 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800980 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000981 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800982 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700983 }
984
985 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +0000986 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -0700987 }
988 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530989}
990
Neha Sharma96b7bf22020-06-15 10:37:32 +0000991func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700992 var intfID uint32
993 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +0000994 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700995 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700996 intfID = onuDevice.ProxyAddress.GetChannelId()
997 onuID = onuDevice.ProxyAddress.GetOnuId()
998 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700999 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001000 intfID = omciMsg.GetProxyAddress().GetChannelId()
1001 onuID = omciMsg.GetProxyAddress().GetOnuId()
1002 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001003 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001004 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001005 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 -08001006
Thomas Lee S94109f12020-03-03 16:39:29 +05301007 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001008 "intf-id": intfID,
1009 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001010 }
1011
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001012 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1013 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001014 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001015 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1016 hex.Encode(hexPkt, omciMsg.Message)
1017 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1018
1019 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1020 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1021 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001022 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001023 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001024
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001025 _, err := dh.Client.OmciMsgOut(context.Background(), omciMessage)
1026 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301027 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001028 "intf-id": intfID,
1029 "onu-id": onuID,
1030 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001031 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001032 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001033}
1034
David K. Bainbridge794735f2020-02-11 21:01:37 -08001035func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001036 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id})
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001037 if err := dh.flowMgr.UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001038 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001039 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001040 // TODO: need resource manager
1041 var pir uint32 = 1000000
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001042 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir}
npujarec5762e2020-01-01 14:08:48 +05301043 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001044 st, _ := status.FromError(err)
1045 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001046 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1047
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001048 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301049 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001050 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001051 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001052 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001053 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001054 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001055}
1056
David K. Bainbridge794735f2020-02-11 21:01:37 -08001057func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001058
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001059 channelID := onuDiscInd.GetIntfId()
1060 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001061
Neha Sharma96b7bf22020-06-15 10:37:32 +00001062 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301063
cuilin20187b2a8c32019-03-26 19:52:28 -07001064 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001065 if sn != "" {
1066 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001067 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001068 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001069 }
1070
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301071 var alarmInd oop.OnuAlarmIndication
1072 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001073 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301074
1075 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1076 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1077 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1078 OnuLosRaise event sent for it */
1079 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1080 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1081 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001082 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301083 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1084 "currentIntfId": onuDiscInd.GetIntfId()})
1085 // TODO:: Should we need to ignore raising OnuLosClear event
1086 // when onu connected to different PON?
1087 }
1088 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1089 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1090 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001091 go func() {
1092 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1093 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1094 }
1095 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301096 }
1097 return true
1098 })
1099
Neha Sharma96b7bf22020-06-15 10:37:32 +00001100 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001101 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001102 }
1103
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001104 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001105
1106 // check the ONU is already know to the OLT
1107 // NOTE the second time the ONU is discovered this should return a device
1108 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1109
1110 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001111 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 -08001112 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001113 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 -08001114 switch e.Code() {
1115 case codes.Internal:
1116 // this probably means NOT FOUND, so just create a new device
1117 onuDevice = nil
1118 case codes.DeadlineExceeded:
1119 // if the call times out, cleanup and exit
1120 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001121 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001122 }
1123 }
1124 }
1125
1126 if onuDevice == nil {
1127 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001128 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001129 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001130 ponintfid := onuDiscInd.GetIntfId()
1131 dh.lockDevice.Lock()
npujarec5762e2020-01-01 14:08:48 +05301132 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Matt Jeanneret53539512019-07-20 14:47:02 -04001133 dh.lockDevice.Unlock()
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001134
Neha Sharma96b7bf22020-06-15 10:37:32 +00001135 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001136
1137 if err != nil {
1138 // if we can't create an ID in resource manager,
1139 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001140 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001141 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001142 "pon-intf-id": ponintfid,
1143 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001144 }
1145
1146 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(context.TODO(), dh.device.Id, int(parentPortNo),
1147 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001148 dh.discOnus.Delete(sn)
1149 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 +05301150 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001151 "pon-intf-id": ponintfid,
1152 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001153 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001154 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1155 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1156 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001157 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301158 log.Fields{"onuDevice": onuDevice,
1159 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001160 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301161 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001162 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001163
1164 // we can now use the existing ONU Id
1165 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001166 //Insert the ONU into cache to use in OnuIndication.
1167 //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 +00001168 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001169 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301170 "intfId": onuDiscInd.GetIntfId(),
1171 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001172 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001173
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301174 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301175 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001176 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301177 log.Fields{"onu": onuDev,
1178 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001179
Kent Hagermane6ff1012020-07-14 15:07:53 -04001180 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301181 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001182 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001183 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001184 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001185 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001186 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301187 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001188 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001189 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001190 }
1191 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001192}
1193
Neha Sharma96b7bf22020-06-15 10:37:32 +00001194func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001195 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1196
1197 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001198 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001199 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001200 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001201 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001202 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301203 log.Fields{"onuId": onuInd.OnuId,
1204 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301205 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001206 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301207
David K. Bainbridge794735f2020-02-11 21:01:37 -08001208 errFields := log.Fields{"device-id": dh.device.Id}
1209
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301210 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1211
Mahir Gunyele77977b2019-06-27 05:36:22 -07001212 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1213 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001214 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001215 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001216 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001217 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1218 if serialNumber != "" {
1219 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001221 } else {
1222 kwargs["onu_id"] = onuInd.OnuId
1223 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001224 errFields["onu-id"] = onuInd.OnuId
1225 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001226 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001227 onuDevice, err = dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001228 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001229
David K. Bainbridge794735f2020-02-11 21:01:37 -08001230 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001231 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001232 }
1233
David K. Bainbridge794735f2020-02-11 21:01:37 -08001234 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001235 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001236 "previousIntfId": onuDevice.ParentPortNo,
1237 "currentIntfId": ponPort})
1238 }
1239
1240 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001241 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301242 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1243 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301244 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001245 }
1246 if !foundInCache {
1247 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1248
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301249 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 -08001250
1251 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001252 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001253 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001254 }
1255 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001256}
1257
Neha Sharma96b7bf22020-06-15 10:37:32 +00001258func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001259 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 -07001260 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1261 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1262 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1263 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001264 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001265 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1266 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001267 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001268 onuInd.OperState = "down"
1269 }
1270 }
1271
David K. Bainbridge794735f2020-02-11 21:01:37 -08001272 switch onuInd.OperState {
1273 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001274 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 -07001275 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301276 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001277 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1278 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301279 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001280 "onu-indicator": onuInd,
1281 "source": "openolt",
1282 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001283 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001284 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001285 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001286 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 -04001287 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301288 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001289 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1290 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301291 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001292 "onu-indicator": onuInd,
1293 "source": "openolt",
1294 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001295 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001296 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001297 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001298 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001299 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001300 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001301}
1302
cuilin20187b2a8c32019-03-26 19:52:28 -07001303func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1304 if serialNum != nil {
1305 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001306 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001307 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001308}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001309func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1310 decodedStr, err := hex.DecodeString(serialNum[4:])
1311 if err != nil {
1312 return nil, err
1313 }
1314 return &oop.SerialNumber{
1315 VendorId: []byte(serialNum[:4]),
1316 VendorSpecific: []byte(decodedStr),
1317 }, nil
1318}
cuilin20187b2a8c32019-03-26 19:52:28 -07001319
1320func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1321 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001322 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001323 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1324 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1325 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1326 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1327 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1328 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1329 return tmp
1330}
1331
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001332//UpdateFlowsBulk upates the bulk flow
1333func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301334 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001335}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001336
1337//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001338func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1339 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301340 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001341 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301342 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001343 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001344 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001345 kwargs["parent_port_no"] = parentPort
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001346 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001347 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001348 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001349 "intf-id": parentPort,
1350 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001351 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001352 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 -08001353 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301354}
1355
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001356// SendPacketInToCore sends packet-in to core
1357// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1358// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001359func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001360 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001361 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001362 "port": logicalPort,
1363 "packet": hex.EncodeToString(packetPayload),
1364 "device-id": dh.device.Id,
1365 })
1366 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001367 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301368 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001369 "source": "adapter",
1370 "destination": "core",
1371 "device-id": dh.device.Id,
1372 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001373 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001374 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001375 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001376 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001377 "packet": hex.EncodeToString(packetPayload),
1378 "device-id": dh.device.Id,
1379 })
1380 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001381 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001382}
1383
A R Karthick1f85b802019-10-11 05:06:05 +00001384// AddUniPortToOnu adds the uni port to the onu device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001385func (dh *DeviceHandler) AddUniPortToOnu(ctx context.Context, intfID, onuID, uniPort uint32) {
A R Karthick1f85b802019-10-11 05:06:05 +00001386 onuKey := dh.formOnuKey(intfID, onuID)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301387
1388 if onuDevice, ok := dh.onus.Load(onuKey); ok {
A R Karthick1f85b802019-10-11 05:06:05 +00001389 // add it to the uniPort map for the onu device
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301390 if _, ok = onuDevice.(*OnuDevice).uniPorts[uniPort]; !ok {
1391 onuDevice.(*OnuDevice).uniPorts[uniPort] = struct{}{}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001392 logger.Debugw(ctx, "adding-uni-port", log.Fields{"port": uniPort, "intf-id": intfID, "onuId": onuID})
A R Karthick1f85b802019-10-11 05:06:05 +00001393 }
1394 }
1395}
1396
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001397// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001398func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001399
Neha Sharma96b7bf22020-06-15 10:37:32 +00001400 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001401
1402 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1403 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001404 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001405 }
1406
Kent Hagermane6ff1012020-07-14 15:07:53 -04001407 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001408 metrics := dh.metrics.GetSubscriberMetrics()
1409 for _, m := range pmConfigs.Metrics {
1410 metrics[m.Name].Enabled = m.Enabled
1411
1412 }
1413 }
1414}
1415
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001416//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301417func (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 +00001418 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 +01001419
1420 var errorsList []error
1421
Girish Gowdru0c588b22019-04-23 23:24:56 -04001422 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001423 for _, flow := range flows.ToRemove.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001424 dh.incrementActiveFlowRemoveCount(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001425
Neha Sharma96b7bf22020-06-15 10:37:32 +00001426 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301427 log.Fields{"device-id": device.Id,
1428 "flowToRemove": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001429 err := dh.flowMgr.RemoveFlow(ctx, flow)
1430 if err != nil {
1431 errorsList = append(errorsList, err)
1432 }
1433
Neha Sharma96b7bf22020-06-15 10:37:32 +00001434 dh.decrementActiveFlowRemoveCount(ctx, flow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001435 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301436
1437 for _, flow := range flows.ToAdd.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001438 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301439 log.Fields{"device-id": device.Id,
1440 "flowToAdd": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001441 // If there are active Flow Remove in progress for a given subscriber, wait until it completes
Neha Sharma96b7bf22020-06-15 10:37:32 +00001442 dh.waitForFlowRemoveToFinish(ctx, flow)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001443 err := dh.flowMgr.AddFlow(ctx, flow, flowMetadata)
1444 if err != nil {
1445 errorsList = append(errorsList, err)
1446 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301447 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001448 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001449
Girish Gowdracefae192020-03-19 18:14:10 -07001450 // 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 +00001451 if groups != nil {
1452 for _, group := range groups.ToAdd.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001453 err := dh.flowMgr.AddGroup(ctx, group)
1454 if err != nil {
1455 errorsList = append(errorsList, err)
1456 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001457 }
1458 for _, group := range groups.ToUpdate.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001459 err := dh.flowMgr.ModifyGroup(ctx, group)
1460 if err != nil {
1461 errorsList = append(errorsList, err)
1462 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001463 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001464 for _, group := range groups.ToRemove.Items {
1465 err := dh.flowMgr.DeleteGroup(ctx, group)
1466 if err != nil {
1467 errorsList = append(errorsList, err)
1468 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001469 }
1470 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001471 if len(errorsList) > 0 {
1472 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1473 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001474 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001475 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301476}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001477
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001478//DisableDevice disables the given device
1479//It marks the following for the given device:
1480//Device-Handler Admin-State : down
1481//Device Port-State: UNKNOWN
1482//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001483func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001484 /* On device disable ,admin state update has to be done prior sending request to agent since
1485 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001486 if dh.Client != nil {
1487 if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
1488 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001489 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001490 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001491 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001492 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001493 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001494 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001495 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301496
1497 dh.discOnus = sync.Map{}
1498 dh.onus = sync.Map{}
1499
Thomas Lee S85f37312020-04-03 17:06:12 +05301500 //stopping the stats collector
1501 dh.stopCollector <- true
1502
Neha Sharma96b7bf22020-06-15 10:37:32 +00001503 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001504 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301505 //Update device Admin state
1506 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001507 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001508 if err := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
1509 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001510 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001511 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001512 return nil
1513}
1514
Neha Sharma96b7bf22020-06-15 10:37:32 +00001515func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001516
1517 // Update onu state as unreachable in onu adapter
1518 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301519 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001520 //get the child device for the parent device
1521 onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
1522 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001523 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 -04001524 }
1525 if onuDevices != nil {
1526 for _, onuDevice := range onuDevices.Items {
1527 err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1528 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1529 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001530 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301531 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001532 }
1533
1534 }
1535 }
1536
1537}
1538
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001539//ReenableDevice re-enables the olt device after disable
1540//It marks the following for the given device:
1541//Device-Handler Admin-State : up
1542//Device Port-State: ACTIVE
1543//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001544func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301545 if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
1546 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001547 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301548 }
1549 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001550 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001551
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001552 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001553
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001554 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1555 if err != nil {
1556 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device": device.Id}, err)
1557 }
1558 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001559 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001560 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001561 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001562 device.OperStatus = voltha.OperStatus_ACTIVE
1563 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001564
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001565 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301566 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001567 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001568 "connect-status": device.ConnectStatus,
1569 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001570 }
kesavand39e0aa32020-01-28 20:58:50 -05001571
Neha Sharma96b7bf22020-06-15 10:37:32 +00001572 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001573
1574 return nil
1575}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001576
npujarec5762e2020-01-01 14:08:48 +05301577func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001578 var uniID uint32
1579 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301580 for _, port := range onu.UniPorts {
1581 uniID = UniIDFromPortNum(uint32(port))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001582 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001583 /* Delete tech-profile instance from the KV store */
npujarec5762e2020-01-01 14:08:48 +05301584 if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001586 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001587 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301588 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001589 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301590 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001591 }
npujarec5762e2020-01-01 14:08:48 +05301592 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001593 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301594 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001596 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001597 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301598 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001599 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001600 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001601 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301602 }
npujarec5762e2020-01-01 14:08:48 +05301603 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1604 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001605 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301606 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Esin Karaman7fb80c22020-07-16 14:23:33 +00001608 if err = dh.resourceMgr.DelGemPortPktInOfAllServices(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001609 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 +00001610 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001611 }
1612 return nil
1613}
1614
npujarec5762e2020-01-01 14:08:48 +05301615func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001616 nniUniID := -1
1617 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301618
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001619 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301620 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001621 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001622 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301623 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301624 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001625 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001626 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001627 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301628 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301629 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001630 logger.Debugw(ctx, "current-flow-ids-for-nni", log.Fields{"flow-ids": flowIDs})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301631 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301632 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301633 }
npujarec5762e2020-01-01 14:08:48 +05301634 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001635 }
npujarec5762e2020-01-01 14:08:48 +05301636 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001637 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301638 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001639 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001640}
1641
1642// 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 +05301643func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001644 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001645 /* Clear the KV store data associated with the all the UNI ports
1646 This clears up flow data and also resource map data for various
1647 other pon resources like alloc_id and gemport_id
1648 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001649 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001650 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001651 // Stop the Stats collector
1652 dh.stopCollector <- true
1653 // stop the heartbeat check routine
1654 dh.stopHeartbeatCheck <- true
1655 //Reset the state
1656 if dh.Client != nil {
1657 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301658 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001659 }
1660 }
1661 cloned := proto.Clone(device).(*voltha.Device)
1662 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1663 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1664 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1665 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1666 "device-id": device.Id,
1667 "connect-status": cloned.ConnectStatus,
1668 "oper-status": cloned.OperStatus}, err).Log()
1669 }
1670 return nil
1671}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001672func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001673 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301674 noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
1675 var ponPort uint32
1676 for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
1677 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301678 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301679 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001680 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001681 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001682 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301683 }
1684 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301685 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001686 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301687 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001688 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301689 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301690 // Clear flowids for gem cache.
1691 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301692 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301693 }
1694 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301695 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301696 }
npujarec5762e2020-01-01 14:08:48 +05301697 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301698 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301699 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301700 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001701 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001702 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001703 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001704 /* Clear the flows from KV store associated with NNI port.
1705 There are mostly trap rules from NNI port (like LLDP)
1706 */
npujarec5762e2020-01-01 14:08:48 +05301707 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001708 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001709 }
A R Karthick1f85b802019-10-11 05:06:05 +00001710
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001711 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001712 go func() {
1713 if err := dh.resourceMgr.Delete(ctx); err != nil {
1714 logger.Debug(ctx, err)
1715 }
1716 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001717 }
A R Karthick1f85b802019-10-11 05:06:05 +00001718
Devmalya Paul495b94a2019-08-27 19:42:00 -04001719 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301720 dh.onus.Range(func(key interface{}, value interface{}) bool {
1721 dh.onus.Delete(key)
1722 return true
1723 })
1724
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001725 /*Delete discovered ONU map for the device*/
1726 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1727 dh.discOnus.Delete(key)
1728 return true
1729 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001730}
1731
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001732//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001733func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001734 if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301735 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001736 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001737 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001738 return nil
1739}
1740
David K. Bainbridge794735f2020-02-11 21:01:37 -08001741func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001742 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001743 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001744 "packet-indication": *packetIn,
1745 "device-id": dh.device.Id,
1746 "packet": hex.EncodeToString(packetIn.Pkt),
1747 })
1748 }
npujarec5762e2020-01-01 14:08:48 +05301749 logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001750 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001751 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001752 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001753 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001754 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001755 "logical-port-num": logicalPortNum,
1756 "device-id": dh.device.Id,
1757 "packet": hex.EncodeToString(packetIn.Pkt),
1758 })
1759 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001760
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001761 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301762 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001763 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301764 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001765 "device-id": dh.device.Id,
1766 "packet": hex.EncodeToString(packetIn.Pkt),
1767 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001768 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001769
Matteo Scandolo92186242020-06-12 10:54:18 -07001770 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001771 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001772 "packet": hex.EncodeToString(packetIn.Pkt),
1773 "device-id": dh.device.Id,
1774 })
1775 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001776 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001777}
1778
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001779// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301780func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001781 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001782 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001783 "device-id": dh.device.Id,
1784 "egress-port-no": egressPortNo,
1785 "pkt-length": len(packet.Data),
1786 "packet": hex.EncodeToString(packet.Data),
1787 })
1788 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001789
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001790 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001791 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001792 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1793 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301794 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1795 // Do not packet-out lldp packets on uni port.
1796 // ONOS has no clue about uni/nni ports, it just packets out on all
1797 // available ports on the Logical Switch. It should not be interested
1798 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001799 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001800 "device-id": dh.device.Id,
1801 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301802 return nil
1803 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001804 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1805 if innerEthType == 0x8100 {
1806 // q-in-q 802.1ad or 802.1q double tagged packet.
1807 // slice out the outer tag.
1808 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001809 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001810 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001811 "packet-data": hex.EncodeToString(packet.Data),
1812 "device-id": dh.device.Id,
1813 })
1814 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001815 }
1816 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001817 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1818 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001819 uniID := UniIDFromPortNum(uint32(egressPortNo))
1820
Esin Karaman7fb80c22020-07-16 14:23:33 +00001821 gemPortID, err := dh.flowMgr.GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001822 if err != nil {
1823 // In this case the openolt agent will receive the gemPortID as 0.
1824 // The agent tries to retrieve the gemPortID in this case.
1825 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001826 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001827 "intf-id": intfID,
1828 "onu-id": onuID,
1829 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001830 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301831 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001832 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001833 }
1834
1835 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001836
Matteo Scandolo92186242020-06-12 10:54:18 -07001837 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001838 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001839 "egress-port-no": egressPortNo,
1840 "intf-id": intfID,
1841 "onu-id": onuID,
1842 "uni-id": uniID,
1843 "gem-port-id": gemPortID,
1844 "packet": hex.EncodeToString(packet.Data),
1845 "device-id": dh.device.Id,
1846 })
1847 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001848
npujarec5762e2020-01-01 14:08:48 +05301849 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301850 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001851 "source": "adapter",
1852 "destination": "onu",
1853 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001854 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001855 "oni-id": onuID,
1856 "uni-id": uniID,
1857 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001858 "packet": hex.EncodeToString(packet.Data),
1859 "device-id": dh.device.Id,
1860 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001861 }
1862 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001863 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001864 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001865 return olterrors.NewErrInvalidValue(log.Fields{
1866 "egress-nni-port": egressPortNo,
1867 "device-id": dh.device.Id,
1868 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001869 }
1870 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001871
Matteo Scandolo92186242020-06-12 10:54:18 -07001872 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001873 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001874 "uplink-pkt": uplinkPkt,
1875 "packet": hex.EncodeToString(packet.Data),
1876 "device-id": dh.device.Id,
1877 })
1878 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001879
npujarec5762e2020-01-01 14:08:48 +05301880 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001881 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1882 "packet": hex.EncodeToString(packet.Data),
1883 "device-id": dh.device.Id,
1884 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001885 }
1886 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001887 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301888 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001889 "egressPortType": egressPortType,
1890 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301891 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001892 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001893 }
1894 return nil
1895}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001896
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001897func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1898 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001899}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301900
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001901func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301902 // start the heartbeat check towards the OLT.
1903 var timerCheck *time.Timer
1904
1905 for {
1906 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1907 select {
1908 case <-heartbeatTimer.C:
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001909 ctxWithTimeout, cancel := context.WithTimeout(context.Background(), dh.openOLT.GrpcTimeoutInterval)
1910 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001911 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301912 if timerCheck == nil {
1913 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001914 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301915 }
1916 } else {
1917 if timerCheck != nil {
1918 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001919 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301920 }
1921 timerCheck = nil
1922 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001923 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301924 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301925 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301926 }
1927 cancel()
1928 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001929 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301930 return
1931 }
1932 }
1933}
1934
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001935func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1936 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1937 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001938 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001939 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301940
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001941 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1942 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001943 _ = 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 -04001944 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001945 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001946 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001947 }
1948 go dh.cleanupDeviceResources(ctx)
1949
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001950 dh.lockDevice.RLock()
1951 // Stop the read indication only if it the routine is active
1952 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1953 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1954 // on next execution of the readIndication routine.
1955 if dh.isReadIndicationRoutineActive {
1956 dh.stopIndications <- true
1957 }
1958 dh.lockDevice.RUnlock()
1959
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001960 dh.transitionMap.Handle(ctx, DeviceInit)
1961
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301962 }
1963}
kesavand39e0aa32020-01-28 20:58:50 -05001964
1965// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001966func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1967 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1968 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001969}
1970
1971// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001972func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1973 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1974 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001975}
1976
kdarapu1afeceb2020-02-12 01:38:09 -05001977//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 +00001978func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1979 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001980 if port.GetType() == voltha.Port_ETHERNET_NNI {
1981 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001982 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301983 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301984 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001985 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001986 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001987 }
1988 // fetch interfaceid from PortNo
1989 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1990 ponIntf := &oop.Interface{IntfId: ponID}
1991 var operStatus voltha.OperStatus_Types
1992 if enablePort {
1993 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301994 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001995
1996 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301997 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001998 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001999 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002000 }
2001 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002002 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002003 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002004 } else {
2005 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302006 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002007 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302008 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002009 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002010 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002011 }
2012 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002013 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002014 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002015 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302016 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 +05302017 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302018 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002019 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002020 }
2021 return nil
2022}
2023
kdarapu1afeceb2020-02-12 01:38:09 -05002024//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002025func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002026 // Disable the port and update the oper_port_status to core
2027 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002028 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002029 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002030 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302031 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302032 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002033 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002034 }
2035 }
2036 }
2037 return nil
2038}
2039
2040//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002041func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2042 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2043 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002044 if port.Type == voltha.Port_ETHERNET_NNI {
2045 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002046 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002047 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002048 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002049 }
2050 }
2051 if port.Type == voltha.Port_PON_OLT {
2052 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002053 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002054 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002055 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002056 }
2057 }
2058 }
2059}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002060
2061// ChildDeviceLost deletes ONU and clears pon resources related to it.
2062func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002063 logger.Debugw(ctx, "child-device-lost", log.Fields{"pdeviceID": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002064 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2065 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002066 onuDevice, ok := dh.onus.Load(onuKey)
2067 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302068 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002069 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002070 "device-id": dh.device.Id,
2071 "onu-id": onuID,
2072 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002073 }
2074 var sn *oop.SerialNumber
2075 var err error
2076 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302077 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002078 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302079 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002080 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2081 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002082
2083 for uniID := 0; uniID < MaxUnisPerOnu; uniID++ {
2084 var flowRemoveData pendingFlowRemoveData
2085 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uint32(uniID)}
2086 dh.lockDevice.RLock()
2087 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
2088 dh.lockDevice.RUnlock()
2089 continue
2090 }
2091 dh.lockDevice.RUnlock()
2092
2093 log.Debugw("wait-for-flow-remove-complete-before-processing-child-device-lost",
2094 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2095 // Wait for all flow removes to finish first
2096 <-flowRemoveData.allFlowsRemoved
2097 log.Debugw("flow-removes-complete-for-subscriber",
2098 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2099 }
2100
2101 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002102 if _, err := dh.Client.DeleteOnu(context.Background(), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302103 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302104 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002105 "onu-id": onuID}, err).Log()
2106 }
2107 //clear PON resources associated with ONU
2108 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002109 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002110 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002111 "device-id": dh.device.Id,
2112 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002113 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002114 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002115 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002116 "device-id": dh.device.Id,
2117 "intf-id": intfID,
2118 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002119 } else {
2120 for i, onu := range onuGemData {
2121 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002122 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002123 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002124 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302125 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002126 "onu-device": onu,
2127 "error": err})
2128 }
2129 // Clear flowids for gem cache.
2130 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002131 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002132 }
2133 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002134 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002135 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002136 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002137 "intf-id": intfID,
2138 "onu-device": onu,
2139 "onu-gem": onuGemData,
2140 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002141 //Not returning error on cleanup.
2142 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002143 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002144 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002145 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002146 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002147 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002148 }
2149 }
2150 dh.onus.Delete(onuKey)
2151 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2152 return nil
2153}
Girish Gowdracefae192020-03-19 18:14:10 -07002154
2155func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2156 for _, field := range flows.GetOfbFields(flow) {
2157 if field.Type == flows.IN_PORT {
2158 return field.GetPort()
2159 }
2160 }
2161 return InvalidPort
2162}
2163
2164func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2165 for _, action := range flows.GetActions(flow) {
2166 if action.Type == flows.OUTPUT {
2167 if out := action.GetOutput(); out != nil {
2168 return out.GetPort()
2169 }
2170 }
2171 }
2172 return InvalidPort
2173}
2174
Neha Sharma96b7bf22020-06-15 10:37:32 +00002175func (dh *DeviceHandler) incrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002176 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002177 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 -07002178 if inPort != InvalidPort && outPort != InvalidPort {
2179 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2180 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002181 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 -07002182
2183 dh.lockDevice.Lock()
2184 defer dh.lockDevice.Unlock()
2185 flowRemoveData, ok := dh.pendingFlowRemoveDataPerSubscriber[key]
2186 if !ok {
2187 flowRemoveData = pendingFlowRemoveData{
2188 pendingFlowRemoveCount: 0,
2189 allFlowsRemoved: make(chan struct{}),
2190 }
2191 }
2192 flowRemoveData.pendingFlowRemoveCount++
2193 dh.pendingFlowRemoveDataPerSubscriber[key] = flowRemoveData
2194
Neha Sharma96b7bf22020-06-15 10:37:32 +00002195 logger.Debugw(ctx, "current-flow-remove-count–increment",
Matteo Scandolo92186242020-06-12 10:54:18 -07002196 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002197 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2198 }
2199}
2200
Neha Sharma96b7bf22020-06-15 10:37:32 +00002201func (dh *DeviceHandler) decrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002202 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002203 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 -07002204 if inPort != InvalidPort && outPort != InvalidPort {
2205 _, intfID, onuID, uniID := ExtractAccessFromFlow(uint32(inPort), uint32(outPort))
2206 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002207 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 -07002208
2209 dh.lockDevice.Lock()
2210 defer dh.lockDevice.Unlock()
2211 if val, ok := dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002212 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 -07002213 } else {
2214 if val.pendingFlowRemoveCount > 0 {
2215 val.pendingFlowRemoveCount--
2216 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002217 logger.Debugw(ctx, "current-flow-remove-count-after-decrement",
Matteo Scandolo92186242020-06-12 10:54:18 -07002218 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002219 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2220 // If all flow removes have finished, then close the channel to signal the receiver
2221 // to go ahead with flow adds.
2222 if val.pendingFlowRemoveCount == 0 {
2223 close(val.allFlowsRemoved)
2224 delete(dh.pendingFlowRemoveDataPerSubscriber, key)
2225 return
2226 }
2227 dh.pendingFlowRemoveDataPerSubscriber[key] = val
2228 }
2229 }
2230}
2231
Neha Sharma96b7bf22020-06-15 10:37:32 +00002232func (dh *DeviceHandler) waitForFlowRemoveToFinish(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002233 var flowRemoveData pendingFlowRemoveData
2234 var ok bool
2235 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002236 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 -07002237 if inPort != InvalidPort && outPort != InvalidPort {
2238 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2239 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002240 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 -07002241
2242 dh.lockDevice.RLock()
2243 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002244 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 -07002245 dh.lockDevice.RUnlock()
2246 return
2247 }
2248 dh.lockDevice.RUnlock()
2249
2250 // Wait for all flow removes to finish first
2251 <-flowRemoveData.allFlowsRemoved
2252
Neha Sharma96b7bf22020-06-15 10:37:32 +00002253 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 -07002254 }
2255}
2256
2257func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2258 inPort := getInPortFromFlow(flow)
2259 outPort := getOutPortFromFlow(flow)
2260
2261 if inPort == InvalidPort || outPort == InvalidPort {
2262 return inPort, outPort
2263 }
2264
2265 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2266 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2267 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2268 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2269 return uniPort, outPort
2270 }
2271 }
2272 } else {
2273 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2274 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2275 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2276 return inPort, uniPort
2277 }
2278 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2279 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2280 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2281 return uniPort, outPort
2282 }
2283 }
2284 }
2285
2286 return InvalidPort, InvalidPort
2287}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002288
2289func extractOmciTransactionID(omciPkt []byte) uint16 {
2290 if len(omciPkt) > 3 {
2291 d := omciPkt[0:2]
2292 transid := binary.BigEndian.Uint16(d)
2293 return transid
2294 }
2295 return 0
2296}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002297
2298// StoreOnuDevice stores the onu parameters to the local cache.
2299func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2300 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2301 dh.onus.Store(onuKey, onuDevice)
2302}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002303
2304func (dh *DeviceHandler) getExtValue(device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
2305 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002306 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002307 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002308 resp := new(voltha.ReturnValues)
2309 valueparam := new(oop.ValueParam)
2310 ctx := context.Background()
2311 log.Infow("getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002312 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2313 return nil, err
2314 }
2315 ID = device.ProxyAddress.GetOnuId()
2316 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2317 valueparam.Onu = &Onu
2318 valueparam.Value = value
2319
2320 // This API is unsupported until agent patch is added
2321 resp.Unsupported = uint32(value)
2322 _ = ctx
2323
2324 // Uncomment this code once agent changes are complete and tests
2325 /*
2326 resp, err = dh.Client.GetValue(ctx, valueparam)
2327 if err != nil {
2328 log.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
2329 return nil, err
2330 }
2331 */
2332
2333 log.Infow("get-ext-value", log.Fields{"resp": resp, "device-id": dh.device, "onu-id": device.Id, "pon-intf": device.ParentPortNo})
2334 return resp, nil
2335}