blob: 3be60ec90a1f86372e4542bc55f85ac95b13dd25 [file] [log] [blame]
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
Phaneendra Manda4c62c802019-03-06 21:37:49 +053019
20import (
cuilin20187b2a8c32019-03-26 19:52:28 -070021 "context"
Matt Jeanneretceea2e02020-03-27 14:19:57 -040022 "encoding/binary"
Matt Jeanneret1359c732019-08-01 21:40:02 -040023 "encoding/hex"
cuilin20187b2a8c32019-03-26 19:52:28 -070024 "fmt"
25 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040026 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070027 "strconv"
28 "strings"
29 "sync"
30 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053031
Matteo Scandolo945e4012019-12-12 14:16:11 -080032 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070033 "github.com/gogo/protobuf/proto"
34 "github.com/golang/protobuf/ptypes"
Girish Kumar93e91742020-07-27 16:43:19 +000035 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
36 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070037 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
38 "github.com/opencord/voltha-lib-go/v4/pkg/flows"
39 "github.com/opencord/voltha-lib-go/v4/pkg/log"
40 "github.com/opencord/voltha-lib-go/v4/pkg/pmmetrics"
Thomas Lee S94109f12020-03-03 16:39:29 +053041 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080042 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070043 "github.com/opencord/voltha-protos/v4/go/common"
44 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
45 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
46 oop "github.com/opencord/voltha-protos/v4/go/openolt"
47 "github.com/opencord/voltha-protos/v4/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070048 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040049 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040050 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053051)
52
salmansiddiqui7ac62132019-08-22 03:58:50 +000053// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040054const (
Girish Gowdraa09aeab2020-09-14 16:30:52 -070055 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040056)
57
Phaneendra Manda4c62c802019-03-06 21:37:49 +053058//DeviceHandler will interact with the OLT device.
59type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070060 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053061 coreProxy adapterif.CoreProxy
62 AdapterProxy adapterif.AdapterProxy
63 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070064 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070065 exitChannel chan int
66 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053067 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070068 transitionMap *TransitionMap
69 clientCon *grpc.ClientConn
Girish Gowdra9602eb42020-09-09 15:50:39 -070070 flowMgr []*OpenOltFlowMgr
71 groupMgr *OpenOltGroupMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040072 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053073 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053074
Girish Gowdra3ab6d212020-03-24 17:33:15 -070075 discOnus sync.Map
76 onus sync.Map
77 portStats *OpenOltStatisticsMgr
78 metrics *pmmetrics.PmMetrics
79 stopCollector chan bool
80 stopHeartbeatCheck chan bool
81 activePorts sync.Map
82 stopIndications chan bool
83 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070084
Girish Gowdra9602eb42020-09-09 15:50:39 -070085 totalPonPorts uint32
Mahir Gunyela3f9add2019-06-06 15:13:19 -070086}
87
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070088//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -070089type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070090 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -070091 deviceType string
92 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070093 onuID uint32
94 intfID uint32
95 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +053096 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -040097 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -070098}
99
Naga Manjunath7615e552019-10-11 22:35:47 +0530100var pmNames = []string{
101 "rx_bytes",
102 "rx_packets",
103 "rx_mcast_packets",
104 "rx_bcast_packets",
105 "tx_bytes",
106 "tx_packets",
107 "tx_mcast_packets",
108 "tx_bcast_packets",
109}
110
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700111//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530112func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700113 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700114 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700115 device.deviceType = deviceTp
116 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700117 device.onuID = onuID
118 device.intfID = intfID
119 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530120 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700121 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530122}
123
124//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530125func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700126 var dh DeviceHandler
127 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400128 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400129 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700130 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700131 dh.device = cloned
132 dh.openOLT = adapter
133 dh.exitChannel = make(chan int, 1)
134 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530135 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530136 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530137 dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Chaitrashree G Sef088112020-02-03 21:39:27 -0500138 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400139 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700140
cuilin20187b2a8c32019-03-26 19:52:28 -0700141 //TODO initialize the support classes.
142 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530143}
144
145// start save the device to the data model
146func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700147 dh.lockDevice.Lock()
148 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000149 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700150 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000151 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530152}
153
154// stop stops the device dh. Not much to do for now
155func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700156 dh.lockDevice.Lock()
157 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000158 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700159 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000160 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530161}
162
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400163func macifyIP(ip net.IP) string {
164 if len(ip) > 0 {
165 oct1 := strconv.FormatInt(int64(ip[12]), 16)
166 oct2 := strconv.FormatInt(int64(ip[13]), 16)
167 oct3 := strconv.FormatInt(int64(ip[14]), 16)
168 oct4 := strconv.FormatInt(int64(ip[15]), 16)
169 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
170 }
171 return ""
172}
173
Neha Sharma96b7bf22020-06-15 10:37:32 +0000174func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400175 var genmac string
176 var addr net.IP
177 var ips []string
178 var err error
179
Neha Sharma96b7bf22020-06-15 10:37:32 +0000180 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400181
182 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000183 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400184
185 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000186 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400187 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000188 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400189 }
190 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000191 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530192 log.Fields{"host": ips[0],
193 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400194 return genmac, nil
195 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000196 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400197 }
198
199 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000200 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530201 log.Fields{"host": host,
202 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400203 return genmac, nil
204}
205
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530206func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700207 slist := strings.Split(mac, ":")
208 result := make([]uint32, len(slist))
209 var err error
210 var tmp int64
211 for index, val := range slist {
212 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
213 return []uint32{1, 2, 3, 4, 5, 6}
214 }
215 result[index] = uint32(tmp)
216 }
217 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530218}
219
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700220//GetportLabel returns the label for the NNI and the PON port based on port number and port type
David K. Bainbridge794735f2020-02-11 21:01:37 -0800221func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530222
David K. Bainbridge794735f2020-02-11 21:01:37 -0800223 switch portType {
224 case voltha.Port_ETHERNET_NNI:
225 return fmt.Sprintf("nni-%d", portNum), nil
226 case voltha.Port_PON_OLT:
227 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700228 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800229
Girish Kumarf26e4882020-03-05 06:49:10 +0000230 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530231}
232
Neha Sharma96b7bf22020-06-15 10:37:32 +0000233func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000234 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700235 if state == "up" {
236 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500237 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500238 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700239 } else {
240 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500241 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700242 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700243 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400244 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800245 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000246 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400247 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500248
Neha Sharma8f4e4322020-08-06 10:51:53 +0000249 if port, err := dh.coreProxy.GetDevicePort(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portNum); err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000250 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000251 if err := dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portType, portNum, operStatus); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400252 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
253 "device-id": dh.device.Id,
254 "port-type": portType,
255 "port-number": portNum,
256 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500257 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400258 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500259 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400260 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700261 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400262 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700263 PortNo: portNum,
264 Label: label,
265 Type: portType,
266 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700267 OfpPort: &of.OfpPort{
268 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
269 Config: 0,
270 State: uint32(of.OfpPortState_OFPPS_LIVE),
271 Curr: capacity,
272 Advertised: capacity,
273 Peer: capacity,
274 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
275 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
276 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700277 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000278 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700279 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000280 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000281 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800282 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000283 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400284 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000285 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530286 return nil
287}
288
Kent Hagermane6ff1012020-07-14 15:07:53 -0400289func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530290 dh.lockDevice.Lock()
291 defer dh.lockDevice.Unlock()
Neha Sharma8f4e4322020-08-06 10:51:53 +0000292 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530293 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400294 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
295 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530296 }
297 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530298}
299
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700300// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530301// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800302func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000303 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700304 defer func() {
305 dh.lockDevice.Lock()
306 dh.isReadIndicationRoutineActive = false
307 dh.lockDevice.Unlock()
308 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700309 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700310 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700311 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700312 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400313 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530314 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400315 if err != nil || device == nil {
316 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000317 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400318 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400319
David Bainbridgef5879ca2019-12-13 21:17:54 +0000320 // Create an exponential backoff around re-enabling indications. The
321 // maximum elapsed time for the back off is set to 0 so that we will
322 // continue to retry. The max interval defaults to 1m, but is set
323 // here for code clarity
324 indicationBackoff := backoff.NewExponentialBackOff()
325 indicationBackoff.MaxElapsedTime = 0
326 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700327
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700328 dh.lockDevice.Lock()
329 dh.isReadIndicationRoutineActive = true
330 dh.lockDevice.Unlock()
331
Girish Gowdra3f974912020-03-23 20:35:18 -0700332Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700333 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400334 select {
335 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000336 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700337 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400338 default:
339 indication, err := indications.Recv()
340 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000341 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530342 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530343 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400344 // Use an exponential back off to prevent getting into a tight loop
345 duration := indicationBackoff.NextBackOff()
346 if duration == backoff.Stop {
347 // If we reach a maximum then warn and reset the backoff
348 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000349 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530350 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530351 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400352 indicationBackoff.Reset()
353 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700354
355 // On failure process a backoff timer while watching for stopIndications
356 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700357 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700358 select {
359 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000360 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700361 if !backoffTimer.Stop() {
362 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700363 }
364 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700365 case <-backoffTimer.C:
366 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700367 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700368 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
369 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400370 }
371 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000372 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530373 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000374 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530375 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530376 "device-id": dh.device.Id})
377 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000378 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700379 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400380 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700381 // Close the stream, and re-initialize it
382 if err = indications.CloseSend(); err != nil {
383 // Ok to ignore here, because we landed here due to a problem on the stream
384 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000385 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530386 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530387 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700388 }
389 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
390 return err
391 }
392 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400393 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530394 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400395 // Reset backoff if we have a successful receive
396 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400397 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530398 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000399 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530400 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530401 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400402 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400403 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400404 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700405 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700406 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700407 // Close the send stream
408 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700409
Girish Gowdra3f974912020-03-23 20:35:18 -0700410 return nil
411}
412
413func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
414
415 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
416 if err != nil {
417 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
418 }
419 if indications == nil {
420 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
421 }
422
423 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400424}
425
426// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
427func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
428 switch indication.Data.(type) {
429 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
430 return true
431
432 default:
433 return false
434 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700435}
436
David K. Bainbridge794735f2020-02-11 21:01:37 -0800437func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000438 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000439 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530440 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700441 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530442 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700443 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000444 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000445 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530446 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000447 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800448 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000449 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800450 }
451 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700452}
453
David K. Bainbridge794735f2020-02-11 21:01:37 -0800454// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530455func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400456 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700457 switch indication.Data.(type) {
458 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000459 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
460 defer span.Finish()
461
David K. Bainbridge794735f2020-02-11 21:01:37 -0800462 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400463 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800464 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700465 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000466 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
467 defer span.Finish()
468
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700469 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800470 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000471 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400472 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800473 }
474 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000475 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700476 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000477 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
478 defer span.Finish()
479
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700480 intfOperInd := indication.GetIntfOperInd()
481 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800482 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000483 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400484 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-nni", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800485 }
486 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400487 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
488 logger.Warn(ctx, err)
489 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700490 } else if intfOperInd.GetType() == "pon" {
491 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
492 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800493 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000494 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400495 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-pon", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800496 }
497 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000498 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700499 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000500 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530501 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530502 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700503 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000504 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
505 defer span.Finish()
506
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700507 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000508 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700509 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800510 go func() {
511 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400512 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu-discovery", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800513 }
514 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000516 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
517 defer span.Finish()
518
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700519 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000520 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800521 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400523 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800524 }
525 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700526 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000527 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
528 defer span.Finish()
529
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700530 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000531 logger.Debugw(ctx, "received-omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800532 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000533 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400534 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800535 }
536 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700537 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000538 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
539 defer span.Finish()
540
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700541 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000542 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700543 "intf-type": pktInd.IntfId,
544 "intf-id": pktInd.IntfId,
545 "gem-port-id": pktInd.GemportId,
546 "port-no": pktInd.PortNo,
547 "device-id": dh.device.Id,
548 })
549
550 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000551 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700552 "intf-type": pktInd.IntfId,
553 "intf-id": pktInd.IntfId,
554 "gem-port-id": pktInd.GemportId,
555 "port-no": pktInd.PortNo,
556 "packet": hex.EncodeToString(pktInd.Pkt),
557 "device-id": dh.device.Id,
558 })
559 }
560
David K. Bainbridge794735f2020-02-11 21:01:37 -0800561 go func() {
562 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400563 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800564 }
565 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000567 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
568 defer span.Finish()
569
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700570 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700571 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700572 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000573 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
574 defer span.Finish()
575
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700576 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000577 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700578 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000579 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
580 defer span.Finish()
581
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700582 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000583 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
584 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700585 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530586}
587
588// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530589func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530590 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000591 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530592
Girish Gowdru0c588b22019-04-23 23:24:56 -0400593 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530594 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400595 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000596 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400597 }
598 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530599}
600
601// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530602func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700603 dh.lockDevice.Lock()
604 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000605 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400606
npujarec5762e2020-01-01 14:08:48 +0530607 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400608 if err != nil || device == nil {
609 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000610 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400611 }
612
613 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400614
615 //Update the device oper state and connection status
616 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400617 dh.device = cloned
618
David K. Bainbridge794735f2020-02-11 21:01:37 -0800619 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000620 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400621 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400622
623 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530624 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400625 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000626 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400627 }
628 for _, onuDevice := range onuDevices.Items {
629
630 // Update onu state as down in onu adapter
631 onuInd := oop.OnuIndication{}
632 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800633 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700634 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800635 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400636 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800637 "source": "openolt",
638 "onu-indicator": onuInd,
639 "device-type": onuDevice.Type,
640 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700641 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700642 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400643 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700644 /* Discovered ONUs entries need to be cleared , since after OLT
645 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530646 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000647 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700648 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530649}
650
651// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530652func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400653 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000654 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
655 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
656 grpc.WithInsecure(),
657 grpc.WithBlock(),
658 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000659 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000660 )),
661 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000662 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000663 )))
664
665 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530666 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530667 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000668 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400669 }
670 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530671}
672
673// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530674func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400675 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530676 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400677 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530678}
679
680// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530681func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530682 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000683 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400684
685 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530686 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
687 if err != nil || device == nil {
688 /*TODO: needs to handle error scenarios */
689 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
690 }
691 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000692 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400693
694 cloned := proto.Clone(device).(*voltha.Device)
695 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
696 cloned.OperStatus = voltha.OperStatus_UNKNOWN
697 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530698 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
699 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400700 }
701
Chaitrashree G S44124192019-08-07 20:21:36 -0400702 // Since the device was disabled before the OLT was rebooted, enforce the OLT to be Disabled after re-connection.
npujarec5762e2020-01-01 14:08:48 +0530703 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400704 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530705 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400706 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400707 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
708 // all the modules initialized and ready to handle incoming ONUs.
709
Thomas Lee S985938d2020-05-04 11:40:41 +0530710 err = dh.initializeDeviceHandlerModules(ctx)
711 if err != nil {
712 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400713 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400714
715 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800716 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530717 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400718 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800719 }
720 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700721
722 go startHeartbeatCheck(ctx, dh)
723
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400724 return nil
725 }
726
Neha Sharma8f4e4322020-08-06 10:51:53 +0000727 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400728 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400729 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400730 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400731 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400732 dh.populateActivePorts(ctx, ports)
733 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
734 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400735 }
736
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400737 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530738 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400739 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530740
cuilin20187b2a8c32019-03-26 19:52:28 -0700741 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800742 go func() {
743 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400744 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800745 }
746 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000747 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000748
749 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000750 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000751 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700752
753 go startHeartbeatCheck(ctx, dh)
754
cuilin20187b2a8c32019-03-26 19:52:28 -0700755 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530756}
757
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400758func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000759 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400760
761 if err != nil {
762 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
763 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700764 dh.totalPonPorts = deviceInfo.GetPonPorts()
765
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400766 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000767 if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, deviceInfo); dh.resourceMgr == nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400768 return olterrors.ErrResourceManagerInstantiating
769 }
770
Girish Gowdra9602eb42020-09-09 15:50:39 -0700771 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400772
Girish Gowdra9602eb42020-09-09 15:50:39 -0700773 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
774 for i := range dh.flowMgr {
775 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700776 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700777 return olterrors.ErrResourceManagerInstantiating
778 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400779 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700780
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400781 /* TODO: Instantiate Alarm , stats , BW managers */
782 /* Instantiating Event Manager to handle Alarms and KPIs */
783 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
784
785 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000786 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400787
788 return nil
789
790}
791
Neha Sharma96b7bf22020-06-15 10:37:32 +0000792func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400793 var err error
794 var deviceInfo *oop.DeviceInfo
795
Neha Sharma8f4e4322020-08-06 10:51:53 +0000796 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400797
798 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000799 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400800 }
801 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000802 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400803 }
804
Neha Sharma96b7bf22020-06-15 10:37:32 +0000805 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400806 dh.device.Root = true
807 dh.device.Vendor = deviceInfo.Vendor
808 dh.device.Model = deviceInfo.Model
809 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
810 dh.device.HardwareVersion = deviceInfo.HardwareVersion
811 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
812
813 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000814 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400815 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000816 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400817 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000818 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400819 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000820 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400821 dh.device.MacAddress = genmac
822 } else {
823 dh.device.MacAddress = deviceInfo.DeviceId
824 }
825
826 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000827 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000828 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400829 }
830
831 return deviceInfo, nil
832}
833
Neha Sharma96b7bf22020-06-15 10:37:32 +0000834func startCollector(ctx context.Context, dh *DeviceHandler) {
835 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530836 for {
837 select {
838 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000839 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530840 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000841 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700842
Neha Sharma8f4e4322020-08-06 10:51:53 +0000843 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400844 if err != nil {
845 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
846 continue
847 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530848 for _, port := range ports {
849 // NNI Stats
850 if port.Type == voltha.Port_ETHERNET_NNI {
851 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
852 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000853 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
854 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
855 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530856 }
857 // PON Stats
858 if port.Type == voltha.Port_PON_OLT {
859 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
860 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
861 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000862 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
863 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530864 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000865 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500866 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530867 }
868 }
869 }
870}
871
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700872//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530873func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400874 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000875 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530876 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530877
878 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400879 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
880 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530881 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530882}
883
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700884//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530885func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700886 return &ic.SwitchCapability{
887 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530888 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700889 HwDesc: "open_pon",
890 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700891 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700892 },
893 SwitchFeatures: &of.OfpSwitchFeatures{
894 NBuffers: 256,
895 NTables: 2,
896 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
897 of.OfpCapabilities_OFPC_TABLE_STATS |
898 of.OfpCapabilities_OFPC_PORT_STATS |
899 of.OfpCapabilities_OFPC_GROUP_STATS),
900 },
901 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530902}
903
Neha Sharma96b7bf22020-06-15 10:37:32 +0000904func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
905 logger.Debugw(ctx, "omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700906 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700907 var deviceID string
908 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700909
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400910 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700911 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000912 logger.Debugw(ctx, "recv-omci-msg", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id,
Matteo Scandolo92186242020-06-12 10:54:18 -0700913 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
914 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400915
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700916 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530917
918 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
919
Neha Sharma96b7bf22020-06-15 10:37:32 +0000920 logger.Debugw(ctx, "omci-indication-for-a-device-not-in-cache.", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700921 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700922 kwargs := make(map[string]interface{})
923 kwargs["onu_id"] = omciInd.OnuId
924 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700925
Neha Sharma8f4e4322020-08-06 10:51:53 +0000926 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700927 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530928 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700929 "intf-id": omciInd.IntfId,
930 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700931 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700932 deviceType = onuDevice.Type
933 deviceID = onuDevice.Id
934 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
935 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530936 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700937 } else {
938 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000939 logger.Debugw(ctx, "omci-indication-for-a-device-in-cache.", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530940 deviceType = onuInCache.(*OnuDevice).deviceType
941 deviceID = onuInCache.(*OnuDevice).deviceID
942 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700943 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700944
945 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +0000946 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530947 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800948 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530949 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530950 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800951 "destination": deviceType,
952 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000953 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700954 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800955 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530956}
957
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700958//ProcessInterAdapterMessage sends the proxied messages to the target device
959// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
960// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000961func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
962 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700963 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700964 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700965 fromTopic := msg.Header.FromTopic
966 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700967 toDeviceID := msg.Header.ToDeviceId
968 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700969
Neha Sharma96b7bf22020-06-15 10:37:32 +0000970 logger.Debugw(ctx, "omci-request-message-header", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
cuilin20187b2a8c32019-03-26 19:52:28 -0700971
972 msgBody := msg.GetBody()
973
974 omciMsg := &ic.InterAdapterOmciMessage{}
975 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000976 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700977 }
978
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700979 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000980 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700981 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530982 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800983 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000984 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700985 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000986 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
987 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530988 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800989 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000990 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800991 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700992 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000993 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
994 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530995 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800996 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000997 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800998 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700999 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001000 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001001 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001002 }
1003 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301004}
1005
Neha Sharma96b7bf22020-06-15 10:37:32 +00001006func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001007 var intfID uint32
1008 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001009 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001010 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001011 intfID = onuDevice.ProxyAddress.GetChannelId()
1012 onuID = onuDevice.ProxyAddress.GetOnuId()
1013 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001014 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001015 intfID = omciMsg.GetProxyAddress().GetChannelId()
1016 onuID = omciMsg.GetProxyAddress().GetOnuId()
1017 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001018 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001019 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001020 logger.Debugw(ctx, "onu-not-reachable--cannot-send-omci", log.Fields{"intf-id": intfID, "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001021
Thomas Lee S94109f12020-03-03 16:39:29 +05301022 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001023 "intf-id": intfID,
1024 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001025 }
1026
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001027 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1028 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001029 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001030 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1031 hex.Encode(hexPkt, omciMsg.Message)
1032 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1033
1034 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1035 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1036 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001037 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001038 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001039
Neha Sharma8f4e4322020-08-06 10:51:53 +00001040 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001041 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301042 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001043 "intf-id": intfID,
1044 "onu-id": onuID,
1045 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001046 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001047 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001048}
1049
David K. Bainbridge794735f2020-02-11 21:01:37 -08001050func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301051 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001052 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001053 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001054 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001055 // TODO: need resource manager
1056 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301057 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301058 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001059 st, _ := status.FromError(err)
1060 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001061 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1062
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001063 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301064 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001065 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001066 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001067 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001068 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001069 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001070}
1071
David K. Bainbridge794735f2020-02-11 21:01:37 -08001072func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001073 channelID := onuDiscInd.GetIntfId()
1074 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001075
Neha Sharma96b7bf22020-06-15 10:37:32 +00001076 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301077
cuilin20187b2a8c32019-03-26 19:52:28 -07001078 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001079 if sn != "" {
1080 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001081 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001082 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001083 }
1084
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301085 var alarmInd oop.OnuAlarmIndication
1086 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001087 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301088
1089 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1090 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1091 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1092 OnuLosRaise event sent for it */
1093 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1094 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1095 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001096 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301097 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1098 "currentIntfId": onuDiscInd.GetIntfId()})
1099 // TODO:: Should we need to ignore raising OnuLosClear event
1100 // when onu connected to different PON?
1101 }
1102 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1103 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1104 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001105 go func() {
1106 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1107 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1108 }
1109 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301110 }
1111 return true
1112 })
1113
Neha Sharma96b7bf22020-06-15 10:37:32 +00001114 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001115 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001116 }
1117
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001118 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001119
1120 // check the ONU is already know to the OLT
1121 // NOTE the second time the ONU is discovered this should return a device
1122 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1123
1124 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001125 logger.Debugw(ctx, "core-proxy-get-child-device-failed", log.Fields{"parentDevice": dh.device.Id, "err": err, "sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001126 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001127 logger.Debugw(ctx, "core-proxy-get-child-device-failed-with-code", log.Fields{"errCode": e.Code(), "sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001128 switch e.Code() {
1129 case codes.Internal:
1130 // this probably means NOT FOUND, so just create a new device
1131 onuDevice = nil
1132 case codes.DeadlineExceeded:
1133 // if the call times out, cleanup and exit
1134 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001135 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001136 }
1137 }
1138 }
1139
1140 if onuDevice == nil {
1141 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001142 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001143 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001144 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301145 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001146
Neha Sharma96b7bf22020-06-15 10:37:32 +00001147 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001148
1149 if err != nil {
1150 // if we can't create an ID in resource manager,
1151 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001152 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001153 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001154 "pon-intf-id": ponintfid,
1155 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001156 }
1157
Neha Sharma8f4e4322020-08-06 10:51:53 +00001158 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001159 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001160 dh.discOnus.Delete(sn)
1161 dh.resourceMgr.FreeonuID(ctx, ponintfid, []uint32{onuID}) // NOTE I'm not sure this method is actually cleaning up the right thing
Thomas Lee S94109f12020-03-03 16:39:29 +05301162 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001163 "pon-intf-id": ponintfid,
1164 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001165 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001166 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1167 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1168 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001169 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301170 log.Fields{"onuDevice": onuDevice,
1171 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001172 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301173 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001174 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001175
1176 // we can now use the existing ONU Id
1177 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001178 //Insert the ONU into cache to use in OnuIndication.
1179 //TODO: Do we need to remove this from the cache on ONU change, or wait for overwritten on next discovery.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001180 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001181 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301182 "intfId": onuDiscInd.GetIntfId(),
1183 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001184 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001185
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301186 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301187 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001188 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301189 log.Fields{"onu": onuDev,
1190 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001191
Kent Hagermane6ff1012020-07-14 15:07:53 -04001192 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301193 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001194 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001195 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001196 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001197 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001198 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301199 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001200 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001201 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001202 }
1203 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001204}
1205
Neha Sharma96b7bf22020-06-15 10:37:32 +00001206func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001207 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1208
1209 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001210 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001211 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001212 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001213 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001214 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301215 log.Fields{"onuId": onuInd.OnuId,
1216 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301217 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001218 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301219
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220 errFields := log.Fields{"device-id": dh.device.Id}
1221
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301222 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1223
Mahir Gunyele77977b2019-06-27 05:36:22 -07001224 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1225 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001226 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001227 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001228 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001229 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1230 if serialNumber != "" {
1231 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001232 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001233 } else {
1234 kwargs["onu_id"] = onuInd.OnuId
1235 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001236 errFields["onu-id"] = onuInd.OnuId
1237 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001238 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001239 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001240 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001241
David K. Bainbridge794735f2020-02-11 21:01:37 -08001242 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001243 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001244 }
1245
David K. Bainbridge794735f2020-02-11 21:01:37 -08001246 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001247 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001248 "previousIntfId": onuDevice.ParentPortNo,
1249 "currentIntfId": ponPort})
1250 }
1251
1252 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001253 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301254 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1255 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301256 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001257 }
1258 if !foundInCache {
1259 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1260
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301261 dh.onus.Store(onuKey, NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuInd.GetOnuId(), onuInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001262
1263 }
kesavand7cf3a052020-08-28 12:49:18 +05301264 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1265 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1266 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1267 }
1268 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001269 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001270 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001271 }
1272 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001273}
1274
Neha Sharma96b7bf22020-06-15 10:37:32 +00001275func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001276 logger.Debugw(ctx, "onu-indication-for-state", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Girish Gowdra748de5c2020-07-01 10:27:52 -07001277 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1278 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1279 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1280 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001281 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001282 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1283 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001284 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001285 onuInd.OperState = "down"
1286 }
1287 }
1288
David K. Bainbridge794735f2020-02-11 21:01:37 -08001289 switch onuInd.OperState {
1290 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001291 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001292 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301293 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001294 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1295 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301296 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001297 "onu-indicator": onuInd,
1298 "source": "openolt",
1299 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001300 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001301 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001302 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001303 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Matt Jeanneret53539512019-07-20 14:47:02 -04001304 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301305 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001306 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1307 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301308 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001309 "onu-indicator": onuInd,
1310 "source": "openolt",
1311 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001312 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001313 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001314 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001315 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001316 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001317 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001318}
1319
cuilin20187b2a8c32019-03-26 19:52:28 -07001320func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1321 if serialNum != nil {
1322 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001323 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001324 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001325}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001326func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1327 decodedStr, err := hex.DecodeString(serialNum[4:])
1328 if err != nil {
1329 return nil, err
1330 }
1331 return &oop.SerialNumber{
1332 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001333 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001334 }, nil
1335}
cuilin20187b2a8c32019-03-26 19:52:28 -07001336
1337func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1338 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001339 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001340 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1341 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1342 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1343 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1344 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1345 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1346 return tmp
1347}
1348
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001349//UpdateFlowsBulk upates the bulk flow
1350func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301351 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001352}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001353
1354//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001355func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1356 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301357 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001358 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301359 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001360 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001361 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001362 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001363 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001364 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001365 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001366 "intf-id": parentPort,
1367 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001368 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001369 logger.Debugw(ctx, "successfully-received-child-device-from-core", log.Fields{"child-device-id": onuDevice.Id, "child-device-sn": onuDevice.SerialNumber})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001370 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301371}
1372
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001373// SendPacketInToCore sends packet-in to core
1374// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1375// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001376func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001377 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001378 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001379 "port": logicalPort,
1380 "packet": hex.EncodeToString(packetPayload),
1381 "device-id": dh.device.Id,
1382 })
1383 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001384 if err := dh.coreProxy.SendPacketIn(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301385 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001386 "source": "adapter",
1387 "destination": "core",
1388 "device-id": dh.device.Id,
1389 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001390 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001391 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001392 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001393 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001394 "packet": hex.EncodeToString(packetPayload),
1395 "device-id": dh.device.Id,
1396 })
1397 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001398 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001399}
1400
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001401// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001402func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001403 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001404
1405 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1406 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001407 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001408 }
1409
Kent Hagermane6ff1012020-07-14 15:07:53 -04001410 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001411 metrics := dh.metrics.GetSubscriberMetrics()
1412 for _, m := range pmConfigs.Metrics {
1413 metrics[m.Name].Enabled = m.Enabled
1414
1415 }
1416 }
1417}
1418
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001419//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301420func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001421 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
Andrea Campanellac63bba92020-03-10 17:01:04 +01001422
1423 var errorsList []error
1424
Girish Gowdru0c588b22019-04-23 23:24:56 -04001425 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001426 for _, flow := range flows.ToRemove.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001427 ponIf := dh.getPonIfFromFlow(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001428
Neha Sharma96b7bf22020-06-15 10:37:32 +00001429 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301430 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001431 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301432 "flowToRemove": flow})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001433 err := dh.flowMgr[ponIf].RemoveFlow(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001434 if err != nil {
1435 errorsList = append(errorsList, err)
1436 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001437 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301438
1439 for _, flow := range flows.ToAdd.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001440 ponIf := dh.getPonIfFromFlow(ctx, flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001441 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301442 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001443 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301444 "flowToAdd": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001445 // If there are active Flow Remove in progress for a given subscriber, wait until it completes
Girish Gowdra9602eb42020-09-09 15:50:39 -07001446 err := dh.flowMgr[ponIf].AddFlow(ctx, flow, flowMetadata)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001447 if err != nil {
1448 errorsList = append(errorsList, err)
1449 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301450 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001451 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001452
Girish Gowdracefae192020-03-19 18:14:10 -07001453 // Whether we need to synchronize multicast group adds and modifies like flow add and delete needs to be investigated
Esin Karamanccb714b2019-11-29 15:02:06 +00001454 if groups != nil {
1455 for _, group := range groups.ToAdd.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001456 err := dh.groupMgr.AddGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001457 if err != nil {
1458 errorsList = append(errorsList, err)
1459 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001460 }
1461 for _, group := range groups.ToUpdate.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001462 err := dh.groupMgr.ModifyGroup(ctx, group)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001463 if err != nil {
1464 errorsList = append(errorsList, err)
1465 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001466 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001467 for _, group := range groups.ToRemove.Items {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001468 err := dh.groupMgr.DeleteGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001469 if err != nil {
1470 errorsList = append(errorsList, err)
1471 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001472 }
1473 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001474 if len(errorsList) > 0 {
1475 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1476 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001477 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001478 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301479}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001480
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001481//DisableDevice disables the given device
1482//It marks the following for the given device:
1483//Device-Handler Admin-State : down
1484//Device Port-State: UNKNOWN
1485//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001486func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001487 /* On device disable ,admin state update has to be done prior sending request to agent since
1488 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001489 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001490 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001491 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001492 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001493 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001494 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001495 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001496 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001497 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001498 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301499
1500 dh.discOnus = sync.Map{}
1501 dh.onus = sync.Map{}
1502
Thomas Lee S85f37312020-04-03 17:06:12 +05301503 //stopping the stats collector
1504 dh.stopCollector <- true
1505
Neha Sharma96b7bf22020-06-15 10:37:32 +00001506 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001507 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301508 //Update device Admin state
1509 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001510 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
Neha Sharma8f4e4322020-08-06 10:51:53 +00001511 if err := dh.coreProxy.PortsStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001512 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001513 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001514 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001515 return nil
1516}
1517
Neha Sharma96b7bf22020-06-15 10:37:32 +00001518func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001519 // Update onu state as unreachable in onu adapter
1520 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301521 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001522 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001523 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001524 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001525 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "error": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001526 }
1527 if onuDevices != nil {
1528 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001529 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001530 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1531 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001532 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301533 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001534 }
1535
1536 }
1537 }
1538
1539}
1540
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001541//ReenableDevice re-enables the olt device after disable
1542//It marks the following for the given device:
1543//Device-Handler Admin-State : up
1544//Device Port-State: ACTIVE
1545//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001546func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001547 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301548 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001549 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301550 }
1551 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001552 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001553
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001554 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001555
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001556 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1557 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001558 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001559 }
1560 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001561 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001562 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001563 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001564 device.OperStatus = voltha.OperStatus_ACTIVE
1565 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001566
Neha Sharma8f4e4322020-08-06 10:51:53 +00001567 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301568 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001569 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001570 "connect-status": device.ConnectStatus,
1571 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001572 }
kesavand39e0aa32020-01-28 20:58:50 -05001573
Neha Sharma96b7bf22020-06-15 10:37:32 +00001574 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001575
1576 return nil
1577}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001578
npujarec5762e2020-01-01 14:08:48 +05301579func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001580 var uniID uint32
1581 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301582 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001583 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001584 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001585 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001586 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001587 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001588 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001589 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301590 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001591 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301592 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001594 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301596 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001597 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001598 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001599 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301600 }
npujarec5762e2020-01-01 14:08:48 +05301601 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1602 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001603 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301604 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001605 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001606 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 logger.Debugw(ctx, "failed-to-remove-gemport-pkt-in", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001608 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001609 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1610 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1611 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001612 }
1613 return nil
1614}
1615
npujarec5762e2020-01-01 14:08:48 +05301616func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001617 nniUniID := -1
1618 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301619
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001620 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301621 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001622 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001623 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301624 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301625 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001626 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001627 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001628 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301629 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301630 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001631 _ = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, nniIntfID, -1, -1)
1632
Devmalya Paul495b94a2019-08-27 19:42:00 -04001633 }
npujarec5762e2020-01-01 14:08:48 +05301634 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001635 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301636 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001637
David K. Bainbridge794735f2020-02-11 21:01:37 -08001638 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001639}
1640
1641// DeleteDevice deletes the device instance from openolt handler array. Also clears allocated resource manager resources. Also reboots the OLT hardware!
npujarec5762e2020-01-01 14:08:48 +05301642func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001643 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001644 /* Clear the KV store data associated with the all the UNI ports
1645 This clears up flow data and also resource map data for various
1646 other pon resources like alloc_id and gemport_id
1647 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001648 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001649 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001650 // Stop the Stats collector
1651 dh.stopCollector <- true
1652 // stop the heartbeat check routine
1653 dh.stopHeartbeatCheck <- true
1654 //Reset the state
1655 if dh.Client != nil {
1656 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301657 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001658 }
1659 }
1660 cloned := proto.Clone(device).(*voltha.Device)
1661 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1662 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1663 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1664 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1665 "device-id": device.Id,
1666 "connect-status": cloned.ConnectStatus,
1667 "oper-status": cloned.OperStatus}, err).Log()
1668 }
1669 return nil
1670}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001671func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001672
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001673 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301674 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001675 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301676 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301677 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301678 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001679 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001680 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001681 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301682 }
1683 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301684 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001685 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301686 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001687 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301688 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301689 // Clear flowids for gem cache.
1690 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301691