blob: 66ca4bb83db2ed8a555b3ca8395990d0b8e4b550 [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})
382 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000383 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700384 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400385 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700386 // Close the stream, and re-initialize it
387 if err = indications.CloseSend(); err != nil {
388 // Ok to ignore here, because we landed here due to a problem on the stream
389 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000390 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530391 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530392 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700393 }
394 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
395 return err
396 }
397 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400398 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530399 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400400 // Reset backoff if we have a successful receive
401 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400402 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530403 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000404 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530405 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530406 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400407 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400408 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400409 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700410 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700411 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700412 // Close the send stream
413 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700414
Girish Gowdra3f974912020-03-23 20:35:18 -0700415 return nil
416}
417
418func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
419
420 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
421 if err != nil {
422 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
423 }
424 if indications == nil {
425 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
426 }
427
428 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400429}
430
431// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
432func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
433 switch indication.Data.(type) {
434 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
435 return true
436
437 default:
438 return false
439 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700440}
441
David K. Bainbridge794735f2020-02-11 21:01:37 -0800442func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000443 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000444 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530445 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700446 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530447 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700448 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000449 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000450 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530451 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000452 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800453 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000454 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800455 }
456 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700457}
458
David K. Bainbridge794735f2020-02-11 21:01:37 -0800459// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530460func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400461 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700462 switch indication.Data.(type) {
463 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000464 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
465 defer span.Finish()
466
David K. Bainbridge794735f2020-02-11 21:01:37 -0800467 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400468 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800469 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700470 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000471 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
472 defer span.Finish()
473
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700474 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800475 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000476 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400477 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800478 }
479 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000480 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700481 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000482 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
483 defer span.Finish()
484
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700485 intfOperInd := indication.GetIntfOperInd()
486 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800487 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000488 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400489 _ = 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 -0800490 }
491 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400492 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
493 logger.Warn(ctx, err)
494 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700495 } else if intfOperInd.GetType() == "pon" {
496 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
497 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800498 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000499 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400500 _ = 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 -0800501 }
502 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000503 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700504 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000505 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530506 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530507 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700508 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000509 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
510 defer span.Finish()
511
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700512 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000513 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700514 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800515 go func() {
516 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400517 _ = 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 -0800518 }
519 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700520 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000521 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
522 defer span.Finish()
523
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700524 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000525 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800526 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000527 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400528 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800529 }
530 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700531 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000532 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
533 defer span.Finish()
534
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700535 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000536 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 -0800537 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000538 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400539 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800540 }
541 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700542 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000543 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
544 defer span.Finish()
545
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700546 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000547 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700548 "intf-type": pktInd.IntfId,
549 "intf-id": pktInd.IntfId,
550 "gem-port-id": pktInd.GemportId,
551 "port-no": pktInd.PortNo,
552 "device-id": dh.device.Id,
553 })
554
555 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000556 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700557 "intf-type": pktInd.IntfId,
558 "intf-id": pktInd.IntfId,
559 "gem-port-id": pktInd.GemportId,
560 "port-no": pktInd.PortNo,
561 "packet": hex.EncodeToString(pktInd.Pkt),
562 "device-id": dh.device.Id,
563 })
564 }
565
David K. Bainbridge794735f2020-02-11 21:01:37 -0800566 go func() {
567 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400568 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800569 }
570 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700571 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000572 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
573 defer span.Finish()
574
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700575 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700576 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000578 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
579 defer span.Finish()
580
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700581 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000582 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700583 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000584 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
585 defer span.Finish()
586
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700587 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000588 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
589 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700590 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530591}
592
593// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530594func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530595 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000596 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530597
Girish Gowdru0c588b22019-04-23 23:24:56 -0400598 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530599 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400600 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000601 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400602 }
603 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530604}
605
606// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530607func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700608 dh.lockDevice.Lock()
609 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000610 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400611
npujarec5762e2020-01-01 14:08:48 +0530612 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400613 if err != nil || device == nil {
614 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000615 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400616 }
617
618 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400619
620 //Update the device oper state and connection status
621 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400622 dh.device = cloned
623
David K. Bainbridge794735f2020-02-11 21:01:37 -0800624 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000625 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400626 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400627
628 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530629 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400630 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000631 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400632 }
633 for _, onuDevice := range onuDevices.Items {
634
635 // Update onu state as down in onu adapter
636 onuInd := oop.OnuIndication{}
637 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800638 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700639 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800640 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400641 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800642 "source": "openolt",
643 "onu-indicator": onuInd,
644 "device-type": onuDevice.Type,
645 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700646 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700647 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400648 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700649 /* Discovered ONUs entries need to be cleared , since after OLT
650 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530651 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000652 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700653 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530654}
655
656// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530657func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400658 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000659 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
660 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
661 grpc.WithInsecure(),
662 grpc.WithBlock(),
663 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000664 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000665 )),
666 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000667 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000668 )))
669
670 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530671 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530672 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000673 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400674 }
675 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530676}
677
678// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530679func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400680 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530681 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400682 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530683}
684
685// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530686func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530687 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000688 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400689
690 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530691 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
692 if err != nil || device == nil {
693 /*TODO: needs to handle error scenarios */
694 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
695 }
696 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000697 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400698
699 cloned := proto.Clone(device).(*voltha.Device)
700 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
701 cloned.OperStatus = voltha.OperStatus_UNKNOWN
702 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530703 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
704 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 -0400705 }
706
Chaitrashree G S44124192019-08-07 20:21:36 -0400707 // 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 +0530708 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400709 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530710 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400711 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400712 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
713 // all the modules initialized and ready to handle incoming ONUs.
714
Thomas Lee S985938d2020-05-04 11:40:41 +0530715 err = dh.initializeDeviceHandlerModules(ctx)
716 if err != nil {
717 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 -0400718 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400719
720 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800721 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530722 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400723 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800724 }
725 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700726
727 go startHeartbeatCheck(ctx, dh)
728
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400729 return nil
730 }
731
Neha Sharma8f4e4322020-08-06 10:51:53 +0000732 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400733 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400734 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400735 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400736 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400737 dh.populateActivePorts(ctx, ports)
738 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
739 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400740 }
741
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400742 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530743 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 -0400744 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530745
cuilin20187b2a8c32019-03-26 19:52:28 -0700746 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800747 go func() {
748 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400749 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800750 }
751 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000752 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000753
754 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000755 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000756 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700757
758 go startHeartbeatCheck(ctx, dh)
759
cuilin20187b2a8c32019-03-26 19:52:28 -0700760 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530761}
762
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400763func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000764 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400765
766 if err != nil {
767 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
768 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700769 dh.totalPonPorts = deviceInfo.GetPonPorts()
770
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400771 // Instantiate resource manager
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800772 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 -0400773 return olterrors.ErrResourceManagerInstantiating
774 }
775
Girish Gowdra9602eb42020-09-09 15:50:39 -0700776 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400777
Girish Gowdra9602eb42020-09-09 15:50:39 -0700778 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
779 for i := range dh.flowMgr {
780 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700781 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700782 return olterrors.ErrResourceManagerInstantiating
783 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400784 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700785
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400786 /* TODO: Instantiate Alarm , stats , BW managers */
787 /* Instantiating Event Manager to handle Alarms and KPIs */
788 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
789
790 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000791 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400792
793 return nil
794
795}
796
Neha Sharma96b7bf22020-06-15 10:37:32 +0000797func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400798 var err error
799 var deviceInfo *oop.DeviceInfo
800
Neha Sharma8f4e4322020-08-06 10:51:53 +0000801 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400802
803 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000804 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400805 }
806 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000807 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400808 }
809
Neha Sharma96b7bf22020-06-15 10:37:32 +0000810 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400811 dh.device.Root = true
812 dh.device.Vendor = deviceInfo.Vendor
813 dh.device.Model = deviceInfo.Model
814 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
815 dh.device.HardwareVersion = deviceInfo.HardwareVersion
816 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
817
818 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000819 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400820 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000821 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400822 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000823 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400824 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000825 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400826 dh.device.MacAddress = genmac
827 } else {
828 dh.device.MacAddress = deviceInfo.DeviceId
829 }
830
831 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000832 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000833 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400834 }
835
836 return deviceInfo, nil
837}
838
Neha Sharma96b7bf22020-06-15 10:37:32 +0000839func startCollector(ctx context.Context, dh *DeviceHandler) {
840 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530841 for {
842 select {
843 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000844 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530845 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000846 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700847
Neha Sharma8f4e4322020-08-06 10:51:53 +0000848 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400849 if err != nil {
850 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
851 continue
852 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530853 for _, port := range ports {
854 // NNI Stats
855 if port.Type == voltha.Port_ETHERNET_NNI {
856 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
857 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000858 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
859 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
860 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530861 }
862 // PON Stats
863 if port.Type == voltha.Port_PON_OLT {
864 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
865 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
866 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000867 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
868 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530869 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000870 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500871 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530872 }
873 }
874 }
875}
876
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700877//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530878func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400879 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000880 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530881 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530882
883 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400884 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
885 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530886 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530887}
888
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700889//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530890func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700891 return &ic.SwitchCapability{
892 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530893 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700894 HwDesc: "open_pon",
895 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700896 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700897 },
898 SwitchFeatures: &of.OfpSwitchFeatures{
899 NBuffers: 256,
900 NTables: 2,
901 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
902 of.OfpCapabilities_OFPC_TABLE_STATS |
903 of.OfpCapabilities_OFPC_PORT_STATS |
904 of.OfpCapabilities_OFPC_GROUP_STATS),
905 },
906 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530907}
908
Neha Sharma96b7bf22020-06-15 10:37:32 +0000909func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
910 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 -0700911 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700912 var deviceID string
913 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700914
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400915 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700916 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000917 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 -0700918 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
919 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400920
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700921 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530922
923 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
924
Neha Sharma96b7bf22020-06-15 10:37:32 +0000925 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 -0700926 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700927 kwargs := make(map[string]interface{})
928 kwargs["onu_id"] = omciInd.OnuId
929 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700930
Neha Sharma8f4e4322020-08-06 10:51:53 +0000931 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700932 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530933 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700934 "intf-id": omciInd.IntfId,
935 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700936 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700937 deviceType = onuDevice.Type
938 deviceID = onuDevice.Id
939 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
940 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530941 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700942 } else {
943 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000944 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 +0530945 deviceType = onuInCache.(*OnuDevice).deviceType
946 deviceID = onuInCache.(*OnuDevice).deviceID
947 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700948 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700949
950 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +0000951 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530952 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800953 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530954 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530955 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800956 "destination": deviceType,
957 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000958 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700959 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800960 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530961}
962
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700963//ProcessInterAdapterMessage sends the proxied messages to the target device
964// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
965// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000966func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
967 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700968 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700969 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700970 fromTopic := msg.Header.FromTopic
971 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700972 toDeviceID := msg.Header.ToDeviceId
973 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700974
Neha Sharma96b7bf22020-06-15 10:37:32 +0000975 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 -0700976
977 msgBody := msg.GetBody()
978
979 omciMsg := &ic.InterAdapterOmciMessage{}
980 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000981 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700982 }
983
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700984 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000985 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700986 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530987 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800988 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000989 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700990 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000991 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
992 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530993 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800994 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000995 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800996 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700997 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000998 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
999 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301000 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001001 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001002 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001003 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001004 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001005 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001006 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001007 }
1008 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301009}
1010
Neha Sharma96b7bf22020-06-15 10:37:32 +00001011func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001012 var intfID uint32
1013 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001014 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001015 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001016 intfID = onuDevice.ProxyAddress.GetChannelId()
1017 onuID = onuDevice.ProxyAddress.GetOnuId()
1018 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001019 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001020 intfID = omciMsg.GetProxyAddress().GetChannelId()
1021 onuID = omciMsg.GetProxyAddress().GetOnuId()
1022 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001023 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001024 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001025 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 -08001026
Thomas Lee S94109f12020-03-03 16:39:29 +05301027 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001028 "intf-id": intfID,
1029 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001030 }
1031
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001032 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1033 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001034 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001035 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1036 hex.Encode(hexPkt, omciMsg.Message)
1037 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1038
1039 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1040 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1041 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001042 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001043 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001044
Neha Sharma8f4e4322020-08-06 10:51:53 +00001045 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001046 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301047 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001048 "intf-id": intfID,
1049 "onu-id": onuID,
1050 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001051 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001052 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001053}
1054
David K. Bainbridge794735f2020-02-11 21:01:37 -08001055func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301056 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 -07001057 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001058 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001059 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001060 // TODO: need resource manager
1061 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301062 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301063 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001064 st, _ := status.FromError(err)
1065 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001066 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1067
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001068 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301069 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001070 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001071 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001072 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001073 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001074 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001075}
1076
David K. Bainbridge794735f2020-02-11 21:01:37 -08001077func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001078 channelID := onuDiscInd.GetIntfId()
1079 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001080
Neha Sharma96b7bf22020-06-15 10:37:32 +00001081 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301082
cuilin20187b2a8c32019-03-26 19:52:28 -07001083 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001084 if sn != "" {
1085 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001086 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001087 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001088 }
1089
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301090 var alarmInd oop.OnuAlarmIndication
1091 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001092 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301093
1094 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1095 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1096 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1097 OnuLosRaise event sent for it */
1098 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1099 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1100 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001101 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301102 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1103 "currentIntfId": onuDiscInd.GetIntfId()})
1104 // TODO:: Should we need to ignore raising OnuLosClear event
1105 // when onu connected to different PON?
1106 }
1107 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1108 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1109 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001110 go func() {
1111 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1112 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1113 }
1114 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301115 }
1116 return true
1117 })
1118
Neha Sharma96b7bf22020-06-15 10:37:32 +00001119 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001120 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001121 }
1122
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001123 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001124
1125 // check the ONU is already know to the OLT
1126 // NOTE the second time the ONU is discovered this should return a device
1127 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1128
1129 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001130 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 -08001131 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001132 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 -08001133 switch e.Code() {
1134 case codes.Internal:
1135 // this probably means NOT FOUND, so just create a new device
1136 onuDevice = nil
1137 case codes.DeadlineExceeded:
1138 // if the call times out, cleanup and exit
1139 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001140 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001141 }
1142 }
1143 }
1144
1145 if onuDevice == nil {
1146 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001147 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001148 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001149 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301150 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001151
Neha Sharma96b7bf22020-06-15 10:37:32 +00001152 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001153
1154 if err != nil {
1155 // if we can't create an ID in resource manager,
1156 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001157 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001158 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001159 "pon-intf-id": ponintfid,
1160 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001161 }
1162
Neha Sharma8f4e4322020-08-06 10:51:53 +00001163 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001164 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001165 dh.discOnus.Delete(sn)
1166 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 +05301167 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001168 "pon-intf-id": ponintfid,
1169 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001170 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001171 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1172 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1173 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001174 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301175 log.Fields{"onuDevice": onuDevice,
1176 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001177 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301178 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001179 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001180
1181 // we can now use the existing ONU Id
1182 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001183 //Insert the ONU into cache to use in OnuIndication.
1184 //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 +00001185 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001186 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301187 "intfId": onuDiscInd.GetIntfId(),
1188 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001189 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001190
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301191 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301192 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001193 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301194 log.Fields{"onu": onuDev,
1195 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001196
Kent Hagermane6ff1012020-07-14 15:07:53 -04001197 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301198 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001199 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001200 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001201 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001202 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001203 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301204 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001205 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001206 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001207 }
1208 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001209}
1210
Neha Sharma96b7bf22020-06-15 10:37:32 +00001211func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001212 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1213
1214 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001215 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001216 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001217 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001218 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001219 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301220 log.Fields{"onuId": onuInd.OnuId,
1221 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301222 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001223 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301224
David K. Bainbridge794735f2020-02-11 21:01:37 -08001225 errFields := log.Fields{"device-id": dh.device.Id}
1226
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301227 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1228
Mahir Gunyele77977b2019-06-27 05:36:22 -07001229 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1230 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001231 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001232 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001233 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001234 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1235 if serialNumber != "" {
1236 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001237 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001238 } else {
1239 kwargs["onu_id"] = onuInd.OnuId
1240 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001241 errFields["onu-id"] = onuInd.OnuId
1242 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001243 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001244 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001245 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001246
David K. Bainbridge794735f2020-02-11 21:01:37 -08001247 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001248 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001249 }
1250
David K. Bainbridge794735f2020-02-11 21:01:37 -08001251 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001252 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001253 "previousIntfId": onuDevice.ParentPortNo,
1254 "currentIntfId": ponPort})
1255 }
1256
1257 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001258 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301259 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1260 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301261 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001262 }
1263 if !foundInCache {
1264 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1265
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301266 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 -08001267
1268 }
kesavand7cf3a052020-08-28 12:49:18 +05301269 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1270 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1271 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1272 }
1273 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001274 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001275 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001276 }
1277 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001278}
1279
Neha Sharma96b7bf22020-06-15 10:37:32 +00001280func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001281 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 -07001282 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1283 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1284 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1285 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001286 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001287 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1288 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001289 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001290 onuInd.OperState = "down"
1291 }
1292 }
1293
David K. Bainbridge794735f2020-02-11 21:01:37 -08001294 switch onuInd.OperState {
1295 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001296 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 -07001297 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301298 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001299 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1300 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301301 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001302 "onu-indicator": onuInd,
1303 "source": "openolt",
1304 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001305 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001306 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001307 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001308 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 -04001309 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301310 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001311 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1312 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301313 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001314 "onu-indicator": onuInd,
1315 "source": "openolt",
1316 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001317 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001318 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001319 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001320 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001321 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001322 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001323}
1324
cuilin20187b2a8c32019-03-26 19:52:28 -07001325func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1326 if serialNum != nil {
1327 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001328 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001329 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001330}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001331func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1332 decodedStr, err := hex.DecodeString(serialNum[4:])
1333 if err != nil {
1334 return nil, err
1335 }
1336 return &oop.SerialNumber{
1337 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001338 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001339 }, nil
1340}
cuilin20187b2a8c32019-03-26 19:52:28 -07001341
1342func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1343 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001344 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001345 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1346 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1347 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1348 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1349 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1350 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1351 return tmp
1352}
1353
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001354//UpdateFlowsBulk upates the bulk flow
1355func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301356 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001357}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001358
1359//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001360func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1361 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301362 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001363 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301364 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001365 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001366 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001367 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001368 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001369 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001370 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001371 "intf-id": parentPort,
1372 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001373 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001374 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 -08001375 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301376}
1377
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001378// SendPacketInToCore sends packet-in to core
1379// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1380// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001381func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001382 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001383 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001384 "port": logicalPort,
1385 "packet": hex.EncodeToString(packetPayload),
1386 "device-id": dh.device.Id,
1387 })
1388 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001389 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 +05301390 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001391 "source": "adapter",
1392 "destination": "core",
1393 "device-id": dh.device.Id,
1394 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001395 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001396 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001397 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001398 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001399 "packet": hex.EncodeToString(packetPayload),
1400 "device-id": dh.device.Id,
1401 })
1402 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001403 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001404}
1405
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001406// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001407func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001408 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001409
1410 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1411 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001412 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001413 }
1414
Kent Hagermane6ff1012020-07-14 15:07:53 -04001415 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001416 metrics := dh.metrics.GetSubscriberMetrics()
1417 for _, m := range pmConfigs.Metrics {
1418 metrics[m.Name].Enabled = m.Enabled
1419
1420 }
1421 }
1422}
1423
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001424//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301425func (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 +00001426 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 +01001427
1428 var errorsList []error
1429
Girish Gowdru0c588b22019-04-23 23:24:56 -04001430 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001431 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001432 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001433
Neha Sharma96b7bf22020-06-15 10:37:32 +00001434 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301435 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001436 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301437 "flowToRemove": flow})
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001438 err := dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
Girish Gowdracefae192020-03-19 18:14:10 -07001439 if err != nil {
1440 errorsList = append(errorsList, err)
1441 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001442 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301443
1444 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001445 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001446 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301447 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001448 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301449 "flowToAdd": flow})
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001450 err := dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001451 if err != nil {
1452 errorsList = append(errorsList, err)
1453 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301454 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001455 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001456
Girish Gowdracefae192020-03-19 18:14:10 -07001457 // 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 +00001458 if groups != nil {
1459 for _, group := range groups.ToAdd.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001460 err := dh.groupMgr.AddGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001461 if err != nil {
1462 errorsList = append(errorsList, err)
1463 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001464 }
1465 for _, group := range groups.ToUpdate.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001466 err := dh.groupMgr.ModifyGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001467 if err != nil {
1468 errorsList = append(errorsList, err)
1469 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001470 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001471 for _, group := range groups.ToRemove.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001472 err := dh.groupMgr.DeleteGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001473 if err != nil {
1474 errorsList = append(errorsList, err)
1475 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001476 }
1477 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001478 if len(errorsList) > 0 {
1479 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1480 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001481 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001482 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301483}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001484
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001485//DisableDevice disables the given device
1486//It marks the following for the given device:
1487//Device-Handler Admin-State : down
1488//Device Port-State: UNKNOWN
1489//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001490func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001491 /* On device disable ,admin state update has to be done prior sending request to agent since
1492 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001493 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001494 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001495 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001496 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001497 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001498 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001499 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001500 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001501 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001502 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301503
1504 dh.discOnus = sync.Map{}
1505 dh.onus = sync.Map{}
1506
Thomas Lee S85f37312020-04-03 17:06:12 +05301507 //stopping the stats collector
1508 dh.stopCollector <- true
1509
Neha Sharma96b7bf22020-06-15 10:37:32 +00001510 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001511 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301512 //Update device Admin state
1513 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001514 // 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 +00001515 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 -04001516 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001517 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001518 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001519 return nil
1520}
1521
Neha Sharma96b7bf22020-06-15 10:37:32 +00001522func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001523 // Update onu state as unreachable in onu adapter
1524 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301525 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001526 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001527 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001528 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001529 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 -04001530 }
1531 if onuDevices != nil {
1532 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001533 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001534 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1535 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001536 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301537 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001538 }
1539
1540 }
1541 }
1542
1543}
1544
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001545//ReenableDevice re-enables the olt device after disable
1546//It marks the following for the given device:
1547//Device-Handler Admin-State : up
1548//Device Port-State: ACTIVE
1549//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001550func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001551 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301552 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001553 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301554 }
1555 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001556 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001557
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001558 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001559
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001560 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1561 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001562 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001563 }
1564 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001565 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001566 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001567 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001568 device.OperStatus = voltha.OperStatus_ACTIVE
1569 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001570
Neha Sharma8f4e4322020-08-06 10:51:53 +00001571 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 +05301572 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001573 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001574 "connect-status": device.ConnectStatus,
1575 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001576 }
kesavand39e0aa32020-01-28 20:58:50 -05001577
Neha Sharma96b7bf22020-06-15 10:37:32 +00001578 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001579
1580 return nil
1581}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001582
npujarec5762e2020-01-01 14:08:48 +05301583func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001584 var uniID uint32
1585 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301586 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001587 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001588 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001589 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001590 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001591 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001592 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301594 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001595 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301596 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", 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-upstream", 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-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301600 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001601 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001602 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001603 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301604 }
npujarec5762e2020-01-01 14:08:48 +05301605 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1606 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301608 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001609 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001610 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001611 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 +00001612 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001613 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1614 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1615 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001616 }
1617 return nil
1618}
1619
npujarec5762e2020-01-01 14:08:48 +05301620func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001621 nniUniID := -1
1622 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301623
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001624 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301625 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001626 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001627 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301628 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301629 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001630 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001631 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001632 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301633 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301634 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001635 _ = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, nniIntfID, -1, -1)
1636
Devmalya Paul495b94a2019-08-27 19:42:00 -04001637 }
npujarec5762e2020-01-01 14:08:48 +05301638 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001639 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301640 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001641
David K. Bainbridge794735f2020-02-11 21:01:37 -08001642 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001643}
1644
1645// 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 +05301646func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001647 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001648 /* Clear the KV store data associated with the all the UNI ports
1649 This clears up flow data and also resource map data for various
1650 other pon resources like alloc_id and gemport_id
1651 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001652 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001653 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001654 // Stop the Stats collector
1655 dh.stopCollector <- true
1656 // stop the heartbeat check routine
1657 dh.stopHeartbeatCheck <- true
1658 //Reset the state
1659 if dh.Client != nil {
1660 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301661 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001662 }
1663 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001664 // There is no need to update the core about operation status and connection status of the OLT.
1665 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1666 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1667 // because the device does not exist in DB.
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001668 return nil
1669}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001670func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001671
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001672 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301673 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001674 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301675 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301676 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301677 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001678 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001679 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001680 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301681 }
1682 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301683 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001684 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301685 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001686 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301687 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301688 // Clear flowids for gem cache.
1689 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301690 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301691 }
1692 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301693 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301694 }
npujarec5762e2020-01-01 14:08:48 +05301695 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301696 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301697 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301698 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001699 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001700 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001701 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001702 /* Clear the flows from KV store associated with NNI port.
1703 There are mostly trap rules from NNI port (like LLDP)
1704 */
npujarec5762e2020-01-01 14:08:48 +05301705 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001706 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001707 }
A R Karthick1f85b802019-10-11 05:06:05 +00001708
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001709 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001710 go func() {
1711 if err := dh.resourceMgr.Delete(ctx); err != nil {
1712 logger.Debug(ctx, err)
1713 }
1714 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001715 }
A R Karthick1f85b802019-10-11 05:06:05 +00001716
Devmalya Paul495b94a2019-08-27 19:42:00 -04001717 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301718 dh.onus.Range(func(key interface{}, value interface{}) bool {
1719 dh.onus.Delete(key)
1720 return true
1721 })
1722
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001723 /*Delete discovered ONU map for the device*/
1724 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1725 dh.discOnus.Delete(key)
1726 return true
1727 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001728}
1729
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001730//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001731func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001732 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301733 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001734 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001735 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001736 return nil
1737}
1738
David K. Bainbridge794735f2020-02-11 21:01:37 -08001739func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001740 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001741 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001742 "packet-indication": *packetIn,
1743 "device-id": dh.device.Id,
1744 "packet": hex.EncodeToString(packetIn.Pkt),
1745 })
1746 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001747 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001748 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001749 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001750 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001751 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001752 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001753 "logical-port-num": logicalPortNum,
1754 "device-id": dh.device.Id,
1755 "packet": hex.EncodeToString(packetIn.Pkt),
1756 })
1757 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001758
Neha Sharma8f4e4322020-08-06 10:51:53 +00001759 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 +05301760 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001761 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301762 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001763 "device-id": dh.device.Id,
1764 "packet": hex.EncodeToString(packetIn.Pkt),
1765 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001766 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001767
Matteo Scandolo92186242020-06-12 10:54:18 -07001768 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001769 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001770 "packet": hex.EncodeToString(packetIn.Pkt),
1771 "device-id": dh.device.Id,
1772 })
1773 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001774 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001775}
1776
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001777// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301778func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001779 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001780 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001781 "device-id": dh.device.Id,
1782 "egress-port-no": egressPortNo,
1783 "pkt-length": len(packet.Data),
1784 "packet": hex.EncodeToString(packet.Data),
1785 })
1786 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001787
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001788 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001789 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001790 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1791 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301792 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1793 // Do not packet-out lldp packets on uni port.
1794 // ONOS has no clue about uni/nni ports, it just packets out on all
1795 // available ports on the Logical Switch. It should not be interested
1796 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001797 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001798 "device-id": dh.device.Id,
1799 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301800 return nil
1801 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001802 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1803 if innerEthType == 0x8100 {
1804 // q-in-q 802.1ad or 802.1q double tagged packet.
1805 // slice out the outer tag.
1806 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001807 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001808 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001809 "packet-data": hex.EncodeToString(packet.Data),
1810 "device-id": dh.device.Id,
1811 })
1812 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001813 }
1814 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001815 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1816 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001817 uniID := UniIDFromPortNum(uint32(egressPortNo))
1818
Girish Gowdra9602eb42020-09-09 15:50:39 -07001819 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001820 if err != nil {
1821 // In this case the openolt agent will receive the gemPortID as 0.
1822 // The agent tries to retrieve the gemPortID in this case.
1823 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001824 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001825 "intf-id": intfID,
1826 "onu-id": onuID,
1827 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001828 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301829 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001830 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001831 }
1832
1833 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001834 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001835 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001836 "egress-port-no": egressPortNo,
1837 "intf-id": intfID,
1838 "onu-id": onuID,
1839 "uni-id": uniID,
1840 "gem-port-id": gemPortID,
1841 "packet": hex.EncodeToString(packet.Data),
1842 "device-id": dh.device.Id,
1843 })
1844 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001845
npujarec5762e2020-01-01 14:08:48 +05301846 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301847 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001848 "source": "adapter",
1849 "destination": "onu",
1850 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001851 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001852 "oni-id": onuID,
1853 "uni-id": uniID,
1854 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001855 "packet": hex.EncodeToString(packet.Data),
1856 "device-id": dh.device.Id,
1857 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001858 }
1859 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001860 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001861 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001862 return olterrors.NewErrInvalidValue(log.Fields{
1863 "egress-nni-port": egressPortNo,
1864 "device-id": dh.device.Id,
1865 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001866 }
1867 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001868
Matteo Scandolo92186242020-06-12 10:54:18 -07001869 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001870 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001871 "uplink-pkt": uplinkPkt,
1872 "packet": hex.EncodeToString(packet.Data),
1873 "device-id": dh.device.Id,
1874 })
1875 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001876
npujarec5762e2020-01-01 14:08:48 +05301877 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001878 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1879 "packet": hex.EncodeToString(packet.Data),
1880 "device-id": dh.device.Id,
1881 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001882 }
1883 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001884 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301885 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001886 "egressPortType": egressPortType,
1887 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301888 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001889 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001890 }
1891 return nil
1892}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001893
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001894func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1895 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001896}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301897
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001898func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001899
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301900 // start the heartbeat check towards the OLT.
1901 var timerCheck *time.Timer
1902
1903 for {
1904 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1905 select {
1906 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001907 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001908 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001909 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301910 if timerCheck == nil {
1911 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001912 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301913 }
1914 } else {
1915 if timerCheck != nil {
1916 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001917 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301918 }
1919 timerCheck = nil
1920 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001921 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301922 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301923 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301924 }
1925 cancel()
1926 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001927 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301928 return
1929 }
1930 }
1931}
1932
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001933func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1934 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1935 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07001936 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
1937 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
1938 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
1939 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
1940 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04001941 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07001942 // Immediately return, otherwise accessing a null 'device' struct would cause panic
1943 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001944 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301945
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001946 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1947 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001948 _ = 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 -04001949 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001950 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001951 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001952 }
1953 go dh.cleanupDeviceResources(ctx)
1954
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001955 dh.lockDevice.RLock()
1956 // Stop the read indication only if it the routine is active
1957 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1958 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1959 // on next execution of the readIndication routine.
1960 if dh.isReadIndicationRoutineActive {
1961 dh.stopIndications <- true
1962 }
1963 dh.lockDevice.RUnlock()
1964
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001965 dh.transitionMap.Handle(ctx, DeviceInit)
1966
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301967 }
1968}
kesavand39e0aa32020-01-28 20:58:50 -05001969
1970// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001971func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1972 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1973 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001974}
1975
1976// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001977func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1978 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1979 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001980}
1981
kdarapu1afeceb2020-02-12 01:38:09 -05001982//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 +00001983func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1984 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001985 if port.GetType() == voltha.Port_ETHERNET_NNI {
1986 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001987 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301988 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301989 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001990 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001991 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001992 }
1993 // fetch interfaceid from PortNo
1994 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1995 ponIntf := &oop.Interface{IntfId: ponID}
1996 var operStatus voltha.OperStatus_Types
1997 if enablePort {
1998 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301999 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002000
2001 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302002 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002003 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002004 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002005 }
2006 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002007 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002008 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002009 } else {
2010 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302011 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002012 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302013 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002014 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002015 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002016 }
2017 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002018 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002019 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002020 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302021 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 +05302022 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302023 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002024 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002025 }
2026 return nil
2027}
2028
kdarapu1afeceb2020-02-12 01:38:09 -05002029//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002030func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002031 // Disable the port and update the oper_port_status to core
2032 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002033 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002034 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002035 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302036 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302037 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002038 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002039 }
2040 }
2041 }
2042 return nil
2043}
2044
2045//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002046func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2047 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2048 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002049 if port.Type == voltha.Port_ETHERNET_NNI {
2050 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002051 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002052 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002053 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002054 }
2055 }
2056 if port.Type == voltha.Port_PON_OLT {
2057 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002058 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002059 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002060 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002061 }
2062 }
2063 }
2064}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002065
2066// ChildDeviceLost deletes ONU and clears pon resources related to it.
2067func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
divyadesai3af43e12020-08-18 07:10:54 +00002068 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002069 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2070 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002071 onuDevice, ok := dh.onus.Load(onuKey)
2072 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302073 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002074 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002075 "device-id": dh.device.Id,
2076 "onu-id": onuID,
2077 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002078 }
2079 var sn *oop.SerialNumber
2080 var err error
2081 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302082 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002083 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302084 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002085 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2086 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002087
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002088 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Neha Sharma8f4e4322020-08-06 10:51:53 +00002089 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302090 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302091 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002092 "onu-id": onuID}, err).Log()
2093 }
2094 //clear PON resources associated with ONU
2095 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002096 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002097 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002098 "device-id": dh.device.Id,
2099 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002100 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002101 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002102 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002103 "device-id": dh.device.Id,
2104 "intf-id": intfID,
2105 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002106 } else {
2107 for i, onu := range onuGemData {
2108 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002109 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002110 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002111 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302112 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002113 "onu-device": onu,
2114 "error": err})
2115 }
2116 // Clear flowids for gem cache.
2117 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002118 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002119 }
2120 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002121 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002122 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002123 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002124 "intf-id": intfID,
2125 "onu-device": onu,
2126 "onu-gem": onuGemData,
2127 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002128 //Not returning error on cleanup.
2129 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002130 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002131 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002132 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002133 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002134 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002135 }
2136 }
2137 dh.onus.Delete(onuKey)
2138 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2139 return nil
2140}
Girish Gowdracefae192020-03-19 18:14:10 -07002141
2142func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2143 for _, field := range flows.GetOfbFields(flow) {
2144 if field.Type == flows.IN_PORT {
2145 return field.GetPort()
2146 }
2147 }
2148 return InvalidPort
2149}
2150
2151func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2152 for _, action := range flows.GetActions(flow) {
2153 if action.Type == flows.OUTPUT {
2154 if out := action.GetOutput(); out != nil {
2155 return out.GetPort()
2156 }
2157 }
2158 }
2159 return InvalidPort
2160}
2161
Girish Gowdracefae192020-03-19 18:14:10 -07002162func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2163 inPort := getInPortFromFlow(flow)
2164 outPort := getOutPortFromFlow(flow)
2165
2166 if inPort == InvalidPort || outPort == InvalidPort {
2167 return inPort, outPort
2168 }
2169
2170 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2171 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2172 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2173 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2174 return uniPort, outPort
2175 }
2176 }
2177 } else {
2178 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2179 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2180 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2181 return inPort, uniPort
2182 }
2183 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2184 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2185 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2186 return uniPort, outPort
2187 }
2188 }
2189 }
2190
2191 return InvalidPort, InvalidPort
2192}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002193
2194func extractOmciTransactionID(omciPkt []byte) uint16 {
2195 if len(omciPkt) > 3 {
2196 d := omciPkt[0:2]
2197 transid := binary.BigEndian.Uint16(d)
2198 return transid
2199 }
2200 return 0
2201}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002202
2203// StoreOnuDevice stores the onu parameters to the local cache.
2204func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2205 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2206 dh.onus.Store(onuKey, onuDevice)
2207}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002208
Neha Sharma8f4e4322020-08-06 10:51:53 +00002209func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002210 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002211 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002212 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002213 resp := new(voltha.ReturnValues)
2214 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002215 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002216 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002217 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2218 return nil, err
2219 }
2220 ID = device.ProxyAddress.GetOnuId()
2221 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2222 valueparam.Onu = &Onu
2223 valueparam.Value = value
2224
2225 // This API is unsupported until agent patch is added
2226 resp.Unsupported = uint32(value)
2227 _ = ctx
2228
2229 // Uncomment this code once agent changes are complete and tests
2230 /*
2231 resp, err = dh.Client.GetValue(ctx, valueparam)
2232 if err != nil {
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002233 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002234 return nil, err
2235 }
2236 */
2237
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002238 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 -08002239 return resp, nil
2240}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002241
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002242func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002243 // Default to PON0
2244 var intfID uint32
2245 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002246 if inPort != InvalidPort && outPort != InvalidPort {
2247 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2248 }
2249 return intfID
2250}