blob: 504526ff5ba26341fb25f1597c64556cfb5b38ed [file] [log] [blame]
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
Phaneendra Manda4c62c802019-03-06 21:37:49 +053019
20import (
cuilin20187b2a8c32019-03-26 19:52:28 -070021 "context"
Matt Jeanneretceea2e02020-03-27 14:19:57 -040022 "encoding/binary"
Matt Jeanneret1359c732019-08-01 21:40:02 -040023 "encoding/hex"
cuilin20187b2a8c32019-03-26 19:52:28 -070024 "fmt"
25 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040026 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070027 "strconv"
28 "strings"
29 "sync"
30 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053031
Matteo Scandolo945e4012019-12-12 14:16:11 -080032 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070033 "github.com/gogo/protobuf/proto"
34 "github.com/golang/protobuf/ptypes"
Girish Kumar93e91742020-07-27 16:43:19 +000035 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
36 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
Esin Karamanccb714b2019-11-29 15:02:06 +000037 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
Kent Hagermanf1db18b2020-07-08 13:38:15 -040038 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
Esin Karamanccb714b2019-11-29 15:02:06 +000039 "github.com/opencord/voltha-lib-go/v3/pkg/log"
40 "github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics"
Thomas Lee S94109f12020-03-03 16:39:29 +053041 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080042 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Esin Karamanccb714b2019-11-29 15:02:06 +000043 "github.com/opencord/voltha-protos/v3/go/common"
44 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
45 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
46 oop "github.com/opencord/voltha-protos/v3/go/openolt"
47 "github.com/opencord/voltha-protos/v3/go/voltha"
Girish Kumar93e91742020-07-27 16:43:19 +000048 "github.com/opentracing/opentracing-go"
cuilin20187b2a8c32019-03-26 19:52:28 -070049 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040050 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040051 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053052)
53
salmansiddiqui7ac62132019-08-22 03:58:50 +000054// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040055const (
salmansiddiqui7ac62132019-08-22 03:58:50 +000056 MaxRetry = 10
57 MaxTimeOutInMs = 500
Girish Gowdracefae192020-03-19 18:14:10 -070058 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040059)
60
Girish Gowdracefae192020-03-19 18:14:10 -070061// pendingFlowRemoveDataKey is key to pendingFlowRemoveDataPerSubscriber map
62type pendingFlowRemoveDataKey struct {
63 intfID uint32
64 onuID uint32
65 uniID uint32
66}
67
68// pendingFlowRemoveData is value stored in pendingFlowRemoveDataPerSubscriber map
69// This holds the number of pending flow removes and also a signal channel to
70// to indicate the receiver when all flow removes are handled
71type pendingFlowRemoveData struct {
72 pendingFlowRemoveCount uint32
73 allFlowsRemoved chan struct{}
74}
75
Phaneendra Manda4c62c802019-03-06 21:37:49 +053076//DeviceHandler will interact with the OLT device.
77type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070078 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053079 coreProxy adapterif.CoreProxy
80 AdapterProxy adapterif.AdapterProxy
81 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070082 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070083 exitChannel chan int
84 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053085 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070086 transitionMap *TransitionMap
87 clientCon *grpc.ClientConn
manikkaraj kbf256be2019-03-25 00:13:48 +053088 flowMgr *OpenOltFlowMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040089 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053090 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053091
Girish Gowdra3ab6d212020-03-24 17:33:15 -070092 discOnus sync.Map
93 onus sync.Map
94 portStats *OpenOltStatisticsMgr
95 metrics *pmmetrics.PmMetrics
96 stopCollector chan bool
97 stopHeartbeatCheck chan bool
98 activePorts sync.Map
99 stopIndications chan bool
100 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -0700101
102 // pendingFlowRemoveDataPerSubscriber map is used to maintain the context on a per
103 // subscriber basis for the number of pending flow removes. This data is used
104 // to process all the flow removes for a subscriber before handling flow adds.
105 // Interleaving flow delete and flow add processing has known to cause PON resource
106 // management contentions on a per subscriber bases, so we need ensure ordering.
107 pendingFlowRemoveDataPerSubscriber map[pendingFlowRemoveDataKey]pendingFlowRemoveData
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700108}
109
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700110//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700111type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700112 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700113 deviceType string
114 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700115 onuID uint32
116 intfID uint32
117 proxyDeviceID string
A R Karthick1f85b802019-10-11 05:06:05 +0000118 uniPorts map[uint32]struct{}
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530119 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400120 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700121}
122
Naga Manjunath7615e552019-10-11 22:35:47 +0530123var pmNames = []string{
124 "rx_bytes",
125 "rx_packets",
126 "rx_mcast_packets",
127 "rx_bcast_packets",
128 "tx_bytes",
129 "tx_packets",
130 "tx_mcast_packets",
131 "tx_bcast_packets",
132}
133
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700134//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530135func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700136 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700137 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700138 device.deviceType = deviceTp
139 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700140 device.onuID = onuID
141 device.intfID = intfID
142 device.proxyDeviceID = proxyDevID
A R Karthick1f85b802019-10-11 05:06:05 +0000143 device.uniPorts = make(map[uint32]struct{})
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530144 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700145 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530146}
147
148//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530149func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700150 var dh DeviceHandler
151 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400152 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400153 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700154 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700155 dh.device = cloned
156 dh.openOLT = adapter
157 dh.exitChannel = make(chan int, 1)
158 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530159 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530160 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530161 dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Chaitrashree G Sef088112020-02-03 21:39:27 -0500162 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400163 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700164 dh.pendingFlowRemoveDataPerSubscriber = make(map[pendingFlowRemoveDataKey]pendingFlowRemoveData)
165
cuilin20187b2a8c32019-03-26 19:52:28 -0700166 //TODO initialize the support classes.
167 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530168}
169
170// start save the device to the data model
171func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700172 dh.lockDevice.Lock()
173 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000174 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700175 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000176 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530177}
178
179// stop stops the device dh. Not much to do for now
180func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700181 dh.lockDevice.Lock()
182 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000183 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700184 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000185 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530186}
187
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400188func macifyIP(ip net.IP) string {
189 if len(ip) > 0 {
190 oct1 := strconv.FormatInt(int64(ip[12]), 16)
191 oct2 := strconv.FormatInt(int64(ip[13]), 16)
192 oct3 := strconv.FormatInt(int64(ip[14]), 16)
193 oct4 := strconv.FormatInt(int64(ip[15]), 16)
194 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
195 }
196 return ""
197}
198
Neha Sharma96b7bf22020-06-15 10:37:32 +0000199func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400200 var genmac string
201 var addr net.IP
202 var ips []string
203 var err error
204
Neha Sharma96b7bf22020-06-15 10:37:32 +0000205 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400206
207 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000208 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400209
210 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000211 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400212 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000213 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400214 }
215 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000216 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530217 log.Fields{"host": ips[0],
218 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400219 return genmac, nil
220 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000221 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400222 }
223
224 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000225 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530226 log.Fields{"host": host,
227 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400228 return genmac, nil
229}
230
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530231func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700232 slist := strings.Split(mac, ":")
233 result := make([]uint32, len(slist))
234 var err error
235 var tmp int64
236 for index, val := range slist {
237 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
238 return []uint32{1, 2, 3, 4, 5, 6}
239 }
240 result[index] = uint32(tmp)
241 }
242 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530243}
244
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700245//GetportLabel returns the label for the NNI and the PON port based on port number and port type
David K. Bainbridge794735f2020-02-11 21:01:37 -0800246func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530247
David K. Bainbridge794735f2020-02-11 21:01:37 -0800248 switch portType {
249 case voltha.Port_ETHERNET_NNI:
250 return fmt.Sprintf("nni-%d", portNum), nil
251 case voltha.Port_PON_OLT:
252 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700253 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800254
Girish Kumarf26e4882020-03-05 06:49:10 +0000255 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530256}
257
Neha Sharma96b7bf22020-06-15 10:37:32 +0000258func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000259 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700260 if state == "up" {
261 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500262 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500263 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700264 } else {
265 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500266 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700267 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700268 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400269 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800270 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000271 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400272 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500273
Neha Sharma8f4e4322020-08-06 10:51:53 +0000274 if port, err := dh.coreProxy.GetDevicePort(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portNum); err == nil && port.Type == portType {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400275 log.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000276 if err := dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portType, portNum, operStatus); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400277 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
278 "device-id": dh.device.Id,
279 "port-type": portType,
280 "port-number": portNum,
281 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500282 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400283 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500284 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400285 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700286 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400287 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700288 PortNo: portNum,
289 Label: label,
290 Type: portType,
291 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700292 OfpPort: &of.OfpPort{
293 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
294 Config: 0,
295 State: uint32(of.OfpPortState_OFPPS_LIVE),
296 Curr: capacity,
297 Advertised: capacity,
298 Peer: capacity,
299 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
300 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
301 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700302 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000303 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700304 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000305 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000306 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800307 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000308 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400309 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000310 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530311 return nil
312}
313
Kent Hagermane6ff1012020-07-14 15:07:53 -0400314func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530315 dh.lockDevice.Lock()
316 defer dh.lockDevice.Unlock()
Neha Sharma8f4e4322020-08-06 10:51:53 +0000317 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530318 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400319 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
320 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530321 }
322 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530323}
324
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700325// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530326// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800327func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000328 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700329 defer func() {
330 dh.lockDevice.Lock()
331 dh.isReadIndicationRoutineActive = false
332 dh.lockDevice.Unlock()
333 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700334 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700335 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700336 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700337 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400338 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530339 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400340 if err != nil || device == nil {
341 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000342 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400343 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400344
David Bainbridgef5879ca2019-12-13 21:17:54 +0000345 // Create an exponential backoff around re-enabling indications. The
346 // maximum elapsed time for the back off is set to 0 so that we will
347 // continue to retry. The max interval defaults to 1m, but is set
348 // here for code clarity
349 indicationBackoff := backoff.NewExponentialBackOff()
350 indicationBackoff.MaxElapsedTime = 0
351 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700352
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700353 dh.lockDevice.Lock()
354 dh.isReadIndicationRoutineActive = true
355 dh.lockDevice.Unlock()
356
Girish Gowdra3f974912020-03-23 20:35:18 -0700357Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700358 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400359 select {
360 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000361 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700362 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400363 default:
364 indication, err := indications.Recv()
365 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000366 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530367 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530368 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400369 // Use an exponential back off to prevent getting into a tight loop
370 duration := indicationBackoff.NextBackOff()
371 if duration == backoff.Stop {
372 // If we reach a maximum then warn and reset the backoff
373 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000374 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530375 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530376 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400377 indicationBackoff.Reset()
378 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700379
380 // On failure process a backoff timer while watching for stopIndications
381 // events
382 backoff := time.NewTimer(indicationBackoff.NextBackOff())
383 select {
384 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000385 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700386 if !backoff.Stop() {
387 <-backoff.C
388 }
389 break Loop
390 case <-backoff.C:
391 // backoff expired continue
392 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700393 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
394 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400395 }
396 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000397 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530398 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000399 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530400 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530401 "device-id": dh.device.Id})
402 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000403 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700404 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400405 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700406 // Close the stream, and re-initialize it
407 if err = indications.CloseSend(); err != nil {
408 // Ok to ignore here, because we landed here due to a problem on the stream
409 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000410 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530411 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530412 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700413 }
414 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
415 return err
416 }
417 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400418 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530419 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400420 // Reset backoff if we have a successful receive
421 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400422 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530423 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000424 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530425 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530426 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400427 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400428 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400429 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700430 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700431 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700432 // Close the send stream
433 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700434
Girish Gowdra3f974912020-03-23 20:35:18 -0700435 return nil
436}
437
438func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
439
440 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
441 if err != nil {
442 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
443 }
444 if indications == nil {
445 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
446 }
447
448 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400449}
450
451// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
452func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
453 switch indication.Data.(type) {
454 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
455 return true
456
457 default:
458 return false
459 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700460}
461
David K. Bainbridge794735f2020-02-11 21:01:37 -0800462func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000463 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000464 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530465 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700466 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530467 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700468 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000469 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000470 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530471 return olterrors.NewErrAdapter("failed-indication", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530472 "device_id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800473 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000474 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800475 }
476 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700477}
478
David K. Bainbridge794735f2020-02-11 21:01:37 -0800479// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530480func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400481 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700482 switch indication.Data.(type) {
483 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000484 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
485 defer span.Finish()
486
David K. Bainbridge794735f2020-02-11 21:01:37 -0800487 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400488 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800489 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700490 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000491 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
492 defer span.Finish()
493
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700494 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800495 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000496 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400497 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800498 }
499 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000500 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700501 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000502 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
503 defer span.Finish()
504
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700505 intfOperInd := indication.GetIntfOperInd()
506 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800507 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000508 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400509 _ = 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 -0800510 }
511 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400512 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
513 logger.Warn(ctx, err)
514 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515 } else if intfOperInd.GetType() == "pon" {
516 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
517 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800518 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000519 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400520 _ = 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 -0800521 }
522 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000523 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700524 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000525 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530526 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530527 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700528 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000529 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
530 defer span.Finish()
531
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700532 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000533 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700534 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800535 go func() {
536 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400537 _ = 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 -0800538 }
539 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700540 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000541 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
542 defer span.Finish()
543
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700544 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000545 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800546 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000547 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400548 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800549 }
550 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700551 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000552 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
553 defer span.Finish()
554
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700555 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000556 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 -0800557 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000558 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400559 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800560 }
561 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700562 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000563 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
564 defer span.Finish()
565
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000567 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700568 "intf-type": pktInd.IntfId,
569 "intf-id": pktInd.IntfId,
570 "gem-port-id": pktInd.GemportId,
571 "port-no": pktInd.PortNo,
572 "device-id": dh.device.Id,
573 })
574
575 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000576 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700577 "intf-type": pktInd.IntfId,
578 "intf-id": pktInd.IntfId,
579 "gem-port-id": pktInd.GemportId,
580 "port-no": pktInd.PortNo,
581 "packet": hex.EncodeToString(pktInd.Pkt),
582 "device-id": dh.device.Id,
583 })
584 }
585
David K. Bainbridge794735f2020-02-11 21:01:37 -0800586 go func() {
587 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400588 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800589 }
590 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700591 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000592 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
593 defer span.Finish()
594
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700595 portStats := indication.GetPortStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000596 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.resourceMgr.DevInfo.GetPonPorts())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700597 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000598 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
599 defer span.Finish()
600
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700601 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000602 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700603 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000604 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
605 defer span.Finish()
606
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700607 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000608 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
609 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700610 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530611}
612
613// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530614func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530615 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000616 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530617
Girish Gowdru0c588b22019-04-23 23:24:56 -0400618 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530619 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400620 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000621 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400622 }
623 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530624}
625
626// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530627func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700628 dh.lockDevice.Lock()
629 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400631
npujarec5762e2020-01-01 14:08:48 +0530632 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400633 if err != nil || device == nil {
634 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000635 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400636 }
637
638 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400639
640 //Update the device oper state and connection status
641 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400642 dh.device = cloned
643
David K. Bainbridge794735f2020-02-11 21:01:37 -0800644 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000645 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400646 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400647
648 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530649 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400650 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000651 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400652 }
653 for _, onuDevice := range onuDevices.Items {
654
655 // Update onu state as down in onu adapter
656 onuInd := oop.OnuIndication{}
657 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800658 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700659 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800660 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400661 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800662 "source": "openolt",
663 "onu-indicator": onuInd,
664 "device-type": onuDevice.Type,
665 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700666 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700667 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400668 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700669 /* Discovered ONUs entries need to be cleared , since after OLT
670 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530671 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000672 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700673 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530674}
675
676// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530677func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400678 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000679 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
680 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
681 grpc.WithInsecure(),
682 grpc.WithBlock(),
683 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
684 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(opentracing.GlobalTracer())),
685 )),
686 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
687 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(opentracing.GlobalTracer())),
688 )))
689
690 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530691 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530692 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000693 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400694 }
695 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530696}
697
698// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530699func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400700 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530701 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400702 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530703}
704
705// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530706func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530707 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000708 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400709
710 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530711 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
712 if err != nil || device == nil {
713 /*TODO: needs to handle error scenarios */
714 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
715 }
716 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000717 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400718
719 cloned := proto.Clone(device).(*voltha.Device)
720 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
721 cloned.OperStatus = voltha.OperStatus_UNKNOWN
722 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530723 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
724 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 -0400725 }
726
Chaitrashree G S44124192019-08-07 20:21:36 -0400727 // 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 +0530728 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400729 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530730 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400731 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400732 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
733 // all the modules initialized and ready to handle incoming ONUs.
734
Thomas Lee S985938d2020-05-04 11:40:41 +0530735 err = dh.initializeDeviceHandlerModules(ctx)
736 if err != nil {
737 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 -0400738 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400739
740 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800741 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530742 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400743 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800744 }
745 }()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400746 return nil
747 }
748
Neha Sharma8f4e4322020-08-06 10:51:53 +0000749 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400750 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400751 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400752 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400753 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400754 dh.populateActivePorts(ctx, ports)
755 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
756 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400757 }
758
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400759 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530760 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 -0400761 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530762
cuilin20187b2a8c32019-03-26 19:52:28 -0700763 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800764 go func() {
765 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400766 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800767 }
768 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000769 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000770
771 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000772 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000773 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700774 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530775}
776
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400777func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000778 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400779
780 if err != nil {
781 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
782 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400783 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000784 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 -0400785 return olterrors.ErrResourceManagerInstantiating
786 }
787
788 // Instantiate flow manager
789 if dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr); dh.flowMgr == nil {
790 return olterrors.ErrResourceManagerInstantiating
791
792 }
793 /* TODO: Instantiate Alarm , stats , BW managers */
794 /* Instantiating Event Manager to handle Alarms and KPIs */
795 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
796
797 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000798 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400799
800 return nil
801
802}
803
Neha Sharma96b7bf22020-06-15 10:37:32 +0000804func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400805 var err error
806 var deviceInfo *oop.DeviceInfo
807
Neha Sharma8f4e4322020-08-06 10:51:53 +0000808 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400809
810 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000811 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400812 }
813 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000814 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400815 }
816
Neha Sharma96b7bf22020-06-15 10:37:32 +0000817 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400818 dh.device.Root = true
819 dh.device.Vendor = deviceInfo.Vendor
820 dh.device.Model = deviceInfo.Model
821 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
822 dh.device.HardwareVersion = deviceInfo.HardwareVersion
823 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
824
825 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000826 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400827 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000828 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400829 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000830 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400831 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000832 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400833 dh.device.MacAddress = genmac
834 } else {
835 dh.device.MacAddress = deviceInfo.DeviceId
836 }
837
838 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000839 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000840 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400841 }
842
843 return deviceInfo, nil
844}
845
Neha Sharma96b7bf22020-06-15 10:37:32 +0000846func startCollector(ctx context.Context, dh *DeviceHandler) {
847 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530848 for {
849 select {
850 case <-dh.stopCollector:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000851 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"deviceID:": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530852 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000853 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700854
Neha Sharma8f4e4322020-08-06 10:51:53 +0000855 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400856 if err != nil {
857 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
858 continue
859 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530860 for _, port := range ports {
861 // NNI Stats
862 if port.Type == voltha.Port_ETHERNET_NNI {
863 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
864 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000865 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
866 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
867 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530868 }
869 // PON Stats
870 if port.Type == voltha.Port_PON_OLT {
871 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
872 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
873 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000874 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
875 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530876 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000877 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500878 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530879 }
880 }
881 }
882}
883
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700884//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530885func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400886 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000887 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530888 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530889
890 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400891 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
892 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530893 }
894
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400895 go startHeartbeatCheck(ctx, dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530896}
897
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700898//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530899func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700900 return &ic.SwitchCapability{
901 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530902 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700903 HwDesc: "open_pon",
904 SwDesc: "open_pon",
905 SerialNum: dh.device.SerialNumber,
906 },
907 SwitchFeatures: &of.OfpSwitchFeatures{
908 NBuffers: 256,
909 NTables: 2,
910 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
911 of.OfpCapabilities_OFPC_TABLE_STATS |
912 of.OfpCapabilities_OFPC_PORT_STATS |
913 of.OfpCapabilities_OFPC_GROUP_STATS),
914 },
915 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530916}
917
Neha Sharma96b7bf22020-06-15 10:37:32 +0000918func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
919 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 -0700920 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700921 var deviceID string
922 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700923
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400924 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700925 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000926 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 -0700927 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
928 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400929
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700930 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530931
932 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
933
Neha Sharma96b7bf22020-06-15 10:37:32 +0000934 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 -0700935 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700936 kwargs := make(map[string]interface{})
937 kwargs["onu_id"] = omciInd.OnuId
938 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700939
Neha Sharma8f4e4322020-08-06 10:51:53 +0000940 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700941 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530942 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700943 "intf-id": omciInd.IntfId,
944 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700945 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700946 deviceType = onuDevice.Type
947 deviceID = onuDevice.Id
948 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
949 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530950 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700951 } else {
952 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000953 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 +0530954 deviceType = onuInCache.(*OnuDevice).deviceType
955 deviceID = onuInCache.(*OnuDevice).deviceID
956 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700957 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700958
959 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +0000960 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530961 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800962 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530963 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530964 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800965 "destination": deviceType,
966 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000967 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700968 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800969 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530970}
971
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700972//ProcessInterAdapterMessage sends the proxied messages to the target device
973// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
974// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000975func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
976 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700977 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700978 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700979 fromTopic := msg.Header.FromTopic
980 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700981 toDeviceID := msg.Header.ToDeviceId
982 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700983
Neha Sharma96b7bf22020-06-15 10:37:32 +0000984 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 -0700985
986 msgBody := msg.GetBody()
987
988 omciMsg := &ic.InterAdapterOmciMessage{}
989 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000990 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700991 }
992
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700993 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000994 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700995 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530996 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800997 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000998 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700999 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001000 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1001 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301002 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001003 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001004 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001005 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001006 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001007 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1008 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301009 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001010 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001011 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001012 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001013 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001014 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001015 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001016 }
1017 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301018}
1019
Neha Sharma96b7bf22020-06-15 10:37:32 +00001020func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001021 var intfID uint32
1022 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001023 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001024 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001025 intfID = onuDevice.ProxyAddress.GetChannelId()
1026 onuID = onuDevice.ProxyAddress.GetOnuId()
1027 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001028 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001029 intfID = omciMsg.GetProxyAddress().GetChannelId()
1030 onuID = omciMsg.GetProxyAddress().GetOnuId()
1031 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001032 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001033 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001034 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 -08001035
Thomas Lee S94109f12020-03-03 16:39:29 +05301036 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001037 "intf-id": intfID,
1038 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001039 }
1040
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001041 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1042 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001043 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001044 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1045 hex.Encode(hexPkt, omciMsg.Message)
1046 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1047
1048 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1049 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1050 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001051 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001052 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001053
Neha Sharma8f4e4322020-08-06 10:51:53 +00001054 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001055 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301056 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001057 "intf-id": intfID,
1058 "onu-id": onuID,
1059 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001060 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001061 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001062}
1063
David K. Bainbridge794735f2020-02-11 21:01:37 -08001064func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001065 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 +02001066 if err := dh.flowMgr.UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001067 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001068 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001069 // TODO: need resource manager
1070 var pir uint32 = 1000000
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001071 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir}
npujarec5762e2020-01-01 14:08:48 +05301072 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001073 st, _ := status.FromError(err)
1074 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001075 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1076
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001077 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301078 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001079 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001080 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001081 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001082 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001083 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001084}
1085
David K. Bainbridge794735f2020-02-11 21:01:37 -08001086func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001087 channelID := onuDiscInd.GetIntfId()
1088 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001089
Neha Sharma96b7bf22020-06-15 10:37:32 +00001090 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301091
cuilin20187b2a8c32019-03-26 19:52:28 -07001092 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001093 if sn != "" {
1094 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001095 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001096 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001097 }
1098
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301099 var alarmInd oop.OnuAlarmIndication
1100 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001101 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301102
1103 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1104 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1105 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1106 OnuLosRaise event sent for it */
1107 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1108 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1109 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001110 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301111 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1112 "currentIntfId": onuDiscInd.GetIntfId()})
1113 // TODO:: Should we need to ignore raising OnuLosClear event
1114 // when onu connected to different PON?
1115 }
1116 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1117 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1118 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001119 go func() {
1120 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1121 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1122 }
1123 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301124 }
1125 return true
1126 })
1127
Neha Sharma96b7bf22020-06-15 10:37:32 +00001128 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001129 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001130 }
1131
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001132 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001133
1134 // check the ONU is already know to the OLT
1135 // NOTE the second time the ONU is discovered this should return a device
1136 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1137
1138 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001139 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 -08001140 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001141 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 -08001142 switch e.Code() {
1143 case codes.Internal:
1144 // this probably means NOT FOUND, so just create a new device
1145 onuDevice = nil
1146 case codes.DeadlineExceeded:
1147 // if the call times out, cleanup and exit
1148 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001149 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001150 }
1151 }
1152 }
1153
1154 if onuDevice == nil {
1155 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001156 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001157 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001158 ponintfid := onuDiscInd.GetIntfId()
1159 dh.lockDevice.Lock()
npujarec5762e2020-01-01 14:08:48 +05301160 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Matt Jeanneret53539512019-07-20 14:47:02 -04001161 dh.lockDevice.Unlock()
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001162
Neha Sharma96b7bf22020-06-15 10:37:32 +00001163 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001164
1165 if err != nil {
1166 // if we can't create an ID in resource manager,
1167 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001168 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001169 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001170 "pon-intf-id": ponintfid,
1171 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001172 }
1173
Neha Sharma8f4e4322020-08-06 10:51:53 +00001174 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001175 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001176 dh.discOnus.Delete(sn)
1177 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 +05301178 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001179 "pon-intf-id": ponintfid,
1180 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001181 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001182 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1183 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1184 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001185 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301186 log.Fields{"onuDevice": onuDevice,
1187 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001188 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301189 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001190 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001191
1192 // we can now use the existing ONU Id
1193 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001194 //Insert the ONU into cache to use in OnuIndication.
1195 //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 +00001196 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001197 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301198 "intfId": onuDiscInd.GetIntfId(),
1199 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001200 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001201
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301202 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301203 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001204 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301205 log.Fields{"onu": onuDev,
1206 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001207
Kent Hagermane6ff1012020-07-14 15:07:53 -04001208 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301209 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001210 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001211 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001212 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001213 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001214 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301215 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001216 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001217 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001218 }
1219 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001220}
1221
Neha Sharma96b7bf22020-06-15 10:37:32 +00001222func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001223 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1224
1225 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001226 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001227 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001228 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001229 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001230 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301231 log.Fields{"onuId": onuInd.OnuId,
1232 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301233 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001234 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301235
David K. Bainbridge794735f2020-02-11 21:01:37 -08001236 errFields := log.Fields{"device-id": dh.device.Id}
1237
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301238 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1239
Mahir Gunyele77977b2019-06-27 05:36:22 -07001240 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1241 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001242 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001243 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001244 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001245 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1246 if serialNumber != "" {
1247 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001248 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001249 } else {
1250 kwargs["onu_id"] = onuInd.OnuId
1251 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001252 errFields["onu-id"] = onuInd.OnuId
1253 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001254 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001255 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001256 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001257
David K. Bainbridge794735f2020-02-11 21:01:37 -08001258 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001259 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001260 }
1261
David K. Bainbridge794735f2020-02-11 21:01:37 -08001262 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001263 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001264 "previousIntfId": onuDevice.ParentPortNo,
1265 "currentIntfId": ponPort})
1266 }
1267
1268 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001269 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301270 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1271 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301272 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001273 }
1274 if !foundInCache {
1275 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1276
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301277 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 -08001278
1279 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001280 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001281 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001282 }
1283 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001284}
1285
Neha Sharma96b7bf22020-06-15 10:37:32 +00001286func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001287 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 -07001288 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1289 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1290 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1291 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001292 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001293 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1294 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001295 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001296 onuInd.OperState = "down"
1297 }
1298 }
1299
David K. Bainbridge794735f2020-02-11 21:01:37 -08001300 switch onuInd.OperState {
1301 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001302 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 -07001303 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301304 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001305 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1306 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301307 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001308 "onu-indicator": onuInd,
1309 "source": "openolt",
1310 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001311 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001312 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001313 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001314 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 -04001315 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301316 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001317 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1318 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301319 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001320 "onu-indicator": onuInd,
1321 "source": "openolt",
1322 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001323 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001324 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001325 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001326 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001327 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001328 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001329}
1330
cuilin20187b2a8c32019-03-26 19:52:28 -07001331func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1332 if serialNum != nil {
1333 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001334 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001335 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001336}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001337func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1338 decodedStr, err := hex.DecodeString(serialNum[4:])
1339 if err != nil {
1340 return nil, err
1341 }
1342 return &oop.SerialNumber{
1343 VendorId: []byte(serialNum[:4]),
1344 VendorSpecific: []byte(decodedStr),
1345 }, nil
1346}
cuilin20187b2a8c32019-03-26 19:52:28 -07001347
1348func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1349 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001350 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001351 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1352 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1353 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1354 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1355 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1356 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1357 return tmp
1358}
1359
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001360//UpdateFlowsBulk upates the bulk flow
1361func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301362 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001363}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001364
1365//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001366func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1367 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301368 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001369 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301370 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001371 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001372 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001373 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001374 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001375 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001376 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001377 "intf-id": parentPort,
1378 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001379 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001380 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 -08001381 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301382}
1383
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001384// SendPacketInToCore sends packet-in to core
1385// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1386// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001387func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001388 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001389 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001390 "port": logicalPort,
1391 "packet": hex.EncodeToString(packetPayload),
1392 "device-id": dh.device.Id,
1393 })
1394 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001395 if err := dh.coreProxy.SendPacketIn(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301396 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001397 "source": "adapter",
1398 "destination": "core",
1399 "device-id": dh.device.Id,
1400 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001401 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001402 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001403 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001404 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001405 "packet": hex.EncodeToString(packetPayload),
1406 "device-id": dh.device.Id,
1407 })
1408 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001409 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001410}
1411
A R Karthick1f85b802019-10-11 05:06:05 +00001412// AddUniPortToOnu adds the uni port to the onu device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001413func (dh *DeviceHandler) AddUniPortToOnu(ctx context.Context, intfID, onuID, uniPort uint32) {
A R Karthick1f85b802019-10-11 05:06:05 +00001414 onuKey := dh.formOnuKey(intfID, onuID)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301415
1416 if onuDevice, ok := dh.onus.Load(onuKey); ok {
A R Karthick1f85b802019-10-11 05:06:05 +00001417 // add it to the uniPort map for the onu device
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301418 if _, ok = onuDevice.(*OnuDevice).uniPorts[uniPort]; !ok {
1419 onuDevice.(*OnuDevice).uniPorts[uniPort] = struct{}{}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001420 logger.Debugw(ctx, "adding-uni-port", log.Fields{"port": uniPort, "intf-id": intfID, "onuId": onuID})
A R Karthick1f85b802019-10-11 05:06:05 +00001421 }
1422 }
1423}
1424
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001425// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001426func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001427 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001428
1429 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1430 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001431 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001432 }
1433
Kent Hagermane6ff1012020-07-14 15:07:53 -04001434 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001435 metrics := dh.metrics.GetSubscriberMetrics()
1436 for _, m := range pmConfigs.Metrics {
1437 metrics[m.Name].Enabled = m.Enabled
1438
1439 }
1440 }
1441}
1442
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001443//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301444func (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 +00001445 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 +01001446
1447 var errorsList []error
1448
Girish Gowdru0c588b22019-04-23 23:24:56 -04001449 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001450 for _, flow := range flows.ToRemove.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001451 dh.incrementActiveFlowRemoveCount(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001452
Neha Sharma96b7bf22020-06-15 10:37:32 +00001453 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301454 log.Fields{"device-id": device.Id,
1455 "flowToRemove": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001456 err := dh.flowMgr.RemoveFlow(ctx, flow)
1457 if err != nil {
1458 errorsList = append(errorsList, err)
1459 }
1460
Neha Sharma96b7bf22020-06-15 10:37:32 +00001461 dh.decrementActiveFlowRemoveCount(ctx, flow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001462 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301463
1464 for _, flow := range flows.ToAdd.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001465 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301466 log.Fields{"device-id": device.Id,
1467 "flowToAdd": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001468 // If there are active Flow Remove in progress for a given subscriber, wait until it completes
Neha Sharma96b7bf22020-06-15 10:37:32 +00001469 dh.waitForFlowRemoveToFinish(ctx, flow)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001470 err := dh.flowMgr.AddFlow(ctx, flow, flowMetadata)
1471 if err != nil {
1472 errorsList = append(errorsList, err)
1473 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301474 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001475 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001476
Girish Gowdracefae192020-03-19 18:14:10 -07001477 // 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 +00001478 if groups != nil {
1479 for _, group := range groups.ToAdd.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001480 err := dh.flowMgr.AddGroup(ctx, group)
1481 if err != nil {
1482 errorsList = append(errorsList, err)
1483 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001484 }
1485 for _, group := range groups.ToUpdate.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001486 err := dh.flowMgr.ModifyGroup(ctx, group)
1487 if err != nil {
1488 errorsList = append(errorsList, err)
1489 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001490 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001491 for _, group := range groups.ToRemove.Items {
1492 err := dh.flowMgr.DeleteGroup(ctx, group)
1493 if err != nil {
1494 errorsList = append(errorsList, err)
1495 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001496 }
1497 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001498 if len(errorsList) > 0 {
1499 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1500 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001501 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001502 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301503}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001504
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001505//DisableDevice disables the given device
1506//It marks the following for the given device:
1507//Device-Handler Admin-State : down
1508//Device Port-State: UNKNOWN
1509//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001510func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001511 /* On device disable ,admin state update has to be done prior sending request to agent since
1512 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001513 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001514 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001515 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001516 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001517 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001518 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001519 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001520 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001521 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001522 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301523
1524 dh.discOnus = sync.Map{}
1525 dh.onus = sync.Map{}
1526
Thomas Lee S85f37312020-04-03 17:06:12 +05301527 //stopping the stats collector
1528 dh.stopCollector <- true
1529
Neha Sharma96b7bf22020-06-15 10:37:32 +00001530 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001531 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301532 //Update device Admin state
1533 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001534 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
Neha Sharma8f4e4322020-08-06 10:51:53 +00001535 if err := dh.coreProxy.PortsStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001536 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001537 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001538 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001539 return nil
1540}
1541
Neha Sharma96b7bf22020-06-15 10:37:32 +00001542func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001543 // Update onu state as unreachable in onu adapter
1544 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301545 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001546 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001547 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001548 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001549 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 -04001550 }
1551 if onuDevices != nil {
1552 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001553 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001554 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1555 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001556 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301557 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001558 }
1559
1560 }
1561 }
1562
1563}
1564
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001565//ReenableDevice re-enables the olt device after disable
1566//It marks the following for the given device:
1567//Device-Handler Admin-State : up
1568//Device Port-State: ACTIVE
1569//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001570func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001571 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301572 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001573 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301574 }
1575 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001576 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001577
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001578 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001579
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001580 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1581 if err != nil {
1582 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device": device.Id}, err)
1583 }
1584 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001585 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001586 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001587 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001588 device.OperStatus = voltha.OperStatus_ACTIVE
1589 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001590
Neha Sharma8f4e4322020-08-06 10:51:53 +00001591 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301592 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001593 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001594 "connect-status": device.ConnectStatus,
1595 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001596 }
kesavand39e0aa32020-01-28 20:58:50 -05001597
Neha Sharma96b7bf22020-06-15 10:37:32 +00001598 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001599
1600 return nil
1601}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001602
npujarec5762e2020-01-01 14:08:48 +05301603func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001604 var uniID uint32
1605 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301606 for _, port := range onu.UniPorts {
1607 uniID = UniIDFromPortNum(uint32(port))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001608 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001609 /* Delete tech-profile instance from the KV store */
npujarec5762e2020-01-01 14:08:48 +05301610 if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001611 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001612 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001613 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301614 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001615 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301616 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001617 }
npujarec5762e2020-01-01 14:08:48 +05301618 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001619 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301620 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001621 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001622 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001623 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301624 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001625 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001626 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001627 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301628 }
npujarec5762e2020-01-01 14:08:48 +05301629 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1630 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001631 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301632 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001633 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Esin Karaman7fb80c22020-07-16 14:23:33 +00001634 if err = dh.resourceMgr.DelGemPortPktInOfAllServices(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001635 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 +00001636 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001637 }
1638 return nil
1639}
1640
npujarec5762e2020-01-01 14:08:48 +05301641func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001642 nniUniID := -1
1643 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301644
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001645 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301646 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001647 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001648 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301649 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301650 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001651 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001652 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001653 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301654 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301655 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001656 logger.Debugw(ctx, "current-flow-ids-for-nni", log.Fields{"flow-ids": flowIDs})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301657 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301658 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301659 }
npujarec5762e2020-01-01 14:08:48 +05301660 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001661 }
npujarec5762e2020-01-01 14:08:48 +05301662 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001663 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301664 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001665 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001666}
1667
1668// 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 +05301669func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001670 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001671 /* Clear the KV store data associated with the all the UNI ports
1672 This clears up flow data and also resource map data for various
1673 other pon resources like alloc_id and gemport_id
1674 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001675 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001676 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001677 // Stop the Stats collector
1678 dh.stopCollector <- true
1679 // stop the heartbeat check routine
1680 dh.stopHeartbeatCheck <- true
1681 //Reset the state
1682 if dh.Client != nil {
1683 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301684 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001685 }
1686 }
1687 cloned := proto.Clone(device).(*voltha.Device)
1688 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1689 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1690 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1691 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1692 "device-id": device.Id,
1693 "connect-status": cloned.ConnectStatus,
1694 "oper-status": cloned.OperStatus}, err).Log()
1695 }
1696 return nil
1697}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001698func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001699
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001700 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301701 noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
1702 var ponPort uint32
1703 for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
1704 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301705 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301706 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001707 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001708 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001709 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301710 }
1711 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301712 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001713 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301714 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001715 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301716 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301717 // Clear flowids for gem cache.
1718 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301719 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301720 }
1721 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +0530