blob: aa6e59f769b21069c33e0144a7e09de0e5905149 [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 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001444 for _, group := range groups.ToRemove.Items {
1445 err := dh.flowMgr.DeleteGroup(ctx, group)
1446 if err != nil {
1447 errorsList = append(errorsList, err)
1448 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001449 }
1450 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001451 if len(errorsList) > 0 {
1452 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1453 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001454 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001455 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301456}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001457
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001458//DisableDevice disables the given device
1459//It marks the following for the given device:
1460//Device-Handler Admin-State : down
1461//Device Port-State: UNKNOWN
1462//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001463func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001464 /* On device disable ,admin state update has to be done prior sending request to agent since
1465 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001466 if dh.Client != nil {
1467 if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
1468 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001469 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001470 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001471 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001472 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001473 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001474 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001475 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301476
1477 dh.discOnus = sync.Map{}
1478 dh.onus = sync.Map{}
1479
Thomas Lee S85f37312020-04-03 17:06:12 +05301480 //stopping the stats collector
1481 dh.stopCollector <- true
1482
Neha Sharma96b7bf22020-06-15 10:37:32 +00001483 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001484 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301485 //Update device Admin state
1486 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001487 // 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 -04001488 if err := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
1489 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001490 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001491 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001492 return nil
1493}
1494
Neha Sharma96b7bf22020-06-15 10:37:32 +00001495func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001496
1497 // Update onu state as unreachable in onu adapter
1498 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301499 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001500 //get the child device for the parent device
1501 onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
1502 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001503 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 -04001504 }
1505 if onuDevices != nil {
1506 for _, onuDevice := range onuDevices.Items {
1507 err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1508 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1509 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001510 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301511 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001512 }
1513
1514 }
1515 }
1516
1517}
1518
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001519//ReenableDevice re-enables the olt device after disable
1520//It marks the following for the given device:
1521//Device-Handler Admin-State : up
1522//Device Port-State: ACTIVE
1523//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001524func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301525 if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
1526 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001527 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301528 }
1529 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001530 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001531
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001532 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001533
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001534 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1535 if err != nil {
1536 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device": device.Id}, err)
1537 }
1538 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001539 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001540 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001541 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001542 device.OperStatus = voltha.OperStatus_ACTIVE
1543 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001544
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001545 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301546 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001547 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001548 "connect-status": device.ConnectStatus,
1549 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001550 }
kesavand39e0aa32020-01-28 20:58:50 -05001551
Neha Sharma96b7bf22020-06-15 10:37:32 +00001552 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001553
1554 return nil
1555}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001556
npujarec5762e2020-01-01 14:08:48 +05301557func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001558 var uniID uint32
1559 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301560 for _, port := range onu.UniPorts {
1561 uniID = UniIDFromPortNum(uint32(port))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001562 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001563 /* Delete tech-profile instance from the KV store */
npujarec5762e2020-01-01 14:08:48 +05301564 if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001565 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001566 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001567 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301568 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001569 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301570 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001571 }
npujarec5762e2020-01-01 14:08:48 +05301572 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001573 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301574 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001575 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001576 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001577 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301578 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001579 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001580 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001581 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301582 }
npujarec5762e2020-01-01 14:08:48 +05301583 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1584 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301586 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001587 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Esin Karaman7fb80c22020-07-16 14:23:33 +00001588 if err = dh.resourceMgr.DelGemPortPktInOfAllServices(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001589 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 +00001590 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001591 }
1592 return nil
1593}
1594
npujarec5762e2020-01-01 14:08:48 +05301595func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001596 nniUniID := -1
1597 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301598
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001599 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301600 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001601 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001602 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301603 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301604 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001605 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001606 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301608 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301609 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001610 logger.Debugw(ctx, "current-flow-ids-for-nni", log.Fields{"flow-ids": flowIDs})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301611 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301612 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301613 }
npujarec5762e2020-01-01 14:08:48 +05301614 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001615 }
npujarec5762e2020-01-01 14:08:48 +05301616 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001617 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301618 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001619 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001620}
1621
1622// 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 +05301623func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001624 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001625 /* Clear the KV store data associated with the all the UNI ports
1626 This clears up flow data and also resource map data for various
1627 other pon resources like alloc_id and gemport_id
1628 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001629 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001630 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001631 // Stop the Stats collector
1632 dh.stopCollector <- true
1633 // stop the heartbeat check routine
1634 dh.stopHeartbeatCheck <- true
1635 //Reset the state
1636 if dh.Client != nil {
1637 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301638 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001639 }
1640 }
1641 cloned := proto.Clone(device).(*voltha.Device)
1642 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1643 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1644 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1645 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1646 "device-id": device.Id,
1647 "connect-status": cloned.ConnectStatus,
1648 "oper-status": cloned.OperStatus}, err).Log()
1649 }
1650 return nil
1651}
1652func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) error {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001653 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301654 noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
1655 var ponPort uint32
1656 for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
1657 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301658 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301659 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301660 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001661 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001662 "pon-port": ponPort}, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301663 }
1664 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301665 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001666 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301667 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001668 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301669 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301670 // Clear flowids for gem cache.
1671 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301672 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301673 }
1674 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301675 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301676 }
npujarec5762e2020-01-01 14:08:48 +05301677 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301678 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301679 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301680 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001681 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001682 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001683 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001684 /* Clear the flows from KV store associated with NNI port.
1685 There are mostly trap rules from NNI port (like LLDP)
1686 */
npujarec5762e2020-01-01 14:08:48 +05301687 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001688 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001689 }
A R Karthick1f85b802019-10-11 05:06:05 +00001690
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001691 /* Clear the resource pool for each PON port in the background */
npujarec5762e2020-01-01 14:08:48 +05301692 go dh.resourceMgr.Delete(ctx)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001693 }
A R Karthick1f85b802019-10-11 05:06:05 +00001694
Devmalya Paul495b94a2019-08-27 19:42:00 -04001695 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301696 dh.onus.Range(func(key interface{}, value interface{}) bool {
1697 dh.onus.Delete(key)
1698 return true
1699 })
1700
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001701 /*Delete discovered ONU map for the device*/
1702 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1703 dh.discOnus.Delete(key)
1704 return true
1705 })
1706
Devmalya Paul495b94a2019-08-27 19:42:00 -04001707 return nil
1708}
1709
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001710//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001711func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001712 if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301713 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001714 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001715 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001716 return nil
1717}
1718
David K. Bainbridge794735f2020-02-11 21:01:37 -08001719func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001720 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001721 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001722 "packet-indication": *packetIn,
1723 "device-id": dh.device.Id,
1724 "packet": hex.EncodeToString(packetIn.Pkt),
1725 })
1726 }
npujarec5762e2020-01-01 14:08:48 +05301727 logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001728 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001729 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001730 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001731 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001732 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001733 "logical-port-num": logicalPortNum,
1734 "device-id": dh.device.Id,
1735 "packet": hex.EncodeToString(packetIn.Pkt),
1736 })
1737 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001738
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001739 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301740 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001741 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301742 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001743 "device-id": dh.device.Id,
1744 "packet": hex.EncodeToString(packetIn.Pkt),
1745 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001746 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001747
Matteo Scandolo92186242020-06-12 10:54:18 -07001748 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001749 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001750 "packet": hex.EncodeToString(packetIn.Pkt),
1751 "device-id": dh.device.Id,
1752 })
1753 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001754 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001755}
1756
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001757// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301758func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001759 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001760 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001761 "device-id": dh.device.Id,
1762 "egress-port-no": egressPortNo,
1763 "pkt-length": len(packet.Data),
1764 "packet": hex.EncodeToString(packet.Data),
1765 })
1766 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001767
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001768 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001769 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001770 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1771 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301772 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1773 // Do not packet-out lldp packets on uni port.
1774 // ONOS has no clue about uni/nni ports, it just packets out on all
1775 // available ports on the Logical Switch. It should not be interested
1776 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001777 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001778 "device-id": dh.device.Id,
1779 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301780 return nil
1781 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001782 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1783 if innerEthType == 0x8100 {
1784 // q-in-q 802.1ad or 802.1q double tagged packet.
1785 // slice out the outer tag.
1786 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001787 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001788 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001789 "packet-data": hex.EncodeToString(packet.Data),
1790 "device-id": dh.device.Id,
1791 })
1792 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001793 }
1794 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001795 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1796 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001797 uniID := UniIDFromPortNum(uint32(egressPortNo))
1798
Esin Karaman7fb80c22020-07-16 14:23:33 +00001799 gemPortID, err := dh.flowMgr.GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001800 if err != nil {
1801 // In this case the openolt agent will receive the gemPortID as 0.
1802 // The agent tries to retrieve the gemPortID in this case.
1803 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001804 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001805 "intf-id": intfID,
1806 "onu-id": onuID,
1807 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001808 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301809 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001810 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001811 }
1812
1813 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001814
Matteo Scandolo92186242020-06-12 10:54:18 -07001815 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001816 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001817 "egress-port-no": egressPortNo,
1818 "intf-id": intfID,
1819 "onu-id": onuID,
1820 "uni-id": uniID,
1821 "gem-port-id": gemPortID,
1822 "packet": hex.EncodeToString(packet.Data),
1823 "device-id": dh.device.Id,
1824 })
1825 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001826
npujarec5762e2020-01-01 14:08:48 +05301827 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301828 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001829 "source": "adapter",
1830 "destination": "onu",
1831 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001832 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001833 "oni-id": onuID,
1834 "uni-id": uniID,
1835 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001836 "packet": hex.EncodeToString(packet.Data),
1837 "device-id": dh.device.Id,
1838 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001839 }
1840 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001841 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001842 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001843 return olterrors.NewErrInvalidValue(log.Fields{
1844 "egress-nni-port": egressPortNo,
1845 "device-id": dh.device.Id,
1846 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001847 }
1848 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001849
Matteo Scandolo92186242020-06-12 10:54:18 -07001850 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001851 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001852 "uplink-pkt": uplinkPkt,
1853 "packet": hex.EncodeToString(packet.Data),
1854 "device-id": dh.device.Id,
1855 })
1856 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001857
npujarec5762e2020-01-01 14:08:48 +05301858 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001859 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1860 "packet": hex.EncodeToString(packet.Data),
1861 "device-id": dh.device.Id,
1862 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001863 }
1864 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001865 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301866 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001867 "egressPortType": egressPortType,
1868 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301869 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001870 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001871 }
1872 return nil
1873}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001874
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001875func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1876 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001877}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301878
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001879func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301880 // start the heartbeat check towards the OLT.
1881 var timerCheck *time.Timer
1882
1883 for {
1884 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1885 select {
1886 case <-heartbeatTimer.C:
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001887 ctxWithTimeout, cancel := context.WithTimeout(context.Background(), dh.openOLT.GrpcTimeoutInterval)
1888 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001889 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301890 if timerCheck == nil {
1891 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001892 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301893 }
1894 } else {
1895 if timerCheck != nil {
1896 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001897 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301898 }
1899 timerCheck = nil
1900 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001901 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301902 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301903 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301904 }
1905 cancel()
1906 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001907 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301908 return
1909 }
1910 }
1911}
1912
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001913func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1914 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1915 if err != nil || device == nil {
1916 olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
1917 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301918
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001919 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1920 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1921 olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
1922 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001923 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001924 olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
1925 }
1926 go dh.cleanupDeviceResources(ctx)
1927
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001928 dh.lockDevice.RLock()
1929 // Stop the read indication only if it the routine is active
1930 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1931 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1932 // on next execution of the readIndication routine.
1933 if dh.isReadIndicationRoutineActive {
1934 dh.stopIndications <- true
1935 }
1936 dh.lockDevice.RUnlock()
1937
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001938 dh.transitionMap.Handle(ctx, DeviceInit)
1939
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301940 }
1941}
kesavand39e0aa32020-01-28 20:58:50 -05001942
1943// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001944func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1945 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1946 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001947}
1948
1949// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001950func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1951 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1952 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001953}
1954
kdarapu1afeceb2020-02-12 01:38:09 -05001955//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 +00001956func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1957 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001958 if port.GetType() == voltha.Port_ETHERNET_NNI {
1959 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001960 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301961 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301962 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001963 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001964 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001965 }
1966 // fetch interfaceid from PortNo
1967 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1968 ponIntf := &oop.Interface{IntfId: ponID}
1969 var operStatus voltha.OperStatus_Types
1970 if enablePort {
1971 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301972 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001973
1974 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301975 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001976 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001977 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001978 }
1979 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001980 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001981 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05001982 } else {
1983 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05301984 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001985 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301986 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001987 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001988 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001989 }
1990 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001991 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001992 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05001993 }
Thomas Lee S985938d2020-05-04 11:40:41 +05301994 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 +05301995 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05301996 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001997 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001998 }
1999 return nil
2000}
2001
kdarapu1afeceb2020-02-12 01:38:09 -05002002//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002003func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002004 // Disable the port and update the oper_port_status to core
2005 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002006 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002007 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002008 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302009 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302010 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002011 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002012 }
2013 }
2014 }
2015 return nil
2016}
2017
2018//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002019func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2020 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2021 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002022 if port.Type == voltha.Port_ETHERNET_NNI {
2023 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002024 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002025 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002026 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002027 }
2028 }
2029 if port.Type == voltha.Port_PON_OLT {
2030 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002031 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002032 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002033 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002034 }
2035 }
2036 }
2037}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002038
2039// ChildDeviceLost deletes ONU and clears pon resources related to it.
2040func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002041 logger.Debugw(ctx, "child-device-lost", log.Fields{"pdeviceID": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002042 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2043 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002044 onuDevice, ok := dh.onus.Load(onuKey)
2045 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302046 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002047 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002048 "device-id": dh.device.Id,
2049 "onu-id": onuID,
2050 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002051 }
2052 var sn *oop.SerialNumber
2053 var err error
2054 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302055 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002056 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302057 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002058 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2059 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002060
2061 for uniID := 0; uniID < MaxUnisPerOnu; uniID++ {
2062 var flowRemoveData pendingFlowRemoveData
2063 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uint32(uniID)}
2064 dh.lockDevice.RLock()
2065 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
2066 dh.lockDevice.RUnlock()
2067 continue
2068 }
2069 dh.lockDevice.RUnlock()
2070
2071 log.Debugw("wait-for-flow-remove-complete-before-processing-child-device-lost",
2072 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2073 // Wait for all flow removes to finish first
2074 <-flowRemoveData.allFlowsRemoved
2075 log.Debugw("flow-removes-complete-for-subscriber",
2076 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2077 }
2078
2079 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002080 if _, err := dh.Client.DeleteOnu(context.Background(), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302081 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302082 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002083 "onu-id": onuID}, err).Log()
2084 }
2085 //clear PON resources associated with ONU
2086 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002087 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002088 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002089 "device-id": dh.device.Id,
2090 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002091 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002092 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002093 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002094 "device-id": dh.device.Id,
2095 "intf-id": intfID,
2096 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002097 } else {
2098 for i, onu := range onuGemData {
2099 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002100 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002101 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002102 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302103 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002104 "onu-device": onu,
2105 "error": err})
2106 }
2107 // Clear flowids for gem cache.
2108 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002109 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002110 }
2111 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002112 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002113 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002114 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002115 "intf-id": intfID,
2116 "onu-device": onu,
2117 "onu-gem": onuGemData,
2118 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002119 //Not returning error on cleanup.
2120 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002121 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002122 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002123 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002124 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002125 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002126 }
2127 }
2128 dh.onus.Delete(onuKey)
2129 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2130 return nil
2131}
Girish Gowdracefae192020-03-19 18:14:10 -07002132
2133func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2134 for _, field := range flows.GetOfbFields(flow) {
2135 if field.Type == flows.IN_PORT {
2136 return field.GetPort()
2137 }
2138 }
2139 return InvalidPort
2140}
2141
2142func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2143 for _, action := range flows.GetActions(flow) {
2144 if action.Type == flows.OUTPUT {
2145 if out := action.GetOutput(); out != nil {
2146 return out.GetPort()
2147 }
2148 }
2149 }
2150 return InvalidPort
2151}
2152
Neha Sharma96b7bf22020-06-15 10:37:32 +00002153func (dh *DeviceHandler) incrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002154 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002155 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 -07002156 if inPort != InvalidPort && outPort != InvalidPort {
2157 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2158 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002159 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 -07002160
2161 dh.lockDevice.Lock()
2162 defer dh.lockDevice.Unlock()
2163 flowRemoveData, ok := dh.pendingFlowRemoveDataPerSubscriber[key]
2164 if !ok {
2165 flowRemoveData = pendingFlowRemoveData{
2166 pendingFlowRemoveCount: 0,
2167 allFlowsRemoved: make(chan struct{}),
2168 }
2169 }
2170 flowRemoveData.pendingFlowRemoveCount++
2171 dh.pendingFlowRemoveDataPerSubscriber[key] = flowRemoveData
2172
Neha Sharma96b7bf22020-06-15 10:37:32 +00002173 logger.Debugw(ctx, "current-flow-remove-count–increment",
Matteo Scandolo92186242020-06-12 10:54:18 -07002174 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002175 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2176 }
2177}
2178
Neha Sharma96b7bf22020-06-15 10:37:32 +00002179func (dh *DeviceHandler) decrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002180 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002181 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 -07002182 if inPort != InvalidPort && outPort != InvalidPort {
2183 _, intfID, onuID, uniID := ExtractAccessFromFlow(uint32(inPort), uint32(outPort))
2184 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002185 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 -07002186
2187 dh.lockDevice.Lock()
2188 defer dh.lockDevice.Unlock()
2189 if val, ok := dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002190 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 -07002191 } else {
2192 if val.pendingFlowRemoveCount > 0 {
2193 val.pendingFlowRemoveCount--
2194 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002195 logger.Debugw(ctx, "current-flow-remove-count-after-decrement",
Matteo Scandolo92186242020-06-12 10:54:18 -07002196 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002197 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2198 // If all flow removes have finished, then close the channel to signal the receiver
2199 // to go ahead with flow adds.
2200 if val.pendingFlowRemoveCount == 0 {
2201 close(val.allFlowsRemoved)
2202 delete(dh.pendingFlowRemoveDataPerSubscriber, key)
2203 return
2204 }
2205 dh.pendingFlowRemoveDataPerSubscriber[key] = val
2206 }
2207 }
2208}
2209
Neha Sharma96b7bf22020-06-15 10:37:32 +00002210func (dh *DeviceHandler) waitForFlowRemoveToFinish(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002211 var flowRemoveData pendingFlowRemoveData
2212 var ok bool
2213 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002214 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 -07002215 if inPort != InvalidPort && outPort != InvalidPort {
2216 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2217 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002218 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 -07002219
2220 dh.lockDevice.RLock()
2221 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002222 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 -07002223 dh.lockDevice.RUnlock()
2224 return
2225 }
2226 dh.lockDevice.RUnlock()
2227
2228 // Wait for all flow removes to finish first
2229 <-flowRemoveData.allFlowsRemoved
2230
Neha Sharma96b7bf22020-06-15 10:37:32 +00002231 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 -07002232 }
2233}
2234
2235func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2236 inPort := getInPortFromFlow(flow)
2237 outPort := getOutPortFromFlow(flow)
2238
2239 if inPort == InvalidPort || outPort == InvalidPort {
2240 return inPort, outPort
2241 }
2242
2243 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2244 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2245 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2246 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2247 return uniPort, outPort
2248 }
2249 }
2250 } else {
2251 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2252 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2253 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2254 return inPort, uniPort
2255 }
2256 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2257 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2258 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2259 return uniPort, outPort
2260 }
2261 }
2262 }
2263
2264 return InvalidPort, InvalidPort
2265}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002266
2267func extractOmciTransactionID(omciPkt []byte) uint16 {
2268 if len(omciPkt) > 3 {
2269 d := omciPkt[0:2]
2270 transid := binary.BigEndian.Uint16(d)
2271 return transid
2272 }
2273 return 0
2274}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002275
2276// StoreOnuDevice stores the onu parameters to the local cache.
2277func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2278 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2279 dh.onus.Store(onuKey, onuDevice)
2280}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002281
Devmalya Paula1efa642020-04-20 01:36:43 -04002282// setOnuITUPonAlarmConfig sets the parameters in the openolt agent for raising the ONU ITU PON alarms.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002283func (dh *DeviceHandler) setOnuITUPonAlarmConfig(ctx context.Context, config *oop.OnuItuPonAlarm) error {
Devmalya Paula1efa642020-04-20 01:36:43 -04002284 if _, err := dh.Client.OnuItuPonAlarmSet(context.Background(), config); err != nil {
2285 return err
2286 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002287 logger.Debugw(ctx, "onu-itu-pon-alarm-config-set-successful", log.Fields{"config": config})
Devmalya Paula1efa642020-04-20 01:36:43 -04002288 return nil
2289}
2290
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002291func (dh *DeviceHandler) getExtValue(device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
2292 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002293 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002294 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002295 resp := new(voltha.ReturnValues)
2296 valueparam := new(oop.ValueParam)
2297 ctx := context.Background()
2298 log.Infow("getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002299 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2300 return nil, err
2301 }
2302 ID = device.ProxyAddress.GetOnuId()
2303 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2304 valueparam.Onu = &Onu
2305 valueparam.Value = value
2306
2307 // This API is unsupported until agent patch is added
2308 resp.Unsupported = uint32(value)
2309 _ = ctx
2310
2311 // Uncomment this code once agent changes are complete and tests
2312 /*
2313 resp, err = dh.Client.GetValue(ctx, valueparam)
2314 if err != nil {
2315 log.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
2316 return nil, err
2317 }
2318 */
2319
2320 log.Infow("get-ext-value", log.Fields{"resp": resp, "device-id": dh.device, "onu-id": device.Id, "pon-intf": device.ParentPortNo})
2321 return resp, nil
2322}