blob: f342bcf3efdffca2b8d0b200ab66ac3ef0248ba7 [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"
Esin Karamanccb714b2019-11-29 15:02:06 +000037 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
Kent Hagermanf1db18b2020-07-08 13:38:15 -040038 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
Esin Karamanccb714b2019-11-29 15:02:06 +000039 "github.com/opencord/voltha-lib-go/v3/pkg/log"
40 "github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics"
Thomas Lee S94109f12020-03-03 16:39:29 +053041 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080042 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Esin Karamanccb714b2019-11-29 15:02:06 +000043 "github.com/opencord/voltha-protos/v3/go/common"
44 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
45 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
46 oop "github.com/opencord/voltha-protos/v3/go/openolt"
47 "github.com/opencord/voltha-protos/v3/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070048 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040049 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040050 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053051)
52
salmansiddiqui7ac62132019-08-22 03:58:50 +000053// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040054const (
salmansiddiqui7ac62132019-08-22 03:58:50 +000055 MaxRetry = 10
56 MaxTimeOutInMs = 500
Girish Gowdracefae192020-03-19 18:14:10 -070057 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040058)
59
Phaneendra Manda4c62c802019-03-06 21:37:49 +053060//DeviceHandler will interact with the OLT device.
61type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070062 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053063 coreProxy adapterif.CoreProxy
64 AdapterProxy adapterif.AdapterProxy
65 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070066 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070067 exitChannel chan int
68 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053069 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070070 transitionMap *TransitionMap
71 clientCon *grpc.ClientConn
Girish Gowdra9602eb42020-09-09 15:50:39 -070072 flowMgr []*OpenOltFlowMgr
73 groupMgr *OpenOltGroupMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040074 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053075 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053076
Girish Gowdra3ab6d212020-03-24 17:33:15 -070077 discOnus sync.Map
78 onus sync.Map
79 portStats *OpenOltStatisticsMgr
80 metrics *pmmetrics.PmMetrics
81 stopCollector chan bool
82 stopHeartbeatCheck chan bool
83 activePorts sync.Map
84 stopIndications chan bool
85 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070086
Girish Gowdra9602eb42020-09-09 15:50:39 -070087 totalPonPorts uint32
Mahir Gunyela3f9add2019-06-06 15:13:19 -070088}
89
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070090//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -070091type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070092 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -070093 deviceType string
94 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070095 onuID uint32
96 intfID uint32
97 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +053098 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -040099 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700100}
101
Naga Manjunath7615e552019-10-11 22:35:47 +0530102var pmNames = []string{
103 "rx_bytes",
104 "rx_packets",
105 "rx_mcast_packets",
106 "rx_bcast_packets",
107 "tx_bytes",
108 "tx_packets",
109 "tx_mcast_packets",
110 "tx_bcast_packets",
111}
112
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700113//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530114func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700115 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700116 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700117 device.deviceType = deviceTp
118 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700119 device.onuID = onuID
120 device.intfID = intfID
121 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530122 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700123 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530124}
125
126//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530127func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700128 var dh DeviceHandler
129 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400130 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400131 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700132 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700133 dh.device = cloned
134 dh.openOLT = adapter
135 dh.exitChannel = make(chan int, 1)
136 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530137 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530138 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530139 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 -0500140 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400141 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700142
cuilin20187b2a8c32019-03-26 19:52:28 -0700143 //TODO initialize the support classes.
144 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530145}
146
147// start save the device to the data model
148func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700149 dh.lockDevice.Lock()
150 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000151 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700152 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000153 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530154}
155
156// stop stops the device dh. Not much to do for now
157func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700158 dh.lockDevice.Lock()
159 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000160 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700161 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000162 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530163}
164
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400165func macifyIP(ip net.IP) string {
166 if len(ip) > 0 {
167 oct1 := strconv.FormatInt(int64(ip[12]), 16)
168 oct2 := strconv.FormatInt(int64(ip[13]), 16)
169 oct3 := strconv.FormatInt(int64(ip[14]), 16)
170 oct4 := strconv.FormatInt(int64(ip[15]), 16)
171 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
172 }
173 return ""
174}
175
Neha Sharma96b7bf22020-06-15 10:37:32 +0000176func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400177 var genmac string
178 var addr net.IP
179 var ips []string
180 var err error
181
Neha Sharma96b7bf22020-06-15 10:37:32 +0000182 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400183
184 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000185 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400186
187 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000188 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400189 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000190 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400191 }
192 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000193 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530194 log.Fields{"host": ips[0],
195 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400196 return genmac, nil
197 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000198 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400199 }
200
201 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000202 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530203 log.Fields{"host": host,
204 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400205 return genmac, nil
206}
207
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530208func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700209 slist := strings.Split(mac, ":")
210 result := make([]uint32, len(slist))
211 var err error
212 var tmp int64
213 for index, val := range slist {
214 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
215 return []uint32{1, 2, 3, 4, 5, 6}
216 }
217 result[index] = uint32(tmp)
218 }
219 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530220}
221
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700222//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 -0800223func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530224
David K. Bainbridge794735f2020-02-11 21:01:37 -0800225 switch portType {
226 case voltha.Port_ETHERNET_NNI:
227 return fmt.Sprintf("nni-%d", portNum), nil
228 case voltha.Port_PON_OLT:
229 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700230 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800231
Girish Kumarf26e4882020-03-05 06:49:10 +0000232 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530233}
234
Neha Sharma96b7bf22020-06-15 10:37:32 +0000235func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000236 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700237 if state == "up" {
238 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500239 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500240 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700241 } else {
242 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500243 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700244 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700245 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400246 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800247 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000248 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400249 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500250
Neha Sharma8f4e4322020-08-06 10:51:53 +0000251 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 +0000252 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000253 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 -0400254 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
255 "device-id": dh.device.Id,
256 "port-type": portType,
257 "port-number": portNum,
258 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500259 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400260 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500261 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400262 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700263 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400264 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700265 PortNo: portNum,
266 Label: label,
267 Type: portType,
268 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700269 OfpPort: &of.OfpPort{
270 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
271 Config: 0,
272 State: uint32(of.OfpPortState_OFPPS_LIVE),
273 Curr: capacity,
274 Advertised: capacity,
275 Peer: capacity,
276 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
277 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
278 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700279 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000280 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700281 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000282 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000283 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800284 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000285 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400286 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000287 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530288 return nil
289}
290
Kent Hagermane6ff1012020-07-14 15:07:53 -0400291func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530292 dh.lockDevice.Lock()
293 defer dh.lockDevice.Unlock()
Neha Sharma8f4e4322020-08-06 10:51:53 +0000294 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530295 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400296 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
297 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530298 }
299 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530300}
301
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700302// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530303// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800304func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000305 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700306 defer func() {
307 dh.lockDevice.Lock()
308 dh.isReadIndicationRoutineActive = false
309 dh.lockDevice.Unlock()
310 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700311 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700312 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700313 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700314 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400315 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530316 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400317 if err != nil || device == nil {
318 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000319 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400320 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400321
David Bainbridgef5879ca2019-12-13 21:17:54 +0000322 // Create an exponential backoff around re-enabling indications. The
323 // maximum elapsed time for the back off is set to 0 so that we will
324 // continue to retry. The max interval defaults to 1m, but is set
325 // here for code clarity
326 indicationBackoff := backoff.NewExponentialBackOff()
327 indicationBackoff.MaxElapsedTime = 0
328 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700329
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700330 dh.lockDevice.Lock()
331 dh.isReadIndicationRoutineActive = true
332 dh.lockDevice.Unlock()
333
Girish Gowdra3f974912020-03-23 20:35:18 -0700334Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700335 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400336 select {
337 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000338 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700339 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400340 default:
341 indication, err := indications.Recv()
342 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000343 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530344 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530345 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400346 // Use an exponential back off to prevent getting into a tight loop
347 duration := indicationBackoff.NextBackOff()
348 if duration == backoff.Stop {
349 // If we reach a maximum then warn and reset the backoff
350 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000351 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530352 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530353 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400354 indicationBackoff.Reset()
355 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700356
357 // On failure process a backoff timer while watching for stopIndications
358 // events
359 backoff := time.NewTimer(indicationBackoff.NextBackOff())
360 select {
361 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000362 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700363 if !backoff.Stop() {
364 <-backoff.C
365 }
366 break Loop
367 case <-backoff.C:
368 // backoff expired continue
369 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700370 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
371 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400372 }
373 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000374 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530375 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000376 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530377 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530378 "device-id": dh.device.Id})
379 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000380 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700381 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400382 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700383 // Close the stream, and re-initialize it
384 if err = indications.CloseSend(); err != nil {
385 // Ok to ignore here, because we landed here due to a problem on the stream
386 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000387 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530388 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530389 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700390 }
391 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
392 return err
393 }
394 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400395 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530396 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400397 // Reset backoff if we have a successful receive
398 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400399 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530400 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000401 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530402 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530403 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400404 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400405 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400406 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700407 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700408 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700409 // Close the send stream
410 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700411
Girish Gowdra3f974912020-03-23 20:35:18 -0700412 return nil
413}
414
415func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
416
417 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
418 if err != nil {
419 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
420 }
421 if indications == nil {
422 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
423 }
424
425 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400426}
427
428// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
429func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
430 switch indication.Data.(type) {
431 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
432 return true
433
434 default:
435 return false
436 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700437}
438
David K. Bainbridge794735f2020-02-11 21:01:37 -0800439func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000440 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000441 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530442 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700443 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530444 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700445 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000446 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000447 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530448 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000449 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800450 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000451 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800452 }
453 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700454}
455
David K. Bainbridge794735f2020-02-11 21:01:37 -0800456// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530457func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400458 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700459 switch indication.Data.(type) {
460 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000461 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
462 defer span.Finish()
463
David K. Bainbridge794735f2020-02-11 21:01:37 -0800464 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400465 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800466 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700467 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000468 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
469 defer span.Finish()
470
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700471 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800472 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000473 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400474 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800475 }
476 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000477 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700478 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000479 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
480 defer span.Finish()
481
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700482 intfOperInd := indication.GetIntfOperInd()
483 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800484 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000485 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400486 _ = 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 -0800487 }
488 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400489 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
490 logger.Warn(ctx, err)
491 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700492 } else if intfOperInd.GetType() == "pon" {
493 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
494 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800495 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000496 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400497 _ = 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 -0800498 }
499 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000500 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700501 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000502 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530503 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530504 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700505 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000506 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
507 defer span.Finish()
508
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700509 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000510 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700511 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800512 go func() {
513 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400514 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu-discovery", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800515 }
516 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700517 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000518 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
519 defer span.Finish()
520
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700521 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800523 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000524 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400525 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800526 }
527 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700528 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000529 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
530 defer span.Finish()
531
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700532 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000533 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 -0800534 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000535 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400536 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800537 }
538 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700539 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000540 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
541 defer span.Finish()
542
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700543 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000544 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700545 "intf-type": pktInd.IntfId,
546 "intf-id": pktInd.IntfId,
547 "gem-port-id": pktInd.GemportId,
548 "port-no": pktInd.PortNo,
549 "device-id": dh.device.Id,
550 })
551
552 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000553 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700554 "intf-type": pktInd.IntfId,
555 "intf-id": pktInd.IntfId,
556 "gem-port-id": pktInd.GemportId,
557 "port-no": pktInd.PortNo,
558 "packet": hex.EncodeToString(pktInd.Pkt),
559 "device-id": dh.device.Id,
560 })
561 }
562
David K. Bainbridge794735f2020-02-11 21:01:37 -0800563 go func() {
564 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400565 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800566 }
567 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700568 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000569 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
570 defer span.Finish()
571
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700572 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700573 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700574 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000575 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
576 defer span.Finish()
577
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700578 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000579 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700580 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000581 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
582 defer span.Finish()
583
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700584 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000585 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
586 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700587 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530588}
589
590// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530591func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530592 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000593 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530594
Girish Gowdru0c588b22019-04-23 23:24:56 -0400595 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530596 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400597 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000598 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400599 }
600 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530601}
602
603// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530604func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700605 dh.lockDevice.Lock()
606 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000607 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400608
npujarec5762e2020-01-01 14:08:48 +0530609 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400610 if err != nil || device == nil {
611 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000612 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400613 }
614
615 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400616
617 //Update the device oper state and connection status
618 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400619 dh.device = cloned
620
David K. Bainbridge794735f2020-02-11 21:01:37 -0800621 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000622 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400623 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400624
625 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530626 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400627 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000628 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400629 }
630 for _, onuDevice := range onuDevices.Items {
631
632 // Update onu state as down in onu adapter
633 onuInd := oop.OnuIndication{}
634 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800635 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700636 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800637 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400638 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800639 "source": "openolt",
640 "onu-indicator": onuInd,
641 "device-type": onuDevice.Type,
642 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700643 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700644 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400645 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700646 /* Discovered ONUs entries need to be cleared , since after OLT
647 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530648 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000649 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700650 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530651}
652
653// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530654func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400655 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000656 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
657 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
658 grpc.WithInsecure(),
659 grpc.WithBlock(),
660 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000661 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000662 )),
663 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000664 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000665 )))
666
667 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530668 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530669 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000670 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400671 }
672 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530673}
674
675// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530676func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400677 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530678 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400679 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530680}
681
682// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530683func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530684 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000685 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400686
687 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530688 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
689 if err != nil || device == nil {
690 /*TODO: needs to handle error scenarios */
691 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
692 }
693 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000694 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400695
696 cloned := proto.Clone(device).(*voltha.Device)
697 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
698 cloned.OperStatus = voltha.OperStatus_UNKNOWN
699 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530700 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
701 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 -0400702 }
703
Chaitrashree G S44124192019-08-07 20:21:36 -0400704 // 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 +0530705 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400706 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530707 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400708 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400709 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
710 // all the modules initialized and ready to handle incoming ONUs.
711
Thomas Lee S985938d2020-05-04 11:40:41 +0530712 err = dh.initializeDeviceHandlerModules(ctx)
713 if err != nil {
714 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 -0400715 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400716
717 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800718 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530719 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400720 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800721 }
722 }()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400723 return nil
724 }
725
Neha Sharma8f4e4322020-08-06 10:51:53 +0000726 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400727 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400728 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400729 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400730 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400731 dh.populateActivePorts(ctx, ports)
732 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
733 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400734 }
735
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400736 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530737 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 -0400738 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530739
cuilin20187b2a8c32019-03-26 19:52:28 -0700740 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800741 go func() {
742 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400743 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800744 }
745 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000746 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000747
748 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000749 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000750 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700751 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530752}
753
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400754func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000755 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400756
757 if err != nil {
758 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
759 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700760 dh.totalPonPorts = deviceInfo.GetPonPorts()
761
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400762 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000763 if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, deviceInfo); dh.resourceMgr == nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400764 return olterrors.ErrResourceManagerInstantiating
765 }
766
Girish Gowdra9602eb42020-09-09 15:50:39 -0700767 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400768
Girish Gowdra9602eb42020-09-09 15:50:39 -0700769 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
770 for i := range dh.flowMgr {
771 // Instantiate flow manager
772 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr); dh.flowMgr[i] == nil {
773 return olterrors.ErrResourceManagerInstantiating
774 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400775 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700776
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400777 /* TODO: Instantiate Alarm , stats , BW managers */
778 /* Instantiating Event Manager to handle Alarms and KPIs */
779 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
780
781 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000782 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400783
784 return nil
785
786}
787
Neha Sharma96b7bf22020-06-15 10:37:32 +0000788func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400789 var err error
790 var deviceInfo *oop.DeviceInfo
791
Neha Sharma8f4e4322020-08-06 10:51:53 +0000792 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400793
794 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000795 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400796 }
797 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000798 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400799 }
800
Neha Sharma96b7bf22020-06-15 10:37:32 +0000801 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400802 dh.device.Root = true
803 dh.device.Vendor = deviceInfo.Vendor
804 dh.device.Model = deviceInfo.Model
805 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
806 dh.device.HardwareVersion = deviceInfo.HardwareVersion
807 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
808
809 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000810 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400811 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000812 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400813 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000814 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400815 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000816 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400817 dh.device.MacAddress = genmac
818 } else {
819 dh.device.MacAddress = deviceInfo.DeviceId
820 }
821
822 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000823 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000824 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400825 }
826
827 return deviceInfo, nil
828}
829
Neha Sharma96b7bf22020-06-15 10:37:32 +0000830func startCollector(ctx context.Context, dh *DeviceHandler) {
831 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530832 for {
833 select {
834 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000835 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530836 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000837 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700838
Neha Sharma8f4e4322020-08-06 10:51:53 +0000839 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400840 if err != nil {
841 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
842 continue
843 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530844 for _, port := range ports {
845 // NNI Stats
846 if port.Type == voltha.Port_ETHERNET_NNI {
847 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
848 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000849 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
850 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
851 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530852 }
853 // PON Stats
854 if port.Type == voltha.Port_PON_OLT {
855 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
856 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
857 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000858 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
859 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530860 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000861 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500862 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530863 }
864 }
865 }
866}
867
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700868//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530869func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400870 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000871 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530872 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530873
874 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400875 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
876 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530877 }
878
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400879 go startHeartbeatCheck(ctx, dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530880}
881
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700882//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530883func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700884 return &ic.SwitchCapability{
885 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530886 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700887 HwDesc: "open_pon",
888 SwDesc: "open_pon",
889 SerialNum: dh.device.SerialNumber,
890 },
891 SwitchFeatures: &of.OfpSwitchFeatures{
892 NBuffers: 256,
893 NTables: 2,
894 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
895 of.OfpCapabilities_OFPC_TABLE_STATS |
896 of.OfpCapabilities_OFPC_PORT_STATS |
897 of.OfpCapabilities_OFPC_GROUP_STATS),
898 },
899 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530900}
901
Neha Sharma96b7bf22020-06-15 10:37:32 +0000902func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
903 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 -0700904 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700905 var deviceID string
906 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700907
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400908 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700909 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000910 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 -0700911 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
912 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400913
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700914 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530915
916 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
917
Neha Sharma96b7bf22020-06-15 10:37:32 +0000918 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 -0700919 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700920 kwargs := make(map[string]interface{})
921 kwargs["onu_id"] = omciInd.OnuId
922 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700923
Neha Sharma8f4e4322020-08-06 10:51:53 +0000924 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700925 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530926 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700927 "intf-id": omciInd.IntfId,
928 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700929 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700930 deviceType = onuDevice.Type
931 deviceID = onuDevice.Id
932 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
933 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530934 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700935 } else {
936 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000937 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 +0530938 deviceType = onuInCache.(*OnuDevice).deviceType
939 deviceID = onuInCache.(*OnuDevice).deviceID
940 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700941 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700942
943 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +0000944 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530945 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800946 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530947 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530948 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800949 "destination": deviceType,
950 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000951 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700952 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800953 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530954}
955
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700956//ProcessInterAdapterMessage sends the proxied messages to the target device
957// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
958// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000959func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
960 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700961 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700962 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700963 fromTopic := msg.Header.FromTopic
964 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700965 toDeviceID := msg.Header.ToDeviceId
966 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700967
Neha Sharma96b7bf22020-06-15 10:37:32 +0000968 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 -0700969
970 msgBody := msg.GetBody()
971
972 omciMsg := &ic.InterAdapterOmciMessage{}
973 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000974 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700975 }
976
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700977 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000978 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700979 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530980 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800981 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000982 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700983 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000984 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
985 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530986 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800987 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000988 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800989 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700990 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000991 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
992 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530993 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800994 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000995 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800996 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700997 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700998 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +0000999 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001000 }
1001 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301002}
1003
Neha Sharma96b7bf22020-06-15 10:37:32 +00001004func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001005 var intfID uint32
1006 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001007 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001008 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001009 intfID = onuDevice.ProxyAddress.GetChannelId()
1010 onuID = onuDevice.ProxyAddress.GetOnuId()
1011 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001012 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001013 intfID = omciMsg.GetProxyAddress().GetChannelId()
1014 onuID = omciMsg.GetProxyAddress().GetOnuId()
1015 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001016 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001017 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001018 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 -08001019
Thomas Lee S94109f12020-03-03 16:39:29 +05301020 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001021 "intf-id": intfID,
1022 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001023 }
1024
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001025 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1026 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001027 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001028 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1029 hex.Encode(hexPkt, omciMsg.Message)
1030 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1031
1032 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1033 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1034 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001035 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001036 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001037
Neha Sharma8f4e4322020-08-06 10:51:53 +00001038 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001039 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301040 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001041 "intf-id": intfID,
1042 "onu-id": onuID,
1043 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001044 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001045 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001046}
1047
David K. Bainbridge794735f2020-02-11 21:01:37 -08001048func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301049 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 -07001050 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001051 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001052 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001053 // TODO: need resource manager
1054 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301055 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301056 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001057 st, _ := status.FromError(err)
1058 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001059 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1060
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001061 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301062 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001063 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001064 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001065 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001066 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001067 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001068}
1069
David K. Bainbridge794735f2020-02-11 21:01:37 -08001070func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001071 channelID := onuDiscInd.GetIntfId()
1072 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001073
Neha Sharma96b7bf22020-06-15 10:37:32 +00001074 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301075
cuilin20187b2a8c32019-03-26 19:52:28 -07001076 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001077 if sn != "" {
1078 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001079 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001080 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001081 }
1082
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301083 var alarmInd oop.OnuAlarmIndication
1084 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001085 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301086
1087 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1088 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1089 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1090 OnuLosRaise event sent for it */
1091 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1092 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1093 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001094 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301095 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1096 "currentIntfId": onuDiscInd.GetIntfId()})
1097 // TODO:: Should we need to ignore raising OnuLosClear event
1098 // when onu connected to different PON?
1099 }
1100 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1101 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1102 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001103 go func() {
1104 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1105 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1106 }
1107 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301108 }
1109 return true
1110 })
1111
Neha Sharma96b7bf22020-06-15 10:37:32 +00001112 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001113 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001114 }
1115
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001116 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001117
1118 // check the ONU is already know to the OLT
1119 // NOTE the second time the ONU is discovered this should return a device
1120 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1121
1122 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001123 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 -08001124 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001125 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 -08001126 switch e.Code() {
1127 case codes.Internal:
1128 // this probably means NOT FOUND, so just create a new device
1129 onuDevice = nil
1130 case codes.DeadlineExceeded:
1131 // if the call times out, cleanup and exit
1132 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001133 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001134 }
1135 }
1136 }
1137
1138 if onuDevice == nil {
1139 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001140 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001141 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001142 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301143 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001144
Neha Sharma96b7bf22020-06-15 10:37:32 +00001145 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001146
1147 if err != nil {
1148 // if we can't create an ID in resource manager,
1149 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001150 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001151 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001152 "pon-intf-id": ponintfid,
1153 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001154 }
1155
Neha Sharma8f4e4322020-08-06 10:51:53 +00001156 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001157 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001158 dh.discOnus.Delete(sn)
1159 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 +05301160 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001161 "pon-intf-id": ponintfid,
1162 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001163 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001164 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1165 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1166 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001167 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301168 log.Fields{"onuDevice": onuDevice,
1169 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001170 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301171 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001172 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001173
1174 // we can now use the existing ONU Id
1175 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001176 //Insert the ONU into cache to use in OnuIndication.
1177 //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 +00001178 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001179 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301180 "intfId": onuDiscInd.GetIntfId(),
1181 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001182 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001183
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301184 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301185 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001186 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301187 log.Fields{"onu": onuDev,
1188 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001189
Kent Hagermane6ff1012020-07-14 15:07:53 -04001190 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301191 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001192 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001193 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001194 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001195 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001196 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301197 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001198 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001199 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001200 }
1201 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001202}
1203
Neha Sharma96b7bf22020-06-15 10:37:32 +00001204func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001205 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1206
1207 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001208 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001209 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001210 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001211 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001212 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301213 log.Fields{"onuId": onuInd.OnuId,
1214 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301215 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001216 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301217
David K. Bainbridge794735f2020-02-11 21:01:37 -08001218 errFields := log.Fields{"device-id": dh.device.Id}
1219
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301220 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1221
Mahir Gunyele77977b2019-06-27 05:36:22 -07001222 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1223 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001224 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001225 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001226 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001227 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1228 if serialNumber != "" {
1229 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001230 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001231 } else {
1232 kwargs["onu_id"] = onuInd.OnuId
1233 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001234 errFields["onu-id"] = onuInd.OnuId
1235 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001236 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001237 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001238 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001239
David K. Bainbridge794735f2020-02-11 21:01:37 -08001240 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001241 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001242 }
1243
David K. Bainbridge794735f2020-02-11 21:01:37 -08001244 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001245 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001246 "previousIntfId": onuDevice.ParentPortNo,
1247 "currentIntfId": ponPort})
1248 }
1249
1250 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001251 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301252 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1253 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301254 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001255 }
1256 if !foundInCache {
1257 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1258
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301259 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 -08001260
1261 }
kesavand7cf3a052020-08-28 12:49:18 +05301262 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1263 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1264 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1265 }
1266 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001267 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001268 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001269 }
1270 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001271}
1272
Neha Sharma96b7bf22020-06-15 10:37:32 +00001273func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001274 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 -07001275 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1276 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1277 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1278 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001279 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001280 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1281 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001282 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001283 onuInd.OperState = "down"
1284 }
1285 }
1286
David K. Bainbridge794735f2020-02-11 21:01:37 -08001287 switch onuInd.OperState {
1288 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001289 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 -07001290 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301291 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001292 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1293 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301294 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001295 "onu-indicator": onuInd,
1296 "source": "openolt",
1297 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001298 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001299 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001300 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001301 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 -04001302 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301303 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001304 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1305 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301306 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001307 "onu-indicator": onuInd,
1308 "source": "openolt",
1309 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001310 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001311 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001312 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001313 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001314 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001315 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001316}
1317
cuilin20187b2a8c32019-03-26 19:52:28 -07001318func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1319 if serialNum != nil {
1320 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001321 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001322 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001323}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001324func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1325 decodedStr, err := hex.DecodeString(serialNum[4:])
1326 if err != nil {
1327 return nil, err
1328 }
1329 return &oop.SerialNumber{
1330 VendorId: []byte(serialNum[:4]),
1331 VendorSpecific: []byte(decodedStr),
1332 }, nil
1333}
cuilin20187b2a8c32019-03-26 19:52:28 -07001334
1335func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1336 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001337 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001338 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1339 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1340 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1341 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1342 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1343 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1344 return tmp
1345}
1346
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001347//UpdateFlowsBulk upates the bulk flow
1348func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301349 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001350}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001351
1352//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001353func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1354 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301355 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001356 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301357 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001358 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001359 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001360 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001361 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001362 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001363 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001364 "intf-id": parentPort,
1365 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001366 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001367 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 -08001368 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301369}
1370
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001371// SendPacketInToCore sends packet-in to core
1372// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1373// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001374func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001375 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001376 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001377 "port": logicalPort,
1378 "packet": hex.EncodeToString(packetPayload),
1379 "device-id": dh.device.Id,
1380 })
1381 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001382 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 +05301383 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001384 "source": "adapter",
1385 "destination": "core",
1386 "device-id": dh.device.Id,
1387 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001388 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001389 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001390 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001391 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001392 "packet": hex.EncodeToString(packetPayload),
1393 "device-id": dh.device.Id,
1394 })
1395 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001396 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001397}
1398
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001399// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001400func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001401 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001402
1403 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1404 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001405 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001406 }
1407
Kent Hagermane6ff1012020-07-14 15:07:53 -04001408 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001409 metrics := dh.metrics.GetSubscriberMetrics()
1410 for _, m := range pmConfigs.Metrics {
1411 metrics[m.Name].Enabled = m.Enabled
1412
1413 }
1414 }
1415}
1416
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001417//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301418func (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 +00001419 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 +01001420
1421 var errorsList []error
1422
Girish Gowdru0c588b22019-04-23 23:24:56 -04001423 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001424 for _, flow := range flows.ToRemove.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001425 ponIf := dh.getPonIfFromFlow(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001426
Neha Sharma96b7bf22020-06-15 10:37:32 +00001427 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301428 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001429 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301430 "flowToRemove": flow})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001431 err := dh.flowMgr[ponIf].RemoveFlow(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001432 if err != nil {
1433 errorsList = append(errorsList, err)
1434 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001435 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301436
1437 for _, flow := range flows.ToAdd.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001438 ponIf := dh.getPonIfFromFlow(ctx, flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001439 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301440 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001441 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301442 "flowToAdd": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001443 // If there are active Flow Remove in progress for a given subscriber, wait until it completes
Girish Gowdra9602eb42020-09-09 15:50:39 -07001444 err := dh.flowMgr[ponIf].AddFlow(ctx, flow, flowMetadata)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001445 if err != nil {
1446 errorsList = append(errorsList, err)
1447 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301448 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001449 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001450
Girish Gowdracefae192020-03-19 18:14:10 -07001451 // 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 +00001452 if groups != nil {
1453 for _, group := range groups.ToAdd.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001454 err := dh.groupMgr.AddGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001455 if err != nil {
1456 errorsList = append(errorsList, err)
1457 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001458 }
1459 for _, group := range groups.ToUpdate.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001460 err := dh.groupMgr.ModifyGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001461 if err != nil {
1462 errorsList = append(errorsList, err)
1463 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001464 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001465 for _, group := range groups.ToRemove.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001466 err := dh.groupMgr.DeleteGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001467 if err != nil {
1468 errorsList = append(errorsList, err)
1469 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001470 }
1471 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001472 if len(errorsList) > 0 {
1473 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1474 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001475 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001476 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301477}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001478
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001479//DisableDevice disables the given device
1480//It marks the following for the given device:
1481//Device-Handler Admin-State : down
1482//Device Port-State: UNKNOWN
1483//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001484func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001485 /* On device disable ,admin state update has to be done prior sending request to agent since
1486 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001487 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001488 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001489 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001490 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001491 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001492 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001493 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001494 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001495 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001496 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301497
1498 dh.discOnus = sync.Map{}
1499 dh.onus = sync.Map{}
1500
Thomas Lee S85f37312020-04-03 17:06:12 +05301501 //stopping the stats collector
1502 dh.stopCollector <- true
1503
Neha Sharma96b7bf22020-06-15 10:37:32 +00001504 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001505 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301506 //Update device Admin state
1507 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001508 // 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 +00001509 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 -04001510 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001511 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001512 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001513 return nil
1514}
1515
Neha Sharma96b7bf22020-06-15 10:37:32 +00001516func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001517 // Update onu state as unreachable in onu adapter
1518 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301519 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001520 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001521 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001522 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001523 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 -04001524 }
1525 if onuDevices != nil {
1526 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001527 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001528 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1529 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001530 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301531 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001532 }
1533
1534 }
1535 }
1536
1537}
1538
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001539//ReenableDevice re-enables the olt device after disable
1540//It marks the following for the given device:
1541//Device-Handler Admin-State : up
1542//Device Port-State: ACTIVE
1543//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001544func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001545 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301546 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001547 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301548 }
1549 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001550 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001551
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001552 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001553
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001554 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1555 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001556 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001557 }
1558 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001559 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001560 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001561 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001562 device.OperStatus = voltha.OperStatus_ACTIVE
1563 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001564
Neha Sharma8f4e4322020-08-06 10:51:53 +00001565 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 +05301566 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001567 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001568 "connect-status": device.ConnectStatus,
1569 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001570 }
kesavand39e0aa32020-01-28 20:58:50 -05001571
Neha Sharma96b7bf22020-06-15 10:37:32 +00001572 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001573
1574 return nil
1575}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001576
npujarec5762e2020-01-01 14:08:48 +05301577func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001578 var uniID uint32
1579 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301580 for _, port := range onu.UniPorts {
1581 uniID = UniIDFromPortNum(uint32(port))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001582 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001583 /* Delete tech-profile instance from the KV store */
Girish Gowdra9602eb42020-09-09 15:50:39 -07001584 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001586 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001587 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301588 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001589 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301590 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001591 }
npujarec5762e2020-01-01 14:08:48 +05301592 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001593 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301594 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001596 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001597 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301598 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001599 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001600 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001601 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301602 }
npujarec5762e2020-01-01 14:08:48 +05301603 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1604 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001605 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301606 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Esin Karaman7fb80c22020-07-16 14:23:33 +00001608 if err = dh.resourceMgr.DelGemPortPktInOfAllServices(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001609 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 +00001610 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001611 }
1612 return nil
1613}
1614
npujarec5762e2020-01-01 14:08:48 +05301615func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001616 nniUniID := -1
1617 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301618
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001619 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301620 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001621 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001622 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301623 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301624 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001625 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001626 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001627 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301628 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301629 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001630 logger.Debugw(ctx, "current-flow-ids-for-nni", log.Fields{"flow-ids": flowIDs})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301631 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301632 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301633 }
npujarec5762e2020-01-01 14:08:48 +05301634 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001635 }
npujarec5762e2020-01-01 14:08:48 +05301636 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001637 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301638 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001639 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001640}
1641
1642// 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 +05301643func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001644 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001645 /* Clear the KV store data associated with the all the UNI ports
1646 This clears up flow data and also resource map data for various
1647 other pon resources like alloc_id and gemport_id
1648 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001649 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001650 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001651 // Stop the Stats collector
1652 dh.stopCollector <- true
1653 // stop the heartbeat check routine
1654 dh.stopHeartbeatCheck <- true
1655 //Reset the state
1656 if dh.Client != nil {
1657 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301658 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001659 }
1660 }
1661 cloned := proto.Clone(device).(*voltha.Device)
1662 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1663 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1664 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1665 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1666 "device-id": device.Id,
1667 "connect-status": cloned.ConnectStatus,
1668 "oper-status": cloned.OperStatus}, err).Log()
1669 }
1670 return nil
1671}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001672func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001673
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001674 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301675 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001676 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301677 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301678 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301679 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001680 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001681 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001682 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301683 }
1684 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301685 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001686 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301687 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001688 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301689 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301690 // Clear flowids for gem cache.
1691 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301692 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301693 }
1694 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +0530