blob: 95b0a745d4a3109105ce8f788f0a1bf2c8b2a228 [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"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070037 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
38 "github.com/opencord/voltha-lib-go/v4/pkg/flows"
39 "github.com/opencord/voltha-lib-go/v4/pkg/log"
40 "github.com/opencord/voltha-lib-go/v4/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"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070043 "github.com/opencord/voltha-protos/v4/go/common"
44 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
45 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
46 oop "github.com/opencord/voltha-protos/v4/go/openolt"
47 "github.com/opencord/voltha-protos/v4/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070048 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040049 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040050 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053051)
52
salmansiddiqui7ac62132019-08-22 03:58:50 +000053// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040054const (
Girish Gowdraa09aeab2020-09-14 16:30:52 -070055 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040056)
57
Phaneendra Manda4c62c802019-03-06 21:37:49 +053058//DeviceHandler will interact with the OLT device.
59type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070060 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053061 coreProxy adapterif.CoreProxy
62 AdapterProxy adapterif.AdapterProxy
63 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070064 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070065 exitChannel chan int
66 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053067 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070068 transitionMap *TransitionMap
69 clientCon *grpc.ClientConn
Girish Gowdra9602eb42020-09-09 15:50:39 -070070 flowMgr []*OpenOltFlowMgr
71 groupMgr *OpenOltGroupMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040072 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053073 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053074
Girish Gowdra3ab6d212020-03-24 17:33:15 -070075 discOnus sync.Map
76 onus sync.Map
77 portStats *OpenOltStatisticsMgr
78 metrics *pmmetrics.PmMetrics
79 stopCollector chan bool
80 stopHeartbeatCheck chan bool
81 activePorts sync.Map
82 stopIndications chan bool
83 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070084
Girish Gowdra9602eb42020-09-09 15:50:39 -070085 totalPonPorts uint32
Mahir Gunyela3f9add2019-06-06 15:13:19 -070086}
87
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070088//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -070089type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070090 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -070091 deviceType string
92 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070093 onuID uint32
94 intfID uint32
95 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +053096 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -040097 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -070098}
99
Naga Manjunath7615e552019-10-11 22:35:47 +0530100var pmNames = []string{
101 "rx_bytes",
102 "rx_packets",
103 "rx_mcast_packets",
104 "rx_bcast_packets",
105 "tx_bytes",
106 "tx_packets",
107 "tx_mcast_packets",
108 "tx_bcast_packets",
109}
110
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700111//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530112func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700113 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700114 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700115 device.deviceType = deviceTp
116 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700117 device.onuID = onuID
118 device.intfID = intfID
119 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530120 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700121 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530122}
123
124//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530125func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700126 var dh DeviceHandler
127 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400128 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400129 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700130 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700131 dh.device = cloned
132 dh.openOLT = adapter
133 dh.exitChannel = make(chan int, 1)
134 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530135 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530136 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530137 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 -0500138 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400139 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700140
cuilin20187b2a8c32019-03-26 19:52:28 -0700141 //TODO initialize the support classes.
142 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530143}
144
145// start save the device to the data model
146func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700147 dh.lockDevice.Lock()
148 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000149 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700150 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000151 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530152}
153
154// stop stops the device dh. Not much to do for now
155func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700156 dh.lockDevice.Lock()
157 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000158 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700159 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000160 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530161}
162
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400163func macifyIP(ip net.IP) string {
164 if len(ip) > 0 {
165 oct1 := strconv.FormatInt(int64(ip[12]), 16)
166 oct2 := strconv.FormatInt(int64(ip[13]), 16)
167 oct3 := strconv.FormatInt(int64(ip[14]), 16)
168 oct4 := strconv.FormatInt(int64(ip[15]), 16)
169 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
170 }
171 return ""
172}
173
Neha Sharma96b7bf22020-06-15 10:37:32 +0000174func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400175 var genmac string
176 var addr net.IP
177 var ips []string
178 var err error
179
Neha Sharma96b7bf22020-06-15 10:37:32 +0000180 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400181
182 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000183 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400184
185 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000186 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400187 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000188 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400189 }
190 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000191 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530192 log.Fields{"host": ips[0],
193 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400194 return genmac, nil
195 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000196 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400197 }
198
199 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000200 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530201 log.Fields{"host": host,
202 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400203 return genmac, nil
204}
205
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530206func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700207 slist := strings.Split(mac, ":")
208 result := make([]uint32, len(slist))
209 var err error
210 var tmp int64
211 for index, val := range slist {
212 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
213 return []uint32{1, 2, 3, 4, 5, 6}
214 }
215 result[index] = uint32(tmp)
216 }
217 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530218}
219
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700220//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 -0800221func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530222
David K. Bainbridge794735f2020-02-11 21:01:37 -0800223 switch portType {
224 case voltha.Port_ETHERNET_NNI:
225 return fmt.Sprintf("nni-%d", portNum), nil
226 case voltha.Port_PON_OLT:
227 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700228 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800229
Girish Kumarf26e4882020-03-05 06:49:10 +0000230 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530231}
232
Neha Sharma96b7bf22020-06-15 10:37:32 +0000233func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000234 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700235 if state == "up" {
236 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500237 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500238 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700239 } else {
240 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500241 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700242 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700243 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400244 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800245 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000246 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400247 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500248
Neha Sharma8f4e4322020-08-06 10:51:53 +0000249 if port, err := dh.coreProxy.GetDevicePort(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portNum); err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000250 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000251 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 -0400252 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
253 "device-id": dh.device.Id,
254 "port-type": portType,
255 "port-number": portNum,
256 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500257 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400258 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500259 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400260 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700261 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400262 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700263 PortNo: portNum,
264 Label: label,
265 Type: portType,
266 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700267 OfpPort: &of.OfpPort{
268 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
269 Config: 0,
270 State: uint32(of.OfpPortState_OFPPS_LIVE),
271 Curr: capacity,
272 Advertised: capacity,
273 Peer: capacity,
274 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
275 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
276 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700277 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000278 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700279 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000280 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000281 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800282 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000283 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400284 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000285 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530286 return nil
287}
288
Kent Hagermane6ff1012020-07-14 15:07:53 -0400289func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530290 dh.lockDevice.Lock()
291 defer dh.lockDevice.Unlock()
Neha Sharma8f4e4322020-08-06 10:51:53 +0000292 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530293 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400294 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
295 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530296 }
297 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530298}
299
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700300// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530301// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800302func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000303 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700304 defer func() {
305 dh.lockDevice.Lock()
306 dh.isReadIndicationRoutineActive = false
307 dh.lockDevice.Unlock()
308 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700309 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700310 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700311 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700312 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400313 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530314 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400315 if err != nil || device == nil {
316 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000317 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400318 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400319
David Bainbridgef5879ca2019-12-13 21:17:54 +0000320 // Create an exponential backoff around re-enabling indications. The
321 // maximum elapsed time for the back off is set to 0 so that we will
322 // continue to retry. The max interval defaults to 1m, but is set
323 // here for code clarity
324 indicationBackoff := backoff.NewExponentialBackOff()
325 indicationBackoff.MaxElapsedTime = 0
326 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700327
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700328 dh.lockDevice.Lock()
329 dh.isReadIndicationRoutineActive = true
330 dh.lockDevice.Unlock()
331
Girish Gowdra3f974912020-03-23 20:35:18 -0700332Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700333 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400334 select {
335 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000336 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700337 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400338 default:
339 indication, err := indications.Recv()
340 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000341 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530342 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530343 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400344 // Use an exponential back off to prevent getting into a tight loop
345 duration := indicationBackoff.NextBackOff()
346 if duration == backoff.Stop {
347 // If we reach a maximum then warn and reset the backoff
348 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000349 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530350 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530351 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400352 indicationBackoff.Reset()
353 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700354
355 // On failure process a backoff timer while watching for stopIndications
356 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700357 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700358 select {
359 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000360 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700361 if !backoffTimer.Stop() {
362 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700363 }
364 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700365 case <-backoffTimer.C:
366 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700367 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700368 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
369 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400370 }
371 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000372 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530373 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000374 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530375 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530376 "device-id": dh.device.Id})
377 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000378 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700379 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400380 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700381 // Close the stream, and re-initialize it
382 if err = indications.CloseSend(); err != nil {
383 // Ok to ignore here, because we landed here due to a problem on the stream
384 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000385 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530386 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530387 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700388 }
389 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
390 return err
391 }
392 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400393 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530394 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400395 // Reset backoff if we have a successful receive
396 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400397 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530398 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000399 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530400 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530401 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400402 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400403 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400404 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700405 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700406 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700407 // Close the send stream
408 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700409
Girish Gowdra3f974912020-03-23 20:35:18 -0700410 return nil
411}
412
413func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
414
415 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
416 if err != nil {
417 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
418 }
419 if indications == nil {
420 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
421 }
422
423 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400424}
425
426// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
427func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
428 switch indication.Data.(type) {
429 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
430 return true
431
432 default:
433 return false
434 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700435}
436
David K. Bainbridge794735f2020-02-11 21:01:37 -0800437func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000438 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000439 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530440 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700441 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530442 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700443 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000444 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000445 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530446 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000447 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800448 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000449 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800450 }
451 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700452}
453
David K. Bainbridge794735f2020-02-11 21:01:37 -0800454// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530455func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400456 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700457 switch indication.Data.(type) {
458 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000459 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
460 defer span.Finish()
461
David K. Bainbridge794735f2020-02-11 21:01:37 -0800462 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400463 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800464 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700465 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000466 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
467 defer span.Finish()
468
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700469 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800470 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000471 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400472 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800473 }
474 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000475 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700476 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000477 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
478 defer span.Finish()
479
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700480 intfOperInd := indication.GetIntfOperInd()
481 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800482 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000483 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400484 _ = 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 -0800485 }
486 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400487 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
488 logger.Warn(ctx, err)
489 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700490 } else if intfOperInd.GetType() == "pon" {
491 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
492 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800493 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000494 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400495 _ = 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 -0800496 }
497 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000498 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700499 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000500 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530501 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530502 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700503 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000504 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
505 defer span.Finish()
506
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700507 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000508 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700509 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800510 go func() {
511 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400512 _ = 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 -0800513 }
514 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000516 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
517 defer span.Finish()
518
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700519 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000520 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800521 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400523 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800524 }
525 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700526 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000527 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
528 defer span.Finish()
529
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700530 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000531 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 -0800532 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000533 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400534 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800535 }
536 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700537 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000538 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
539 defer span.Finish()
540
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700541 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000542 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700543 "intf-type": pktInd.IntfId,
544 "intf-id": pktInd.IntfId,
545 "gem-port-id": pktInd.GemportId,
546 "port-no": pktInd.PortNo,
547 "device-id": dh.device.Id,
548 })
549
550 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000551 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700552 "intf-type": pktInd.IntfId,
553 "intf-id": pktInd.IntfId,
554 "gem-port-id": pktInd.GemportId,
555 "port-no": pktInd.PortNo,
556 "packet": hex.EncodeToString(pktInd.Pkt),
557 "device-id": dh.device.Id,
558 })
559 }
560
David K. Bainbridge794735f2020-02-11 21:01:37 -0800561 go func() {
562 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400563 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800564 }
565 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000567 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
568 defer span.Finish()
569
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700570 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700571 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700572 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000573 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
574 defer span.Finish()
575
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700576 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000577 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700578 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000579 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
580 defer span.Finish()
581
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700582 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000583 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
584 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700585 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530586}
587
588// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530589func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530590 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000591 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530592
Girish Gowdru0c588b22019-04-23 23:24:56 -0400593 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530594 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400595 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000596 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400597 }
598 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530599}
600
601// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530602func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700603 dh.lockDevice.Lock()
604 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000605 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400606
npujarec5762e2020-01-01 14:08:48 +0530607 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400608 if err != nil || device == nil {
609 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000610 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400611 }
612
613 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400614
615 //Update the device oper state and connection status
616 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400617 dh.device = cloned
618
David K. Bainbridge794735f2020-02-11 21:01:37 -0800619 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000620 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400621 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400622
623 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530624 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400625 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000626 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400627 }
628 for _, onuDevice := range onuDevices.Items {
629
630 // Update onu state as down in onu adapter
631 onuInd := oop.OnuIndication{}
632 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800633 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700634 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800635 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400636 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800637 "source": "openolt",
638 "onu-indicator": onuInd,
639 "device-type": onuDevice.Type,
640 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700641 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700642 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400643 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700644 /* Discovered ONUs entries need to be cleared , since after OLT
645 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530646 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000647 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700648 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530649}
650
651// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530652func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400653 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000654 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
655 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
656 grpc.WithInsecure(),
657 grpc.WithBlock(),
658 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000659 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000660 )),
661 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000662 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000663 )))
664
665 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530666 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530667 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000668 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400669 }
670 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530671}
672
673// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530674func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400675 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530676 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400677 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530678}
679
680// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530681func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530682 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000683 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400684
685 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530686 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
687 if err != nil || device == nil {
688 /*TODO: needs to handle error scenarios */
689 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
690 }
691 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000692 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400693
694 cloned := proto.Clone(device).(*voltha.Device)
695 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
696 cloned.OperStatus = voltha.OperStatus_UNKNOWN
697 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530698 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
699 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 -0400700 }
701
Chaitrashree G S44124192019-08-07 20:21:36 -0400702 // 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 +0530703 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400704 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530705 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400706 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400707 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
708 // all the modules initialized and ready to handle incoming ONUs.
709
Thomas Lee S985938d2020-05-04 11:40:41 +0530710 err = dh.initializeDeviceHandlerModules(ctx)
711 if err != nil {
712 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 -0400713 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400714
715 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800716 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530717 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400718 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800719 }
720 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700721
722 go startHeartbeatCheck(ctx, dh)
723
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400724 return nil
725 }
726
Neha Sharma8f4e4322020-08-06 10:51:53 +0000727 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400728 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400729 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400730 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400731 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400732 dh.populateActivePorts(ctx, ports)
733 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
734 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400735 }
736
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400737 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530738 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 -0400739 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530740
cuilin20187b2a8c32019-03-26 19:52:28 -0700741 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800742 go func() {
743 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400744 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800745 }
746 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000747 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000748
749 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000750 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000751 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700752
753 go startHeartbeatCheck(ctx, dh)
754
cuilin20187b2a8c32019-03-26 19:52:28 -0700755 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530756}
757
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400758func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000759 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400760
761 if err != nil {
762 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
763 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700764 dh.totalPonPorts = deviceInfo.GetPonPorts()
765
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400766 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000767 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 -0400768 return olterrors.ErrResourceManagerInstantiating
769 }
770
Girish Gowdra9602eb42020-09-09 15:50:39 -0700771 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400772
Girish Gowdra9602eb42020-09-09 15:50:39 -0700773 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
774 for i := range dh.flowMgr {
775 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700776 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700777 return olterrors.ErrResourceManagerInstantiating
778 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400779 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700780
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400781 /* TODO: Instantiate Alarm , stats , BW managers */
782 /* Instantiating Event Manager to handle Alarms and KPIs */
783 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
784
785 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000786 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400787
788 return nil
789
790}
791
Neha Sharma96b7bf22020-06-15 10:37:32 +0000792func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400793 var err error
794 var deviceInfo *oop.DeviceInfo
795
Neha Sharma8f4e4322020-08-06 10:51:53 +0000796 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400797
798 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000799 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400800 }
801 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000802 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400803 }
804
Neha Sharma96b7bf22020-06-15 10:37:32 +0000805 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400806 dh.device.Root = true
807 dh.device.Vendor = deviceInfo.Vendor
808 dh.device.Model = deviceInfo.Model
809 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
810 dh.device.HardwareVersion = deviceInfo.HardwareVersion
811 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
812
813 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000814 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400815 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000816 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400817 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000818 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400819 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000820 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400821 dh.device.MacAddress = genmac
822 } else {
823 dh.device.MacAddress = deviceInfo.DeviceId
824 }
825
826 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000827 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000828 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400829 }
830
831 return deviceInfo, nil
832}
833
Neha Sharma96b7bf22020-06-15 10:37:32 +0000834func startCollector(ctx context.Context, dh *DeviceHandler) {
835 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530836 for {
837 select {
838 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000839 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530840 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000841 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700842
Neha Sharma8f4e4322020-08-06 10:51:53 +0000843 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400844 if err != nil {
845 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
846 continue
847 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530848 for _, port := range ports {
849 // NNI Stats
850 if port.Type == voltha.Port_ETHERNET_NNI {
851 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
852 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000853 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
854 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
855 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530856 }
857 // PON Stats
858 if port.Type == voltha.Port_PON_OLT {
859 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
860 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
861 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000862 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
863 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530864 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000865 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500866 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530867 }
868 }
869 }
870}
871
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700872//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530873func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400874 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000875 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530876 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530877
878 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400879 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
880 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530881 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530882}
883
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700884//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530885func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700886 return &ic.SwitchCapability{
887 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530888 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700889 HwDesc: "open_pon",
890 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700891 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700892 },
893 SwitchFeatures: &of.OfpSwitchFeatures{
894 NBuffers: 256,
895 NTables: 2,
896 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
897 of.OfpCapabilities_OFPC_TABLE_STATS |
898 of.OfpCapabilities_OFPC_PORT_STATS |
899 of.OfpCapabilities_OFPC_GROUP_STATS),
900 },
901 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530902}
903
Neha Sharma96b7bf22020-06-15 10:37:32 +0000904func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
905 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 -0700906 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700907 var deviceID string
908 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700909
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400910 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700911 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000912 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 -0700913 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
914 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400915
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700916 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530917
918 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
919
Neha Sharma96b7bf22020-06-15 10:37:32 +0000920 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 -0700921 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700922 kwargs := make(map[string]interface{})
923 kwargs["onu_id"] = omciInd.OnuId
924 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700925
Neha Sharma8f4e4322020-08-06 10:51:53 +0000926 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700927 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530928 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700929 "intf-id": omciInd.IntfId,
930 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700931 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700932 deviceType = onuDevice.Type
933 deviceID = onuDevice.Id
934 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
935 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530936 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700937 } else {
938 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000939 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 +0530940 deviceType = onuInCache.(*OnuDevice).deviceType
941 deviceID = onuInCache.(*OnuDevice).deviceID
942 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700943 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700944
945 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +0000946 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530947 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800948 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530949 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530950 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800951 "destination": deviceType,
952 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000953 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700954 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800955 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530956}
957
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700958//ProcessInterAdapterMessage sends the proxied messages to the target device
959// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
960// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000961func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
962 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700963 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700964 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700965 fromTopic := msg.Header.FromTopic
966 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700967 toDeviceID := msg.Header.ToDeviceId
968 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700969
Neha Sharma96b7bf22020-06-15 10:37:32 +0000970 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 -0700971
972 msgBody := msg.GetBody()
973
974 omciMsg := &ic.InterAdapterOmciMessage{}
975 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000976 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700977 }
978
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700979 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000980 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700981 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530982 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800983 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000984 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700985 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000986 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
987 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530988 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800989 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000990 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800991 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700992 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000993 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
994 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530995 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800996 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000997 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800998 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700999 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001000 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001001 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001002 }
1003 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301004}
1005
Neha Sharma96b7bf22020-06-15 10:37:32 +00001006func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001007 var intfID uint32
1008 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001009 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001010 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001011 intfID = onuDevice.ProxyAddress.GetChannelId()
1012 onuID = onuDevice.ProxyAddress.GetOnuId()
1013 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001014 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001015 intfID = omciMsg.GetProxyAddress().GetChannelId()
1016 onuID = omciMsg.GetProxyAddress().GetOnuId()
1017 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001018 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001019 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001020 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 -08001021
Thomas Lee S94109f12020-03-03 16:39:29 +05301022 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001023 "intf-id": intfID,
1024 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001025 }
1026
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001027 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1028 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001029 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001030 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1031 hex.Encode(hexPkt, omciMsg.Message)
1032 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1033
1034 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1035 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1036 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001037 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001038 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001039
Neha Sharma8f4e4322020-08-06 10:51:53 +00001040 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001041 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301042 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001043 "intf-id": intfID,
1044 "onu-id": onuID,
1045 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001046 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001047 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001048}
1049
David K. Bainbridge794735f2020-02-11 21:01:37 -08001050func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301051 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001052 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001053 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001054 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001055 // TODO: need resource manager
1056 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301057 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301058 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001059 st, _ := status.FromError(err)
1060 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001061 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1062
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001063 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301064 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001065 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001066 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001067 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001068 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001069 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001070}
1071
David K. Bainbridge794735f2020-02-11 21:01:37 -08001072func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001073 channelID := onuDiscInd.GetIntfId()
1074 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001075
Neha Sharma96b7bf22020-06-15 10:37:32 +00001076 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301077
cuilin20187b2a8c32019-03-26 19:52:28 -07001078 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001079 if sn != "" {
1080 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001081 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001082 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001083 }
1084
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301085 var alarmInd oop.OnuAlarmIndication
1086 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001087 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301088
1089 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1090 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1091 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1092 OnuLosRaise event sent for it */
1093 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1094 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1095 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001096 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301097 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1098 "currentIntfId": onuDiscInd.GetIntfId()})
1099 // TODO:: Should we need to ignore raising OnuLosClear event
1100 // when onu connected to different PON?
1101 }
1102 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1103 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1104 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001105 go func() {
1106 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1107 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1108 }
1109 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301110 }
1111 return true
1112 })
1113
Neha Sharma96b7bf22020-06-15 10:37:32 +00001114 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001115 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001116 }
1117
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001118 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001119
1120 // check the ONU is already know to the OLT
1121 // NOTE the second time the ONU is discovered this should return a device
1122 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1123
1124 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001125 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 -08001126 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001127 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 -08001128 switch e.Code() {
1129 case codes.Internal:
1130 // this probably means NOT FOUND, so just create a new device
1131 onuDevice = nil
1132 case codes.DeadlineExceeded:
1133 // if the call times out, cleanup and exit
1134 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001135 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001136 }
1137 }
1138 }
1139
1140 if onuDevice == nil {
1141 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001142 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001143 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001144 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301145 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001146
Neha Sharma96b7bf22020-06-15 10:37:32 +00001147 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001148
1149 if err != nil {
1150 // if we can't create an ID in resource manager,
1151 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001152 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001153 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001154 "pon-intf-id": ponintfid,
1155 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001156 }
1157
Neha Sharma8f4e4322020-08-06 10:51:53 +00001158 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001159 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001160 dh.discOnus.Delete(sn)
1161 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 +05301162 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001163 "pon-intf-id": ponintfid,
1164 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001165 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001166 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1167 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1168 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001169 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301170 log.Fields{"onuDevice": onuDevice,
1171 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001172 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301173 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001174 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001175
1176 // we can now use the existing ONU Id
1177 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001178 //Insert the ONU into cache to use in OnuIndication.
1179 //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 +00001180 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001181 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301182 "intfId": onuDiscInd.GetIntfId(),
1183 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001184 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001185
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301186 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301187 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001188 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301189 log.Fields{"onu": onuDev,
1190 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001191
Kent Hagermane6ff1012020-07-14 15:07:53 -04001192 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301193 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001194 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001195 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001196 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001197 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001198 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301199 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001200 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001201 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001202 }
1203 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001204}
1205
Neha Sharma96b7bf22020-06-15 10:37:32 +00001206func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001207 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1208
1209 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001210 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001211 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001212 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001213 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001214 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301215 log.Fields{"onuId": onuInd.OnuId,
1216 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301217 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001218 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301219
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220 errFields := log.Fields{"device-id": dh.device.Id}
1221
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301222 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1223
Mahir Gunyele77977b2019-06-27 05:36:22 -07001224 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1225 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001226 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001227 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001228 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001229 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1230 if serialNumber != "" {
1231 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001232 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001233 } else {
1234 kwargs["onu_id"] = onuInd.OnuId
1235 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001236 errFields["onu-id"] = onuInd.OnuId
1237 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001238 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001239 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001240 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001241
David K. Bainbridge794735f2020-02-11 21:01:37 -08001242 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001243 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001244 }
1245
David K. Bainbridge794735f2020-02-11 21:01:37 -08001246 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001247 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001248 "previousIntfId": onuDevice.ParentPortNo,
1249 "currentIntfId": ponPort})
1250 }
1251
1252 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001253 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301254 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1255 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301256 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001257 }
1258 if !foundInCache {
1259 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1260
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301261 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 -08001262
1263 }
kesavand7cf3a052020-08-28 12:49:18 +05301264 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1265 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1266 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1267 }
1268 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001269 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001270 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001271 }
1272 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001273}
1274
Neha Sharma96b7bf22020-06-15 10:37:32 +00001275func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001276 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 -07001277 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1278 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1279 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1280 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001281 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001282 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1283 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001284 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001285 onuInd.OperState = "down"
1286 }
1287 }
1288
David K. Bainbridge794735f2020-02-11 21:01:37 -08001289 switch onuInd.OperState {
1290 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001291 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 -07001292 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301293 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001294 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1295 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301296 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001297 "onu-indicator": onuInd,
1298 "source": "openolt",
1299 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001300 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001301 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001302 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001303 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 -04001304 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301305 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001306 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1307 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301308 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001309 "onu-indicator": onuInd,
1310 "source": "openolt",
1311 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001312 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001313 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001314 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001315 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001316 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001317 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001318}
1319
cuilin20187b2a8c32019-03-26 19:52:28 -07001320func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1321 if serialNum != nil {
1322 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001323 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001324 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001325}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001326func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1327 decodedStr, err := hex.DecodeString(serialNum[4:])
1328 if err != nil {
1329 return nil, err
1330 }
1331 return &oop.SerialNumber{
1332 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001333 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001334 }, nil
1335}
cuilin20187b2a8c32019-03-26 19:52:28 -07001336
1337func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1338 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001339 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001340 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1341 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1342 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1343 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1344 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1345 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1346 return tmp
1347}
1348
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001349//UpdateFlowsBulk upates the bulk flow
1350func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301351 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001352}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001353
1354//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001355func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1356 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301357 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001358 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301359 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001360 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001361 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001362 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001363 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001364 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001365 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001366 "intf-id": parentPort,
1367 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001368 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001369 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 -08001370 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301371}
1372
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001373// SendPacketInToCore sends packet-in to core
1374// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1375// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001376func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001377 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001378 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001379 "port": logicalPort,
1380 "packet": hex.EncodeToString(packetPayload),
1381 "device-id": dh.device.Id,
1382 })
1383 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001384 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 +05301385 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001386 "source": "adapter",
1387 "destination": "core",
1388 "device-id": dh.device.Id,
1389 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001390 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001391 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001392 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001393 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001394 "packet": hex.EncodeToString(packetPayload),
1395 "device-id": dh.device.Id,
1396 })
1397 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001398 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001399}
1400
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001401// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001402func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001403 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001404
1405 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1406 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001407 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001408 }
1409
Kent Hagermane6ff1012020-07-14 15:07:53 -04001410 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001411 metrics := dh.metrics.GetSubscriberMetrics()
1412 for _, m := range pmConfigs.Metrics {
1413 metrics[m.Name].Enabled = m.Enabled
1414
1415 }
1416 }
1417}
1418
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001419//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301420func (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 +00001421 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 +01001422
1423 var errorsList []error
1424
Girish Gowdru0c588b22019-04-23 23:24:56 -04001425 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001426 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001427 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001428
Neha Sharma96b7bf22020-06-15 10:37:32 +00001429 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301430 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001431 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301432 "flowToRemove": flow})
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001433 err := dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
Girish Gowdracefae192020-03-19 18:14:10 -07001434 if err != nil {
1435 errorsList = append(errorsList, err)
1436 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001437 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301438
1439 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001440 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001441 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301442 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001443 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301444 "flowToAdd": flow})
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001445 err := dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001446 if err != nil {
1447 errorsList = append(errorsList, err)
1448 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301449 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001450 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001451
Girish Gowdracefae192020-03-19 18:14:10 -07001452 // 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 +00001453 if groups != nil {
1454 for _, group := range groups.ToAdd.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001455 err := dh.groupMgr.AddGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001456 if err != nil {
1457 errorsList = append(errorsList, err)
1458 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001459 }
1460 for _, group := range groups.ToUpdate.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001461 err := dh.groupMgr.ModifyGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001462 if err != nil {
1463 errorsList = append(errorsList, err)
1464 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001465 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001466 for _, group := range groups.ToRemove.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001467 err := dh.groupMgr.DeleteGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001468 if err != nil {
1469 errorsList = append(errorsList, err)
1470 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001471 }
1472 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001473 if len(errorsList) > 0 {
1474 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1475 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001476 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001477 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301478}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001479
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001480//DisableDevice disables the given device
1481//It marks the following for the given device:
1482//Device-Handler Admin-State : down
1483//Device Port-State: UNKNOWN
1484//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001485func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001486 /* On device disable ,admin state update has to be done prior sending request to agent since
1487 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001488 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001489 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001490 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001491 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001492 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001493 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001494 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001495 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001496 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001497 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301498
1499 dh.discOnus = sync.Map{}
1500 dh.onus = sync.Map{}
1501
Thomas Lee S85f37312020-04-03 17:06:12 +05301502 //stopping the stats collector
1503 dh.stopCollector <- true
1504
Neha Sharma96b7bf22020-06-15 10:37:32 +00001505 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001506 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301507 //Update device Admin state
1508 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001509 // 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 +00001510 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 -04001511 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001512 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001513 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001514 return nil
1515}
1516
Neha Sharma96b7bf22020-06-15 10:37:32 +00001517func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001518 // Update onu state as unreachable in onu adapter
1519 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301520 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001521 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001522 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001523 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001524 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 -04001525 }
1526 if onuDevices != nil {
1527 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001528 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001529 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1530 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001531 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301532 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001533 }
1534
1535 }
1536 }
1537
1538}
1539
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001540//ReenableDevice re-enables the olt device after disable
1541//It marks the following for the given device:
1542//Device-Handler Admin-State : up
1543//Device Port-State: ACTIVE
1544//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001545func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001546 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301547 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001548 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301549 }
1550 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001551 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001552
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001553 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001554
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001555 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1556 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001557 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001558 }
1559 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001560 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001561 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001562 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001563 device.OperStatus = voltha.OperStatus_ACTIVE
1564 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001565
Neha Sharma8f4e4322020-08-06 10:51:53 +00001566 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 +05301567 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001568 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001569 "connect-status": device.ConnectStatus,
1570 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001571 }
kesavand39e0aa32020-01-28 20:58:50 -05001572
Neha Sharma96b7bf22020-06-15 10:37:32 +00001573 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001574
1575 return nil
1576}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001577
npujarec5762e2020-01-01 14:08:48 +05301578func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001579 var uniID uint32
1580 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301581 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001582 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001583 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001584 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001585 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001586 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001587 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001588 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301589 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001590 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301591 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001592 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001593 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301595 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001596 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001597 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001598 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301599 }
npujarec5762e2020-01-01 14:08:48 +05301600 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1601 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001602 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301603 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001604 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001605 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001606 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 +00001607 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001608 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1609 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1610 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001611 }
1612 return nil
1613}
1614
npujarec5762e2020-01-01 14:08:48 +05301615func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001616 nniUniID := -1
1617 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301618
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001619 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301620 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001621 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001622 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301623 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301624 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001625 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001626 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001627 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301628 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301629 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001630 _ = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, nniIntfID, -1, -1)
1631
Devmalya Paul495b94a2019-08-27 19:42:00 -04001632 }
npujarec5762e2020-01-01 14:08:48 +05301633 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001634 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301635 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001636
David K. Bainbridge794735f2020-02-11 21:01:37 -08001637 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001638}
1639
1640// 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 +05301641func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001642 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001643 /* Clear the KV store data associated with the all the UNI ports
1644 This clears up flow data and also resource map data for various
1645 other pon resources like alloc_id and gemport_id
1646 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001647 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001648 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001649 // Stop the Stats collector
1650 dh.stopCollector <- true
1651 // stop the heartbeat check routine
1652 dh.stopHeartbeatCheck <- true
1653 //Reset the state
1654 if dh.Client != nil {
1655 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301656 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001657 }
1658 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001659 // There is no need to update the core about operation status and connection status of the OLT.
1660 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1661 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1662 // because the device does not exist in DB.
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001663 return nil
1664}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001665func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001666
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001667 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301668 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001669 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301670 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301671 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301672 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001673 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001674 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001675 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301676 }
1677 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301678 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001679 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301680 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001681 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301682 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301683 // Clear flowids for gem cache.
1684 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301685 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301686 }
1687 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301688 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301689 }
npujarec5762e2020-01-01 14:08:48 +05301690 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301691 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301692 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301693 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001694 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001695 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001696 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001697 /* Clear the flows from KV store associated with NNI port.
1698 There are mostly trap rules from NNI port (like LLDP)
1699 */
npujarec5762e2020-01-01 14:08:48 +05301700 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001701 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001702 }
A R Karthick1f85b802019-10-11 05:06:05 +00001703
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001704 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001705 go func() {
1706 if err := dh.resourceMgr.Delete(ctx); err != nil {
1707 logger.Debug(ctx, err)
1708 }
1709 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001710 }
A R Karthick1f85b802019-10-11 05:06:05 +00001711
Devmalya Paul495b94a2019-08-27 19:42:00 -04001712 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301713 dh.onus.Range(func(key interface{}, value interface{}) bool {
1714 dh.onus.Delete(key)
1715 return true
1716 })
1717
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001718 /*Delete discovered ONU map for the device*/
1719 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1720 dh.discOnus.Delete(key)
1721 return true
1722 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001723}
1724
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001725//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001726func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001727 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301728 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001729 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001730 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001731 return nil
1732}
1733
David K. Bainbridge794735f2020-02-11 21:01:37 -08001734func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001735 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001736 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001737 "packet-indication": *packetIn,
1738 "device-id": dh.device.Id,
1739 "packet": hex.EncodeToString(packetIn.Pkt),
1740 })
1741 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001742 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001743 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001744 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001745 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001746 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001747 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001748 "logical-port-num": logicalPortNum,
1749 "device-id": dh.device.Id,
1750 "packet": hex.EncodeToString(packetIn.Pkt),
1751 })
1752 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001753
Neha Sharma8f4e4322020-08-06 10:51:53 +00001754 if err := dh.coreProxy.SendPacketIn(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301755 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001756 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301757 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001758 "device-id": dh.device.Id,
1759 "packet": hex.EncodeToString(packetIn.Pkt),
1760 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001761 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001762
Matteo Scandolo92186242020-06-12 10:54:18 -07001763 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001764 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001765 "packet": hex.EncodeToString(packetIn.Pkt),
1766 "device-id": dh.device.Id,
1767 })
1768 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001769 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001770}
1771
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001772// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301773func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001774 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001775 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001776 "device-id": dh.device.Id,
1777 "egress-port-no": egressPortNo,
1778 "pkt-length": len(packet.Data),
1779 "packet": hex.EncodeToString(packet.Data),
1780 })
1781 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001782
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001783 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001784 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001785 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1786 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301787 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1788 // Do not packet-out lldp packets on uni port.
1789 // ONOS has no clue about uni/nni ports, it just packets out on all
1790 // available ports on the Logical Switch. It should not be interested
1791 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001792 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001793 "device-id": dh.device.Id,
1794 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301795 return nil
1796 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001797 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1798 if innerEthType == 0x8100 {
1799 // q-in-q 802.1ad or 802.1q double tagged packet.
1800 // slice out the outer tag.
1801 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001802 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001803 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001804 "packet-data": hex.EncodeToString(packet.Data),
1805 "device-id": dh.device.Id,
1806 })
1807 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001808 }
1809 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001810 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1811 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001812 uniID := UniIDFromPortNum(uint32(egressPortNo))
1813
Girish Gowdra9602eb42020-09-09 15:50:39 -07001814 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001815 if err != nil {
1816 // In this case the openolt agent will receive the gemPortID as 0.
1817 // The agent tries to retrieve the gemPortID in this case.
1818 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001819 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001820 "intf-id": intfID,
1821 "onu-id": onuID,
1822 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001823 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301824 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001825 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001826 }
1827
1828 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001829 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001830 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001831 "egress-port-no": egressPortNo,
1832 "intf-id": intfID,
1833 "onu-id": onuID,
1834 "uni-id": uniID,
1835 "gem-port-id": gemPortID,
1836 "packet": hex.EncodeToString(packet.Data),
1837 "device-id": dh.device.Id,
1838 })
1839 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001840
npujarec5762e2020-01-01 14:08:48 +05301841 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301842 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001843 "source": "adapter",
1844 "destination": "onu",
1845 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001846 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001847 "oni-id": onuID,
1848 "uni-id": uniID,
1849 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001850 "packet": hex.EncodeToString(packet.Data),
1851 "device-id": dh.device.Id,
1852 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001853 }
1854 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001855 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001856 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001857 return olterrors.NewErrInvalidValue(log.Fields{
1858 "egress-nni-port": egressPortNo,
1859 "device-id": dh.device.Id,
1860 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001861 }
1862 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001863
Matteo Scandolo92186242020-06-12 10:54:18 -07001864 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001865 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001866 "uplink-pkt": uplinkPkt,
1867 "packet": hex.EncodeToString(packet.Data),
1868 "device-id": dh.device.Id,
1869 })
1870 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001871
npujarec5762e2020-01-01 14:08:48 +05301872 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001873 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1874 "packet": hex.EncodeToString(packet.Data),
1875 "device-id": dh.device.Id,
1876 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001877 }
1878 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001879 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301880 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001881 "egressPortType": egressPortType,
1882 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301883 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001884 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001885 }
1886 return nil
1887}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001888
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001889func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1890 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001891}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301892
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001893func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001894
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301895 // start the heartbeat check towards the OLT.
1896 var timerCheck *time.Timer
1897
1898 for {
1899 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1900 select {
1901 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001902 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001903 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001904 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301905 if timerCheck == nil {
1906 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001907 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301908 }
1909 } else {
1910 if timerCheck != nil {
1911 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001912 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301913 }
1914 timerCheck = nil
1915 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001916 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301917 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301918 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301919 }
1920 cancel()
1921 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001922 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301923 return
1924 }
1925 }
1926}
1927
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001928func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1929 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1930 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07001931 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
1932 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
1933 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
1934 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
1935 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04001936 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07001937 // Immediately return, otherwise accessing a null 'device' struct would cause panic
1938 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001939 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301940
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001941 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1942 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001943 _ = olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001944 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001945 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001946 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001947 }
1948 go dh.cleanupDeviceResources(ctx)
1949
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001950 dh.lockDevice.RLock()
1951 // Stop the read indication only if it the routine is active
1952 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1953 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1954 // on next execution of the readIndication routine.
1955 if dh.isReadIndicationRoutineActive {
1956 dh.stopIndications <- true
1957 }
1958 dh.lockDevice.RUnlock()
1959
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001960 dh.transitionMap.Handle(ctx, DeviceInit)
1961
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301962 }
1963}
kesavand39e0aa32020-01-28 20:58:50 -05001964
1965// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001966func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1967 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1968 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001969}
1970
1971// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001972func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1973 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1974 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001975}
1976
kdarapu1afeceb2020-02-12 01:38:09 -05001977//modifyPhyPort is common function to enable and disable the port. parm :enablePort, true to enablePort and false to disablePort.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001978func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1979 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001980 if port.GetType() == voltha.Port_ETHERNET_NNI {
1981 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001982 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301983 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301984 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001985 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001986 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001987 }
1988 // fetch interfaceid from PortNo
1989 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1990 ponIntf := &oop.Interface{IntfId: ponID}
1991 var operStatus voltha.OperStatus_Types
1992 if enablePort {
1993 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301994 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001995
1996 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301997 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001998 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001999 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002000 }
2001 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002002 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002003 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002004 } else {
2005 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302006 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002007 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302008 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002009 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002010 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002011 }
2012 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002013 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002014 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002015 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302016 if err := dh.coreProxy.PortStateUpdate(ctx, dh.device.Id, voltha.Port_PON_OLT, port.PortNo, operStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302017 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302018 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002019 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002020 }
2021 return nil
2022}
2023
kdarapu1afeceb2020-02-12 01:38:09 -05002024//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002025func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002026 // Disable the port and update the oper_port_status to core
2027 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002028 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002029 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002030 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302031 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302032 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002033 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002034 }
2035 }
2036 }
2037 return nil
2038}
2039
2040//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002041func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2042 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2043 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002044 if port.Type == voltha.Port_ETHERNET_NNI {
2045 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002046 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002047 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002048 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002049 }
2050 }
2051 if port.Type == voltha.Port_PON_OLT {
2052 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002053 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002054 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002055 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002056 }
2057 }
2058 }
2059}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002060
2061// ChildDeviceLost deletes ONU and clears pon resources related to it.
2062func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
divyadesai3af43e12020-08-18 07:10:54 +00002063 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002064 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2065 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002066 onuDevice, ok := dh.onus.Load(onuKey)
2067 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302068 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002069 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002070 "device-id": dh.device.Id,
2071 "onu-id": onuID,
2072 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002073 }
2074 var sn *oop.SerialNumber
2075 var err error
2076 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302077 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002078 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302079 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002080 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2081 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002082
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002083 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Neha Sharma8f4e4322020-08-06 10:51:53 +00002084 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302085 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302086 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002087 "onu-id": onuID}, err).Log()
2088 }
2089 //clear PON resources associated with ONU
2090 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002091 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002092 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002093 "device-id": dh.device.Id,
2094 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002095 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002096 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002097 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002098 "device-id": dh.device.Id,
2099 "intf-id": intfID,
2100 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002101 } else {
2102 for i, onu := range onuGemData {
2103 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002104 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002105 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002106 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302107 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002108 "onu-device": onu,
2109 "error": err})
2110 }
2111 // Clear flowids for gem cache.
2112 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002113 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002114 }
2115 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002116 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002117 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002118 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002119 "intf-id": intfID,
2120 "onu-device": onu,
2121 "onu-gem": onuGemData,
2122 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002123 //Not returning error on cleanup.
2124 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002125 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002126 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002127 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002128 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002129 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002130 }
2131 }
2132 dh.onus.Delete(onuKey)
2133 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2134 return nil
2135}
Girish Gowdracefae192020-03-19 18:14:10 -07002136
2137func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2138 for _, field := range flows.GetOfbFields(flow) {
2139 if field.Type == flows.IN_PORT {
2140 return field.GetPort()
2141 }
2142 }
2143 return InvalidPort
2144}
2145
2146func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2147 for _, action := range flows.GetActions(flow) {
2148 if action.Type == flows.OUTPUT {
2149 if out := action.GetOutput(); out != nil {
2150 return out.GetPort()
2151 }
2152 }
2153 }
2154 return InvalidPort
2155}
2156
Girish Gowdracefae192020-03-19 18:14:10 -07002157func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2158 inPort := getInPortFromFlow(flow)
2159 outPort := getOutPortFromFlow(flow)
2160
2161 if inPort == InvalidPort || outPort == InvalidPort {
2162 return inPort, outPort
2163 }
2164
2165 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2166 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2167 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2168 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2169 return uniPort, outPort
2170 }
2171 }
2172 } else {
2173 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2174 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2175 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2176 return inPort, uniPort
2177 }
2178 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2179 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2180 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2181 return uniPort, outPort
2182 }
2183 }
2184 }
2185
2186 return InvalidPort, InvalidPort
2187}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002188
2189func extractOmciTransactionID(omciPkt []byte) uint16 {
2190 if len(omciPkt) > 3 {
2191 d := omciPkt[0:2]
2192 transid := binary.BigEndian.Uint16(d)
2193 return transid
2194 }
2195 return 0
2196}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002197
2198// StoreOnuDevice stores the onu parameters to the local cache.
2199func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2200 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2201 dh.onus.Store(onuKey, onuDevice)
2202}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002203
Neha Sharma8f4e4322020-08-06 10:51:53 +00002204func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002205 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002206 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002207 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002208 resp := new(voltha.ReturnValues)
2209 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002210 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002211 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002212 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2213 return nil, err
2214 }
2215 ID = device.ProxyAddress.GetOnuId()
2216 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2217 valueparam.Onu = &Onu
2218 valueparam.Value = value
2219
2220 // This API is unsupported until agent patch is added
2221 resp.Unsupported = uint32(value)
2222 _ = ctx
2223
2224 // Uncomment this code once agent changes are complete and tests
2225 /*
2226 resp, err = dh.Client.GetValue(ctx, valueparam)
2227 if err != nil {
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002228 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002229 return nil, err
2230 }
2231 */
2232
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002233 logger.Infow(ctx, "get-ext-value", log.Fields{"resp": resp, "device-id": dh.device, "onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002234 return resp, nil
2235}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002236
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002237func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002238 // Default to PON0
2239 var intfID uint32
2240 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002241 if inPort != InvalidPort && outPort != InvalidPort {
2242 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2243 }
2244 return intfID
2245}