blob: 229481f6bca6a650f00988f26b72d2091ec5df3b [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"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080037
Girish Gowdraa09aeab2020-09-14 16:30:52 -070038 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080039 "github.com/opencord/voltha-lib-go/v4/pkg/config"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070040 "github.com/opencord/voltha-lib-go/v4/pkg/flows"
41 "github.com/opencord/voltha-lib-go/v4/pkg/log"
42 "github.com/opencord/voltha-lib-go/v4/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080043
Thomas Lee S94109f12020-03-03 16:39:29 +053044 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080045 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070046 "github.com/opencord/voltha-protos/v4/go/common"
47 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
48 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
49 oop "github.com/opencord/voltha-protos/v4/go/openolt"
50 "github.com/opencord/voltha-protos/v4/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070051 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040052 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040053 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053054)
55
salmansiddiqui7ac62132019-08-22 03:58:50 +000056// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040057const (
Girish Gowdraa09aeab2020-09-14 16:30:52 -070058 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040059)
60
Phaneendra Manda4c62c802019-03-06 21:37:49 +053061//DeviceHandler will interact with the OLT device.
62type DeviceHandler struct {
Matteo Scandolodfa7a972020-11-06 13:03:40 -080063 cm *config.ConfigManager
cuilin20187b2a8c32019-03-26 19:52:28 -070064 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053065 coreProxy adapterif.CoreProxy
66 AdapterProxy adapterif.AdapterProxy
67 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070068 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070069 exitChannel chan int
70 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053071 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070072 transitionMap *TransitionMap
73 clientCon *grpc.ClientConn
Girish Gowdra9602eb42020-09-09 15:50:39 -070074 flowMgr []*OpenOltFlowMgr
75 groupMgr *OpenOltGroupMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040076 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053077 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053078
Girish Gowdra3ab6d212020-03-24 17:33:15 -070079 discOnus sync.Map
80 onus sync.Map
81 portStats *OpenOltStatisticsMgr
82 metrics *pmmetrics.PmMetrics
83 stopCollector chan bool
84 stopHeartbeatCheck chan bool
85 activePorts sync.Map
86 stopIndications chan bool
87 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070088
Girish Gowdra9602eb42020-09-09 15:50:39 -070089 totalPonPorts uint32
Mahir Gunyela3f9add2019-06-06 15:13:19 -070090}
91
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070092//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -070093type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070094 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -070095 deviceType string
96 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070097 onuID uint32
98 intfID uint32
99 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530100 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400101 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700102}
103
Naga Manjunath7615e552019-10-11 22:35:47 +0530104var pmNames = []string{
105 "rx_bytes",
106 "rx_packets",
107 "rx_mcast_packets",
108 "rx_bcast_packets",
109 "tx_bytes",
110 "tx_packets",
111 "tx_mcast_packets",
112 "tx_bcast_packets",
113}
114
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700115//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530116func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700117 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700118 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700119 device.deviceType = deviceTp
120 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700121 device.onuID = onuID
122 device.intfID = intfID
123 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530124 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700125 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530126}
127
128//NewDeviceHandler creates a new device handler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800129func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT, cm *config.ConfigManager) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700130 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800131 dh.cm = cm
cuilin20187b2a8c32019-03-26 19:52:28 -0700132 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400133 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400134 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700135 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700136 dh.device = cloned
137 dh.openOLT = adapter
138 dh.exitChannel = make(chan int, 1)
139 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530140 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530141 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530142 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 -0500143 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400144 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700145
cuilin20187b2a8c32019-03-26 19:52:28 -0700146 //TODO initialize the support classes.
147 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530148}
149
150// start save the device to the data model
151func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700152 dh.lockDevice.Lock()
153 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000154 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700155 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000156 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530157}
158
159// stop stops the device dh. Not much to do for now
160func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700161 dh.lockDevice.Lock()
162 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000163 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700164 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000165 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530166}
167
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400168func macifyIP(ip net.IP) string {
169 if len(ip) > 0 {
170 oct1 := strconv.FormatInt(int64(ip[12]), 16)
171 oct2 := strconv.FormatInt(int64(ip[13]), 16)
172 oct3 := strconv.FormatInt(int64(ip[14]), 16)
173 oct4 := strconv.FormatInt(int64(ip[15]), 16)
174 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
175 }
176 return ""
177}
178
Neha Sharma96b7bf22020-06-15 10:37:32 +0000179func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400180 var genmac string
181 var addr net.IP
182 var ips []string
183 var err error
184
Neha Sharma96b7bf22020-06-15 10:37:32 +0000185 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400186
187 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000188 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400189
190 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000191 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400192 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000193 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400194 }
195 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000196 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530197 log.Fields{"host": ips[0],
198 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400199 return genmac, nil
200 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000201 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400202 }
203
204 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000205 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530206 log.Fields{"host": host,
207 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400208 return genmac, nil
209}
210
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530211func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700212 slist := strings.Split(mac, ":")
213 result := make([]uint32, len(slist))
214 var err error
215 var tmp int64
216 for index, val := range slist {
217 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
218 return []uint32{1, 2, 3, 4, 5, 6}
219 }
220 result[index] = uint32(tmp)
221 }
222 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530223}
224
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700225//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 -0800226func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530227
David K. Bainbridge794735f2020-02-11 21:01:37 -0800228 switch portType {
229 case voltha.Port_ETHERNET_NNI:
230 return fmt.Sprintf("nni-%d", portNum), nil
231 case voltha.Port_PON_OLT:
232 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700233 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800234
Girish Kumarf26e4882020-03-05 06:49:10 +0000235 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530236}
237
Neha Sharma96b7bf22020-06-15 10:37:32 +0000238func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000239 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700240 if state == "up" {
241 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500242 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500243 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700244 } else {
245 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500246 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700247 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700248 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400249 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800250 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000251 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400252 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500253
Neha Sharma8f4e4322020-08-06 10:51:53 +0000254 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 +0000255 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000256 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 -0400257 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
258 "device-id": dh.device.Id,
259 "port-type": portType,
260 "port-number": portNum,
261 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500262 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400263 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500264 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400265 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700266 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400267 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700268 PortNo: portNum,
269 Label: label,
270 Type: portType,
271 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700272 OfpPort: &of.OfpPort{
273 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
274 Config: 0,
275 State: uint32(of.OfpPortState_OFPPS_LIVE),
276 Curr: capacity,
277 Advertised: capacity,
278 Peer: capacity,
279 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
280 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
281 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700282 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000283 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700284 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000285 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000286 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800287 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000288 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400289 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000290 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530291 return nil
292}
293
Kent Hagermane6ff1012020-07-14 15:07:53 -0400294func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530295 dh.lockDevice.Lock()
296 defer dh.lockDevice.Unlock()
Neha Sharma8f4e4322020-08-06 10:51:53 +0000297 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530298 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400299 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
300 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530301 }
302 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530303}
304
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700305// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530306// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800307func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000308 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700309 defer func() {
310 dh.lockDevice.Lock()
311 dh.isReadIndicationRoutineActive = false
312 dh.lockDevice.Unlock()
313 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700314 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700315 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700316 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700317 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400318 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530319 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400320 if err != nil || device == nil {
321 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000322 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400323 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400324
David Bainbridgef5879ca2019-12-13 21:17:54 +0000325 // Create an exponential backoff around re-enabling indications. The
326 // maximum elapsed time for the back off is set to 0 so that we will
327 // continue to retry. The max interval defaults to 1m, but is set
328 // here for code clarity
329 indicationBackoff := backoff.NewExponentialBackOff()
330 indicationBackoff.MaxElapsedTime = 0
331 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700332
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700333 dh.lockDevice.Lock()
334 dh.isReadIndicationRoutineActive = true
335 dh.lockDevice.Unlock()
336
Girish Gowdra3f974912020-03-23 20:35:18 -0700337Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700338 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400339 select {
340 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000341 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700342 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400343 default:
344 indication, err := indications.Recv()
345 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000346 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530347 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530348 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400349 // Use an exponential back off to prevent getting into a tight loop
350 duration := indicationBackoff.NextBackOff()
351 if duration == backoff.Stop {
352 // If we reach a maximum then warn and reset the backoff
353 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000354 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530355 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530356 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400357 indicationBackoff.Reset()
358 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700359
360 // On failure process a backoff timer while watching for stopIndications
361 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700362 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700363 select {
364 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000365 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700366 if !backoffTimer.Stop() {
367 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700368 }
369 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700370 case <-backoffTimer.C:
371 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700372 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700373 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
374 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400375 }
376 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000377 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530378 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000379 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530380 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530381 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700382 // Close the stream, and re-initialize it
383 if err = indications.CloseSend(); err != nil {
384 // Ok to ignore here, because we landed here due to a problem on the stream
385 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000386 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530387 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530388 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700389 }
390 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
391 return err
392 }
393 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400394 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530395 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400396 // Reset backoff if we have a successful receive
397 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400398 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530399 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000400 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530401 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530402 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400403 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400404 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400405 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700406 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700407 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700408 // Close the send stream
409 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700410
Girish Gowdra3f974912020-03-23 20:35:18 -0700411 return nil
412}
413
414func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
415
416 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
417 if err != nil {
418 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
419 }
420 if indications == nil {
421 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
422 }
423
424 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400425}
426
427// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
428func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
429 switch indication.Data.(type) {
430 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
431 return true
432
433 default:
434 return false
435 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700436}
437
David K. Bainbridge794735f2020-02-11 21:01:37 -0800438func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000439 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000440 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530441 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700442 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530443 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700444 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000445 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000446 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530447 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000448 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800449 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000450 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800451 }
452 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700453}
454
David K. Bainbridge794735f2020-02-11 21:01:37 -0800455// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530456func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400457 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700458 switch indication.Data.(type) {
459 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000460 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
461 defer span.Finish()
462
David K. Bainbridge794735f2020-02-11 21:01:37 -0800463 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400464 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800465 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700466 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000467 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
468 defer span.Finish()
469
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700470 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800471 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000472 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400473 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800474 }
475 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000476 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700477 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000478 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
479 defer span.Finish()
480
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700481 intfOperInd := indication.GetIntfOperInd()
482 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800483 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000484 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400485 _ = 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 -0800486 }
487 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400488 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
489 logger.Warn(ctx, err)
490 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700491 } else if intfOperInd.GetType() == "pon" {
492 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
493 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800494 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000495 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400496 _ = 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 -0800497 }
498 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000499 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700500 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000501 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530502 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530503 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700504 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000505 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
506 defer span.Finish()
507
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700508 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000509 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700510 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800511 go func() {
512 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400513 _ = 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 -0800514 }
515 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700516 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000517 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
518 defer span.Finish()
519
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700520 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000521 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800522 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000523 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400524 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800525 }
526 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700527 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000528 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
529 defer span.Finish()
530
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700531 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000532 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 -0800533 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000534 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400535 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800536 }
537 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700538 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000539 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
540 defer span.Finish()
541
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700542 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000543 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700544 "intf-type": pktInd.IntfId,
545 "intf-id": pktInd.IntfId,
546 "gem-port-id": pktInd.GemportId,
547 "port-no": pktInd.PortNo,
548 "device-id": dh.device.Id,
549 })
550
551 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700553 "intf-type": pktInd.IntfId,
554 "intf-id": pktInd.IntfId,
555 "gem-port-id": pktInd.GemportId,
556 "port-no": pktInd.PortNo,
557 "packet": hex.EncodeToString(pktInd.Pkt),
558 "device-id": dh.device.Id,
559 })
560 }
561
David K. Bainbridge794735f2020-02-11 21:01:37 -0800562 go func() {
563 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400564 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800565 }
566 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700567 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000568 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
569 defer span.Finish()
570
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700571 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700572 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000574 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
575 defer span.Finish()
576
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000578 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700579 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000580 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
581 defer span.Finish()
582
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700583 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000584 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
585 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700586 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530587}
588
589// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530590func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530591 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000592 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530593
Girish Gowdru0c588b22019-04-23 23:24:56 -0400594 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530595 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400596 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000597 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400598 }
599 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530600}
601
602// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530603func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700604 dh.lockDevice.Lock()
605 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000606 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400607
npujarec5762e2020-01-01 14:08:48 +0530608 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400609 if err != nil || device == nil {
610 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000611 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400612 }
613
614 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400615
616 //Update the device oper state and connection status
617 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400618 dh.device = cloned
619
David K. Bainbridge794735f2020-02-11 21:01:37 -0800620 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000621 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400622 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400623
624 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530625 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400626 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000627 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400628 }
629 for _, onuDevice := range onuDevices.Items {
630
631 // Update onu state as down in onu adapter
632 onuInd := oop.OnuIndication{}
633 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800634 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300635 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800636 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400637 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300638 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800639 "onu-indicator": onuInd,
640 "device-type": onuDevice.Type,
641 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700642 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700643 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400644 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700645 /* Discovered ONUs entries need to be cleared , since after OLT
646 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530647 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000648 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700649 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530650}
651
652// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530653func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400654 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000655 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
656 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
657 grpc.WithInsecure(),
658 grpc.WithBlock(),
659 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000660 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000661 )),
662 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000663 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000664 )))
665
666 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530667 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530668 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000669 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400670 }
671 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530672}
673
674// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530675func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400676 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530677 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400678 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530679}
680
681// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530682func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530683 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000684 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400685
686 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530687 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
688 if err != nil || device == nil {
689 /*TODO: needs to handle error scenarios */
690 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
691 }
692 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000693 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400694
695 cloned := proto.Clone(device).(*voltha.Device)
696 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
697 cloned.OperStatus = voltha.OperStatus_UNKNOWN
698 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530699 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
700 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 -0400701 }
702
Chaitrashree G S44124192019-08-07 20:21:36 -0400703 // 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 +0530704 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400705 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530706 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400707 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400708 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
709 // all the modules initialized and ready to handle incoming ONUs.
710
Thomas Lee S985938d2020-05-04 11:40:41 +0530711 err = dh.initializeDeviceHandlerModules(ctx)
712 if err != nil {
713 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 -0400714 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400715
716 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800717 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530718 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400719 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800720 }
721 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700722
723 go startHeartbeatCheck(ctx, dh)
724
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400725 return nil
726 }
727
Neha Sharma8f4e4322020-08-06 10:51:53 +0000728 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400729 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400730 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400731 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400732 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400733 dh.populateActivePorts(ctx, ports)
734 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
735 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400736 }
737
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400738 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530739 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 -0400740 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530741
cuilin20187b2a8c32019-03-26 19:52:28 -0700742 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800743 go func() {
744 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400745 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800746 }
747 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000748 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000749
750 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000751 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000752 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700753
754 go startHeartbeatCheck(ctx, dh)
755
cuilin20187b2a8c32019-03-26 19:52:28 -0700756 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530757}
758
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400759func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000760 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400761
762 if err != nil {
763 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
764 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700765 dh.totalPonPorts = deviceInfo.GetPonPorts()
766
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400767 // Instantiate resource manager
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800768 if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr == nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400769 return olterrors.ErrResourceManagerInstantiating
770 }
771
Girish Gowdra9602eb42020-09-09 15:50:39 -0700772 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400773
Girish Gowdra9602eb42020-09-09 15:50:39 -0700774 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
775 for i := range dh.flowMgr {
776 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700777 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700778 return olterrors.ErrResourceManagerInstantiating
779 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400780 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700781
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400782 /* TODO: Instantiate Alarm , stats , BW managers */
783 /* Instantiating Event Manager to handle Alarms and KPIs */
784 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
785
786 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000787 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400788
789 return nil
790
791}
792
Neha Sharma96b7bf22020-06-15 10:37:32 +0000793func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400794 var err error
795 var deviceInfo *oop.DeviceInfo
796
Neha Sharma8f4e4322020-08-06 10:51:53 +0000797 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400798
799 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000800 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400801 }
802 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000803 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400804 }
805
Neha Sharma96b7bf22020-06-15 10:37:32 +0000806 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400807 dh.device.Root = true
808 dh.device.Vendor = deviceInfo.Vendor
809 dh.device.Model = deviceInfo.Model
810 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
811 dh.device.HardwareVersion = deviceInfo.HardwareVersion
812 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
813
814 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000815 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400816 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000817 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400818 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000819 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400820 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000821 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400822 dh.device.MacAddress = genmac
823 } else {
824 dh.device.MacAddress = deviceInfo.DeviceId
825 }
826
827 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000828 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000829 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400830 }
831
832 return deviceInfo, nil
833}
834
Neha Sharma96b7bf22020-06-15 10:37:32 +0000835func startCollector(ctx context.Context, dh *DeviceHandler) {
836 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530837 for {
838 select {
839 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000840 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530841 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000842 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700843
Neha Sharma8f4e4322020-08-06 10:51:53 +0000844 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400845 if err != nil {
846 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
847 continue
848 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530849 for _, port := range ports {
850 // NNI Stats
851 if port.Type == voltha.Port_ETHERNET_NNI {
852 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
853 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000854 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
855 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
856 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530857 }
858 // PON Stats
859 if port.Type == voltha.Port_PON_OLT {
860 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
861 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
862 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000863 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
864 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530865 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000866 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500867 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530868 }
869 }
870 }
871}
872
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700873//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530874func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400875 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000876 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530877 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530878
879 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400880 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
881 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530882 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530883}
884
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700885//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530886func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700887 return &ic.SwitchCapability{
888 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530889 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700890 HwDesc: "open_pon",
891 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700892 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700893 },
894 SwitchFeatures: &of.OfpSwitchFeatures{
895 NBuffers: 256,
896 NTables: 2,
897 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
898 of.OfpCapabilities_OFPC_TABLE_STATS |
899 of.OfpCapabilities_OFPC_PORT_STATS |
900 of.OfpCapabilities_OFPC_GROUP_STATS),
901 },
902 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530903}
904
Neha Sharma96b7bf22020-06-15 10:37:32 +0000905func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
906 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 -0700907 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700908 var deviceID string
909 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700910
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400911 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700912 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000913 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 -0700914 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
915 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400916
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700917 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530918
919 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
920
Neha Sharma96b7bf22020-06-15 10:37:32 +0000921 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 -0700922 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700923 kwargs := make(map[string]interface{})
924 kwargs["onu_id"] = omciInd.OnuId
925 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700926
Neha Sharma8f4e4322020-08-06 10:51:53 +0000927 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700928 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530929 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700930 "intf-id": omciInd.IntfId,
931 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700932 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700933 deviceType = onuDevice.Type
934 deviceID = onuDevice.Id
935 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
936 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530937 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700938 } else {
939 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000940 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 +0530941 deviceType = onuInCache.(*OnuDevice).deviceType
942 deviceID = onuInCache.(*OnuDevice).deviceID
943 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700944 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700945
946 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +0000947 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300948 ic.InterAdapterMessageType_OMCI_REQUEST, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800949 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530950 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300951 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800952 "destination": deviceType,
953 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000954 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700955 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800956 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530957}
958
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700959//ProcessInterAdapterMessage sends the proxied messages to the target device
960// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
961// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000962func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
963 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700964 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700965 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700966 fromTopic := msg.Header.FromTopic
967 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700968 toDeviceID := msg.Header.ToDeviceId
969 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700970
Neha Sharma96b7bf22020-06-15 10:37:32 +0000971 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 -0700972
973 msgBody := msg.GetBody()
974
975 omciMsg := &ic.InterAdapterOmciMessage{}
976 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000977 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700978 }
979
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700980 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000981 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700982 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530983 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800984 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000985 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700986 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000987 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
988 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530989 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800990 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000991 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800992 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700993 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000994 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
995 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530996 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800997 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000998 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800999 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001000 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001001 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001002 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001003 }
1004 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301005}
1006
Neha Sharma96b7bf22020-06-15 10:37:32 +00001007func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001008 var intfID uint32
1009 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001010 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001011 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001012 intfID = onuDevice.ProxyAddress.GetChannelId()
1013 onuID = onuDevice.ProxyAddress.GetOnuId()
1014 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001015 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001016 intfID = omciMsg.GetProxyAddress().GetChannelId()
1017 onuID = omciMsg.GetProxyAddress().GetOnuId()
1018 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001019 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001020 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001021 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 -08001022
Thomas Lee S94109f12020-03-03 16:39:29 +05301023 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001024 "intf-id": intfID,
1025 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001026 }
1027
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001028 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1029 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001030 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001031 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1032 hex.Encode(hexPkt, omciMsg.Message)
1033 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1034
1035 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1036 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1037 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001038 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001039 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001040
Neha Sharma8f4e4322020-08-06 10:51:53 +00001041 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001042 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301043 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001044 "intf-id": intfID,
1045 "onu-id": onuID,
1046 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001047 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001048 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001049}
1050
David K. Bainbridge794735f2020-02-11 21:01:37 -08001051func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301052 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 -07001053 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001054 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001055 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001056 // TODO: need resource manager
1057 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301058 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301059 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001060 st, _ := status.FromError(err)
1061 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001062 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1063
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001064 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301065 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001066 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001067 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001068 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001069 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001070 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001071}
1072
David K. Bainbridge794735f2020-02-11 21:01:37 -08001073func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001074 channelID := onuDiscInd.GetIntfId()
1075 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001076
Neha Sharma96b7bf22020-06-15 10:37:32 +00001077 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301078
cuilin20187b2a8c32019-03-26 19:52:28 -07001079 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001080 if sn != "" {
1081 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001082 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001083 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001084 }
1085
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301086 var alarmInd oop.OnuAlarmIndication
1087 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001088 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301089
1090 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1091 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1092 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1093 OnuLosRaise event sent for it */
1094 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1095 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1096 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001097 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301098 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1099 "currentIntfId": onuDiscInd.GetIntfId()})
1100 // TODO:: Should we need to ignore raising OnuLosClear event
1101 // when onu connected to different PON?
1102 }
1103 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1104 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1105 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001106 go func() {
1107 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1108 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1109 }
1110 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301111 }
1112 return true
1113 })
1114
Neha Sharma96b7bf22020-06-15 10:37:32 +00001115 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001116 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001117 }
1118
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001119 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001120
1121 // check the ONU is already know to the OLT
1122 // NOTE the second time the ONU is discovered this should return a device
1123 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1124
1125 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001126 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 -08001127 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001128 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 -08001129 switch e.Code() {
1130 case codes.Internal:
1131 // this probably means NOT FOUND, so just create a new device
1132 onuDevice = nil
1133 case codes.DeadlineExceeded:
1134 // if the call times out, cleanup and exit
1135 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001136 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001137 }
1138 }
1139 }
1140
1141 if onuDevice == nil {
1142 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001143 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001144 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001145 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301146 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001147
Neha Sharma96b7bf22020-06-15 10:37:32 +00001148 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001149
1150 if err != nil {
1151 // if we can't create an ID in resource manager,
1152 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001153 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001154 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001155 "pon-intf-id": ponintfid,
1156 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001157 }
1158
Neha Sharma8f4e4322020-08-06 10:51:53 +00001159 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001160 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001161 dh.discOnus.Delete(sn)
1162 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 +05301163 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001164 "pon-intf-id": ponintfid,
1165 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001166 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001167 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1168 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1169 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301171 log.Fields{"onuDevice": onuDevice,
1172 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001173 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301174 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001175 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001176
1177 // we can now use the existing ONU Id
1178 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001179 //Insert the ONU into cache to use in OnuIndication.
1180 //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 +00001181 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001182 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301183 "intfId": onuDiscInd.GetIntfId(),
1184 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001185 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001186
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301187 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301188 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001189 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301190 log.Fields{"onu": onuDev,
1191 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001192
Kent Hagermane6ff1012020-07-14 15:07:53 -04001193 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301194 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001195 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001196 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001197 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001198 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001199 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301200 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001201 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001202 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001203 }
1204 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001205}
1206
Neha Sharma96b7bf22020-06-15 10:37:32 +00001207func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001208 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1209
1210 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001211 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001212 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001213 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001214 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001215 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301216 log.Fields{"onuId": onuInd.OnuId,
1217 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301218 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001219 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301220
David K. Bainbridge794735f2020-02-11 21:01:37 -08001221 errFields := log.Fields{"device-id": dh.device.Id}
1222
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301223 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1224
Mahir Gunyele77977b2019-06-27 05:36:22 -07001225 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1226 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001227 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001228 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001229 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001230 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1231 if serialNumber != "" {
1232 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001233 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001234 } else {
1235 kwargs["onu_id"] = onuInd.OnuId
1236 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001237 errFields["onu-id"] = onuInd.OnuId
1238 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001239 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001240 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001241 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001242
David K. Bainbridge794735f2020-02-11 21:01:37 -08001243 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001244 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001245 }
1246
David K. Bainbridge794735f2020-02-11 21:01:37 -08001247 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001248 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001249 "previousIntfId": onuDevice.ParentPortNo,
1250 "currentIntfId": ponPort})
1251 }
1252
1253 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001254 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301255 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1256 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301257 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001258 }
1259 if !foundInCache {
1260 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1261
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301262 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 -08001263
1264 }
kesavand7cf3a052020-08-28 12:49:18 +05301265 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1266 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1267 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1268 }
1269 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001270 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001271 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001272 }
1273 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001274}
1275
Neha Sharma96b7bf22020-06-15 10:37:32 +00001276func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001277 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 -07001278 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1279 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1280 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1281 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001282 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001283 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1284 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001285 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001286 onuInd.OperState = "down"
1287 }
1288 }
1289
David K. Bainbridge794735f2020-02-11 21:01:37 -08001290 switch onuInd.OperState {
1291 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001292 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 -07001293 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301294 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001295 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001296 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301297 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001298 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001299 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001300 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001301 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001302 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001303 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001304 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 -04001305 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301306 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001307 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001308 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301309 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001310 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001311 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001312 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001313 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001314 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001315 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001316 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001317 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001318 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001319}
1320
cuilin20187b2a8c32019-03-26 19:52:28 -07001321func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1322 if serialNum != nil {
1323 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001324 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001325 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001326}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001327func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1328 decodedStr, err := hex.DecodeString(serialNum[4:])
1329 if err != nil {
1330 return nil, err
1331 }
1332 return &oop.SerialNumber{
1333 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001334 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001335 }, nil
1336}
cuilin20187b2a8c32019-03-26 19:52:28 -07001337
1338func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1339 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001340 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001341 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1342 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1343 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1344 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1345 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1346 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1347 return tmp
1348}
1349
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001350//UpdateFlowsBulk upates the bulk flow
1351func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301352 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001353}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001354
1355//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001356func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1357 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301358 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001359 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301360 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001361 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001362 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001363 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001364 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001365 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001366 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001367 "intf-id": parentPort,
1368 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001369 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001370 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 -08001371 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301372}
1373
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001374// SendPacketInToCore sends packet-in to core
1375// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1376// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001377func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001378 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001379 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001380 "port": logicalPort,
1381 "packet": hex.EncodeToString(packetPayload),
1382 "device-id": dh.device.Id,
1383 })
1384 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001385 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 +05301386 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001387 "source": "adapter",
1388 "destination": "core",
1389 "device-id": dh.device.Id,
1390 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001391 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001392 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001393 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001394 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001395 "packet": hex.EncodeToString(packetPayload),
1396 "device-id": dh.device.Id,
1397 })
1398 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001399 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001400}
1401
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001402// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001403func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001404 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001405
1406 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1407 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001408 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001409 }
1410
Kent Hagermane6ff1012020-07-14 15:07:53 -04001411 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001412 metrics := dh.metrics.GetSubscriberMetrics()
1413 for _, m := range pmConfigs.Metrics {
1414 metrics[m.Name].Enabled = m.Enabled
1415
1416 }
1417 }
1418}
1419
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001420//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301421func (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 +00001422 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 +01001423
1424 var errorsList []error
1425
Girish Gowdru0c588b22019-04-23 23:24:56 -04001426 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001427 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001428 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001429
Neha Sharma96b7bf22020-06-15 10:37:32 +00001430 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301431 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001432 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301433 "flowToRemove": flow})
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001434 err := dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
Girish Gowdracefae192020-03-19 18:14:10 -07001435 if err != nil {
1436 errorsList = append(errorsList, err)
1437 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001438 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301439
1440 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001441 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001442 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301443 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001444 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301445 "flowToAdd": flow})
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001446 err := dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001447 if err != nil {
1448 errorsList = append(errorsList, err)
1449 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301450 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001451 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001452
Girish Gowdracefae192020-03-19 18:14:10 -07001453 // 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 +00001454 if groups != nil {
1455 for _, group := range groups.ToAdd.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001456 err := dh.groupMgr.AddGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001457 if err != nil {
1458 errorsList = append(errorsList, err)
1459 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001460 }
1461 for _, group := range groups.ToUpdate.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001462 err := dh.groupMgr.ModifyGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001463 if err != nil {
1464 errorsList = append(errorsList, err)
1465 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001466 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001467 for _, group := range groups.ToRemove.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001468 err := dh.groupMgr.DeleteGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001469 if err != nil {
1470 errorsList = append(errorsList, err)
1471 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001472 }
1473 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001474 if len(errorsList) > 0 {
1475 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1476 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001477 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001478 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301479}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001480
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001481//DisableDevice disables the given device
1482//It marks the following for the given device:
1483//Device-Handler Admin-State : down
1484//Device Port-State: UNKNOWN
1485//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001486func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001487 /* On device disable ,admin state update has to be done prior sending request to agent since
1488 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001489 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001490 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001491 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001492 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001493 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001494 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001495 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001496 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001497 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001498 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301499
1500 dh.discOnus = sync.Map{}
1501 dh.onus = sync.Map{}
1502
Thomas Lee S85f37312020-04-03 17:06:12 +05301503 //stopping the stats collector
1504 dh.stopCollector <- true
1505
Neha Sharma96b7bf22020-06-15 10:37:32 +00001506 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001507 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301508 //Update device Admin state
1509 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001510 // 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 +00001511 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 -04001512 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001513 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001514 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001515 return nil
1516}
1517
Neha Sharma96b7bf22020-06-15 10:37:32 +00001518func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001519 // Update onu state as unreachable in onu adapter
1520 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301521 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001522 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001523 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001524 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001525 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 -04001526 }
1527 if onuDevices != nil {
1528 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001529 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001530 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001531 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001532 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001533 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001534 }
1535
1536 }
1537 }
1538
1539}
1540
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001541//ReenableDevice re-enables the olt device after disable
1542//It marks the following for the given device:
1543//Device-Handler Admin-State : up
1544//Device Port-State: ACTIVE
1545//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001546func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001547 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301548 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001549 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301550 }
1551 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001552 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001553
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001554 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001555
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001556 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1557 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001558 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001559 }
1560 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001561 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001562 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001563 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001564 device.OperStatus = voltha.OperStatus_ACTIVE
1565 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001566
Neha Sharma8f4e4322020-08-06 10:51:53 +00001567 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 +05301568 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001569 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001570 "connect-status": device.ConnectStatus,
1571 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001572 }
kesavand39e0aa32020-01-28 20:58:50 -05001573
Neha Sharma96b7bf22020-06-15 10:37:32 +00001574 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001575
1576 return nil
1577}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001578
npujarec5762e2020-01-01 14:08:48 +05301579func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001580 var uniID uint32
1581 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301582 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001583 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001584 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001585 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001586 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001587 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001588 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001589 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301590 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001591 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301592 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001594 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301596 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001597 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001598 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001599 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301600 }
npujarec5762e2020-01-01 14:08:48 +05301601 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1602 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001603 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301604 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001605 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001606 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 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 +00001608 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001609 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1610 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1611 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001612 }
1613 return nil
1614}
1615
npujarec5762e2020-01-01 14:08:48 +05301616func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001617 nniUniID := -1
1618 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301619
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001620 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301621 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001622 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001623 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301624 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301625 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001626 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001627 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001628 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301629 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301630 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001631 _ = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, nniIntfID, -1, -1)
1632
Devmalya Paul495b94a2019-08-27 19:42:00 -04001633 }
npujarec5762e2020-01-01 14:08:48 +05301634 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001635 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301636 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001637
David K. Bainbridge794735f2020-02-11 21:01:37 -08001638 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001639}
1640
1641// 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 +05301642func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001643 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001644 /* Clear the KV store data associated with the all the UNI ports
1645 This clears up flow data and also resource map data for various
1646 other pon resources like alloc_id and gemport_id
1647 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001648 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001649 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001650 // Stop the Stats collector
1651 dh.stopCollector <- true
1652 // stop the heartbeat check routine
1653 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301654 dh.lockDevice.RLock()
1655 // Stop the read indication only if it the routine is active
1656 if dh.isReadIndicationRoutineActive {
1657 dh.stopIndications <- true
1658 }
1659 dh.lockDevice.RUnlock()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001660 //Reset the state
1661 if dh.Client != nil {
1662 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301663 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001664 }
1665 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001666 // There is no need to update the core about operation status and connection status of the OLT.
1667 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1668 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1669 // because the device does not exist in DB.
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001670 return nil
1671}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001672func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001673
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001674 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301675 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001676 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301677 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301678 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301679 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001680 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001681 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001682 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301683 }
1684 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301685 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001686 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301687 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001688 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301689 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301690 // Clear flowids for gem cache.
1691 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301692 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301693 }
1694 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301695 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301696 }
npujarec5762e2020-01-01 14:08:48 +05301697 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301698 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301699 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301700 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001701 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001702 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001703 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001704 /* Clear the flows from KV store associated with NNI port.
1705 There are mostly trap rules from NNI port (like LLDP)
1706 */
npujarec5762e2020-01-01 14:08:48 +05301707 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001708 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001709 }
A R Karthick1f85b802019-10-11 05:06:05 +00001710
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001711 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001712 go func() {
1713 if err := dh.resourceMgr.Delete(ctx); err != nil {
1714 logger.Debug(ctx, err)
1715 }
1716 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001717 }
A R Karthick1f85b802019-10-11 05:06:05 +00001718
Devmalya Paul495b94a2019-08-27 19:42:00 -04001719 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301720 dh.onus.Range(func(key interface{}, value interface{}) bool {
1721 dh.onus.Delete(key)
1722 return true
1723 })
1724
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001725 /*Delete discovered ONU map for the device*/
1726 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1727 dh.discOnus.Delete(key)
1728 return true
1729 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001730}
1731
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001732//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001733func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001734 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301735 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001736 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001737 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001738 return nil
1739}
1740
David K. Bainbridge794735f2020-02-11 21:01:37 -08001741func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001742 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001743 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001744 "packet-indication": *packetIn,
1745 "device-id": dh.device.Id,
1746 "packet": hex.EncodeToString(packetIn.Pkt),
1747 })
1748 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001749 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001750 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001751 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001752 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001753 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001754 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001755 "logical-port-num": logicalPortNum,
1756 "device-id": dh.device.Id,
1757 "packet": hex.EncodeToString(packetIn.Pkt),
1758 })
1759 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001760
Neha Sharma8f4e4322020-08-06 10:51:53 +00001761 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 +05301762 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001763 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301764 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001765 "device-id": dh.device.Id,
1766 "packet": hex.EncodeToString(packetIn.Pkt),
1767 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001768 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001769
Matteo Scandolo92186242020-06-12 10:54:18 -07001770 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001771 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001772 "packet": hex.EncodeToString(packetIn.Pkt),
1773 "device-id": dh.device.Id,
1774 })
1775 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001776 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001777}
1778
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001779// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301780func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001781 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001782 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001783 "device-id": dh.device.Id,
1784 "egress-port-no": egressPortNo,
1785 "pkt-length": len(packet.Data),
1786 "packet": hex.EncodeToString(packet.Data),
1787 })
1788 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001789
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001790 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001791 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001792 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1793 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301794 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1795 // Do not packet-out lldp packets on uni port.
1796 // ONOS has no clue about uni/nni ports, it just packets out on all
1797 // available ports on the Logical Switch. It should not be interested
1798 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001799 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001800 "device-id": dh.device.Id,
1801 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301802 return nil
1803 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001804 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1805 if innerEthType == 0x8100 {
1806 // q-in-q 802.1ad or 802.1q double tagged packet.
1807 // slice out the outer tag.
1808 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001809 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001810 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001811 "packet-data": hex.EncodeToString(packet.Data),
1812 "device-id": dh.device.Id,
1813 })
1814 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001815 }
1816 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001817 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1818 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001819 uniID := UniIDFromPortNum(uint32(egressPortNo))
1820
Girish Gowdra9602eb42020-09-09 15:50:39 -07001821 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001822 if err != nil {
1823 // In this case the openolt agent will receive the gemPortID as 0.
1824 // The agent tries to retrieve the gemPortID in this case.
1825 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001826 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001827 "intf-id": intfID,
1828 "onu-id": onuID,
1829 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001830 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301831 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001832 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001833 }
1834
1835 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001836 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001837 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001838 "egress-port-no": egressPortNo,
1839 "intf-id": intfID,
1840 "onu-id": onuID,
1841 "uni-id": uniID,
1842 "gem-port-id": gemPortID,
1843 "packet": hex.EncodeToString(packet.Data),
1844 "device-id": dh.device.Id,
1845 })
1846 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001847
npujarec5762e2020-01-01 14:08:48 +05301848 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301849 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001850 "source": "adapter",
1851 "destination": "onu",
1852 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001853 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001854 "oni-id": onuID,
1855 "uni-id": uniID,
1856 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001857 "packet": hex.EncodeToString(packet.Data),
1858 "device-id": dh.device.Id,
1859 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001860 }
1861 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001862 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001863 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001864 return olterrors.NewErrInvalidValue(log.Fields{
1865 "egress-nni-port": egressPortNo,
1866 "device-id": dh.device.Id,
1867 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001868 }
1869 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001870
Matteo Scandolo92186242020-06-12 10:54:18 -07001871 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001872 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001873 "uplink-pkt": uplinkPkt,
1874 "packet": hex.EncodeToString(packet.Data),
1875 "device-id": dh.device.Id,
1876 })
1877 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001878
npujarec5762e2020-01-01 14:08:48 +05301879 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001880 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1881 "packet": hex.EncodeToString(packet.Data),
1882 "device-id": dh.device.Id,
1883 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001884 }
1885 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001886 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301887 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001888 "egressPortType": egressPortType,
1889 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301890 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001891 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001892 }
1893 return nil
1894}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001895
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001896func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1897 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001898}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301899
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001900func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001901
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301902 // start the heartbeat check towards the OLT.
1903 var timerCheck *time.Timer
1904
1905 for {
1906 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1907 select {
1908 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001909 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001910 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001911 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301912 if timerCheck == nil {
1913 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001914 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301915 }
1916 } else {
1917 if timerCheck != nil {
1918 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001919 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301920 }
1921 timerCheck = nil
1922 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001923 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301924 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301925 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301926 }
1927 cancel()
1928 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001929 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301930 return
1931 }
1932 }
1933}
1934
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001935func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1936 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1937 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07001938 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
1939 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
1940 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
1941 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
1942 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04001943 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07001944 // Immediately return, otherwise accessing a null 'device' struct would cause panic
1945 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001946 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301947
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001948 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1949 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001950 _ = 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 -04001951 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001952 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001953 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001954 }
1955 go dh.cleanupDeviceResources(ctx)
1956
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001957 dh.lockDevice.RLock()
1958 // Stop the read indication only if it the routine is active
1959 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1960 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1961 // on next execution of the readIndication routine.
1962 if dh.isReadIndicationRoutineActive {
1963 dh.stopIndications <- true
1964 }
1965 dh.lockDevice.RUnlock()
1966
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001967 dh.transitionMap.Handle(ctx, DeviceInit)
1968
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301969 }
1970}
kesavand39e0aa32020-01-28 20:58:50 -05001971
1972// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001973func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1974 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1975 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001976}
1977
1978// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001979func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1980 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1981 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001982}
1983
kdarapu1afeceb2020-02-12 01:38:09 -05001984//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 +00001985func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1986 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001987 if port.GetType() == voltha.Port_ETHERNET_NNI {
1988 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001989 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301990 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301991 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001992 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001993 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001994 }
1995 // fetch interfaceid from PortNo
1996 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1997 ponIntf := &oop.Interface{IntfId: ponID}
1998 var operStatus voltha.OperStatus_Types
1999 if enablePort {
2000 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302001 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002002
2003 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302004 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002005 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002006 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002007 }
2008 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002009 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002010 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002011 } else {
2012 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302013 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002014 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302015 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002016 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002017 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002018 }
2019 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002020 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002021 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002022 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302023 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 +05302024 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302025 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002026 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002027 }
2028 return nil
2029}
2030
kdarapu1afeceb2020-02-12 01:38:09 -05002031//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002032func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002033 // Disable the port and update the oper_port_status to core
2034 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002035 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002036 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002037 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302038 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302039 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002040 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002041 }
2042 }
2043 }
2044 return nil
2045}
2046
2047//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002048func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2049 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2050 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002051 if port.Type == voltha.Port_ETHERNET_NNI {
2052 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002053 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002054 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002055 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002056 }
2057 }
2058 if port.Type == voltha.Port_PON_OLT {
2059 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002060 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002061 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002062 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002063 }
2064 }
2065 }
2066}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002067
2068// ChildDeviceLost deletes ONU and clears pon resources related to it.
2069func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
divyadesai3af43e12020-08-18 07:10:54 +00002070 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002071 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2072 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002073 onuDevice, ok := dh.onus.Load(onuKey)
2074 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302075 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002076 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002077 "device-id": dh.device.Id,
2078 "onu-id": onuID,
2079 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002080 }
2081 var sn *oop.SerialNumber
2082 var err error
2083 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302084 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002085 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302086 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002087 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2088 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002089
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002090 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Neha Sharma8f4e4322020-08-06 10:51:53 +00002091 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302092 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302093 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002094 "onu-id": onuID}, err).Log()
2095 }
2096 //clear PON resources associated with ONU
2097 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002098 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002099 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002100 "device-id": dh.device.Id,
2101 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002102 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002103 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002104 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002105 "device-id": dh.device.Id,
2106 "intf-id": intfID,
2107 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002108 } else {
2109 for i, onu := range onuGemData {
2110 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002111 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002112 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002113 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302114 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002115 "onu-device": onu,
2116 "error": err})
2117 }
2118 // Clear flowids for gem cache.
2119 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002120 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002121 }
2122 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002123 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002124 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002125 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002126 "intf-id": intfID,
2127 "onu-device": onu,
2128 "onu-gem": onuGemData,
2129 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002130 //Not returning error on cleanup.
2131 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002132 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002133 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002134 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002135 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002136 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002137 }
2138 }
2139 dh.onus.Delete(onuKey)
2140 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2141 return nil
2142}
Girish Gowdracefae192020-03-19 18:14:10 -07002143
2144func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2145 for _, field := range flows.GetOfbFields(flow) {
2146 if field.Type == flows.IN_PORT {
2147 return field.GetPort()
2148 }
2149 }
2150 return InvalidPort
2151}
2152
2153func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2154 for _, action := range flows.GetActions(flow) {
2155 if action.Type == flows.OUTPUT {
2156 if out := action.GetOutput(); out != nil {
2157 return out.GetPort()
2158 }
2159 }
2160 }
2161 return InvalidPort
2162}
2163
Girish Gowdracefae192020-03-19 18:14:10 -07002164func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2165 inPort := getInPortFromFlow(flow)
2166 outPort := getOutPortFromFlow(flow)
2167
2168 if inPort == InvalidPort || outPort == InvalidPort {
2169 return inPort, outPort
2170 }
2171
2172 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2173 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2174 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2175 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2176 return uniPort, outPort
2177 }
2178 }
2179 } else {
2180 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2181 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2182 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2183 return inPort, uniPort
2184 }
2185 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2186 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2187 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2188 return uniPort, outPort
2189 }
2190 }
2191 }
2192
2193 return InvalidPort, InvalidPort
2194}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002195
2196func extractOmciTransactionID(omciPkt []byte) uint16 {
2197 if len(omciPkt) > 3 {
2198 d := omciPkt[0:2]
2199 transid := binary.BigEndian.Uint16(d)
2200 return transid
2201 }
2202 return 0
2203}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002204
2205// StoreOnuDevice stores the onu parameters to the local cache.
2206func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2207 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2208 dh.onus.Store(onuKey, onuDevice)
2209}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002210
Neha Sharma8f4e4322020-08-06 10:51:53 +00002211func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002212 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002213 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002214 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002215 resp := new(voltha.ReturnValues)
2216 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002217 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002218 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002219 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2220 return nil, err
2221 }
2222 ID = device.ProxyAddress.GetOnuId()
2223 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2224 valueparam.Onu = &Onu
2225 valueparam.Value = value
2226
2227 // This API is unsupported until agent patch is added
2228 resp.Unsupported = uint32(value)
2229 _ = ctx
2230
2231 // Uncomment this code once agent changes are complete and tests
2232 /*
2233 resp, err = dh.Client.GetValue(ctx, valueparam)
2234 if err != nil {
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002235 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002236 return nil, err
2237 }
2238 */
2239
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002240 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 -08002241 return resp, nil
2242}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002243
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002244func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002245 // Default to PON0
2246 var intfID uint32
2247 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002248 if inPort != InvalidPort && outPort != InvalidPort {
2249 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2250 }
2251 return intfID
2252}