blob: a098387ee8e4b139d0a11a94ddf4a28589d7779c [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}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001829
Matteo Scandolo92186242020-06-12 10:54:18 -07001830 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001831 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001832 "egress-port-no": egressPortNo,
1833 "intf-id": intfID,
1834 "onu-id": onuID,
1835 "uni-id": uniID,
1836 "gem-port-id": gemPortID,
1837 "packet": hex.EncodeToString(packet.Data),
1838 "device-id": dh.device.Id,
1839 })
1840 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001841
npujarec5762e2020-01-01 14:08:48 +05301842 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301843 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001844 "source": "adapter",
1845 "destination": "onu",
1846 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001847 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001848 "oni-id": onuID,
1849 "uni-id": uniID,
1850 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001851 "packet": hex.EncodeToString(packet.Data),
1852 "device-id": dh.device.Id,
1853 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001854 }
1855 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001856 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001857 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001858 return olterrors.NewErrInvalidValue(log.Fields{
1859 "egress-nni-port": egressPortNo,
1860 "device-id": dh.device.Id,
1861 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001862 }
1863 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001864
Matteo Scandolo92186242020-06-12 10:54:18 -07001865 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001866 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001867 "uplink-pkt": uplinkPkt,
1868 "packet": hex.EncodeToString(packet.Data),
1869 "device-id": dh.device.Id,
1870 })
1871 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001872
npujarec5762e2020-01-01 14:08:48 +05301873 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001874 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1875 "packet": hex.EncodeToString(packet.Data),
1876 "device-id": dh.device.Id,
1877 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001878 }
1879 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001880 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301881 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001882 "egressPortType": egressPortType,
1883 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301884 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001885 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001886 }
1887 return nil
1888}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001889
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001890func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1891 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001892}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301893
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001894func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001895
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301896 // start the heartbeat check towards the OLT.
1897 var timerCheck *time.Timer
1898
1899 for {
1900 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1901 select {
1902 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001903 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001904 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001905 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301906 if timerCheck == nil {
1907 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001908 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301909 }
1910 } else {
1911 if timerCheck != nil {
1912 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001913 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301914 }
1915 timerCheck = nil
1916 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001917 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301918 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301919 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301920 }
1921 cancel()
1922 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001923 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301924 return
1925 }
1926 }
1927}
1928
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001929func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1930 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1931 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07001932 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
1933 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
1934 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
1935 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
1936 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04001937 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07001938 // Immediately return, otherwise accessing a null 'device' struct would cause panic
1939 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001940 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301941
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001942 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1943 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001944 _ = 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 -04001945 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001946 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001947 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001948 }
1949 go dh.cleanupDeviceResources(ctx)
1950
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001951 dh.lockDevice.RLock()
1952 // Stop the read indication only if it the routine is active
1953 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1954 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1955 // on next execution of the readIndication routine.
1956 if dh.isReadIndicationRoutineActive {
1957 dh.stopIndications <- true
1958 }
1959 dh.lockDevice.RUnlock()
1960
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001961 dh.transitionMap.Handle(ctx, DeviceInit)
1962
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301963 }
1964}
kesavand39e0aa32020-01-28 20:58:50 -05001965
1966// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001967func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1968 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1969 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001970}
1971
1972// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001973func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1974 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1975 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001976}
1977
kdarapu1afeceb2020-02-12 01:38:09 -05001978//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 +00001979func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1980 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001981 if port.GetType() == voltha.Port_ETHERNET_NNI {
1982 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001983 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301984 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301985 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001986 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001987 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001988 }
1989 // fetch interfaceid from PortNo
1990 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1991 ponIntf := &oop.Interface{IntfId: ponID}
1992 var operStatus voltha.OperStatus_Types
1993 if enablePort {
1994 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301995 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001996
1997 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301998 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001999 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002000 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002001 }
2002 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002003 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002004 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002005 } else {
2006 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302007 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002008 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302009 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002010 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002011 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002012 }
2013 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002014 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002015 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002016 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302017 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 +05302018 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302019 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002020 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002021 }
2022 return nil
2023}
2024
kdarapu1afeceb2020-02-12 01:38:09 -05002025//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002026func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002027 // Disable the port and update the oper_port_status to core
2028 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002029 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002030 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002031 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302032 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302033 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002034 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002035 }
2036 }
2037 }
2038 return nil
2039}
2040
2041//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002042func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2043 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2044 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002045 if port.Type == voltha.Port_ETHERNET_NNI {
2046 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002047 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002048 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002049 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002050 }
2051 }
2052 if port.Type == voltha.Port_PON_OLT {
2053 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002054 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002055 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002056 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002057 }
2058 }
2059 }
2060}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002061
2062// ChildDeviceLost deletes ONU and clears pon resources related to it.
2063func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
divyadesai3af43e12020-08-18 07:10:54 +00002064 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002065 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2066 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002067 onuDevice, ok := dh.onus.Load(onuKey)
2068 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302069 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002070 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002071 "device-id": dh.device.Id,
2072 "onu-id": onuID,
2073 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002074 }
2075 var sn *oop.SerialNumber
2076 var err error
2077 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302078 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002079 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302080 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002081 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2082 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002083
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002084 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Neha Sharma8f4e4322020-08-06 10:51:53 +00002085 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302086 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302087 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002088 "onu-id": onuID}, err).Log()
2089 }
2090 //clear PON resources associated with ONU
2091 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002092 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002093 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002094 "device-id": dh.device.Id,
2095 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002096 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002097 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002098 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002099 "device-id": dh.device.Id,
2100 "intf-id": intfID,
2101 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002102 } else {
2103 for i, onu := range onuGemData {
2104 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002105 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002106 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002107 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302108 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002109 "onu-device": onu,
2110 "error": err})
2111 }
2112 // Clear flowids for gem cache.
2113 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002114 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002115 }
2116 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002117 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002118 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002119 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002120 "intf-id": intfID,
2121 "onu-device": onu,
2122 "onu-gem": onuGemData,
2123 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002124 //Not returning error on cleanup.
2125 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002126 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002127 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002128 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002129 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002130 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002131 }
2132 }
2133 dh.onus.Delete(onuKey)
2134 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2135 return nil
2136}
Girish Gowdracefae192020-03-19 18:14:10 -07002137
2138func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2139 for _, field := range flows.GetOfbFields(flow) {
2140 if field.Type == flows.IN_PORT {
2141 return field.GetPort()
2142 }
2143 }
2144 return InvalidPort
2145}
2146
2147func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2148 for _, action := range flows.GetActions(flow) {
2149 if action.Type == flows.OUTPUT {
2150 if out := action.GetOutput(); out != nil {
2151 return out.GetPort()
2152 }
2153 }
2154 }
2155 return InvalidPort
2156}
2157
Girish Gowdracefae192020-03-19 18:14:10 -07002158func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2159 inPort := getInPortFromFlow(flow)
2160 outPort := getOutPortFromFlow(flow)
2161
2162 if inPort == InvalidPort || outPort == InvalidPort {
2163 return inPort, outPort
2164 }
2165
2166 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2167 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2168 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2169 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2170 return uniPort, outPort
2171 }
2172 }
2173 } else {
2174 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2175 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2176 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2177 return inPort, uniPort
2178 }
2179 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2180 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2181 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2182 return uniPort, outPort
2183 }
2184 }
2185 }
2186
2187 return InvalidPort, InvalidPort
2188}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002189
2190func extractOmciTransactionID(omciPkt []byte) uint16 {
2191 if len(omciPkt) > 3 {
2192 d := omciPkt[0:2]
2193 transid := binary.BigEndian.Uint16(d)
2194 return transid
2195 }
2196 return 0
2197}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002198
2199// StoreOnuDevice stores the onu parameters to the local cache.
2200func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2201 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2202 dh.onus.Store(onuKey, onuDevice)
2203}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002204
Neha Sharma8f4e4322020-08-06 10:51:53 +00002205func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002206 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002207 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002208 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002209 resp := new(voltha.ReturnValues)
2210 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002211 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002212 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002213 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2214 return nil, err
2215 }
2216 ID = device.ProxyAddress.GetOnuId()
2217 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2218 valueparam.Onu = &Onu
2219 valueparam.Value = value
2220
2221 // This API is unsupported until agent patch is added
2222 resp.Unsupported = uint32(value)
2223 _ = ctx
2224
2225 // Uncomment this code once agent changes are complete and tests
2226 /*
2227 resp, err = dh.Client.GetValue(ctx, valueparam)
2228 if err != nil {
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002229 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002230 return nil, err
2231 }
2232 */
2233
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002234 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 -08002235 return resp, nil
2236}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002237
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002238func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002239 // Default to PON0
2240 var intfID uint32
2241 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002242 if inPort != InvalidPort && outPort != InvalidPort {
2243 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2244 }
2245 return intfID
2246}