blob: 246348234a20e5365c3c1a74a17e7841ec614e0a [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"
Esin Karamanccb714b2019-11-29 15:02:06 +000035 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
Kent Hagermanf1db18b2020-07-08 13:38:15 -040036 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
Esin Karamanccb714b2019-11-29 15:02:06 +000037 "github.com/opencord/voltha-lib-go/v3/pkg/log"
38 "github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics"
Thomas Lee S94109f12020-03-03 16:39:29 +053039 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080040 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Esin Karamanccb714b2019-11-29 15:02:06 +000041 "github.com/opencord/voltha-protos/v3/go/common"
42 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
43 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
44 oop "github.com/opencord/voltha-protos/v3/go/openolt"
45 "github.com/opencord/voltha-protos/v3/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070046 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040047 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040048 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053049)
50
salmansiddiqui7ac62132019-08-22 03:58:50 +000051// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040052const (
salmansiddiqui7ac62132019-08-22 03:58:50 +000053 MaxRetry = 10
54 MaxTimeOutInMs = 500
Girish Gowdracefae192020-03-19 18:14:10 -070055 InvalidPort = 0xffffffff
Manikkaraj kb1d51442019-07-23 10:41:02 -040056)
57
Girish Gowdracefae192020-03-19 18:14:10 -070058// pendingFlowRemoveDataKey is key to pendingFlowRemoveDataPerSubscriber map
59type pendingFlowRemoveDataKey struct {
60 intfID uint32
61 onuID uint32
62 uniID uint32
63}
64
65// pendingFlowRemoveData is value stored in pendingFlowRemoveDataPerSubscriber map
66// This holds the number of pending flow removes and also a signal channel to
67// to indicate the receiver when all flow removes are handled
68type pendingFlowRemoveData struct {
69 pendingFlowRemoveCount uint32
70 allFlowsRemoved chan struct{}
71}
72
Phaneendra Manda4c62c802019-03-06 21:37:49 +053073//DeviceHandler will interact with the OLT device.
74type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070075 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053076 coreProxy adapterif.CoreProxy
77 AdapterProxy adapterif.AdapterProxy
78 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070079 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070080 exitChannel chan int
81 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053082 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070083 transitionMap *TransitionMap
84 clientCon *grpc.ClientConn
manikkaraj kbf256be2019-03-25 00:13:48 +053085 flowMgr *OpenOltFlowMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040086 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053087 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053088
Girish Gowdra3ab6d212020-03-24 17:33:15 -070089 discOnus sync.Map
90 onus sync.Map
91 portStats *OpenOltStatisticsMgr
92 metrics *pmmetrics.PmMetrics
93 stopCollector chan bool
94 stopHeartbeatCheck chan bool
95 activePorts sync.Map
96 stopIndications chan bool
97 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070098
99 // pendingFlowRemoveDataPerSubscriber map is used to maintain the context on a per
100 // subscriber basis for the number of pending flow removes. This data is used
101 // to process all the flow removes for a subscriber before handling flow adds.
102 // Interleaving flow delete and flow add processing has known to cause PON resource
103 // management contentions on a per subscriber bases, so we need ensure ordering.
104 pendingFlowRemoveDataPerSubscriber map[pendingFlowRemoveDataKey]pendingFlowRemoveData
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700105}
106
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700107//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700108type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700109 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700110 deviceType string
111 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700112 onuID uint32
113 intfID uint32
114 proxyDeviceID string
A R Karthick1f85b802019-10-11 05:06:05 +0000115 uniPorts map[uint32]struct{}
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530116 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400117 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700118}
119
Naga Manjunath7615e552019-10-11 22:35:47 +0530120var pmNames = []string{
121 "rx_bytes",
122 "rx_packets",
123 "rx_mcast_packets",
124 "rx_bcast_packets",
125 "tx_bytes",
126 "tx_packets",
127 "tx_mcast_packets",
128 "tx_bcast_packets",
129}
130
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700131//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530132func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700133 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700134 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700135 device.deviceType = deviceTp
136 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700137 device.onuID = onuID
138 device.intfID = intfID
139 device.proxyDeviceID = proxyDevID
A R Karthick1f85b802019-10-11 05:06:05 +0000140 device.uniPorts = make(map[uint32]struct{})
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530141 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700142 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530143}
144
145//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530146func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700147 var dh DeviceHandler
148 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400149 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400150 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700151 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700152 dh.device = cloned
153 dh.openOLT = adapter
154 dh.exitChannel = make(chan int, 1)
155 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530156 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530157 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530158 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 -0500159 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400160 dh.stopIndications = make(chan bool, 1)
Girish Gowdracefae192020-03-19 18:14:10 -0700161 dh.pendingFlowRemoveDataPerSubscriber = make(map[pendingFlowRemoveDataKey]pendingFlowRemoveData)
162
cuilin20187b2a8c32019-03-26 19:52:28 -0700163 //TODO initialize the support classes.
164 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530165}
166
167// start save the device to the data model
168func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700169 dh.lockDevice.Lock()
170 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000171 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700172 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000173 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530174}
175
176// stop stops the device dh. Not much to do for now
177func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700178 dh.lockDevice.Lock()
179 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000180 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700181 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000182 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530183}
184
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400185func macifyIP(ip net.IP) string {
186 if len(ip) > 0 {
187 oct1 := strconv.FormatInt(int64(ip[12]), 16)
188 oct2 := strconv.FormatInt(int64(ip[13]), 16)
189 oct3 := strconv.FormatInt(int64(ip[14]), 16)
190 oct4 := strconv.FormatInt(int64(ip[15]), 16)
191 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
192 }
193 return ""
194}
195
Neha Sharma96b7bf22020-06-15 10:37:32 +0000196func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400197 var genmac string
198 var addr net.IP
199 var ips []string
200 var err error
201
Neha Sharma96b7bf22020-06-15 10:37:32 +0000202 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400203
204 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000205 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400206
207 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000208 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400209 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000210 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400211 }
212 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000213 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530214 log.Fields{"host": ips[0],
215 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400216 return genmac, nil
217 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000218 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400219 }
220
221 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000222 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530223 log.Fields{"host": host,
224 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400225 return genmac, nil
226}
227
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530228func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700229 slist := strings.Split(mac, ":")
230 result := make([]uint32, len(slist))
231 var err error
232 var tmp int64
233 for index, val := range slist {
234 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
235 return []uint32{1, 2, 3, 4, 5, 6}
236 }
237 result[index] = uint32(tmp)
238 }
239 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530240}
241
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700242//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 -0800243func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530244
David K. Bainbridge794735f2020-02-11 21:01:37 -0800245 switch portType {
246 case voltha.Port_ETHERNET_NNI:
247 return fmt.Sprintf("nni-%d", portNum), nil
248 case voltha.Port_PON_OLT:
249 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700250 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800251
Girish Kumarf26e4882020-03-05 06:49:10 +0000252 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530253}
254
Neha Sharma96b7bf22020-06-15 10:37:32 +0000255func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000256 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700257 if state == "up" {
258 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500259 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500260 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700261 } else {
262 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500263 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700264 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700265 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400266 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800267 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000268 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400269 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500270
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400271 if port, err := dh.coreProxy.GetDevicePort(context.TODO(), dh.device.Id, portNum); err == nil && port.Type == portType {
272 log.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
273 if err := dh.coreProxy.PortStateUpdate(context.TODO(), dh.device.Id, portType, portNum, operStatus); err != nil {
274 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
275 "device-id": dh.device.Id,
276 "port-type": portType,
277 "port-number": portNum,
278 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500279 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400280 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500281 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400282 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700283 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400284 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700285 PortNo: portNum,
286 Label: label,
287 Type: portType,
288 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700289 OfpPort: &of.OfpPort{
290 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
291 Config: 0,
292 State: uint32(of.OfpPortState_OFPPS_LIVE),
293 Curr: capacity,
294 Advertised: capacity,
295 Peer: capacity,
296 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
297 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
298 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700299 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000300 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700301 // Synchronous call to update device - this method is run in its own go routine
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700302 if err := dh.coreProxy.PortCreated(context.TODO(), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000303 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800304 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000305 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400306 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000307 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530308 return nil
309}
310
Neha Sharma96b7bf22020-06-15 10:37:32 +0000311func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) error {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530312 dh.lockDevice.Lock()
313 defer dh.lockDevice.Unlock()
314 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
315 if err != nil || device == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000316 logger.Errorf(ctx, "device", log.Fields{"device-id": dh.device.Id}, err)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530317 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
318 }
319 dh.device = device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800320 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530321}
322
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700323// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530324// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800325func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000326 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700327 defer func() {
328 dh.lockDevice.Lock()
329 dh.isReadIndicationRoutineActive = false
330 dh.lockDevice.Unlock()
331 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700332 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700333 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700334 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700335 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400336 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530337 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400338 if err != nil || device == nil {
339 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000340 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400341 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400342
David Bainbridgef5879ca2019-12-13 21:17:54 +0000343 // Create an exponential backoff around re-enabling indications. The
344 // maximum elapsed time for the back off is set to 0 so that we will
345 // continue to retry. The max interval defaults to 1m, but is set
346 // here for code clarity
347 indicationBackoff := backoff.NewExponentialBackOff()
348 indicationBackoff.MaxElapsedTime = 0
349 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700350
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700351 dh.lockDevice.Lock()
352 dh.isReadIndicationRoutineActive = true
353 dh.lockDevice.Unlock()
354
Girish Gowdra3f974912020-03-23 20:35:18 -0700355Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700356 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400357 select {
358 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000359 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700360 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400361 default:
362 indication, err := indications.Recv()
363 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000364 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530365 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530366 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400367 // Use an exponential back off to prevent getting into a tight loop
368 duration := indicationBackoff.NextBackOff()
369 if duration == backoff.Stop {
370 // If we reach a maximum then warn and reset the backoff
371 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000372 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530373 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530374 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400375 indicationBackoff.Reset()
376 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700377
378 // On failure process a backoff timer while watching for stopIndications
379 // events
380 backoff := time.NewTimer(indicationBackoff.NextBackOff())
381 select {
382 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000383 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700384 if !backoff.Stop() {
385 <-backoff.C
386 }
387 break Loop
388 case <-backoff.C:
389 // backoff expired continue
390 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700391 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
392 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400393 }
394 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000395 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530396 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000397 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530398 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530399 "device-id": dh.device.Id})
400 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000401 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700402 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400403 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700404 // Close the stream, and re-initialize it
405 if err = indications.CloseSend(); err != nil {
406 // Ok to ignore here, because we landed here due to a problem on the stream
407 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000408 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530409 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530410 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700411 }
412 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
413 return err
414 }
415 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400416 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530417 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400418 // Reset backoff if we have a successful receive
419 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400420 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530421 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000422 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530423 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530424 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400425 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400426 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400427 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700428 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700429 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700430 // Close the send stream
431 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700432
Girish Gowdra3f974912020-03-23 20:35:18 -0700433 return nil
434}
435
436func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
437
438 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
439 if err != nil {
440 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
441 }
442 if indications == nil {
443 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
444 }
445
446 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400447}
448
449// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
450func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
451 switch indication.Data.(type) {
452 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
453 return true
454
455 default:
456 return false
457 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700458}
459
David K. Bainbridge794735f2020-02-11 21:01:37 -0800460func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000461 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000462 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530463 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700464 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530465 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700466 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000467 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000468 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530469 return olterrors.NewErrAdapter("failed-indication", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530470 "device_id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800471 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000472 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800473 }
474 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700475}
476
David K. Bainbridge794735f2020-02-11 21:01:37 -0800477// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530478func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400479 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700480 switch indication.Data.(type) {
481 case *oop.Indication_OltInd:
David K. Bainbridge794735f2020-02-11 21:01:37 -0800482 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530483 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800484 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700485 case *oop.Indication_IntfInd:
486 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800487 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000488 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530489 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800490 }
491 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000492 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700493 case *oop.Indication_IntfOperInd:
494 intfOperInd := indication.GetIntfOperInd()
495 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800496 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000497 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530498 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-nni", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800499 }
500 }()
npujarec5762e2020-01-01 14:08:48 +0530501 dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700502 } else if intfOperInd.GetType() == "pon" {
503 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
504 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800505 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000506 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530507 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 -0800508 }
509 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000510 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700511 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000512 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530513 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530514 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515 case *oop.Indication_OnuDiscInd:
516 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000517 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700518 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800519 go func() {
520 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530521 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 -0800522 }
523 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700524 case *oop.Indication_OnuInd:
525 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000526 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800527 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000528 if err := dh.onuIndication(ctx, onuInd); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530529 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800530 }
531 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700532 case *oop.Indication_OmciInd:
533 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000534 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 -0800535 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000536 if err := dh.omciIndication(ctx, omciInd); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530537 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800538 }
539 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700540 case *oop.Indication_PktInd:
541 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 {
Thomas Lee S985938d2020-05-04 11:40:41 +0530563 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:
567 portStats := indication.GetPortStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000568 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.resourceMgr.DevInfo.GetPonPorts())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700569 case *oop.Indication_FlowStats:
570 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000571 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700572 case *oop.Indication_AlarmInd:
573 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000574 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
575 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700576 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530577}
578
579// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530580func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530581 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000582 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530583
Girish Gowdru0c588b22019-04-23 23:24:56 -0400584 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530585 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400586 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000587 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400588 }
589 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530590}
591
592// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530593func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700594 dh.lockDevice.Lock()
595 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000596 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400597
npujarec5762e2020-01-01 14:08:48 +0530598 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400599 if err != nil || device == nil {
600 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000601 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400602 }
603
604 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400605
606 //Update the device oper state and connection status
607 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400608 dh.device = cloned
609
David K. Bainbridge794735f2020-02-11 21:01:37 -0800610 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000611 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400612 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400613
614 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530615 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400616 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000617 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400618 }
619 for _, onuDevice := range onuDevices.Items {
620
621 // Update onu state as down in onu adapter
622 onuInd := oop.OnuIndication{}
623 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800624 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700625 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800626 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530627 olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800628 "source": "openolt",
629 "onu-indicator": onuInd,
630 "device-type": onuDevice.Type,
631 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700632 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700633 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400634 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700635 /* Discovered ONUs entries need to be cleared , since after OLT
636 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530637 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000638 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700639 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530640}
641
642// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530643func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400644 var err error
David K. Bainbridge794735f2020-02-11 21:01:37 -0800645 if dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure(), grpc.WithBlock()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530646 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530647 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000648 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400649 }
650 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530651}
652
653// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530654func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400655 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530656 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400657 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530658}
659
660// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530661func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530662 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000663 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400664
665 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530666 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
667 if err != nil || device == nil {
668 /*TODO: needs to handle error scenarios */
669 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
670 }
671 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000672 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400673
674 cloned := proto.Clone(device).(*voltha.Device)
675 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
676 cloned.OperStatus = voltha.OperStatus_UNKNOWN
677 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530678 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
679 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 -0400680 }
681
Chaitrashree G S44124192019-08-07 20:21:36 -0400682 // 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 +0530683 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400684 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530685 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400686 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400687 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
688 // all the modules initialized and ready to handle incoming ONUs.
689
Thomas Lee S985938d2020-05-04 11:40:41 +0530690 err = dh.initializeDeviceHandlerModules(ctx)
691 if err != nil {
692 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 -0400693 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400694
695 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800696 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530697 if err = dh.readIndications(ctx); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530698 olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800699 }
700 }()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400701 return nil
702 }
703
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400704 ports, err := dh.coreProxy.ListDevicePorts(context.TODO(), dh.device.Id)
705 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400706 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400707 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400708 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400709 dh.populateActivePorts(ctx, ports)
710 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
711 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400712 }
713
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400714 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530715 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 -0400716 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530717
cuilin20187b2a8c32019-03-26 19:52:28 -0700718 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800719 go func() {
720 if err := dh.readIndications(ctx); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530721 olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800722 }
723 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000724 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000725
726 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000727 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000728 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700729 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530730}
731
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400732func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000733 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400734
735 if err != nil {
736 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
737 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400738 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000739 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 -0400740 return olterrors.ErrResourceManagerInstantiating
741 }
742
743 // Instantiate flow manager
744 if dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr); dh.flowMgr == nil {
745 return olterrors.ErrResourceManagerInstantiating
746
747 }
748 /* TODO: Instantiate Alarm , stats , BW managers */
749 /* Instantiating Event Manager to handle Alarms and KPIs */
750 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
751
752 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000753 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400754
755 return nil
756
757}
758
Neha Sharma96b7bf22020-06-15 10:37:32 +0000759func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400760 var err error
761 var deviceInfo *oop.DeviceInfo
762
763 deviceInfo, err = dh.Client.GetDeviceInfo(context.Background(), new(oop.Empty))
764
765 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000766 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400767 }
768 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000769 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400770 }
771
Neha Sharma96b7bf22020-06-15 10:37:32 +0000772 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400773 dh.device.Root = true
774 dh.device.Vendor = deviceInfo.Vendor
775 dh.device.Model = deviceInfo.Model
776 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
777 dh.device.HardwareVersion = deviceInfo.HardwareVersion
778 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
779
780 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000781 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400782 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000783 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400784 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000785 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400786 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000787 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400788 dh.device.MacAddress = genmac
789 } else {
790 dh.device.MacAddress = deviceInfo.DeviceId
791 }
792
793 // Synchronous call to update device - this method is run in its own go routine
794 if err := dh.coreProxy.DeviceUpdate(context.TODO(), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000795 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400796 }
797
798 return deviceInfo, nil
799}
800
Neha Sharma96b7bf22020-06-15 10:37:32 +0000801func startCollector(ctx context.Context, dh *DeviceHandler) {
802 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530803 for {
804 select {
805 case <-dh.stopCollector:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000806 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"deviceID:": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530807 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000808 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700809
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400810 ports, err := dh.coreProxy.ListDevicePorts(context.Background(), dh.device.Id)
811 if err != nil {
812 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
813 continue
814 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530815 for _, port := range ports {
816 // NNI Stats
817 if port.Type == voltha.Port_ETHERNET_NNI {
818 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
819 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000820 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
821 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
822 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530823 }
824 // PON Stats
825 if port.Type == voltha.Port_PON_OLT {
826 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
827 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
828 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000829 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
830 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530831 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000832 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500833 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530834 }
835 }
836 }
837}
838
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700839//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530840func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400841 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000842 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530843 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530844
845 // Now, set the initial PM configuration for that device
846 if err := dh.coreProxy.DevicePMConfigUpdate(nil, dh.metrics.ToPmConfigs()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530847 olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530848 }
849
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400850 go startHeartbeatCheck(ctx, dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530851}
852
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700853//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530854func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700855 return &ic.SwitchCapability{
856 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530857 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700858 HwDesc: "open_pon",
859 SwDesc: "open_pon",
860 SerialNum: dh.device.SerialNumber,
861 },
862 SwitchFeatures: &of.OfpSwitchFeatures{
863 NBuffers: 256,
864 NTables: 2,
865 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
866 of.OfpCapabilities_OFPC_TABLE_STATS |
867 of.OfpCapabilities_OFPC_PORT_STATS |
868 of.OfpCapabilities_OFPC_GROUP_STATS),
869 },
870 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530871}
872
Neha Sharma96b7bf22020-06-15 10:37:32 +0000873func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
874 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 -0700875 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700876 var deviceID string
877 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700878
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400879 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700880 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000881 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 -0700882 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
883 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400884
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700885 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530886
887 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
888
Neha Sharma96b7bf22020-06-15 10:37:32 +0000889 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 -0700890 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700891 kwargs := make(map[string]interface{})
892 kwargs["onu_id"] = omciInd.OnuId
893 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700894
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700895 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
896 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530897 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700898 "intf-id": omciInd.IntfId,
899 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700900 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700901 deviceType = onuDevice.Type
902 deviceID = onuDevice.Id
903 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
904 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530905 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700906 } else {
907 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000908 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 +0530909 deviceType = onuInCache.(*OnuDevice).deviceType
910 deviceID = onuInCache.(*OnuDevice).deviceID
911 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700912 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700913
914 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
David K. Bainbridge794735f2020-02-11 21:01:37 -0800915 if err := dh.AdapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530916 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800917 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530918 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530919 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800920 "destination": deviceType,
921 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000922 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700923 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800924 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530925}
926
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700927//ProcessInterAdapterMessage sends the proxied messages to the target device
928// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
929// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000930func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
931 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700932 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700933 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700934 fromTopic := msg.Header.FromTopic
935 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700936 toDeviceID := msg.Header.ToDeviceId
937 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700938
Neha Sharma96b7bf22020-06-15 10:37:32 +0000939 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 -0700940
941 msgBody := msg.GetBody()
942
943 omciMsg := &ic.InterAdapterOmciMessage{}
944 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000945 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700946 }
947
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700948 if omciMsg.GetProxyAddress() == nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700949 onuDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, toDeviceID)
950 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530951 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800952 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000953 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700954 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000955 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
956 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530957 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800958 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000959 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800960 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700961 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000962 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
963 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530964 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800965 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000966 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800967 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700968 }
969
970 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +0000971 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -0700972 }
973 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530974}
975
Neha Sharma96b7bf22020-06-15 10:37:32 +0000976func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700977 var intfID uint32
978 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +0000979 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700980 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700981 intfID = onuDevice.ProxyAddress.GetChannelId()
982 onuID = onuDevice.ProxyAddress.GetOnuId()
983 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700984 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700985 intfID = omciMsg.GetProxyAddress().GetChannelId()
986 onuID = omciMsg.GetProxyAddress().GetOnuId()
987 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700988 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700989 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000990 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 -0800991
Thomas Lee S94109f12020-03-03 16:39:29 +0530992 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700993 "intf-id": intfID,
994 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -0700995 }
996
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400997 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
998 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -0700999 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001000 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1001 hex.Encode(hexPkt, omciMsg.Message)
1002 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1003
1004 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1005 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1006 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001007 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001008 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001009
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001010 _, err := dh.Client.OmciMsgOut(context.Background(), omciMessage)
1011 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301012 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001013 "intf-id": intfID,
1014 "onu-id": onuID,
1015 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001016 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001017 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001018}
1019
David K. Bainbridge794735f2020-02-11 21:01:37 -08001020func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001021 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id})
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001022 if err := dh.flowMgr.UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001023 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001024 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001025 // TODO: need resource manager
1026 var pir uint32 = 1000000
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001027 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir}
npujarec5762e2020-01-01 14:08:48 +05301028 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001029 st, _ := status.FromError(err)
1030 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001031 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1032
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001033 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301034 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001035 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001036 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001037 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001038 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001039 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001040}
1041
David K. Bainbridge794735f2020-02-11 21:01:37 -08001042func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001043
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001044 channelID := onuDiscInd.GetIntfId()
1045 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001046
Neha Sharma96b7bf22020-06-15 10:37:32 +00001047 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301048
cuilin20187b2a8c32019-03-26 19:52:28 -07001049 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001050 if sn != "" {
1051 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001052 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001053 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001054 }
1055
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301056 var alarmInd oop.OnuAlarmIndication
1057 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001058 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301059
1060 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1061 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1062 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1063 OnuLosRaise event sent for it */
1064 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1065 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1066 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001067 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301068 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1069 "currentIntfId": onuDiscInd.GetIntfId()})
1070 // TODO:: Should we need to ignore raising OnuLosClear event
1071 // when onu connected to different PON?
1072 }
1073 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1074 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1075 alarmInd.LosStatus = statusCheckOff
Neha Sharma96b7bf22020-06-15 10:37:32 +00001076 go dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs)
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301077 }
1078 return true
1079 })
1080
Neha Sharma96b7bf22020-06-15 10:37:32 +00001081 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001082 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001083 }
1084
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001085 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001086
1087 // check the ONU is already know to the OLT
1088 // NOTE the second time the ONU is discovered this should return a device
1089 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1090
1091 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001092 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 -08001093 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001094 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 -08001095 switch e.Code() {
1096 case codes.Internal:
1097 // this probably means NOT FOUND, so just create a new device
1098 onuDevice = nil
1099 case codes.DeadlineExceeded:
1100 // if the call times out, cleanup and exit
1101 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001102 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001103 }
1104 }
1105 }
1106
1107 if onuDevice == nil {
1108 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001109 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001110 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001111 ponintfid := onuDiscInd.GetIntfId()
1112 dh.lockDevice.Lock()
npujarec5762e2020-01-01 14:08:48 +05301113 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Matt Jeanneret53539512019-07-20 14:47:02 -04001114 dh.lockDevice.Unlock()
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001115
Neha Sharma96b7bf22020-06-15 10:37:32 +00001116 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001117
1118 if err != nil {
1119 // if we can't create an ID in resource manager,
1120 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001121 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001122 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001123 "pon-intf-id": ponintfid,
1124 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001125 }
1126
1127 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(context.TODO(), dh.device.Id, int(parentPortNo),
1128 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001129 dh.discOnus.Delete(sn)
1130 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 +05301131 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001132 "pon-intf-id": ponintfid,
1133 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001134 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001135 dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano())
1136 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301137 log.Fields{"onuDevice": onuDevice,
1138 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001139 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301140 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001141 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001142
1143 // we can now use the existing ONU Id
1144 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001145 //Insert the ONU into cache to use in OnuIndication.
1146 //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 +00001147 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001148 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301149 "intfId": onuDiscInd.GetIntfId(),
1150 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001151 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001152
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301153 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301154 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001155 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301156 log.Fields{"onu": onuDev,
1157 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001158
David K. Bainbridge794735f2020-02-11 21:01:37 -08001159 if err = dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301160 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001161 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001162 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001163 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001164 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001165 if err = dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301166 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001167 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001168 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001169 }
1170 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001171}
1172
Neha Sharma96b7bf22020-06-15 10:37:32 +00001173func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001174 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1175
1176 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001177 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001178 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001179 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001180 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001181 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301182 log.Fields{"onuId": onuInd.OnuId,
1183 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301184 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001185 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301186
David K. Bainbridge794735f2020-02-11 21:01:37 -08001187 errFields := log.Fields{"device-id": dh.device.Id}
1188
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301189 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1190
Mahir Gunyele77977b2019-06-27 05:36:22 -07001191 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1192 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001193 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
1194 onuDevice, err = dh.coreProxy.GetDevice(nil, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001195 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001196 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1197 if serialNumber != "" {
1198 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001199 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001200 } else {
1201 kwargs["onu_id"] = onuInd.OnuId
1202 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001203 errFields["onu-id"] = onuInd.OnuId
1204 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001205 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001206 onuDevice, err = dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001207 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001208
David K. Bainbridge794735f2020-02-11 21:01:37 -08001209 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001210 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001211 }
1212
David K. Bainbridge794735f2020-02-11 21:01:37 -08001213 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001214 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001215 "previousIntfId": onuDevice.ParentPortNo,
1216 "currentIntfId": ponPort})
1217 }
1218
1219 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001220 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301221 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1222 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301223 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001224 }
1225 if !foundInCache {
1226 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1227
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301228 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 -08001229
1230 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001231 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001232 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001233 }
1234 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001235}
1236
Neha Sharma96b7bf22020-06-15 10:37:32 +00001237func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
1238 ctx = context.TODO()
1239 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 -07001240 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1241 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1242 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1243 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001244 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001245 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1246 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001247 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001248 onuInd.OperState = "down"
1249 }
1250 }
1251
David K. Bainbridge794735f2020-02-11 21:01:37 -08001252 switch onuInd.OperState {
1253 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001254 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 -07001255 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301256 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001257 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1258 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301259 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001260 "onu-indicator": onuInd,
1261 "source": "openolt",
1262 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001263 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001264 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001265 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001266 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 -04001267 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301268 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001269 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1270 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301271 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001272 "onu-indicator": onuInd,
1273 "source": "openolt",
1274 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001275 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001276 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001277 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001278 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001279 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001280 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001281}
1282
cuilin20187b2a8c32019-03-26 19:52:28 -07001283func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1284 if serialNum != nil {
1285 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001286 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001287 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001288}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001289func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1290 decodedStr, err := hex.DecodeString(serialNum[4:])
1291 if err != nil {
1292 return nil, err
1293 }
1294 return &oop.SerialNumber{
1295 VendorId: []byte(serialNum[:4]),
1296 VendorSpecific: []byte(decodedStr),
1297 }, nil
1298}
cuilin20187b2a8c32019-03-26 19:52:28 -07001299
1300func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1301 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001302 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001303 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1304 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1305 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1306 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1307 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1308 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1309 return tmp
1310}
1311
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001312//UpdateFlowsBulk upates the bulk flow
1313func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301314 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001315}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001316
1317//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001318func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1319 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301320 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001321 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301322 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001323 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001324 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001325 kwargs["parent_port_no"] = parentPort
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001326 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001327 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001328 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001329 "intf-id": parentPort,
1330 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001331 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001332 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 -08001333 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301334}
1335
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001336// SendPacketInToCore sends packet-in to core
1337// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1338// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001339func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001340 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001341 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001342 "port": logicalPort,
1343 "packet": hex.EncodeToString(packetPayload),
1344 "device-id": dh.device.Id,
1345 })
1346 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001347 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301348 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001349 "source": "adapter",
1350 "destination": "core",
1351 "device-id": dh.device.Id,
1352 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001353 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001354 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001355 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001356 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001357 "packet": hex.EncodeToString(packetPayload),
1358 "device-id": dh.device.Id,
1359 })
1360 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001361 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001362}
1363
A R Karthick1f85b802019-10-11 05:06:05 +00001364// AddUniPortToOnu adds the uni port to the onu device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001365func (dh *DeviceHandler) AddUniPortToOnu(ctx context.Context, intfID, onuID, uniPort uint32) {
A R Karthick1f85b802019-10-11 05:06:05 +00001366 onuKey := dh.formOnuKey(intfID, onuID)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301367
1368 if onuDevice, ok := dh.onus.Load(onuKey); ok {
A R Karthick1f85b802019-10-11 05:06:05 +00001369 // add it to the uniPort map for the onu device
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301370 if _, ok = onuDevice.(*OnuDevice).uniPorts[uniPort]; !ok {
1371 onuDevice.(*OnuDevice).uniPorts[uniPort] = struct{}{}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001372 logger.Debugw(ctx, "adding-uni-port", log.Fields{"port": uniPort, "intf-id": intfID, "onuId": onuID})
A R Karthick1f85b802019-10-11 05:06:05 +00001373 }
1374 }
1375}
1376
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001377// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001378func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001379
Neha Sharma96b7bf22020-06-15 10:37:32 +00001380 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001381
1382 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1383 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001384 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001385 }
1386
1387 if pmConfigs.Grouped == false {
1388 metrics := dh.metrics.GetSubscriberMetrics()
1389 for _, m := range pmConfigs.Metrics {
1390 metrics[m.Name].Enabled = m.Enabled
1391
1392 }
1393 }
1394}
1395
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001396//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301397func (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 +00001398 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 +01001399
1400 var errorsList []error
1401
Girish Gowdru0c588b22019-04-23 23:24:56 -04001402 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001403 for _, flow := range flows.ToRemove.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001404 dh.incrementActiveFlowRemoveCount(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001405
Neha Sharma96b7bf22020-06-15 10:37:32 +00001406 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301407 log.Fields{"device-id": device.Id,
1408 "flowToRemove": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001409 err := dh.flowMgr.RemoveFlow(ctx, flow)
1410 if err != nil {
1411 errorsList = append(errorsList, err)
1412 }
1413
Neha Sharma96b7bf22020-06-15 10:37:32 +00001414 dh.decrementActiveFlowRemoveCount(ctx, flow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001415 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301416
1417 for _, flow := range flows.ToAdd.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001418 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301419 log.Fields{"device-id": device.Id,
1420 "flowToAdd": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001421 // If there are active Flow Remove in progress for a given subscriber, wait until it completes
Neha Sharma96b7bf22020-06-15 10:37:32 +00001422 dh.waitForFlowRemoveToFinish(ctx, flow)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001423 err := dh.flowMgr.AddFlow(ctx, flow, flowMetadata)
1424 if err != nil {
1425 errorsList = append(errorsList, err)
1426 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301427 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001428 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001429
Girish Gowdracefae192020-03-19 18:14:10 -07001430 // 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 +00001431 if groups != nil {
1432 for _, group := range groups.ToAdd.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001433 err := dh.flowMgr.AddGroup(ctx, group)
1434 if err != nil {
1435 errorsList = append(errorsList, err)
1436 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001437 }
1438 for _, group := range groups.ToUpdate.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001439 err := dh.flowMgr.ModifyGroup(ctx, group)
1440 if err != nil {
1441 errorsList = append(errorsList, err)
1442 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001443 }
1444 if len(groups.ToRemove.Items) != 0 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001445 logger.Debugw(ctx, "group-delete-operation-not-supported", log.Fields{"device-id": dh.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +00001446 }
1447 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001448 if len(errorsList) > 0 {
1449 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1450 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001451 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001452 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301453}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001454
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001455//DisableDevice disables the given device
1456//It marks the following for the given device:
1457//Device-Handler Admin-State : down
1458//Device Port-State: UNKNOWN
1459//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001460func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001461 /* On device disable ,admin state update has to be done prior sending request to agent since
1462 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001463 if dh.Client != nil {
1464 if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
1465 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001466 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001467 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001468 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001469 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001470 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001471 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001472 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301473
1474 dh.discOnus = sync.Map{}
1475 dh.onus = sync.Map{}
1476
Thomas Lee S85f37312020-04-03 17:06:12 +05301477 //stopping the stats collector
1478 dh.stopCollector <- true
1479
Neha Sharma96b7bf22020-06-15 10:37:32 +00001480 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001481 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301482 //Update device Admin state
1483 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001484 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001485 if err := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
1486 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001487 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001488 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001489 return nil
1490}
1491
Neha Sharma96b7bf22020-06-15 10:37:32 +00001492func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001493
1494 // Update onu state as unreachable in onu adapter
1495 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301496 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001497 //get the child device for the parent device
1498 onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
1499 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001500 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 -04001501 }
1502 if onuDevices != nil {
1503 for _, onuDevice := range onuDevices.Items {
1504 err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1505 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1506 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001507 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301508 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001509 }
1510
1511 }
1512 }
1513
1514}
1515
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001516//ReenableDevice re-enables the olt device after disable
1517//It marks the following for the given device:
1518//Device-Handler Admin-State : up
1519//Device Port-State: ACTIVE
1520//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001521func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301522 if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
1523 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001524 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301525 }
1526 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001527 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001528
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001529 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001530
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001531 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1532 if err != nil {
1533 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device": device.Id}, err)
1534 }
1535 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001536 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001537 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001538 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001539 device.OperStatus = voltha.OperStatus_ACTIVE
1540 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001541
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001542 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301543 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001544 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001545 "connect-status": device.ConnectStatus,
1546 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001547 }
kesavand39e0aa32020-01-28 20:58:50 -05001548
Neha Sharma96b7bf22020-06-15 10:37:32 +00001549 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001550
1551 return nil
1552}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001553
npujarec5762e2020-01-01 14:08:48 +05301554func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001555 var uniID uint32
1556 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301557 for _, port := range onu.UniPorts {
1558 uniID = UniIDFromPortNum(uint32(port))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001559 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001560 /* Delete tech-profile instance from the KV store */
npujarec5762e2020-01-01 14:08:48 +05301561 if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001562 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001563 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001564 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301565 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001566 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301567 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001568 }
npujarec5762e2020-01-01 14:08:48 +05301569 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001570 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301571 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001572 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001573 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001574 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301575 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001576 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001577 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001578 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301579 }
npujarec5762e2020-01-01 14:08:48 +05301580 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1581 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001582 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301583 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001584 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301585 if err = dh.resourceMgr.DelGemPortPktIn(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001586 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 +00001587 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001588 }
1589 return nil
1590}
1591
npujarec5762e2020-01-01 14:08:48 +05301592func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001593 nniUniID := -1
1594 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301595
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001596 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301597 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001598 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001599 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301600 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301601 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001602 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001603 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001604 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301605 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301606 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 logger.Debugw(ctx, "current-flow-ids-for-nni", log.Fields{"flow-ids": flowIDs})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301608 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301609 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301610 }
npujarec5762e2020-01-01 14:08:48 +05301611 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001612 }
npujarec5762e2020-01-01 14:08:48 +05301613 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001614 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301615 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001616 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001617}
1618
1619// 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 +05301620func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001621 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001622 /* Clear the KV store data associated with the all the UNI ports
1623 This clears up flow data and also resource map data for various
1624 other pon resources like alloc_id and gemport_id
1625 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001626 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001627 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001628 // Stop the Stats collector
1629 dh.stopCollector <- true
1630 // stop the heartbeat check routine
1631 dh.stopHeartbeatCheck <- true
1632 //Reset the state
1633 if dh.Client != nil {
1634 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301635 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001636 }
1637 }
1638 cloned := proto.Clone(device).(*voltha.Device)
1639 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1640 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1641 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1642 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1643 "device-id": device.Id,
1644 "connect-status": cloned.ConnectStatus,
1645 "oper-status": cloned.OperStatus}, err).Log()
1646 }
1647 return nil
1648}
1649func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) error {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001650 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301651 noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
1652 var ponPort uint32
1653 for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
1654 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301655 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301656 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301657 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001658 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001659 "pon-port": ponPort}, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301660 }
1661 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301662 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001663 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301664 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001665 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301666 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301667 // Clear flowids for gem cache.
1668 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301669 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301670 }
1671 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301672 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301673 }
npujarec5762e2020-01-01 14:08:48 +05301674 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301675 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301676 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301677 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001678 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001679 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001680 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001681 /* Clear the flows from KV store associated with NNI port.
1682 There are mostly trap rules from NNI port (like LLDP)
1683 */
npujarec5762e2020-01-01 14:08:48 +05301684 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001685 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001686 }
A R Karthick1f85b802019-10-11 05:06:05 +00001687
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001688 /* Clear the resource pool for each PON port in the background */
npujarec5762e2020-01-01 14:08:48 +05301689 go dh.resourceMgr.Delete(ctx)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001690 }
A R Karthick1f85b802019-10-11 05:06:05 +00001691
Devmalya Paul495b94a2019-08-27 19:42:00 -04001692 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301693 dh.onus.Range(func(key interface{}, value interface{}) bool {
1694 dh.onus.Delete(key)
1695 return true
1696 })
1697
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001698 /*Delete discovered ONU map for the device*/
1699 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1700 dh.discOnus.Delete(key)
1701 return true
1702 })
1703
Devmalya Paul495b94a2019-08-27 19:42:00 -04001704 return nil
1705}
1706
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001707//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001708func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001709 if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301710 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001711 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001712 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001713 return nil
1714}
1715
David K. Bainbridge794735f2020-02-11 21:01:37 -08001716func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001717 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001718 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001719 "packet-indication": *packetIn,
1720 "device-id": dh.device.Id,
1721 "packet": hex.EncodeToString(packetIn.Pkt),
1722 })
1723 }
npujarec5762e2020-01-01 14:08:48 +05301724 logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001725 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001726 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001727 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001728 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001729 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001730 "logical-port-num": logicalPortNum,
1731 "device-id": dh.device.Id,
1732 "packet": hex.EncodeToString(packetIn.Pkt),
1733 })
1734 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001735
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001736 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301737 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001738 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301739 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001740 "device-id": dh.device.Id,
1741 "packet": hex.EncodeToString(packetIn.Pkt),
1742 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001743 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001744
Matteo Scandolo92186242020-06-12 10:54:18 -07001745 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001746 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001747 "packet": hex.EncodeToString(packetIn.Pkt),
1748 "device-id": dh.device.Id,
1749 })
1750 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001751 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001752}
1753
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001754// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301755func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001756 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001757 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001758 "device-id": dh.device.Id,
1759 "egress-port-no": egressPortNo,
1760 "pkt-length": len(packet.Data),
1761 "packet": hex.EncodeToString(packet.Data),
1762 })
1763 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001764
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001765 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001766 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001767 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1768 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301769 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1770 // Do not packet-out lldp packets on uni port.
1771 // ONOS has no clue about uni/nni ports, it just packets out on all
1772 // available ports on the Logical Switch. It should not be interested
1773 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001774 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001775 "device-id": dh.device.Id,
1776 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301777 return nil
1778 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001779 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1780 if innerEthType == 0x8100 {
1781 // q-in-q 802.1ad or 802.1q double tagged packet.
1782 // slice out the outer tag.
1783 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001784 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001785 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001786 "packet-data": hex.EncodeToString(packet.Data),
1787 "device-id": dh.device.Id,
1788 })
1789 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001790 }
1791 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001792 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1793 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001794 uniID := UniIDFromPortNum(uint32(egressPortNo))
1795
npujarec5762e2020-01-01 14:08:48 +05301796 gemPortID, err := dh.flowMgr.GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001797 if err != nil {
1798 // In this case the openolt agent will receive the gemPortID as 0.
1799 // The agent tries to retrieve the gemPortID in this case.
1800 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001801 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001802 "intf-id": intfID,
1803 "onu-id": onuID,
1804 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001805 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301806 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001807 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001808 }
1809
1810 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001811
Matteo Scandolo92186242020-06-12 10:54:18 -07001812 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001813 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001814 "egress-port-no": egressPortNo,
1815 "intf-id": intfID,
1816 "onu-id": onuID,
1817 "uni-id": uniID,
1818 "gem-port-id": gemPortID,
1819 "packet": hex.EncodeToString(packet.Data),
1820 "device-id": dh.device.Id,
1821 })
1822 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001823
npujarec5762e2020-01-01 14:08:48 +05301824 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301825 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001826 "source": "adapter",
1827 "destination": "onu",
1828 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001829 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001830 "oni-id": onuID,
1831 "uni-id": uniID,
1832 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001833 "packet": hex.EncodeToString(packet.Data),
1834 "device-id": dh.device.Id,
1835 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001836 }
1837 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001838 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001839 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001840 return olterrors.NewErrInvalidValue(log.Fields{
1841 "egress-nni-port": egressPortNo,
1842 "device-id": dh.device.Id,
1843 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001844 }
1845 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001846
Matteo Scandolo92186242020-06-12 10:54:18 -07001847 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001848 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001849 "uplink-pkt": uplinkPkt,
1850 "packet": hex.EncodeToString(packet.Data),
1851 "device-id": dh.device.Id,
1852 })
1853 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001854
npujarec5762e2020-01-01 14:08:48 +05301855 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001856 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1857 "packet": hex.EncodeToString(packet.Data),
1858 "device-id": dh.device.Id,
1859 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001860 }
1861 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001862 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301863 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001864 "egressPortType": egressPortType,
1865 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301866 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001867 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001868 }
1869 return nil
1870}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001871
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001872func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1873 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001874}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301875
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001876func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301877 // start the heartbeat check towards the OLT.
1878 var timerCheck *time.Timer
1879
1880 for {
1881 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1882 select {
1883 case <-heartbeatTimer.C:
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001884 ctxWithTimeout, cancel := context.WithTimeout(context.Background(), dh.openOLT.GrpcTimeoutInterval)
1885 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001886 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301887 if timerCheck == nil {
1888 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001889 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301890 }
1891 } else {
1892 if timerCheck != nil {
1893 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001894 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301895 }
1896 timerCheck = nil
1897 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001898 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301899 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301900 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301901 }
1902 cancel()
1903 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001904 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301905 return
1906 }
1907 }
1908}
1909
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001910func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1911 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1912 if err != nil || device == nil {
1913 olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
1914 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301915
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001916 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1917 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1918 olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
1919 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001920 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001921 olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
1922 }
1923 go dh.cleanupDeviceResources(ctx)
1924
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001925 dh.lockDevice.RLock()
1926 // Stop the read indication only if it the routine is active
1927 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1928 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1929 // on next execution of the readIndication routine.
1930 if dh.isReadIndicationRoutineActive {
1931 dh.stopIndications <- true
1932 }
1933 dh.lockDevice.RUnlock()
1934
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001935 dh.transitionMap.Handle(ctx, DeviceInit)
1936
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301937 }
1938}
kesavand39e0aa32020-01-28 20:58:50 -05001939
1940// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001941func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1942 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1943 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001944}
1945
1946// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001947func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1948 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1949 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001950}
1951
kdarapu1afeceb2020-02-12 01:38:09 -05001952//modifyPhyPort is common function to enable and disable the port. parm :enablePort, true to enablePort and false to disablePort.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001953func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1954 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001955 if port.GetType() == voltha.Port_ETHERNET_NNI {
1956 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001957 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301958 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301959 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001960 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001961 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001962 }
1963 // fetch interfaceid from PortNo
1964 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1965 ponIntf := &oop.Interface{IntfId: ponID}
1966 var operStatus voltha.OperStatus_Types
1967 if enablePort {
1968 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301969 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001970
1971 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301972 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001973 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001974 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001975 }
1976 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001977 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001978 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05001979 } else {
1980 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05301981 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001982 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301983 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001984 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001985 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001986 }
1987 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001988 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001989 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05001990 }
Thomas Lee S985938d2020-05-04 11:40:41 +05301991 if err := dh.coreProxy.PortStateUpdate(ctx, dh.device.Id, voltha.Port_PON_OLT, port.PortNo, operStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301992 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05301993 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001994 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001995 }
1996 return nil
1997}
1998
kdarapu1afeceb2020-02-12 01:38:09 -05001999//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002000func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002001 // Disable the port and update the oper_port_status to core
2002 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002003 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002004 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002005 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302006 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302007 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002008 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002009 }
2010 }
2011 }
2012 return nil
2013}
2014
2015//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002016func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2017 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2018 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002019 if port.Type == voltha.Port_ETHERNET_NNI {
2020 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002021 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002022 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002023 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002024 }
2025 }
2026 if port.Type == voltha.Port_PON_OLT {
2027 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002028 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002029 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002030 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002031 }
2032 }
2033 }
2034}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002035
2036// ChildDeviceLost deletes ONU and clears pon resources related to it.
2037func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002038 logger.Debugw(ctx, "child-device-lost", log.Fields{"pdeviceID": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002039 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2040 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002041 onuDevice, ok := dh.onus.Load(onuKey)
2042 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302043 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002044 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002045 "device-id": dh.device.Id,
2046 "onu-id": onuID,
2047 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002048 }
2049 var sn *oop.SerialNumber
2050 var err error
2051 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302052 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002053 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302054 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002055 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2056 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002057
2058 for uniID := 0; uniID < MaxUnisPerOnu; uniID++ {
2059 var flowRemoveData pendingFlowRemoveData
2060 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uint32(uniID)}
2061 dh.lockDevice.RLock()
2062 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
2063 dh.lockDevice.RUnlock()
2064 continue
2065 }
2066 dh.lockDevice.RUnlock()
2067
2068 log.Debugw("wait-for-flow-remove-complete-before-processing-child-device-lost",
2069 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2070 // Wait for all flow removes to finish first
2071 <-flowRemoveData.allFlowsRemoved
2072 log.Debugw("flow-removes-complete-for-subscriber",
2073 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2074 }
2075
2076 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002077 if _, err := dh.Client.DeleteOnu(context.Background(), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302078 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302079 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002080 "onu-id": onuID}, err).Log()
2081 }
2082 //clear PON resources associated with ONU
2083 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002084 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002085 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002086 "device-id": dh.device.Id,
2087 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002088 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002089 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002090 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002091 "device-id": dh.device.Id,
2092 "intf-id": intfID,
2093 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002094 } else {
2095 for i, onu := range onuGemData {
2096 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002097 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002098 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002099 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302100 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002101 "onu-device": onu,
2102 "error": err})
2103 }
2104 // Clear flowids for gem cache.
2105 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002106 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002107 }
2108 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002109 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002110 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002111 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002112 "intf-id": intfID,
2113 "onu-device": onu,
2114 "onu-gem": onuGemData,
2115 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002116 //Not returning error on cleanup.
2117 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002118 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002119 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002120 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002121 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002122 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002123 }
2124 }
2125 dh.onus.Delete(onuKey)
2126 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2127 return nil
2128}
Girish Gowdracefae192020-03-19 18:14:10 -07002129
2130func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2131 for _, field := range flows.GetOfbFields(flow) {
2132 if field.Type == flows.IN_PORT {
2133 return field.GetPort()
2134 }
2135 }
2136 return InvalidPort
2137}
2138
2139func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2140 for _, action := range flows.GetActions(flow) {
2141 if action.Type == flows.OUTPUT {
2142 if out := action.GetOutput(); out != nil {
2143 return out.GetPort()
2144 }
2145 }
2146 }
2147 return InvalidPort
2148}
2149
Neha Sharma96b7bf22020-06-15 10:37:32 +00002150func (dh *DeviceHandler) incrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002151 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002152 logger.Debugw(ctx, "increment-flow-remove-count-for-inPort-out-port", log.Fields{"inPort": inPort, "out-port": outPort})
Girish Gowdracefae192020-03-19 18:14:10 -07002153 if inPort != InvalidPort && outPort != InvalidPort {
2154 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2155 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002156 logger.Debugw(ctx, "increment-flow-remove-count-for-subscriber", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002157
2158 dh.lockDevice.Lock()
2159 defer dh.lockDevice.Unlock()
2160 flowRemoveData, ok := dh.pendingFlowRemoveDataPerSubscriber[key]
2161 if !ok {
2162 flowRemoveData = pendingFlowRemoveData{
2163 pendingFlowRemoveCount: 0,
2164 allFlowsRemoved: make(chan struct{}),
2165 }
2166 }
2167 flowRemoveData.pendingFlowRemoveCount++
2168 dh.pendingFlowRemoveDataPerSubscriber[key] = flowRemoveData
2169
Neha Sharma96b7bf22020-06-15 10:37:32 +00002170 logger.Debugw(ctx, "current-flow-remove-count–increment",
Matteo Scandolo92186242020-06-12 10:54:18 -07002171 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002172 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2173 }
2174}
2175
Neha Sharma96b7bf22020-06-15 10:37:32 +00002176func (dh *DeviceHandler) decrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002177 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002178 logger.Debugw(ctx, "decrement-flow-remove-count-for-inPort-out-port", log.Fields{"inPort": inPort, "out-port": outPort})
Girish Gowdracefae192020-03-19 18:14:10 -07002179 if inPort != InvalidPort && outPort != InvalidPort {
2180 _, intfID, onuID, uniID := ExtractAccessFromFlow(uint32(inPort), uint32(outPort))
2181 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002182 logger.Debugw(ctx, "decrement-flow-remove-count-for-subscriber", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002183
2184 dh.lockDevice.Lock()
2185 defer dh.lockDevice.Unlock()
2186 if val, ok := dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002187 logger.Fatalf(ctx, "flow-remove-key-not-found", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002188 } else {
2189 if val.pendingFlowRemoveCount > 0 {
2190 val.pendingFlowRemoveCount--
2191 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002192 logger.Debugw(ctx, "current-flow-remove-count-after-decrement",
Matteo Scandolo92186242020-06-12 10:54:18 -07002193 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002194 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2195 // If all flow removes have finished, then close the channel to signal the receiver
2196 // to go ahead with flow adds.
2197 if val.pendingFlowRemoveCount == 0 {
2198 close(val.allFlowsRemoved)
2199 delete(dh.pendingFlowRemoveDataPerSubscriber, key)
2200 return
2201 }
2202 dh.pendingFlowRemoveDataPerSubscriber[key] = val
2203 }
2204 }
2205}
2206
Neha Sharma96b7bf22020-06-15 10:37:32 +00002207func (dh *DeviceHandler) waitForFlowRemoveToFinish(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002208 var flowRemoveData pendingFlowRemoveData
2209 var ok bool
2210 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002211 logger.Debugw(ctx, "wait-for-flow-remove-to-finish-for-inPort-out-port", log.Fields{"inPort": inPort, "out-port": outPort})
Girish Gowdracefae192020-03-19 18:14:10 -07002212 if inPort != InvalidPort && outPort != InvalidPort {
2213 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2214 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002215 logger.Debugw(ctx, "wait-for-flow-remove-to-finish-for-subscriber", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002216
2217 dh.lockDevice.RLock()
2218 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002219 logger.Debugw(ctx, "no-pending-flow-to-remove", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002220 dh.lockDevice.RUnlock()
2221 return
2222 }
2223 dh.lockDevice.RUnlock()
2224
2225 // Wait for all flow removes to finish first
2226 <-flowRemoveData.allFlowsRemoved
2227
Neha Sharma96b7bf22020-06-15 10:37:32 +00002228 logger.Debugw(ctx, "all-flows-cleared--handling-flow-add-now", log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID})
Girish Gowdracefae192020-03-19 18:14:10 -07002229 }
2230}
2231
2232func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2233 inPort := getInPortFromFlow(flow)
2234 outPort := getOutPortFromFlow(flow)
2235
2236 if inPort == InvalidPort || outPort == InvalidPort {
2237 return inPort, outPort
2238 }
2239
2240 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2241 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2242 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2243 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2244 return uniPort, outPort
2245 }
2246 }
2247 } else {
2248 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2249 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2250 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2251 return inPort, uniPort
2252 }
2253 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2254 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2255 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2256 return uniPort, outPort
2257 }
2258 }
2259 }
2260
2261 return InvalidPort, InvalidPort
2262}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002263
2264func extractOmciTransactionID(omciPkt []byte) uint16 {
2265 if len(omciPkt) > 3 {
2266 d := omciPkt[0:2]
2267 transid := binary.BigEndian.Uint16(d)
2268 return transid
2269 }
2270 return 0
2271}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002272
2273// StoreOnuDevice stores the onu parameters to the local cache.
2274func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2275 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2276 dh.onus.Store(onuKey, onuDevice)
2277}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002278
Devmalya Paula1efa642020-04-20 01:36:43 -04002279// setOnuITUPonAlarmConfig sets the parameters in the openolt agent for raising the ONU ITU PON alarms.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002280func (dh *DeviceHandler) setOnuITUPonAlarmConfig(ctx context.Context, config *oop.OnuItuPonAlarm) error {
Devmalya Paula1efa642020-04-20 01:36:43 -04002281 if _, err := dh.Client.OnuItuPonAlarmSet(context.Background(), config); err != nil {
2282 return err
2283 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002284 logger.Debugw(ctx, "onu-itu-pon-alarm-config-set-successful", log.Fields{"config": config})
Devmalya Paula1efa642020-04-20 01:36:43 -04002285 return nil
2286}
2287
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002288func (dh *DeviceHandler) getExtValue(device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
2289 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002290 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002291 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002292 resp := new(voltha.ReturnValues)
2293 valueparam := new(oop.ValueParam)
2294 ctx := context.Background()
2295 log.Infow("getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002296 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2297 return nil, err
2298 }
2299 ID = device.ProxyAddress.GetOnuId()
2300 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2301 valueparam.Onu = &Onu
2302 valueparam.Value = value
2303
2304 // This API is unsupported until agent patch is added
2305 resp.Unsupported = uint32(value)
2306 _ = ctx
2307
2308 // Uncomment this code once agent changes are complete and tests
2309 /*
2310 resp, err = dh.Client.GetValue(ctx, valueparam)
2311 if err != nil {
2312 log.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
2313 return nil, err
2314 }
2315 */
2316
2317 log.Infow("get-ext-value", log.Fields{"resp": resp, "device-id": dh.device, "onu-id": device.Id, "pon-intf": device.ParentPortNo})
2318 return resp, nil
2319}