blob: fe30de54f1af3fcef45b2520d043d97022f9b72f [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
Shrey Baid807a2a02020-04-09 12:52:45 +053032 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
33
Matteo Scandolo945e4012019-12-12 14:16:11 -080034 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070035 "github.com/gogo/protobuf/proto"
36 "github.com/golang/protobuf/ptypes"
Esin Karamanccb714b2019-11-29 15:02:06 +000037 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
38 "github.com/opencord/voltha-lib-go/v3/pkg/log"
39 "github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics"
Thomas Lee S94109f12020-03-03 16:39:29 +053040 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080041 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Esin Karamanccb714b2019-11-29 15:02:06 +000042 "github.com/opencord/voltha-protos/v3/go/common"
43 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
44 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
45 oop "github.com/opencord/voltha-protos/v3/go/openolt"
46 "github.com/opencord/voltha-protos/v3/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070047 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040048 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040049 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053050)
51
salmansiddiqui7ac62132019-08-22 03:58:50 +000052// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040053const (
salmansiddiqui7ac62132019-08-22 03:58:50 +000054 MaxRetry = 10
55 MaxTimeOutInMs = 500
Girish Gowdracefae192020-03-19 18:14:10 -070056 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040057)
58
Girish Gowdracefae192020-03-19 18:14:10 -070059// pendingFlowRemoveDataKey is key to pendingFlowRemoveDataPerSubscriber map
60type pendingFlowRemoveDataKey struct {
61 intfID uint32
62 onuID uint32
63 uniID uint32
64}
65
66// pendingFlowRemoveData is value stored in pendingFlowRemoveDataPerSubscriber map
67// This holds the number of pending flow removes and also a signal channel to
68// to indicate the receiver when all flow removes are handled
69type pendingFlowRemoveData struct {
70 pendingFlowRemoveCount uint32
71 allFlowsRemoved chan struct{}
72}
73
Phaneendra Manda4c62c802019-03-06 21:37:49 +053074//DeviceHandler will interact with the OLT device.
75type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070076 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053077 coreProxy adapterif.CoreProxy
78 AdapterProxy adapterif.AdapterProxy
79 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070080 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070081 exitChannel chan int
82 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053083 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070084 transitionMap *TransitionMap
85 clientCon *grpc.ClientConn
manikkaraj kbf256be2019-03-25 00:13:48 +053086 flowMgr *OpenOltFlowMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040087 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053088 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053089
Girish Gowdra3ab6d212020-03-24 17:33:15 -070090 discOnus sync.Map
91 onus sync.Map
92 portStats *OpenOltStatisticsMgr
93 metrics *pmmetrics.PmMetrics
94 stopCollector chan bool
95 stopHeartbeatCheck chan bool
96 activePorts sync.Map
97 stopIndications chan bool
98 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070099
100 // pendingFlowRemoveDataPerSubscriber map is used to maintain the context on a per
101 // subscriber basis for the number of pending flow removes. This data is used
102 // to process all the flow removes for a subscriber before handling flow adds.
103 // Interleaving flow delete and flow add processing has known to cause PON resource
104 // management contentions on a per subscriber bases, so we need ensure ordering.
105 pendingFlowRemoveDataPerSubscriber map[pendingFlowRemoveDataKey]pendingFlowRemoveData
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700106}
107
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700108//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700109type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700110 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700111 deviceType string
112 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113 onuID uint32
114 intfID uint32
115 proxyDeviceID string
A R Karthick1f85b802019-10-11 05:06:05 +0000116 uniPorts map[uint32]struct{}
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530117 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400118 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700119}
120
Naga Manjunath7615e552019-10-11 22:35:47 +0530121var pmNames = []string{
122 "rx_bytes",
123 "rx_packets",
124 "rx_mcast_packets",
125 "rx_bcast_packets",
126 "tx_bytes",
127 "tx_packets",
128 "tx_mcast_packets",
129 "tx_bcast_packets",
130}
131
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700132//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530133func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700134 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700135 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700136 device.deviceType = deviceTp
137 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700138 device.onuID = onuID
139 device.intfID = intfID
140 device.proxyDeviceID = proxyDevID
A R Karthick1f85b802019-10-11 05:06:05 +0000141 device.uniPorts = make(map[uint32]struct{})
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530142 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700143 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530144}
145
146//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530147func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700148 var dh DeviceHandler
149 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400150 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400151 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700152 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700153 dh.device = cloned
154 dh.openOLT = adapter
155 dh.exitChannel = make(chan int, 1)
156 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530157 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530158 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530159 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 -0500160 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400161 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700162 dh.pendingFlowRemoveDataPerSubscriber = make(map[pendingFlowRemoveDataKey]pendingFlowRemoveData)
163
cuilin20187b2a8c32019-03-26 19:52:28 -0700164 //TODO initialize the support classes.
165 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530166}
167
168// start save the device to the data model
169func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700170 dh.lockDevice.Lock()
171 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000172 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700173 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000174 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530175}
176
177// stop stops the device dh. Not much to do for now
178func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700179 dh.lockDevice.Lock()
180 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000181 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700182 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000183 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530184}
185
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400186func macifyIP(ip net.IP) string {
187 if len(ip) > 0 {
188 oct1 := strconv.FormatInt(int64(ip[12]), 16)
189 oct2 := strconv.FormatInt(int64(ip[13]), 16)
190 oct3 := strconv.FormatInt(int64(ip[14]), 16)
191 oct4 := strconv.FormatInt(int64(ip[15]), 16)
192 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
193 }
194 return ""
195}
196
Neha Sharma96b7bf22020-06-15 10:37:32 +0000197func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400198 var genmac string
199 var addr net.IP
200 var ips []string
201 var err error
202
Neha Sharma96b7bf22020-06-15 10:37:32 +0000203 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400204
205 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000206 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400207
208 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000209 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400210 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000211 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400212 }
213 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000214 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530215 log.Fields{"host": ips[0],
216 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400217 return genmac, nil
218 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000219 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400220 }
221
222 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000223 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530224 log.Fields{"host": host,
225 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400226 return genmac, nil
227}
228
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530229func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700230 slist := strings.Split(mac, ":")
231 result := make([]uint32, len(slist))
232 var err error
233 var tmp int64
234 for index, val := range slist {
235 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
236 return []uint32{1, 2, 3, 4, 5, 6}
237 }
238 result[index] = uint32(tmp)
239 }
240 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530241}
242
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700243//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 -0800244func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530245
David K. Bainbridge794735f2020-02-11 21:01:37 -0800246 switch portType {
247 case voltha.Port_ETHERNET_NNI:
248 return fmt.Sprintf("nni-%d", portNum), nil
249 case voltha.Port_PON_OLT:
250 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700251 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800252
Girish Kumarf26e4882020-03-05 06:49:10 +0000253 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530254}
255
Neha Sharma96b7bf22020-06-15 10:37:32 +0000256func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000257 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700258 if state == "up" {
259 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500260 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500261 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700262 } else {
263 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500264 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700265 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700266 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400267 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800268 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000269 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400270 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500271
272 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
273 if err != nil || device == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000274 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500275 }
276 if device.Ports != nil {
277 for _, dPort := range device.Ports {
278 if dPort.Type == portType && dPort.PortNo == portNum {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000279 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500280 if err := dh.coreProxy.PortStateUpdate(context.TODO(), dh.device.Id, portType, portNum, operStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530281 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800282 "device-id": dh.device.Id,
283 "port-type": portType,
284 "port-number": portNum,
Girish Kumarf26e4882020-03-05 06:49:10 +0000285 "oper-status": operStatus}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800286
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500287 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800288 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500289 }
290 }
291 }
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700292 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400293 // Now create Port
294 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700295 PortNo: portNum,
296 Label: label,
297 Type: portType,
298 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700299 OfpPort: &of.OfpPort{
300 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
301 Config: 0,
302 State: uint32(of.OfpPortState_OFPPS_LIVE),
303 Curr: capacity,
304 Advertised: capacity,
305 Peer: capacity,
306 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
307 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
308 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700309 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000310 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700311 // Synchronous call to update device - this method is run in its own go routine
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700312 if err := dh.coreProxy.PortCreated(context.TODO(), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000313 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800314 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000315 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400316 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000317 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530318 return nil
319}
320
Neha Sharma96b7bf22020-06-15 10:37:32 +0000321func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) error {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530322 dh.lockDevice.Lock()
323 defer dh.lockDevice.Unlock()
324 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
325 if err != nil || device == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000326 logger.Errorf(ctx, "device", log.Fields{"device-id": dh.device.Id}, err)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530327 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
328 }
329 dh.device = device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800330 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530331}
332
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700333// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530334// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800335func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000336 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700337 defer func() {
338 dh.lockDevice.Lock()
339 dh.isReadIndicationRoutineActive = false
340 dh.lockDevice.Unlock()
341 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700342 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700343 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700344 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700345 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400346 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530347 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400348 if err != nil || device == nil {
349 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000350 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400351 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400352
David Bainbridgef5879ca2019-12-13 21:17:54 +0000353 // Create an exponential backoff around re-enabling indications. The
354 // maximum elapsed time for the back off is set to 0 so that we will
355 // continue to retry. The max interval defaults to 1m, but is set
356 // here for code clarity
357 indicationBackoff := backoff.NewExponentialBackOff()
358 indicationBackoff.MaxElapsedTime = 0
359 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700360
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700361 dh.lockDevice.Lock()
362 dh.isReadIndicationRoutineActive = true
363 dh.lockDevice.Unlock()
364
Girish Gowdra3f974912020-03-23 20:35:18 -0700365Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700366 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400367 select {
368 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000369 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700370 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400371 default:
372 indication, err := indications.Recv()
373 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000374 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530375 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530376 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400377 // Use an exponential back off to prevent getting into a tight loop
378 duration := indicationBackoff.NextBackOff()
379 if duration == backoff.Stop {
380 // If we reach a maximum then warn and reset the backoff
381 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000382 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530383 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530384 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400385 indicationBackoff.Reset()
386 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700387
388 // On failure process a backoff timer while watching for stopIndications
389 // events
390 backoff := time.NewTimer(indicationBackoff.NextBackOff())
391 select {
392 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000393 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700394 if !backoff.Stop() {
395 <-backoff.C
396 }
397 break Loop
398 case <-backoff.C:
399 // backoff expired continue
400 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700401 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
402 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400403 }
404 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000405 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530406 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000407 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530408 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530409 "device-id": dh.device.Id})
410 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000411 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700412 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400413 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700414 // Close the stream, and re-initialize it
415 if err = indications.CloseSend(); err != nil {
416 // Ok to ignore here, because we landed here due to a problem on the stream
417 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000418 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530419 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530420 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700421 }
422 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
423 return err
424 }
425 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400426 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530427 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400428 // Reset backoff if we have a successful receive
429 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400430 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530431 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000432 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530433 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530434 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400435 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400436 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400437 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700438 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700439 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700440 // Close the send stream
441 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700442
Girish Gowdra3f974912020-03-23 20:35:18 -0700443 return nil
444}
445
446func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
447
448 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
449 if err != nil {
450 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
451 }
452 if indications == nil {
453 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
454 }
455
456 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400457}
458
459// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
460func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
461 switch indication.Data.(type) {
462 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
463 return true
464
465 default:
466 return false
467 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700468}
469
David K. Bainbridge794735f2020-02-11 21:01:37 -0800470func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000471 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000472 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530473 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700474 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530475 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700476 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000477 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000478 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530479 return olterrors.NewErrAdapter("failed-indication", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530480 "device_id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800481 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000482 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800483 }
484 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700485}
486
David K. Bainbridge794735f2020-02-11 21:01:37 -0800487// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530488func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400489 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700490 switch indication.Data.(type) {
491 case *oop.Indication_OltInd:
David K. Bainbridge794735f2020-02-11 21:01:37 -0800492 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530493 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800494 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700495 case *oop.Indication_IntfInd:
496 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800497 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000498 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530499 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800500 }
501 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000502 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700503 case *oop.Indication_IntfOperInd:
504 intfOperInd := indication.GetIntfOperInd()
505 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800506 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000507 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530508 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 -0800509 }
510 }()
npujarec5762e2020-01-01 14:08:48 +0530511 dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700512 } else if intfOperInd.GetType() == "pon" {
513 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
514 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800515 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000516 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530517 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-pon", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800518 }
519 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000520 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700521 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530523 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530524 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700525 case *oop.Indication_OnuDiscInd:
526 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000527 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700528 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800529 go func() {
530 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530531 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 -0800532 }
533 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700534 case *oop.Indication_OnuInd:
535 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000536 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800537 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000538 if err := dh.onuIndication(ctx, onuInd); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530539 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800540 }
541 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700542 case *oop.Indication_OmciInd:
543 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000544 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 -0800545 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000546 if err := dh.omciIndication(ctx, omciInd); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530547 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800548 }
549 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700550 case *oop.Indication_PktInd:
551 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700553 "intf-type": pktInd.IntfId,
554 "intf-id": pktInd.IntfId,
555 "gem-port-id": pktInd.GemportId,
556 "port-no": pktInd.PortNo,
557 "device-id": dh.device.Id,
558 })
559
560 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000561 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700562 "intf-type": pktInd.IntfId,
563 "intf-id": pktInd.IntfId,
564 "gem-port-id": pktInd.GemportId,
565 "port-no": pktInd.PortNo,
566 "packet": hex.EncodeToString(pktInd.Pkt),
567 "device-id": dh.device.Id,
568 })
569 }
570
David K. Bainbridge794735f2020-02-11 21:01:37 -0800571 go func() {
572 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530573 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800574 }
575 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700576 case *oop.Indication_PortStats:
577 portStats := indication.GetPortStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000578 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.resourceMgr.DevInfo.GetPonPorts())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700579 case *oop.Indication_FlowStats:
580 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000581 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700582 case *oop.Indication_AlarmInd:
583 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000584 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
585 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700586 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530587}
588
589// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530590func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530591 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000592 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530593
Girish Gowdru0c588b22019-04-23 23:24:56 -0400594 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530595 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400596 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000597 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400598 }
599 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530600}
601
602// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530603func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700604 dh.lockDevice.Lock()
605 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000606 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400607
npujarec5762e2020-01-01 14:08:48 +0530608 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400609 if err != nil || device == nil {
610 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000611 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400612 }
613
614 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400615
616 //Update the device oper state and connection status
617 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400618 dh.device = cloned
619
David K. Bainbridge794735f2020-02-11 21:01:37 -0800620 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000621 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400622 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400623
624 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530625 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400626 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000627 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400628 }
629 for _, onuDevice := range onuDevices.Items {
630
631 // Update onu state as down in onu adapter
632 onuInd := oop.OnuIndication{}
633 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800634 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700635 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800636 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530637 olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800638 "source": "openolt",
639 "onu-indicator": onuInd,
640 "device-type": onuDevice.Type,
641 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700642 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700643 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400644 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700645 /* Discovered ONUs entries need to be cleared , since after OLT
646 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530647 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000648 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700649 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530650}
651
652// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530653func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400654 var err error
David K. Bainbridge794735f2020-02-11 21:01:37 -0800655 if dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure(), grpc.WithBlock()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530656 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530657 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000658 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400659 }
660 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530661}
662
663// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530664func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400665 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530666 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400667 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530668}
669
670// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530671func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530672 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000673 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400674
675 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530676 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
677 if err != nil || device == nil {
678 /*TODO: needs to handle error scenarios */
679 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
680 }
681 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000682 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400683
684 cloned := proto.Clone(device).(*voltha.Device)
685 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
686 cloned.OperStatus = voltha.OperStatus_UNKNOWN
687 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530688 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
689 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 -0400690 }
691
Chaitrashree G S44124192019-08-07 20:21:36 -0400692 // 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 +0530693 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400694 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530695 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400696 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400697 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
698 // all the modules initialized and ready to handle incoming ONUs.
699
Thomas Lee S985938d2020-05-04 11:40:41 +0530700 err = dh.initializeDeviceHandlerModules(ctx)
701 if err != nil {
702 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 -0400703 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400704
705 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800706 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530707 if err = dh.readIndications(ctx); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530708 olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800709 }
710 }()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400711 return nil
712 }
713
Thomas Lee S985938d2020-05-04 11:40:41 +0530714 device, err = dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400715 if err != nil || device == nil {
716 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000717 return olterrors.NewErrAdapter("fetch-device-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400718 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000719 dh.populateActivePorts(ctx, device)
720 if err := dh.disableAdminDownPorts(ctx, device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000721 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"device": device}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400722 }
723
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400724 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530725 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 -0400726 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530727
cuilin20187b2a8c32019-03-26 19:52:28 -0700728 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800729 go func() {
730 if err := dh.readIndications(ctx); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530731 olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800732 }
733 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000734 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000735
736 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000737 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000738 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700739 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530740}
741
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400742func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000743 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400744
745 if err != nil {
746 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
747 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400748 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000749 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 -0400750 return olterrors.ErrResourceManagerInstantiating
751 }
752
753 // Instantiate flow manager
754 if dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr); dh.flowMgr == nil {
755 return olterrors.ErrResourceManagerInstantiating
756
757 }
758 /* TODO: Instantiate Alarm , stats , BW managers */
759 /* Instantiating Event Manager to handle Alarms and KPIs */
760 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
761
762 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000763 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400764
765 return nil
766
767}
768
Neha Sharma96b7bf22020-06-15 10:37:32 +0000769func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400770 var err error
771 var deviceInfo *oop.DeviceInfo
772
773 deviceInfo, err = dh.Client.GetDeviceInfo(context.Background(), new(oop.Empty))
774
775 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000776 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400777 }
778 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000779 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400780 }
781
Neha Sharma96b7bf22020-06-15 10:37:32 +0000782 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400783 dh.device.Root = true
784 dh.device.Vendor = deviceInfo.Vendor
785 dh.device.Model = deviceInfo.Model
786 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
787 dh.device.HardwareVersion = deviceInfo.HardwareVersion
788 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
789
790 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000791 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400792 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000793 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400794 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000795 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400796 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000797 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400798 dh.device.MacAddress = genmac
799 } else {
800 dh.device.MacAddress = deviceInfo.DeviceId
801 }
802
803 // Synchronous call to update device - this method is run in its own go routine
804 if err := dh.coreProxy.DeviceUpdate(context.TODO(), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000805 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400806 }
807
808 return deviceInfo, nil
809}
810
Neha Sharma96b7bf22020-06-15 10:37:32 +0000811func startCollector(ctx context.Context, dh *DeviceHandler) {
812 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530813 for {
814 select {
815 case <-dh.stopCollector:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000816 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"deviceID:": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530817 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000818 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700819
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530820 ports := make([]*voltha.Port, len(dh.device.Ports))
821 copy(ports, dh.device.Ports)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530822 for _, port := range ports {
823 // NNI Stats
824 if port.Type == voltha.Port_ETHERNET_NNI {
825 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
826 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000827 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
828 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
829 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530830 }
831 // PON Stats
832 if port.Type == voltha.Port_PON_OLT {
833 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
834 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
835 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000836 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
837 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530838 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000839 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500840 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530841 }
842 }
843 }
844}
845
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700846//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530847func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400848 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000849 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530850 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530851
852 // Now, set the initial PM configuration for that device
853 if err := dh.coreProxy.DevicePMConfigUpdate(nil, dh.metrics.ToPmConfigs()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530854 olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530855 }
856
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400857 go startHeartbeatCheck(ctx, dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530858}
859
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700860//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530861func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700862 return &ic.SwitchCapability{
863 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530864 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700865 HwDesc: "open_pon",
866 SwDesc: "open_pon",
867 SerialNum: dh.device.SerialNumber,
868 },
869 SwitchFeatures: &of.OfpSwitchFeatures{
870 NBuffers: 256,
871 NTables: 2,
872 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
873 of.OfpCapabilities_OFPC_TABLE_STATS |
874 of.OfpCapabilities_OFPC_PORT_STATS |
875 of.OfpCapabilities_OFPC_GROUP_STATS),
876 },
877 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530878}
879
Neha Sharma96b7bf22020-06-15 10:37:32 +0000880func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
881 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 -0700882 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700883 var deviceID string
884 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700885
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400886 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700887 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000888 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 -0700889 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
890 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400891
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700892 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530893
894 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
895
Neha Sharma96b7bf22020-06-15 10:37:32 +0000896 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 -0700897 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700898 kwargs := make(map[string]interface{})
899 kwargs["onu_id"] = omciInd.OnuId
900 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700901
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700902 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
903 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530904 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700905 "intf-id": omciInd.IntfId,
906 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700907 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700908 deviceType = onuDevice.Type
909 deviceID = onuDevice.Id
910 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
911 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530912 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700913 } else {
914 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000915 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 +0530916 deviceType = onuInCache.(*OnuDevice).deviceType
917 deviceID = onuInCache.(*OnuDevice).deviceID
918 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700919 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700920
921 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
David K. Bainbridge794735f2020-02-11 21:01:37 -0800922 if err := dh.AdapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530923 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800924 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530925 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530926 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800927 "destination": deviceType,
928 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000929 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700930 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800931 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530932}
933
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700934//ProcessInterAdapterMessage sends the proxied messages to the target device
935// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
936// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000937func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
938 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700939 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700940 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700941 fromTopic := msg.Header.FromTopic
942 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700943 toDeviceID := msg.Header.ToDeviceId
944 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700945
Neha Sharma96b7bf22020-06-15 10:37:32 +0000946 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 -0700947
948 msgBody := msg.GetBody()
949
950 omciMsg := &ic.InterAdapterOmciMessage{}
951 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000952 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700953 }
954
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700955 if omciMsg.GetProxyAddress() == nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700956 onuDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, toDeviceID)
957 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530958 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800959 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000960 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700961 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000962 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
963 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530964 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800965 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000966 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800967 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700968 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000969 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
970 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530971 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800972 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000973 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800974 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700975 }
976
977 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +0000978 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -0700979 }
980 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530981}
982
Neha Sharma96b7bf22020-06-15 10:37:32 +0000983func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700984 var intfID uint32
985 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +0000986 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700987 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700988 intfID = onuDevice.ProxyAddress.GetChannelId()
989 onuID = onuDevice.ProxyAddress.GetOnuId()
990 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700991 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700992 intfID = omciMsg.GetProxyAddress().GetChannelId()
993 onuID = omciMsg.GetProxyAddress().GetOnuId()
994 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700995 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700996 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000997 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 -0800998
Thomas Lee S94109f12020-03-03 16:39:29 +0530999 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001000 "intf-id": intfID,
1001 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001002 }
1003
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001004 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1005 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001006 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001007 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1008 hex.Encode(hexPkt, omciMsg.Message)
1009 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1010
1011 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1012 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1013 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001014 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001015 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001016
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001017 _, err := dh.Client.OmciMsgOut(context.Background(), omciMessage)
1018 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301019 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001020 "intf-id": intfID,
1021 "onu-id": onuID,
1022 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001023 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001024 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001025}
1026
David K. Bainbridge794735f2020-02-11 21:01:37 -08001027func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001028 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 +02001029 if err := dh.flowMgr.UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001030 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001031 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001032 // TODO: need resource manager
1033 var pir uint32 = 1000000
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001034 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir}
npujarec5762e2020-01-01 14:08:48 +05301035 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001036 st, _ := status.FromError(err)
1037 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001038 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1039
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001040 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301041 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001042 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001043 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001044 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001045 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001046 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001047}
1048
David K. Bainbridge794735f2020-02-11 21:01:37 -08001049func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001050
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001051 channelID := onuDiscInd.GetIntfId()
1052 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001053
Neha Sharma96b7bf22020-06-15 10:37:32 +00001054 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301055
cuilin20187b2a8c32019-03-26 19:52:28 -07001056 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001057 if sn != "" {
1058 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001059 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001060 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001061 }
1062
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301063 var alarmInd oop.OnuAlarmIndication
1064 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001065 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301066
1067 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1068 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1069 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1070 OnuLosRaise event sent for it */
1071 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1072 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1073 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001074 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301075 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1076 "currentIntfId": onuDiscInd.GetIntfId()})
1077 // TODO:: Should we need to ignore raising OnuLosClear event
1078 // when onu connected to different PON?
1079 }
1080 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1081 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1082 alarmInd.LosStatus = statusCheckOff
Neha Sharma96b7bf22020-06-15 10:37:32 +00001083 go dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs)
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301084 }
1085 return true
1086 })
1087
Neha Sharma96b7bf22020-06-15 10:37:32 +00001088 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001089 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001090 }
1091
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001092 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001093
1094 // check the ONU is already know to the OLT
1095 // NOTE the second time the ONU is discovered this should return a device
1096 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1097
1098 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001099 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 -08001100 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001101 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 -08001102 switch e.Code() {
1103 case codes.Internal:
1104 // this probably means NOT FOUND, so just create a new device
1105 onuDevice = nil
1106 case codes.DeadlineExceeded:
1107 // if the call times out, cleanup and exit
1108 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001109 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001110 }
1111 }
1112 }
1113
1114 if onuDevice == nil {
1115 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001116 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001117 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001118 ponintfid := onuDiscInd.GetIntfId()
1119 dh.lockDevice.Lock()
npujarec5762e2020-01-01 14:08:48 +05301120 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Matt Jeanneret53539512019-07-20 14:47:02 -04001121 dh.lockDevice.Unlock()
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001122
Neha Sharma96b7bf22020-06-15 10:37:32 +00001123 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001124
1125 if err != nil {
1126 // if we can't create an ID in resource manager,
1127 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001128 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001129 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001130 "pon-intf-id": ponintfid,
1131 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001132 }
1133
1134 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(context.TODO(), dh.device.Id, int(parentPortNo),
1135 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001136 dh.discOnus.Delete(sn)
1137 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 +05301138 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001139 "pon-intf-id": ponintfid,
1140 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001141 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001142 dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano())
1143 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301144 log.Fields{"onuDevice": onuDevice,
1145 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001146 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301147 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001148 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001149
1150 // we can now use the existing ONU Id
1151 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001152 //Insert the ONU into cache to use in OnuIndication.
1153 //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 +00001154 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001155 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301156 "intfId": onuDiscInd.GetIntfId(),
1157 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001158 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001159
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301160 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301161 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001162 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301163 log.Fields{"onu": onuDev,
1164 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001165
David K. Bainbridge794735f2020-02-11 21:01:37 -08001166 if err = dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301167 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001168 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001169 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001170 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001171 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001172 if err = dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301173 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001174 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001175 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001176 }
1177 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001178}
1179
Neha Sharma96b7bf22020-06-15 10:37:32 +00001180func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001181 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1182
1183 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001184 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001185 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001186 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001187 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001188 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301189 log.Fields{"onuId": onuInd.OnuId,
1190 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301191 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001192 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301193
David K. Bainbridge794735f2020-02-11 21:01:37 -08001194 errFields := log.Fields{"device-id": dh.device.Id}
1195
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301196 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1197
Mahir Gunyele77977b2019-06-27 05:36:22 -07001198 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1199 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001200 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
1201 onuDevice, err = dh.coreProxy.GetDevice(nil, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001202 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001203 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1204 if serialNumber != "" {
1205 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001206 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001207 } else {
1208 kwargs["onu_id"] = onuInd.OnuId
1209 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001210 errFields["onu-id"] = onuInd.OnuId
1211 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001212 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001213 onuDevice, err = dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001214 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001215
David K. Bainbridge794735f2020-02-11 21:01:37 -08001216 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001217 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001218 }
1219
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001221 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001222 "previousIntfId": onuDevice.ParentPortNo,
1223 "currentIntfId": ponPort})
1224 }
1225
1226 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001227 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301228 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1229 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301230 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001231 }
1232 if !foundInCache {
1233 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1234
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301235 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 -08001236
1237 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001238 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001239 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001240 }
1241 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001242}
1243
Neha Sharma96b7bf22020-06-15 10:37:32 +00001244func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
1245 ctx = context.TODO()
1246 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 -07001247 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1248 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1249 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1250 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001251 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001252 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1253 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001254 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001255 onuInd.OperState = "down"
1256 }
1257 }
1258
David K. Bainbridge794735f2020-02-11 21:01:37 -08001259 switch onuInd.OperState {
1260 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001261 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 -07001262 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301263 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001264 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1265 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301266 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001267 "onu-indicator": onuInd,
1268 "source": "openolt",
1269 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001270 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001271 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001272 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001273 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 -04001274 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301275 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001276 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1277 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301278 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001279 "onu-indicator": onuInd,
1280 "source": "openolt",
1281 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001282 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001283 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001284 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001285 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001286 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001287 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001288}
1289
cuilin20187b2a8c32019-03-26 19:52:28 -07001290func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1291 if serialNum != nil {
1292 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001293 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001294 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001295}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001296func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1297 decodedStr, err := hex.DecodeString(serialNum[4:])
1298 if err != nil {
1299 return nil, err
1300 }
1301 return &oop.SerialNumber{
1302 VendorId: []byte(serialNum[:4]),
1303 VendorSpecific: []byte(decodedStr),
1304 }, nil
1305}
cuilin20187b2a8c32019-03-26 19:52:28 -07001306
1307func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1308 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001309 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001310 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1311 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1312 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1313 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1314 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1315 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1316 return tmp
1317}
1318
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001319//UpdateFlowsBulk upates the bulk flow
1320func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301321 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001322}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001323
1324//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001325func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1326 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301327 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001328 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301329 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001330 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001331 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001332 kwargs["parent_port_no"] = parentPort
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001333 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001334 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001335 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001336 "intf-id": parentPort,
1337 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001338 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001339 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 -08001340 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301341}
1342
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001343// SendPacketInToCore sends packet-in to core
1344// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1345// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001346func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001347 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001348 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001349 "port": logicalPort,
1350 "packet": hex.EncodeToString(packetPayload),
1351 "device-id": dh.device.Id,
1352 })
1353 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001354 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301355 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001356 "source": "adapter",
1357 "destination": "core",
1358 "device-id": dh.device.Id,
1359 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001360 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001361 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001362 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001363 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001364 "packet": hex.EncodeToString(packetPayload),
1365 "device-id": dh.device.Id,
1366 })
1367 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001368 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001369}
1370
A R Karthick1f85b802019-10-11 05:06:05 +00001371// AddUniPortToOnu adds the uni port to the onu device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001372func (dh *DeviceHandler) AddUniPortToOnu(ctx context.Context, intfID, onuID, uniPort uint32) {
A R Karthick1f85b802019-10-11 05:06:05 +00001373 onuKey := dh.formOnuKey(intfID, onuID)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301374
1375 if onuDevice, ok := dh.onus.Load(onuKey); ok {
A R Karthick1f85b802019-10-11 05:06:05 +00001376 // add it to the uniPort map for the onu device
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301377 if _, ok = onuDevice.(*OnuDevice).uniPorts[uniPort]; !ok {
1378 onuDevice.(*OnuDevice).uniPorts[uniPort] = struct{}{}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001379 logger.Debugw(ctx, "adding-uni-port", log.Fields{"port": uniPort, "intf-id": intfID, "onuId": onuID})
A R Karthick1f85b802019-10-11 05:06:05 +00001380 }
1381 }
1382}
1383
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001384// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001385func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001386
Neha Sharma96b7bf22020-06-15 10:37:32 +00001387 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001388
1389 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1390 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001391 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001392 }
1393
1394 if pmConfigs.Grouped == false {
1395 metrics := dh.metrics.GetSubscriberMetrics()
1396 for _, m := range pmConfigs.Metrics {
1397 metrics[m.Name].Enabled = m.Enabled
1398
1399 }
1400 }
1401}
1402
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001403//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301404func (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 +00001405 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 +01001406
1407 var errorsList []error
1408
Girish Gowdru0c588b22019-04-23 23:24:56 -04001409 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001410 for _, flow := range flows.ToRemove.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001411 dh.incrementActiveFlowRemoveCount(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001412
Neha Sharma96b7bf22020-06-15 10:37:32 +00001413 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301414 log.Fields{"device-id": device.Id,
1415 "flowToRemove": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001416 err := dh.flowMgr.RemoveFlow(ctx, flow)
1417 if err != nil {
1418 errorsList = append(errorsList, err)
1419 }
1420
Neha Sharma96b7bf22020-06-15 10:37:32 +00001421 dh.decrementActiveFlowRemoveCount(ctx, flow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001422 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301423
1424 for _, flow := range flows.ToAdd.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001425 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301426 log.Fields{"device-id": device.Id,
1427 "flowToAdd": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001428 // If there are active Flow Remove in progress for a given subscriber, wait until it completes
Neha Sharma96b7bf22020-06-15 10:37:32 +00001429 dh.waitForFlowRemoveToFinish(ctx, flow)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001430 err := dh.flowMgr.AddFlow(ctx, flow, flowMetadata)
1431 if err != nil {
1432 errorsList = append(errorsList, err)
1433 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301434 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001435 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001436
Girish Gowdracefae192020-03-19 18:14:10 -07001437 // 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 +00001438 if groups != nil {
1439 for _, group := range groups.ToAdd.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001440 err := dh.flowMgr.AddGroup(ctx, group)
1441 if err != nil {
1442 errorsList = append(errorsList, err)
1443 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001444 }
1445 for _, group := range groups.ToUpdate.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001446 err := dh.flowMgr.ModifyGroup(ctx, group)
1447 if err != nil {
1448 errorsList = append(errorsList, err)
1449 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001450 }
1451 if len(groups.ToRemove.Items) != 0 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001452 logger.Debugw(ctx, "group-delete-operation-not-supported", log.Fields{"device-id": dh.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +00001453 }
1454 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001455 if len(errorsList) > 0 {
1456 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1457 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001458 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001459 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301460}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001461
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001462//DisableDevice disables the given device
1463//It marks the following for the given device:
1464//Device-Handler Admin-State : down
1465//Device Port-State: UNKNOWN
1466//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001467func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001468 /* On device disable ,admin state update has to be done prior sending request to agent since
1469 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001470 if dh.Client != nil {
1471 if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
1472 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001473 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001474 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001475 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001476 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001477 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001478 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001479 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301480
1481 dh.discOnus = sync.Map{}
1482 dh.onus = sync.Map{}
1483
Thomas Lee S85f37312020-04-03 17:06:12 +05301484 //stopping the stats collector
1485 dh.stopCollector <- true
1486
Neha Sharma96b7bf22020-06-15 10:37:32 +00001487 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001488 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301489 //Update device Admin state
1490 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001491 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
1492 for _, port := range cloned.Ports {
1493 if port.GetType() == voltha.Port_PON_OLT {
1494 if err := dh.coreProxy.PortStateUpdate(context.TODO(), cloned.Id,
1495 voltha.Port_PON_OLT, port.GetPortNo(), voltha.OperStatus_UNKNOWN); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001496 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{"device-id": device.Id, "port-number": port.GetPortNo()}, err)
kdarapu1afeceb2020-02-12 01:38:09 -05001497 }
1498 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001499 }
1500
Neha Sharma96b7bf22020-06-15 10:37:32 +00001501 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001502 return nil
1503}
1504
Neha Sharma96b7bf22020-06-15 10:37:32 +00001505func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001506
1507 // Update onu state as unreachable in onu adapter
1508 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301509 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001510 //get the child device for the parent device
1511 onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
1512 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001513 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 -04001514 }
1515 if onuDevices != nil {
1516 for _, onuDevice := range onuDevices.Items {
1517 err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1518 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1519 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001520 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301521 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001522 }
1523
1524 }
1525 }
1526
1527}
1528
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001529//ReenableDevice re-enables the olt device after disable
1530//It marks the following for the given device:
1531//Device-Handler Admin-State : up
1532//Device Port-State: ACTIVE
1533//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001534func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301535
1536 if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
1537 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001538 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301539 }
1540 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001541 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001542
1543 cloned := proto.Clone(device).(*voltha.Device)
1544 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001545
Neha Sharma96b7bf22020-06-15 10:37:32 +00001546 if err := dh.disableAdminDownPorts(ctx, device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001547 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001548 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001549 //Update the device oper status as ACTIVE
1550 cloned.OperStatus = voltha.OperStatus_ACTIVE
1551 dh.device = cloned
1552
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001553 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301554 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001555 "device-id": device.Id,
1556 "connect-status": cloned.ConnectStatus,
Girish Kumarf26e4882020-03-05 06:49:10 +00001557 "oper-status": cloned.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001558 }
kesavand39e0aa32020-01-28 20:58:50 -05001559
Neha Sharma96b7bf22020-06-15 10:37:32 +00001560 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001561
1562 return nil
1563}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001564
npujarec5762e2020-01-01 14:08:48 +05301565func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001566 var uniID uint32
1567 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301568 for _, port := range onu.UniPorts {
1569 uniID = UniIDFromPortNum(uint32(port))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001570 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001571 /* Delete tech-profile instance from the KV store */
npujarec5762e2020-01-01 14:08:48 +05301572 if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001573 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001574 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001575 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301576 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001577 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301578 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001579 }
npujarec5762e2020-01-01 14:08:48 +05301580 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001581 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301582 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001583 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001584 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301586 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001587 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001588 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001589 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301590 }
npujarec5762e2020-01-01 14:08:48 +05301591 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1592 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301594 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301596 if err = dh.resourceMgr.DelGemPortPktIn(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001597 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 +00001598 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001599 }
1600 return nil
1601}
1602
npujarec5762e2020-01-01 14:08:48 +05301603func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001604 nniUniID := -1
1605 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301606
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001607 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301608 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001609 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001610 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301611 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301612 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001613 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001614 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001615 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301616 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301617 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001618 logger.Debugw(ctx, "current-flow-ids-for-nni", log.Fields{"flow-ids": flowIDs})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301619 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301620 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301621 }
npujarec5762e2020-01-01 14:08:48 +05301622 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001623 }
npujarec5762e2020-01-01 14:08:48 +05301624 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001625 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301626 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001627 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001628}
1629
1630// 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 +05301631func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001632 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001633 /* Clear the KV store data associated with the all the UNI ports
1634 This clears up flow data and also resource map data for various
1635 other pon resources like alloc_id and gemport_id
1636 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001637 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001638 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001639 // Stop the Stats collector
1640 dh.stopCollector <- true
1641 // stop the heartbeat check routine
1642 dh.stopHeartbeatCheck <- true
1643 //Reset the state
1644 if dh.Client != nil {
1645 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301646 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001647 }
1648 }
1649 cloned := proto.Clone(device).(*voltha.Device)
1650 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1651 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1652 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1653 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1654 "device-id": device.Id,
1655 "connect-status": cloned.ConnectStatus,
1656 "oper-status": cloned.OperStatus}, err).Log()
1657 }
1658 return nil
1659}
1660func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) error {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001661 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301662 noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
1663 var ponPort uint32
1664 for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
1665 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301666 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301667 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301668 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001669 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001670 "pon-port": ponPort}, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301671 }
1672 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301673 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001674 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301675 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001676 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301677 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301678 // Clear flowids for gem cache.
1679 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301680 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301681 }
1682 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301683 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301684 }
npujarec5762e2020-01-01 14:08:48 +05301685 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301686 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301687 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301688 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001689 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001690 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001691 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001692 /* Clear the flows from KV store associated with NNI port.
1693 There are mostly trap rules from NNI port (like LLDP)
1694 */
npujarec5762e2020-01-01 14:08:48 +05301695 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001696 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001697 }
A R Karthick1f85b802019-10-11 05:06:05 +00001698
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001699 /* Clear the resource pool for each PON port in the background */
npujarec5762e2020-01-01 14:08:48 +05301700 go dh.resourceMgr.Delete(ctx)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001701 }
A R Karthick1f85b802019-10-11 05:06:05 +00001702
Devmalya Paul495b94a2019-08-27 19:42:00 -04001703 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301704 dh.onus.Range(func(key interface{}, value interface{}) bool {
1705 dh.onus.Delete(key)
1706 return true
1707 })
1708
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001709 /*Delete discovered ONU map for the device*/
1710 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1711 dh.discOnus.Delete(key)
1712 return true
1713 })
1714
Devmalya Paul495b94a2019-08-27 19:42:00 -04001715 return nil
1716}
1717
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001718//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001719func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001720 if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301721 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001722 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001723 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001724 return nil
1725}
1726
David K. Bainbridge794735f2020-02-11 21:01:37 -08001727func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001728 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001729 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001730 "packet-indication": *packetIn,
1731 "device-id": dh.device.Id,
1732 "packet": hex.EncodeToString(packetIn.Pkt),
1733 })
1734 }
npujarec5762e2020-01-01 14:08:48 +05301735 logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001736 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001737 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001738 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001739 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001740 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001741 "logical-port-num": logicalPortNum,
1742 "device-id": dh.device.Id,
1743 "packet": hex.EncodeToString(packetIn.Pkt),
1744 })
1745 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001746
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001747 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301748 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001749 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301750 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001751 "device-id": dh.device.Id,
1752 "packet": hex.EncodeToString(packetIn.Pkt),
1753 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001754 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001755
Matteo Scandolo92186242020-06-12 10:54:18 -07001756 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001757 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001758 "packet": hex.EncodeToString(packetIn.Pkt),
1759 "device-id": dh.device.Id,
1760 })
1761 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001762 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001763}
1764
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001765// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301766func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001767 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001768 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001769 "device-id": dh.device.Id,
1770 "egress-port-no": egressPortNo,
1771 "pkt-length": len(packet.Data),
1772 "packet": hex.EncodeToString(packet.Data),
1773 })
1774 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001775
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001776 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001777 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001778 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1779 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301780 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1781 // Do not packet-out lldp packets on uni port.
1782 // ONOS has no clue about uni/nni ports, it just packets out on all
1783 // available ports on the Logical Switch. It should not be interested
1784 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001785 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001786 "device-id": dh.device.Id,
1787 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301788 return nil
1789 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001790 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1791 if innerEthType == 0x8100 {
1792 // q-in-q 802.1ad or 802.1q double tagged packet.
1793 // slice out the outer tag.
1794 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001795 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001796 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001797 "packet-data": hex.EncodeToString(packet.Data),
1798 "device-id": dh.device.Id,
1799 })
1800 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001801 }
1802 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001803 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1804 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001805 uniID := UniIDFromPortNum(uint32(egressPortNo))
1806
npujarec5762e2020-01-01 14:08:48 +05301807 gemPortID, err := dh.flowMgr.GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001808 if err != nil {
1809 // In this case the openolt agent will receive the gemPortID as 0.
1810 // The agent tries to retrieve the gemPortID in this case.
1811 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001812 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001813 "intf-id": intfID,
1814 "onu-id": onuID,
1815 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001816 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301817 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001818 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001819 }
1820
1821 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001822
Matteo Scandolo92186242020-06-12 10:54:18 -07001823 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001824 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001825 "egress-port-no": egressPortNo,
1826 "intf-id": intfID,
1827 "onu-id": onuID,
1828 "uni-id": uniID,
1829 "gem-port-id": gemPortID,
1830 "packet": hex.EncodeToString(packet.Data),
1831 "device-id": dh.device.Id,
1832 })
1833 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001834
npujarec5762e2020-01-01 14:08:48 +05301835 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301836 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001837 "source": "adapter",
1838 "destination": "onu",
1839 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001840 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001841 "oni-id": onuID,
1842 "uni-id": uniID,
1843 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001844 "packet": hex.EncodeToString(packet.Data),
1845 "device-id": dh.device.Id,
1846 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001847 }
1848 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001849 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001850 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001851 return olterrors.NewErrInvalidValue(log.Fields{
1852 "egress-nni-port": egressPortNo,
1853 "device-id": dh.device.Id,
1854 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001855 }
1856 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001857
Matteo Scandolo92186242020-06-12 10:54:18 -07001858 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001859 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001860 "uplink-pkt": uplinkPkt,
1861 "packet": hex.EncodeToString(packet.Data),
1862 "device-id": dh.device.Id,
1863 })
1864 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001865
npujarec5762e2020-01-01 14:08:48 +05301866 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001867 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1868 "packet": hex.EncodeToString(packet.Data),
1869 "device-id": dh.device.Id,
1870 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001871 }
1872 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001873 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301874 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001875 "egressPortType": egressPortType,
1876 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301877 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001878 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001879 }
1880 return nil
1881}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001882
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001883func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1884 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001885}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301886
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001887func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301888 // start the heartbeat check towards the OLT.
1889 var timerCheck *time.Timer
1890
1891 for {
1892 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1893 select {
1894 case <-heartbeatTimer.C:
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001895 ctxWithTimeout, cancel := context.WithTimeout(context.Background(), dh.openOLT.GrpcTimeoutInterval)
1896 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001897 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301898 if timerCheck == nil {
1899 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001900 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301901 }
1902 } else {
1903 if timerCheck != nil {
1904 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001905 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301906 }
1907 timerCheck = nil
1908 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001909 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301910 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301911 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301912 }
1913 cancel()
1914 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001915 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301916 return
1917 }
1918 }
1919}
1920
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001921func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1922 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1923 if err != nil || device == nil {
1924 olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
1925 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301926
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001927 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1928 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1929 olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
1930 }
1931 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, voltha.OperStatus_UNKNOWN); err != nil {
1932 olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
1933 }
1934 go dh.cleanupDeviceResources(ctx)
1935
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001936 dh.lockDevice.RLock()
1937 // Stop the read indication only if it the routine is active
1938 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1939 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1940 // on next execution of the readIndication routine.
1941 if dh.isReadIndicationRoutineActive {
1942 dh.stopIndications <- true
1943 }
1944 dh.lockDevice.RUnlock()
1945
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001946 dh.transitionMap.Handle(ctx, DeviceInit)
1947
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301948 }
1949}
kesavand39e0aa32020-01-28 20:58:50 -05001950
1951// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001952func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1953 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1954 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001955}
1956
1957// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001958func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1959 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1960 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001961}
1962
kdarapu1afeceb2020-02-12 01:38:09 -05001963//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 +00001964func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1965 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001966 if port.GetType() == voltha.Port_ETHERNET_NNI {
1967 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001968 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301969 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301970 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001971 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001972 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001973 }
1974 // fetch interfaceid from PortNo
1975 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1976 ponIntf := &oop.Interface{IntfId: ponID}
1977 var operStatus voltha.OperStatus_Types
1978 if enablePort {
1979 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301980 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001981
1982 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301983 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001984 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001985 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001986 }
1987 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001988 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001989 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05001990 } else {
1991 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05301992 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001993 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301994 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001995 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001996 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001997 }
1998 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001999 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002000 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002001 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302002 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 +05302003 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302004 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002005 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002006 }
2007 return nil
2008}
2009
kdarapu1afeceb2020-02-12 01:38:09 -05002010//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002011func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, device *voltha.Device) error {
kesavand39e0aa32020-01-28 20:58:50 -05002012 cloned := proto.Clone(device).(*voltha.Device)
2013 // Disable the port and update the oper_port_status to core
2014 // if the Admin state of the port is disabled on reboot and re-enable device.
2015 for _, port := range cloned.Ports {
2016 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002017 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302018 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302019 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002020 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002021 }
2022 }
2023 }
2024 return nil
2025}
2026
2027//populateActivePorts to populate activePorts map
Neha Sharma96b7bf22020-06-15 10:37:32 +00002028func (dh *DeviceHandler) populateActivePorts(ctx context.Context, device *voltha.Device) {
2029 logger.Infow(ctx, "populateActiveports", log.Fields{"Device": device})
kesavand39e0aa32020-01-28 20:58:50 -05002030 for _, port := range device.Ports {
2031 if port.Type == voltha.Port_ETHERNET_NNI {
2032 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002033 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002034 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002035 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002036 }
2037 }
2038 if port.Type == voltha.Port_PON_OLT {
2039 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002040 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002041 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002042 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002043 }
2044 }
2045 }
2046}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002047
2048// ChildDeviceLost deletes ONU and clears pon resources related to it.
2049func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002050 logger.Debugw(ctx, "child-device-lost", log.Fields{"pdeviceID": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002051 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2052 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002053 onuDevice, ok := dh.onus.Load(onuKey)
2054 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302055 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002056 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002057 "device-id": dh.device.Id,
2058 "onu-id": onuID,
2059 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002060 }
2061 var sn *oop.SerialNumber
2062 var err error
2063 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302064 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002065 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302066 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002067 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2068 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002069
2070 for uniID := 0; uniID < MaxUnisPerOnu; uniID++ {
2071 var flowRemoveData pendingFlowRemoveData
2072 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uint32(uniID)}
2073 dh.lockDevice.RLock()
2074 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
2075 dh.lockDevice.RUnlock()
2076 continue
2077 }
2078 dh.lockDevice.RUnlock()
2079
2080 log.Debugw("wait-for-flow-remove-complete-before-processing-child-device-lost",
2081 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2082 // Wait for all flow removes to finish first
2083 <-flowRemoveData.allFlowsRemoved
2084 log.Debugw("flow-removes-complete-for-subscriber",
2085 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2086 }
2087
2088 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002089 if _, err := dh.Client.DeleteOnu(context.Background(), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302090 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302091 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002092 "onu-id": onuID}, err).Log()
2093 }
2094 //clear PON resources associated with ONU
2095 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002096 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002097 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002098 "device-id": dh.device.Id,
2099 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002100 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002101 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002102 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002103 "device-id": dh.device.Id,
2104 "intf-id": intfID,
2105 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002106 } else {
2107 for i, onu := range onuGemData {
2108 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002109 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002110 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002111 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302112 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002113 "onu-device": onu,
2114 "error": err})
2115 }
2116 // Clear flowids for gem cache.
2117 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002118 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002119 }
2120 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002121 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002122 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002123 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002124 "intf-id": intfID,
2125 "onu-device": onu,
2126 "onu-gem": onuGemData,
2127 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002128 //Not returning error on cleanup.
2129 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002130 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002131 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002132 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002133 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002134 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002135 }
2136 }
2137 dh.onus.Delete(onuKey)
2138 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2139 return nil
2140}
Girish Gowdracefae192020-03-19 18:14:10 -07002141
2142func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2143 for _, field := range flows.GetOfbFields(flow) {
2144 if field.Type == flows.IN_PORT {
2145 return field.GetPort()
2146 }
2147 }
2148 return InvalidPort
2149}
2150
2151func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2152 for _, action := range flows.GetActions(flow) {
2153 if action.Type == flows.OUTPUT {
2154 if out := action.GetOutput(); out != nil {
2155 return out.GetPort()
2156 }
2157 }
2158 }
2159 return InvalidPort
2160}
2161
Neha Sharma96b7bf22020-06-15 10:37:32 +00002162func (dh *DeviceHandler) incrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002163 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002164 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 -07002165 if inPort != InvalidPort && outPort != InvalidPort {
2166 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2167 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002168 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 -07002169
2170 dh.lockDevice.Lock()
2171 defer dh.lockDevice.Unlock()
2172 flowRemoveData, ok := dh.pendingFlowRemoveDataPerSubscriber[key]
2173 if !ok {
2174 flowRemoveData = pendingFlowRemoveData{
2175 pendingFlowRemoveCount: 0,
2176 allFlowsRemoved: make(chan struct{}),
2177 }
2178 }
2179 flowRemoveData.pendingFlowRemoveCount++
2180 dh.pendingFlowRemoveDataPerSubscriber[key] = flowRemoveData
2181
Neha Sharma96b7bf22020-06-15 10:37:32 +00002182 logger.Debugw(ctx, "current-flow-remove-count–increment",
Matteo Scandolo92186242020-06-12 10:54:18 -07002183 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002184 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2185 }
2186}
2187
Neha Sharma96b7bf22020-06-15 10:37:32 +00002188func (dh *DeviceHandler) decrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002189 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002190 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 -07002191 if inPort != InvalidPort && outPort != InvalidPort {
2192 _, intfID, onuID, uniID := ExtractAccessFromFlow(uint32(inPort), uint32(outPort))
2193 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002194 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 -07002195
2196 dh.lockDevice.Lock()
2197 defer dh.lockDevice.Unlock()
2198 if val, ok := dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002199 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 -07002200 } else {
2201 if val.pendingFlowRemoveCount > 0 {
2202 val.pendingFlowRemoveCount--
2203 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002204 logger.Debugw(ctx, "current-flow-remove-count-after-decrement",
Matteo Scandolo92186242020-06-12 10:54:18 -07002205 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002206 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2207 // If all flow removes have finished, then close the channel to signal the receiver
2208 // to go ahead with flow adds.
2209 if val.pendingFlowRemoveCount == 0 {
2210 close(val.allFlowsRemoved)
2211 delete(dh.pendingFlowRemoveDataPerSubscriber, key)
2212 return
2213 }
2214 dh.pendingFlowRemoveDataPerSubscriber[key] = val
2215 }
2216 }
2217}
2218
Neha Sharma96b7bf22020-06-15 10:37:32 +00002219func (dh *DeviceHandler) waitForFlowRemoveToFinish(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002220 var flowRemoveData pendingFlowRemoveData
2221 var ok bool
2222 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002223 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 -07002224 if inPort != InvalidPort && outPort != InvalidPort {
2225 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2226 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002227 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 -07002228
2229 dh.lockDevice.RLock()
2230 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002231 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 -07002232 dh.lockDevice.RUnlock()
2233 return
2234 }
2235 dh.lockDevice.RUnlock()
2236
2237 // Wait for all flow removes to finish first
2238 <-flowRemoveData.allFlowsRemoved
2239
Neha Sharma96b7bf22020-06-15 10:37:32 +00002240 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 -07002241 }
2242}
2243
2244func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2245 inPort := getInPortFromFlow(flow)
2246 outPort := getOutPortFromFlow(flow)
2247
2248 if inPort == InvalidPort || outPort == InvalidPort {
2249 return inPort, outPort
2250 }
2251
2252 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2253 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2254 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2255 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2256 return uniPort, outPort
2257 }
2258 }
2259 } else {
2260 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2261 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2262 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2263 return inPort, uniPort
2264 }
2265 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2266 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2267 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2268 return uniPort, outPort
2269 }
2270 }
2271 }
2272
2273 return InvalidPort, InvalidPort
2274}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002275
2276func extractOmciTransactionID(omciPkt []byte) uint16 {
2277 if len(omciPkt) > 3 {
2278 d := omciPkt[0:2]
2279 transid := binary.BigEndian.Uint16(d)
2280 return transid
2281 }
2282 return 0
2283}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002284
2285// StoreOnuDevice stores the onu parameters to the local cache.
2286func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2287 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2288 dh.onus.Store(onuKey, onuDevice)
2289}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002290
Devmalya Paula1efa642020-04-20 01:36:43 -04002291// setOnuITUPonAlarmConfig sets the parameters in the openolt agent for raising the ONU ITU PON alarms.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002292func (dh *DeviceHandler) setOnuITUPonAlarmConfig(ctx context.Context, config *oop.OnuItuPonAlarm) error {
Devmalya Paula1efa642020-04-20 01:36:43 -04002293 if _, err := dh.Client.OnuItuPonAlarmSet(context.Background(), config); err != nil {
2294 return err
2295 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002296 logger.Debugw(ctx, "onu-itu-pon-alarm-config-set-successful", log.Fields{"config": config})
Devmalya Paula1efa642020-04-20 01:36:43 -04002297 return nil
2298}
2299
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002300func (dh *DeviceHandler) getExtValue(device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
2301 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002302 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002303 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002304 resp := new(voltha.ReturnValues)
2305 valueparam := new(oop.ValueParam)
2306 ctx := context.Background()
2307 log.Infow("getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002308 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2309 return nil, err
2310 }
2311 ID = device.ProxyAddress.GetOnuId()
2312 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2313 valueparam.Onu = &Onu
2314 valueparam.Value = value
2315
2316 // This API is unsupported until agent patch is added
2317 resp.Unsupported = uint32(value)
2318 _ = ctx
2319
2320 // Uncomment this code once agent changes are complete and tests
2321 /*
2322 resp, err = dh.Client.GetValue(ctx, valueparam)
2323 if err != nil {
2324 log.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
2325 return nil, err
2326 }
2327 */
2328
2329 log.Infow("get-ext-value", log.Fields{"resp": resp, "device-id": dh.device, "onu-id": device.Id, "pon-intf": device.ParentPortNo})
2330 return resp, nil
2331}