blob: 413e490451a467f1845afd9d7410dbbf7b5b2f95 [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
Mahir Gunyel2fb81472020-12-16 23:18:34 -080089 totalPonPorts uint32
90 perOnuChannel map[string]onuIndicationChannels
91 perOnuChannelLock sync.Mutex
Mahir Gunyela3f9add2019-06-06 15:13:19 -070092}
93
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070094//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -070095type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070096 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -070097 deviceType string
98 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070099 onuID uint32
100 intfID uint32
101 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530102 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400103 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700104}
105
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800106type perOnuIndication struct {
107 ctx context.Context
108 indication *oop.Indication
109 serialNumber string
110}
111
112type onuIndicationChannels struct {
113 indicationChannel chan perOnuIndication
114 stopChannel chan struct{}
115}
116
Naga Manjunath7615e552019-10-11 22:35:47 +0530117var pmNames = []string{
118 "rx_bytes",
119 "rx_packets",
120 "rx_mcast_packets",
121 "rx_bcast_packets",
122 "tx_bytes",
123 "tx_packets",
124 "tx_mcast_packets",
125 "tx_bcast_packets",
126}
127
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700128//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530129func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700130 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700131 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700132 device.deviceType = deviceTp
133 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700134 device.onuID = onuID
135 device.intfID = intfID
136 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530137 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700138 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530139}
140
141//NewDeviceHandler creates a new device handler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800142func 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 -0700143 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800144 dh.cm = cm
cuilin20187b2a8c32019-03-26 19:52:28 -0700145 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400146 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400147 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700148 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700149 dh.device = cloned
150 dh.openOLT = adapter
151 dh.exitChannel = make(chan int, 1)
152 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530153 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530154 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530155 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 -0500156 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400157 dh.stopIndications = make(chan bool, 1)
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800158 dh.perOnuChannel = make(map[string]onuIndicationChannels)
cuilin20187b2a8c32019-03-26 19:52:28 -0700159 //TODO initialize the support classes.
160 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530161}
162
163// start save the device to the data model
164func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700165 dh.lockDevice.Lock()
166 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000167 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700168 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000169 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530170}
171
172// stop stops the device dh. Not much to do for now
173func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700174 dh.lockDevice.Lock()
175 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000176 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700177 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000178 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530179}
180
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400181func macifyIP(ip net.IP) string {
182 if len(ip) > 0 {
183 oct1 := strconv.FormatInt(int64(ip[12]), 16)
184 oct2 := strconv.FormatInt(int64(ip[13]), 16)
185 oct3 := strconv.FormatInt(int64(ip[14]), 16)
186 oct4 := strconv.FormatInt(int64(ip[15]), 16)
187 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
188 }
189 return ""
190}
191
Neha Sharma96b7bf22020-06-15 10:37:32 +0000192func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400193 var genmac string
194 var addr net.IP
195 var ips []string
196 var err error
197
Neha Sharma96b7bf22020-06-15 10:37:32 +0000198 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400199
200 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000201 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400202
203 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000204 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400205 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000206 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400207 }
208 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000209 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530210 log.Fields{"host": ips[0],
211 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400212 return genmac, nil
213 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000214 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400215 }
216
217 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000218 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530219 log.Fields{"host": host,
220 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400221 return genmac, nil
222}
223
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530224func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700225 slist := strings.Split(mac, ":")
226 result := make([]uint32, len(slist))
227 var err error
228 var tmp int64
229 for index, val := range slist {
230 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
231 return []uint32{1, 2, 3, 4, 5, 6}
232 }
233 result[index] = uint32(tmp)
234 }
235 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530236}
237
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700238//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 -0800239func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530240
David K. Bainbridge794735f2020-02-11 21:01:37 -0800241 switch portType {
242 case voltha.Port_ETHERNET_NNI:
243 return fmt.Sprintf("nni-%d", portNum), nil
244 case voltha.Port_PON_OLT:
245 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700246 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800247
Girish Kumarf26e4882020-03-05 06:49:10 +0000248 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530249}
250
Neha Sharma96b7bf22020-06-15 10:37:32 +0000251func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000252 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700253 if state == "up" {
254 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500255 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500256 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700257 } else {
258 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500259 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700260 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700261 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400262 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800263 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000264 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400265 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500266
Neha Sharma8f4e4322020-08-06 10:51:53 +0000267 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 +0000268 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000269 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 -0400270 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
271 "device-id": dh.device.Id,
272 "port-type": portType,
273 "port-number": portNum,
274 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500275 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400276 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500277 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400278 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700279 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400280 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700281 PortNo: portNum,
282 Label: label,
283 Type: portType,
284 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700285 OfpPort: &of.OfpPort{
286 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
287 Config: 0,
288 State: uint32(of.OfpPortState_OFPPS_LIVE),
289 Curr: capacity,
290 Advertised: capacity,
291 Peer: capacity,
292 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
293 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
294 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700295 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000296 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700297 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000298 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000299 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800300 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000301 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400302 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000303 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530304 return nil
305}
306
Kent Hagermane6ff1012020-07-14 15:07:53 -0400307func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530308 dh.lockDevice.Lock()
309 defer dh.lockDevice.Unlock()
Neha Sharma8f4e4322020-08-06 10:51:53 +0000310 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530311 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400312 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
313 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530314 }
315 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530316}
317
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700318// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530319// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800320func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000321 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700322 defer func() {
323 dh.lockDevice.Lock()
324 dh.isReadIndicationRoutineActive = false
325 dh.lockDevice.Unlock()
326 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700327 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700328 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700329 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700330 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400331 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530332 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400333 if err != nil || device == nil {
334 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000335 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400336 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400337
David Bainbridgef5879ca2019-12-13 21:17:54 +0000338 // Create an exponential backoff around re-enabling indications. The
339 // maximum elapsed time for the back off is set to 0 so that we will
340 // continue to retry. The max interval defaults to 1m, but is set
341 // here for code clarity
342 indicationBackoff := backoff.NewExponentialBackOff()
343 indicationBackoff.MaxElapsedTime = 0
344 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700345
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700346 dh.lockDevice.Lock()
347 dh.isReadIndicationRoutineActive = true
348 dh.lockDevice.Unlock()
349
Girish Gowdra3f974912020-03-23 20:35:18 -0700350Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700351 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400352 select {
353 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000354 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700355 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400356 default:
357 indication, err := indications.Recv()
358 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000359 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530360 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530361 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400362 // Use an exponential back off to prevent getting into a tight loop
363 duration := indicationBackoff.NextBackOff()
364 if duration == backoff.Stop {
365 // If we reach a maximum then warn and reset the backoff
366 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000367 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530368 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530369 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400370 indicationBackoff.Reset()
371 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700372
373 // On failure process a backoff timer while watching for stopIndications
374 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700375 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700376 select {
377 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000378 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700379 if !backoffTimer.Stop() {
380 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700381 }
382 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700383 case <-backoffTimer.C:
384 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700385 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700386 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
387 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400388 }
389 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000390 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530391 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000392 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530393 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530394 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700395 // Close the stream, and re-initialize it
396 if err = indications.CloseSend(); err != nil {
397 // Ok to ignore here, because we landed here due to a problem on the stream
398 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000399 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530400 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530401 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700402 }
403 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
404 return err
405 }
406 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400407 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530408 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400409 // Reset backoff if we have a successful receive
410 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400411 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530412 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000413 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530414 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530415 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400416 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400417 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400418 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700419 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700420 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700421 // Close the send stream
422 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700423
Girish Gowdra3f974912020-03-23 20:35:18 -0700424 return nil
425}
426
427func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
428
429 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
430 if err != nil {
431 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
432 }
433 if indications == nil {
434 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
435 }
436
437 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400438}
439
440// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
441func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
442 switch indication.Data.(type) {
443 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
444 return true
445
446 default:
447 return false
448 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700449}
450
David K. Bainbridge794735f2020-02-11 21:01:37 -0800451func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000452 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000453 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530454 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700455 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530456 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700457 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000458 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000459 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530460 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000461 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800462 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000463 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800464 }
465 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700466}
467
David K. Bainbridge794735f2020-02-11 21:01:37 -0800468// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530469func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400470 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700471 switch indication.Data.(type) {
472 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000473 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
474 defer span.Finish()
475
David K. Bainbridge794735f2020-02-11 21:01:37 -0800476 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400477 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800478 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700479 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000480 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
481 defer span.Finish()
482
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700483 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800484 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000485 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400486 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800487 }
488 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000489 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700490 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000491 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
492 defer span.Finish()
493
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700494 intfOperInd := indication.GetIntfOperInd()
495 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800496 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000497 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400498 _ = 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 -0800499 }
500 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400501 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
502 logger.Warn(ctx, err)
503 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700504 } else if intfOperInd.GetType() == "pon" {
505 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
506 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800507 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000508 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400509 _ = 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 -0800510 }
511 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000512 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700513 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000514 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530515 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530516 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700517 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000518 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
519 defer span.Finish()
520
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700521 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700523 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800524 //put message to channel and return immediately
525 dh.putOnuIndicationToChannel(ctx, indication, sn)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700526 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000527 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
528 defer span.Finish()
529
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700530 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000531 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800532 sn := dh.stringifySerialNumber(onuInd.SerialNumber)
533 //put message to channel and return immediately
534 dh.putOnuIndicationToChannel(ctx, indication, sn)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700535 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000536 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
537 defer span.Finish()
538
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700539 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000540 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 -0800541 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000542 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400543 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800544 }
545 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700546 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000547 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
548 defer span.Finish()
549
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700550 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000551 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700552 "intf-type": pktInd.IntfId,
553 "intf-id": pktInd.IntfId,
554 "gem-port-id": pktInd.GemportId,
555 "port-no": pktInd.PortNo,
556 "device-id": dh.device.Id,
557 })
558
559 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000560 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700561 "intf-type": pktInd.IntfId,
562 "intf-id": pktInd.IntfId,
563 "gem-port-id": pktInd.GemportId,
564 "port-no": pktInd.PortNo,
565 "packet": hex.EncodeToString(pktInd.Pkt),
566 "device-id": dh.device.Id,
567 })
568 }
569
David K. Bainbridge794735f2020-02-11 21:01:37 -0800570 go func() {
571 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400572 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800573 }
574 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700575 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000576 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
577 defer span.Finish()
578
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700579 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700580 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700581 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000582 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
583 defer span.Finish()
584
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700585 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000586 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700587 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000588 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
589 defer span.Finish()
590
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700591 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000592 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
593 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700594 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530595}
596
597// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530598func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530599 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000600 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530601
Girish Gowdru0c588b22019-04-23 23:24:56 -0400602 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530603 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400604 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000605 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400606 }
607 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530608}
609
610// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530611func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700612 dh.lockDevice.Lock()
613 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000614 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400615
npujarec5762e2020-01-01 14:08:48 +0530616 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400617 if err != nil || device == nil {
618 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000619 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400620 }
621
622 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400623
624 //Update the device oper state and connection status
625 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400626 dh.device = cloned
627
David K. Bainbridge794735f2020-02-11 21:01:37 -0800628 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000629 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400630 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400631
632 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530633 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400634 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000635 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400636 }
637 for _, onuDevice := range onuDevices.Items {
638
639 // Update onu state as down in onu adapter
640 onuInd := oop.OnuIndication{}
641 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800642 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300643 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800644 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400645 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300646 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800647 "onu-indicator": onuInd,
648 "device-type": onuDevice.Type,
649 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700650 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700651 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400652 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700653 /* Discovered ONUs entries need to be cleared , since after OLT
654 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530655 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000656 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700657 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530658}
659
660// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530661func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400662 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000663 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
664 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
665 grpc.WithInsecure(),
666 grpc.WithBlock(),
667 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000668 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000669 )),
670 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000671 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000672 )))
673
674 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530675 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530676 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000677 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400678 }
679 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530680}
681
682// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530683func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400684 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530685 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400686 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530687}
688
689// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530690func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530691 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000692 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400693
694 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530695 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
696 if err != nil || device == nil {
697 /*TODO: needs to handle error scenarios */
698 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
699 }
700 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000701 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400702
703 cloned := proto.Clone(device).(*voltha.Device)
704 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
705 cloned.OperStatus = voltha.OperStatus_UNKNOWN
706 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530707 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
708 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 -0400709 }
710
Chaitrashree G S44124192019-08-07 20:21:36 -0400711 // 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 +0530712 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400713 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530714 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400715 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400716 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
717 // all the modules initialized and ready to handle incoming ONUs.
718
Thomas Lee S985938d2020-05-04 11:40:41 +0530719 err = dh.initializeDeviceHandlerModules(ctx)
720 if err != nil {
721 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 -0400722 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400723
724 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800725 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530726 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400727 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800728 }
729 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700730
731 go startHeartbeatCheck(ctx, dh)
732
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400733 return nil
734 }
735
Neha Sharma8f4e4322020-08-06 10:51:53 +0000736 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400737 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400738 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400739 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400740 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400741 dh.populateActivePorts(ctx, ports)
742 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
743 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400744 }
745
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400746 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530747 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 -0400748 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530749
cuilin20187b2a8c32019-03-26 19:52:28 -0700750 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800751 go func() {
752 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400753 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800754 }
755 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000756 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000757
758 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000759 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000760 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700761
762 go startHeartbeatCheck(ctx, dh)
763
cuilin20187b2a8c32019-03-26 19:52:28 -0700764 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530765}
766
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400767func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000768 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400769
770 if err != nil {
771 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
772 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700773 dh.totalPonPorts = deviceInfo.GetPonPorts()
774
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400775 // Instantiate resource manager
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800776 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 -0400777 return olterrors.ErrResourceManagerInstantiating
778 }
779
Girish Gowdra9602eb42020-09-09 15:50:39 -0700780 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400781
Girish Gowdra9602eb42020-09-09 15:50:39 -0700782 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
783 for i := range dh.flowMgr {
784 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700785 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700786 return olterrors.ErrResourceManagerInstantiating
787 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400788 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700789
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400790 /* TODO: Instantiate Alarm , stats , BW managers */
791 /* Instantiating Event Manager to handle Alarms and KPIs */
792 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
793
794 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000795 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400796
797 return nil
798
799}
800
Neha Sharma96b7bf22020-06-15 10:37:32 +0000801func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400802 var err error
803 var deviceInfo *oop.DeviceInfo
804
Neha Sharma8f4e4322020-08-06 10:51:53 +0000805 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400806
807 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000808 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400809 }
810 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000811 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400812 }
813
Neha Sharma96b7bf22020-06-15 10:37:32 +0000814 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400815 dh.device.Root = true
816 dh.device.Vendor = deviceInfo.Vendor
817 dh.device.Model = deviceInfo.Model
818 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
819 dh.device.HardwareVersion = deviceInfo.HardwareVersion
820 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
821
822 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000823 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400824 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000825 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400826 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000827 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400828 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000829 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400830 dh.device.MacAddress = genmac
831 } else {
832 dh.device.MacAddress = deviceInfo.DeviceId
833 }
834
835 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000836 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000837 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400838 }
839
840 return deviceInfo, nil
841}
842
Neha Sharma96b7bf22020-06-15 10:37:32 +0000843func startCollector(ctx context.Context, dh *DeviceHandler) {
844 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530845 for {
846 select {
847 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000848 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530849 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000850 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700851
Neha Sharma8f4e4322020-08-06 10:51:53 +0000852 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400853 if err != nil {
854 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
855 continue
856 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530857 for _, port := range ports {
858 // NNI Stats
859 if port.Type == voltha.Port_ETHERNET_NNI {
860 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
861 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000862 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
863 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
864 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530865 }
866 // PON Stats
867 if port.Type == voltha.Port_PON_OLT {
868 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
869 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
870 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000871 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
872 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530873 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000874 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500875 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530876 }
877 }
878 }
879}
880
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700881//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530882func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400883 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000884 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530885 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530886
887 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400888 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
889 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530890 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530891}
892
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700893//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530894func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700895 return &ic.SwitchCapability{
896 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530897 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700898 HwDesc: "open_pon",
899 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700900 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700901 },
902 SwitchFeatures: &of.OfpSwitchFeatures{
903 NBuffers: 256,
904 NTables: 2,
905 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
906 of.OfpCapabilities_OFPC_TABLE_STATS |
907 of.OfpCapabilities_OFPC_PORT_STATS |
908 of.OfpCapabilities_OFPC_GROUP_STATS),
909 },
910 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530911}
912
Neha Sharma96b7bf22020-06-15 10:37:32 +0000913func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
914 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 -0700915 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700916 var deviceID string
917 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700918
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400919 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700920 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000921 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 -0700922 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
923 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400924
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700925 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530926
927 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
928
Neha Sharma96b7bf22020-06-15 10:37:32 +0000929 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 -0700930 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700931 kwargs := make(map[string]interface{})
932 kwargs["onu_id"] = omciInd.OnuId
933 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700934
Neha Sharma8f4e4322020-08-06 10:51:53 +0000935 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700936 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530937 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700938 "intf-id": omciInd.IntfId,
939 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700940 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700941 deviceType = onuDevice.Type
942 deviceID = onuDevice.Id
943 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
944 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530945 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700946 } else {
947 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000948 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 +0530949 deviceType = onuInCache.(*OnuDevice).deviceType
950 deviceID = onuInCache.(*OnuDevice).deviceID
951 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700952 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700953
954 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +0000955 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300956 ic.InterAdapterMessageType_OMCI_REQUEST, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800957 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530958 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300959 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800960 "destination": deviceType,
961 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000962 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700963 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800964 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530965}
966
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700967//ProcessInterAdapterMessage sends the proxied messages to the target device
968// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
969// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000970func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
971 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700972 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700973 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700974 fromTopic := msg.Header.FromTopic
975 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700976 toDeviceID := msg.Header.ToDeviceId
977 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700978
Neha Sharma96b7bf22020-06-15 10:37:32 +0000979 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 -0700980
981 msgBody := msg.GetBody()
982
983 omciMsg := &ic.InterAdapterOmciMessage{}
984 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000985 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700986 }
987
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700988 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000989 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700990 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530991 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800992 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000993 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700994 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000995 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
996 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530997 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800998 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000999 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001000 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001001 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001002 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1003 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301004 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001005 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001006 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001007 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001008 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001009 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001010 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001011 }
1012 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301013}
1014
Neha Sharma96b7bf22020-06-15 10:37:32 +00001015func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001016 var intfID uint32
1017 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001018 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001019 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001020 intfID = onuDevice.ProxyAddress.GetChannelId()
1021 onuID = onuDevice.ProxyAddress.GetOnuId()
1022 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001023 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001024 intfID = omciMsg.GetProxyAddress().GetChannelId()
1025 onuID = omciMsg.GetProxyAddress().GetOnuId()
1026 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001027 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001028 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001029 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 -08001030
Thomas Lee S94109f12020-03-03 16:39:29 +05301031 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001032 "intf-id": intfID,
1033 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001034 }
1035
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001036 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1037 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001038 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001039 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1040 hex.Encode(hexPkt, omciMsg.Message)
1041 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1042
1043 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1044 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1045 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001046 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001047 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001048
Neha Sharma8f4e4322020-08-06 10:51:53 +00001049 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001050 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301051 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001052 "intf-id": intfID,
1053 "onu-id": onuID,
1054 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001055 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001056 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001057}
1058
David K. Bainbridge794735f2020-02-11 21:01:37 -08001059func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301060 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 -07001061 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001062 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001063 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001064 // TODO: need resource manager
1065 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301066 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301067 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001068 st, _ := status.FromError(err)
1069 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001070 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1071
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001072 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301073 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001074 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001075 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001076 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001077 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001078 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001079}
1080
David K. Bainbridge794735f2020-02-11 21:01:37 -08001081func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001082 channelID := onuDiscInd.GetIntfId()
1083 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001084
Neha Sharma96b7bf22020-06-15 10:37:32 +00001085 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301086
cuilin20187b2a8c32019-03-26 19:52:28 -07001087 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001088 if sn != "" {
1089 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001090 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001091 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001092 }
1093
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301094 var alarmInd oop.OnuAlarmIndication
1095 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001096 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301097
1098 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1099 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1100 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1101 OnuLosRaise event sent for it */
1102 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1103 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1104 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001105 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301106 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1107 "currentIntfId": onuDiscInd.GetIntfId()})
1108 // TODO:: Should we need to ignore raising OnuLosClear event
1109 // when onu connected to different PON?
1110 }
1111 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1112 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1113 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001114 go func() {
1115 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1116 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1117 }
1118 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301119 }
1120 return true
1121 })
1122
Neha Sharma96b7bf22020-06-15 10:37:32 +00001123 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001124 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001125 }
1126
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001127 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001128
1129 // check the ONU is already know to the OLT
1130 // NOTE the second time the ONU is discovered this should return a device
1131 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1132
1133 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001134 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 -08001135 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001136 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 -08001137 switch e.Code() {
1138 case codes.Internal:
1139 // this probably means NOT FOUND, so just create a new device
1140 onuDevice = nil
1141 case codes.DeadlineExceeded:
1142 // if the call times out, cleanup and exit
1143 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001144 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001145 }
1146 }
1147 }
1148
1149 if onuDevice == nil {
1150 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001151 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001152 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001153 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301154 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001155
Neha Sharma96b7bf22020-06-15 10:37:32 +00001156 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001157
1158 if err != nil {
1159 // if we can't create an ID in resource manager,
1160 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001161 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001162 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001163 "pon-intf-id": ponintfid,
1164 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001165 }
1166
Neha Sharma8f4e4322020-08-06 10:51:53 +00001167 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001168 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001169 dh.discOnus.Delete(sn)
1170 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 +05301171 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001172 "pon-intf-id": ponintfid,
1173 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001174 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001175 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1176 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1177 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001178 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301179 log.Fields{"onuDevice": onuDevice,
1180 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001181 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301182 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001183 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001184
1185 // we can now use the existing ONU Id
1186 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001187 //Insert the ONU into cache to use in OnuIndication.
1188 //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 +00001189 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001190 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301191 "intfId": onuDiscInd.GetIntfId(),
1192 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001193 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001194
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301195 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301196 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001197 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301198 log.Fields{"onu": onuDev,
1199 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001200
Kent Hagermane6ff1012020-07-14 15:07:53 -04001201 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301202 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001203 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001204 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001205 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001206 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001207 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301208 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001209 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001210 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001211 }
1212 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001213}
1214
Mahir Gunyel2fb81472020-12-16 23:18:34 -08001215func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication, serialNumber string) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001216
1217 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001218 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001219 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001221 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001222 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301223 log.Fields{"onuId": onuInd.OnuId,
1224 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301225 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001226 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301227
David K. Bainbridge794735f2020-02-11 21:01:37 -08001228 errFields := log.Fields{"device-id": dh.device.Id}
1229
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301230 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1231
Mahir Gunyele77977b2019-06-27 05:36:22 -07001232 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1233 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001234 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001235 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001236 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001237 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1238 if serialNumber != "" {
1239 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001240 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001241 } else {
1242 kwargs["onu_id"] = onuInd.OnuId
1243 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001244 errFields["onu-id"] = onuInd.OnuId
1245 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001246 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001247 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001248 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001249
David K. Bainbridge794735f2020-02-11 21:01:37 -08001250 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001251 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001252 }
1253
David K. Bainbridge794735f2020-02-11 21:01:37 -08001254 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001255 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001256 "previousIntfId": onuDevice.ParentPortNo,
1257 "currentIntfId": ponPort})
1258 }
1259
1260 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001261 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301262 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1263 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301264 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001265 }
1266 if !foundInCache {
1267 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1268
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301269 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 -08001270
1271 }
kesavand7cf3a052020-08-28 12:49:18 +05301272 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1273 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1274 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1275 }
1276 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001277 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001278 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001279 }
1280 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001281}
1282
Neha Sharma96b7bf22020-06-15 10:37:32 +00001283func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001284 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 -07001285 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1286 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1287 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1288 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001289 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001290 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1291 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001292 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001293 onuInd.OperState = "down"
1294 }
1295 }
1296
David K. Bainbridge794735f2020-02-11 21:01:37 -08001297 switch onuInd.OperState {
1298 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001299 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 -07001300 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301301 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001302 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001303 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301304 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001305 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001306 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001307 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001308 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001309 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001310 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001311 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 -04001312 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301313 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001314 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001315 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301316 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001317 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001318 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001319 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001320 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001321 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001322 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001323 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001324 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001325 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001326}
1327
cuilin20187b2a8c32019-03-26 19:52:28 -07001328func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1329 if serialNum != nil {
1330 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001331 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001332 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001333}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001334func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1335 decodedStr, err := hex.DecodeString(serialNum[4:])
1336 if err != nil {
1337 return nil, err
1338 }
1339 return &oop.SerialNumber{
1340 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001341 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001342 }, nil
1343}
cuilin20187b2a8c32019-03-26 19:52:28 -07001344
1345func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1346 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001347 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001348 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1349 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1350 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1351 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1352 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1353 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1354 return tmp
1355}
1356
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001357//UpdateFlowsBulk upates the bulk flow
1358func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301359 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001360}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001361
1362//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001363func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1364 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301365 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001366 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301367 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001368 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001369 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001370 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001371 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001372 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001373 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001374 "intf-id": parentPort,
1375 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001376 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001377 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 -08001378 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301379}
1380
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001381// SendPacketInToCore sends packet-in to core
1382// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1383// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001384func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001385 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001386 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001387 "port": logicalPort,
1388 "packet": hex.EncodeToString(packetPayload),
1389 "device-id": dh.device.Id,
1390 })
1391 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001392 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 +05301393 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001394 "source": "adapter",
1395 "destination": "core",
1396 "device-id": dh.device.Id,
1397 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001398 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001399 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001400 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001401 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001402 "packet": hex.EncodeToString(packetPayload),
1403 "device-id": dh.device.Id,
1404 })
1405 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001406 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001407}
1408
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001409// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001410func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001411 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001412
1413 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1414 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001415 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001416 }
1417
Kent Hagermane6ff1012020-07-14 15:07:53 -04001418 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001419 metrics := dh.metrics.GetSubscriberMetrics()
1420 for _, m := range pmConfigs.Metrics {
1421 metrics[m.Name].Enabled = m.Enabled
1422
1423 }
1424 }
1425}
1426
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001427//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301428func (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 +00001429 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 +01001430
1431 var errorsList []error
1432
Girish Gowdru0c588b22019-04-23 23:24:56 -04001433 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001434 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001435 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001436
Neha Sharma96b7bf22020-06-15 10:37:32 +00001437 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301438 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001439 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301440 "flowToRemove": flow})
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001441 err := dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
Girish Gowdracefae192020-03-19 18:14:10 -07001442 if err != nil {
1443 errorsList = append(errorsList, err)
1444 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001445 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301446
1447 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001448 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001449 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301450 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001451 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301452 "flowToAdd": flow})
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001453 err := dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001454 if err != nil {
1455 errorsList = append(errorsList, err)
1456 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301457 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001458 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001459
Girish Gowdracefae192020-03-19 18:14:10 -07001460 // 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 +00001461 if groups != nil {
1462 for _, group := range groups.ToAdd.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001463 err := dh.groupMgr.AddGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001464 if err != nil {
1465 errorsList = append(errorsList, err)
1466 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001467 }
1468 for _, group := range groups.ToUpdate.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001469 err := dh.groupMgr.ModifyGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001470 if err != nil {
1471 errorsList = append(errorsList, err)
1472 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001473 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001474 for _, group := range groups.ToRemove.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001475 err := dh.groupMgr.DeleteGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001476 if err != nil {
1477 errorsList = append(errorsList, err)
1478 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001479 }
1480 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001481 if len(errorsList) > 0 {
1482 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1483 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001484 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001485 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301486}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001487
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001488//DisableDevice disables the given device
1489//It marks the following for the given device:
1490//Device-Handler Admin-State : down
1491//Device Port-State: UNKNOWN
1492//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001493func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001494 /* On device disable ,admin state update has to be done prior sending request to agent since
1495 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001496 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001497 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001498 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001499 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001500 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001501 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001502 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001503 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001504 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001505 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301506
1507 dh.discOnus = sync.Map{}
1508 dh.onus = sync.Map{}
1509
Thomas Lee S85f37312020-04-03 17:06:12 +05301510 //stopping the stats collector
1511 dh.stopCollector <- true
1512
Neha Sharma96b7bf22020-06-15 10:37:32 +00001513 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001514 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301515 //Update device Admin state
1516 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001517 // 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 +00001518 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 -04001519 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001520 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001521 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001522 return nil
1523}
1524
Neha Sharma96b7bf22020-06-15 10:37:32 +00001525func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001526 // Update onu state as unreachable in onu adapter
1527 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301528 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001529 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001530 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001531 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001532 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "error": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001533 }
1534 if onuDevices != nil {
1535 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001536 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001537 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001538 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001539 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001540 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001541 }
1542
1543 }
1544 }
1545
1546}
1547
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001548//ReenableDevice re-enables the olt device after disable
1549//It marks the following for the given device:
1550//Device-Handler Admin-State : up
1551//Device Port-State: ACTIVE
1552//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001553func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001554 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301555 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001556 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301557 }
1558 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001559 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001560
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001561 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001562
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001563 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1564 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001565 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001566 }
1567 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001568 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001569 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001570 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001571 device.OperStatus = voltha.OperStatus_ACTIVE
1572 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001573
Neha Sharma8f4e4322020-08-06 10:51:53 +00001574 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 +05301575 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001576 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001577 "connect-status": device.ConnectStatus,
1578 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001579 }
kesavand39e0aa32020-01-28 20:58:50 -05001580
Neha Sharma96b7bf22020-06-15 10:37:32 +00001581 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001582
1583 return nil
1584}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001585
npujarec5762e2020-01-01 14:08:48 +05301586func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001587 var uniID uint32
1588 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301589 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001590 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001591 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001592 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001593 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001595 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001596 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301597 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001598 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301599 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001600 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001601 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001602 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301603 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001604 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001605 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001606 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301607 }
npujarec5762e2020-01-01 14:08:48 +05301608 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1609 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001610 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301611 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001612 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001613 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001614 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 +00001615 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001616 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1617 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1618 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001619 }
1620 return nil
1621}
1622
npujarec5762e2020-01-01 14:08:48 +05301623func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001624 nniUniID := -1
1625 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301626
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001627 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301628 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001629 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001630 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301631 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301632 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001633 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001634 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001635 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301636 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301637 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001638 _ = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, nniIntfID, -1, -1)
1639
Devmalya Paul495b94a2019-08-27 19:42:00 -04001640 }
npujarec5762e2020-01-01 14:08:48 +05301641 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001642 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301643 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001644
David K. Bainbridge794735f2020-02-11 21:01:37 -08001645 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001646}
1647
1648// 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 +05301649func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001650 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001651 /* Clear the KV store data associated with the all the UNI ports
1652 This clears up flow data and also resource map data for various
1653 other pon resources like alloc_id and gemport_id
1654 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001655 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001656 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001657 // Stop the Stats collector
1658 dh.stopCollector <- true
1659 // stop the heartbeat check routine
1660 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301661 dh.lockDevice.RLock()
1662 // Stop the read indication only if it the routine is active
1663 if dh.isReadIndicationRoutineActive {
1664 dh.stopIndications <- true
1665 }
1666 dh.lockDevice.RUnlock()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001667 //Reset the state
1668 if dh.Client != nil {
1669 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301670 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001671 }
1672 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001673 // There is no need to update the core about operation status and connection status of the OLT.
1674 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1675 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1676 // because the device does not exist in DB.
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001677 return nil
1678}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001679func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001680
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001681 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301682 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001683 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301684 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301685 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301686 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001687 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001688 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001689 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301690 }
1691 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301692 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001693 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301694 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001695 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301696 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301697 // Clear flowids for gem cache.
1698 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301699 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301700 }
1701 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301702 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301703 }
npujarec5762e2020-01-01 14:08:48 +05301704 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301705 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301706 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301707 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001708 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001709 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001710 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001711 /* Clear the flows from KV store associated with NNI port.
1712 There are mostly trap rules from NNI port (like LLDP)
1713 */
npujarec5762e2020-01-01 14:08:48 +05301714 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001715 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001716 }
A R Karthick1f85b802019-10-11 05:06:05 +00001717
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001718 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001719 go func() {
1720 if err := dh.resourceMgr.Delete(ctx); err != nil {
1721 logger.Debug(ctx, err)
1722 }
1723 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001724 }
A R Karthick1f85b802019-10-11 05:06:05 +00001725
Devmalya Paul495b94a2019-08-27 19:42:00 -04001726 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301727 dh.onus.Range(func(key interface{}, value interface{}) bool {
1728 dh.onus.Delete(key)
1729 return true
1730 })
1731
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001732 /*Delete discovered ONU map for the device*/
1733 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1734 dh.discOnus.Delete(key)
1735 return true
1736 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001737}
1738
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001739//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001740func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001741 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301742 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001743 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001744 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001745 return nil
1746}
1747
David K. Bainbridge794735f2020-02-11 21:01:37 -08001748func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001749 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001750 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001751 "packet-indication": *packetIn,
1752 "device-id": dh.device.Id,
1753 "packet": hex.EncodeToString(packetIn.Pkt),
1754 })
1755 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001756 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001757 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001758 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001759 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001760 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001761 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001762 "logical-port-num": logicalPortNum,
1763 "device-id": dh.device.Id,
1764 "packet": hex.EncodeToString(packetIn.Pkt),
1765 })
1766 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001767
Neha Sharma8f4e4322020-08-06 10:51:53 +00001768 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 +05301769 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001770 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301771 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001772 "device-id": dh.device.Id,
1773 "packet": hex.EncodeToString(packetIn.Pkt),
1774 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001775 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001776
Matteo Scandolo92186242020-06-12 10:54:18 -07001777 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001778 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001779 "packet": hex.EncodeToString(packetIn.Pkt),
1780 "device-id": dh.device.Id,
1781 })
1782 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001783 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001784}
1785
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001786// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301787func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001788 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001789 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001790 "device-id": dh.device.Id,
1791 "egress-port-no": egressPortNo,
1792 "pkt-length": len(packet.Data),
1793 "packet": hex.EncodeToString(packet.Data),
1794 })
1795 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001796
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001797 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001798 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001799 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1800 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301801 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1802 // Do not packet-out lldp packets on uni port.
1803 // ONOS has no clue about uni/nni ports, it just packets out on all
1804 // available ports on the Logical Switch. It should not be interested
1805 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001806 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001807 "device-id": dh.device.Id,
1808 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301809 return nil
1810 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001811 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1812 if innerEthType == 0x8100 {
1813 // q-in-q 802.1ad or 802.1q double tagged packet.
1814 // slice out the outer tag.
1815 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001816 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001817 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001818 "packet-data": hex.EncodeToString(packet.Data),
1819 "device-id": dh.device.Id,
1820 })
1821 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001822 }
1823 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001824 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1825 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001826 uniID := UniIDFromPortNum(uint32(egressPortNo))
1827
Girish Gowdra9602eb42020-09-09 15:50:39 -07001828 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001829 if err != nil {
1830 // In this case the openolt agent will receive the gemPortID as 0.
1831 // The agent tries to retrieve the gemPortID in this case.
1832 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001833 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001834 "intf-id": intfID,
1835 "onu-id": onuID,
1836 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001837 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301838 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001839 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001840 }
1841
1842 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001843 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001844 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001845 "egress-port-no": egressPortNo,
1846 "intf-id": intfID,
1847 "onu-id": onuID,
1848 "uni-id": uniID,
1849 "gem-port-id": gemPortID,
1850 "packet": hex.EncodeToString(packet.Data),
1851 "device-id": dh.device.Id,
1852 })
1853 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001854
npujarec5762e2020-01-01 14:08:48 +05301855 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301856 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001857 "source": "adapter",
1858 "destination": "onu",
1859 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001860 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001861 "oni-id": onuID,
1862 "uni-id": uniID,
1863 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001864 "packet": hex.EncodeToString(packet.Data),
1865 "device-id": dh.device.Id,
1866 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001867 }
1868 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001869 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001870 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001871 return olterrors.NewErrInvalidValue(log.Fields{
1872 "egress-nni-port": egressPortNo,
1873 "device-id": dh.device.Id,
1874 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001875 }
1876 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001877
Matteo Scandolo92186242020-06-12 10:54:18 -07001878 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001879 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001880 "uplink-pkt": uplinkPkt,
1881 "packet": hex.EncodeToString(packet.Data),
1882 "device-id": dh.device.Id,
1883 })
1884 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001885
npujarec5762e2020-01-01 14:08:48 +05301886 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001887 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1888 "packet": hex.EncodeToString(packet.Data),
1889 "device-id": dh.device.Id,
1890 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001891 }
1892 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001893 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301894 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001895 "egressPortType": egressPortType,
1896 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301897 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001898 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001899 }
1900 return nil
1901}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001902
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001903func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1904 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001905}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301906
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001907func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001908
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301909 // start the heartbeat check towards the OLT.
1910 var timerCheck *time.Timer
1911
1912 for {
1913 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1914 select {
1915 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001916 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001917 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001918 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301919 if timerCheck == nil {
1920 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001921 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301922 }
1923 } else {
1924 if timerCheck != nil {
1925 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001926 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301927 }
1928 timerCheck = nil
1929 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001930 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301931 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301932 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301933 }
1934 cancel()
1935 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001936 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301937 return
1938 }
1939 }
1940}
1941
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001942func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1943 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1944 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07001945 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
1946 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
1947 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
1948 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
1949 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04001950 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07001951 // Immediately return, otherwise accessing a null 'device' struct would cause panic
1952 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001953 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301954
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001955 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1956 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001957 _ = 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 -04001958 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001959 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001960 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001961 }
1962 go dh.cleanupDeviceResources(ctx)
1963
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001964 dh.lockDevice.RLock()
1965 // Stop the read indication only if it the routine is active
1966 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1967 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1968 // on next execution of the readIndication routine.
1969 if dh.isReadIndicationRoutineActive {
1970 dh.stopIndications <- true
1971 }
1972 dh.lockDevice.RUnlock()
1973
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001974 dh.transitionMap.Handle(ctx, DeviceInit)
1975
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301976 }
1977}
kesavand39e0aa32020-01-28 20:58:50 -05001978
1979// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001980func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1981 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1982 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001983}
1984
1985// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001986func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1987 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1988 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001989}
1990
kdarapu1afeceb2020-02-12 01:38:09 -05001991//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 +00001992func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1993 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001994 if port.GetType() == voltha.Port_ETHERNET_NNI {
1995 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001996 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301997 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301998 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001999 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002000 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002001 }
2002 // fetch interfaceid from PortNo
2003 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2004 ponIntf := &oop.Interface{IntfId: ponID}
2005 var operStatus voltha.OperStatus_Types
2006 if enablePort {
2007 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302008 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002009
2010 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302011 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002012 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002013 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002014 }
2015 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002016 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002017 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002018 } else {
2019 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302020 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002021 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302022 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002023 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002024 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002025 }
2026 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002027 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002028 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002029 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302030 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 +05302031 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302032 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002033 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002034 }
2035 return nil
2036}
2037
kdarapu1afeceb2020-02-12 01:38:09 -05002038//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002039func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002040 // Disable the port and update the oper_port_status to core
2041 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002042 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002043 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002044 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302045 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302046 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002047 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002048 }
2049 }
2050 }
2051 return nil
2052}
2053
2054//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002055func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2056 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2057 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002058 if port.Type == voltha.Port_ETHERNET_NNI {
2059 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002060 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002061 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002062 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002063 }
2064 }
2065 if port.Type == voltha.Port_PON_OLT {
2066 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002067 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002068 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002069 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002070 }
2071 }
2072 }
2073}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002074
2075// ChildDeviceLost deletes ONU and clears pon resources related to it.
2076func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
divyadesai3af43e12020-08-18 07:10:54 +00002077 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002078 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2079 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002080 onuDevice, ok := dh.onus.Load(onuKey)
2081 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302082 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002083 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002084 "device-id": dh.device.Id,
2085 "onu-id": onuID,
2086 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002087 }
2088 var sn *oop.SerialNumber
2089 var err error
2090 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302091 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002092 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302093 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002094 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2095 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002096
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002097 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Neha Sharma8f4e4322020-08-06 10:51:53 +00002098 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302099 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302100 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002101 "onu-id": onuID}, err).Log()
2102 }
2103 //clear PON resources associated with ONU
2104 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002105 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002106 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002107 "device-id": dh.device.Id,
2108 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002109 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002110 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002111 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002112 "device-id": dh.device.Id,
2113 "intf-id": intfID,
2114 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002115 } else {
2116 for i, onu := range onuGemData {
2117 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002118 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002119 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002120 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302121 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002122 "onu-device": onu,
2123 "error": err})
2124 }
2125 // Clear flowids for gem cache.
2126 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002127 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002128 }
2129 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002130 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002131 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002132 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002133 "intf-id": intfID,
2134 "onu-device": onu,
2135 "onu-gem": onuGemData,
2136 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002137 //Not returning error on cleanup.
2138 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002139 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002140 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002141 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002142 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002143 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002144 }
2145 }
2146 dh.onus.Delete(onuKey)
2147 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002148 dh.removeOnuIndicationChannels(ctx, onuDevice.(*OnuDevice).serialNumber)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002149 return nil
2150}
Girish Gowdracefae192020-03-19 18:14:10 -07002151
2152func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2153 for _, field := range flows.GetOfbFields(flow) {
2154 if field.Type == flows.IN_PORT {
2155 return field.GetPort()
2156 }
2157 }
2158 return InvalidPort
2159}
2160
2161func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2162 for _, action := range flows.GetActions(flow) {
2163 if action.Type == flows.OUTPUT {
2164 if out := action.GetOutput(); out != nil {
2165 return out.GetPort()
2166 }
2167 }
2168 }
2169 return InvalidPort
2170}
2171
Girish Gowdracefae192020-03-19 18:14:10 -07002172func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2173 inPort := getInPortFromFlow(flow)
2174 outPort := getOutPortFromFlow(flow)
2175
2176 if inPort == InvalidPort || outPort == InvalidPort {
2177 return inPort, outPort
2178 }
2179
2180 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2181 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2182 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2183 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2184 return uniPort, outPort
2185 }
2186 }
2187 } else {
2188 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2189 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2190 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2191 return inPort, uniPort
2192 }
2193 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2194 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2195 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2196 return uniPort, outPort
2197 }
2198 }
2199 }
2200
2201 return InvalidPort, InvalidPort
2202}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002203
2204func extractOmciTransactionID(omciPkt []byte) uint16 {
2205 if len(omciPkt) > 3 {
2206 d := omciPkt[0:2]
2207 transid := binary.BigEndian.Uint16(d)
2208 return transid
2209 }
2210 return 0
2211}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002212
2213// StoreOnuDevice stores the onu parameters to the local cache.
2214func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2215 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2216 dh.onus.Store(onuKey, onuDevice)
2217}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002218
Neha Sharma8f4e4322020-08-06 10:51:53 +00002219func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002220 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002221 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002222 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002223 resp := new(voltha.ReturnValues)
2224 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002225 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002226 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002227 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2228 return nil, err
2229 }
2230 ID = device.ProxyAddress.GetOnuId()
2231 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2232 valueparam.Onu = &Onu
2233 valueparam.Value = value
2234
2235 // This API is unsupported until agent patch is added
2236 resp.Unsupported = uint32(value)
2237 _ = ctx
2238
2239 // Uncomment this code once agent changes are complete and tests
2240 /*
2241 resp, err = dh.Client.GetValue(ctx, valueparam)
2242 if err != nil {
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002243 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002244 return nil, err
2245 }
2246 */
2247
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002248 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 -08002249 return resp, nil
2250}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002251
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002252func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002253 // Default to PON0
2254 var intfID uint32
2255 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002256 if inPort != InvalidPort && outPort != InvalidPort {
2257 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2258 }
2259 return intfID
2260}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002261
2262func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, sn string) chan perOnuIndication {
2263 dh.perOnuChannelLock.Lock()
2264 if ch, ok := dh.perOnuChannel[sn]; ok {
2265 dh.perOnuChannelLock.Unlock()
2266 return ch.indicationChannel
2267 }
2268 channels := onuIndicationChannels{
2269 //We create a buffered channel here to avoid calling function to be blocked
2270 //in case of multiple indications from the same ONU,
2271 //especially in the case where indications are buffered in OLT.
2272 indicationChannel: make(chan perOnuIndication, 5),
2273 stopChannel: make(chan struct{}),
2274 }
2275 dh.perOnuChannel[sn] = channels
2276 dh.perOnuChannelLock.Unlock()
2277 go dh.perOnuIndicationsRoutine(&channels)
2278 return channels.indicationChannel
2279
2280}
2281
2282func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context, sn string) {
2283 logger.Debugw(ctx, "remove-onu-indication-channels", log.Fields{"sn": sn})
2284 dh.perOnuChannelLock.Lock()
2285 defer dh.perOnuChannelLock.Unlock()
2286 if ch, ok := dh.perOnuChannel[sn]; ok {
2287 close(ch.stopChannel)
2288 delete(dh.perOnuChannel, sn)
2289 }
2290
2291}
2292
2293func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, sn string) {
2294 ind := perOnuIndication{
2295 ctx: ctx,
2296 indication: indication,
2297 serialNumber: sn,
2298 }
2299 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "sn": sn})
2300 // Send the onuIndication on the ONU channel
2301 dh.getOnuIndicationChannel(ctx, sn) <- ind
2302}
2303
2304func (dh *DeviceHandler) perOnuIndicationsRoutine(onuChannels *onuIndicationChannels) {
2305 for {
2306 select {
2307 // process one indication per onu, before proceeding to the next one
2308 case onuInd := <-onuChannels.indicationChannel:
2309 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
2310 "ind": onuInd.indication, "sn": onuInd.serialNumber})
2311 switch onuInd.indication.Data.(type) {
2312 case *oop.Indication_OnuInd:
2313 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd(), onuInd.serialNumber); err != nil {
2314 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2315 "type": "onu-indication",
2316 "device-id": dh.device.Id,
2317 "sn": onuInd.serialNumber}, err).Log()
2318 }
2319 case *oop.Indication_OnuDiscInd:
2320 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd(), onuInd.serialNumber); err != nil {
2321 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2322 "type": "onu-discovery",
2323 "device-id": dh.device.Id,
2324 "sn": onuInd.serialNumber}, err).Log()
2325 }
2326 }
2327 case <-onuChannels.stopChannel:
2328 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2329 close(onuChannels.indicationChannel)
2330 return
2331 }
2332 }
2333}