blob: 4452b8f95922784e7735e4bdbb97d009035b3d1f [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
Kent Hagermane6ff1012020-07-14 15:07:53 -0400311func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
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 {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400316 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
317 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530318 }
319 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530320}
321
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700322// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530323// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800324func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000325 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700326 defer func() {
327 dh.lockDevice.Lock()
328 dh.isReadIndicationRoutineActive = false
329 dh.lockDevice.Unlock()
330 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700331 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700332 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700333 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700334 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400335 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530336 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400337 if err != nil || device == nil {
338 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000339 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400340 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400341
David Bainbridgef5879ca2019-12-13 21:17:54 +0000342 // Create an exponential backoff around re-enabling indications. The
343 // maximum elapsed time for the back off is set to 0 so that we will
344 // continue to retry. The max interval defaults to 1m, but is set
345 // here for code clarity
346 indicationBackoff := backoff.NewExponentialBackOff()
347 indicationBackoff.MaxElapsedTime = 0
348 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700349
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700350 dh.lockDevice.Lock()
351 dh.isReadIndicationRoutineActive = true
352 dh.lockDevice.Unlock()
353
Girish Gowdra3f974912020-03-23 20:35:18 -0700354Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700355 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400356 select {
357 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000358 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700359 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400360 default:
361 indication, err := indications.Recv()
362 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000363 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530364 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530365 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400366 // Use an exponential back off to prevent getting into a tight loop
367 duration := indicationBackoff.NextBackOff()
368 if duration == backoff.Stop {
369 // If we reach a maximum then warn and reset the backoff
370 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000371 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530372 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530373 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400374 indicationBackoff.Reset()
375 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700376
377 // On failure process a backoff timer while watching for stopIndications
378 // events
379 backoff := time.NewTimer(indicationBackoff.NextBackOff())
380 select {
381 case <-dh.stopIndications:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000382 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"deviceID:": dh.device.Id})
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700383 if !backoff.Stop() {
384 <-backoff.C
385 }
386 break Loop
387 case <-backoff.C:
388 // backoff expired continue
389 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700390 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
391 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400392 }
393 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000394 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530395 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000396 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530397 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530398 "device-id": dh.device.Id})
399 if device.AdminState == voltha.AdminState_DELETED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000400 logger.Debug(ctx, "device-deleted--stopping-the-read-indication-thread")
Girish Gowdra3f974912020-03-23 20:35:18 -0700401 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400402 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700403 // Close the stream, and re-initialize it
404 if err = indications.CloseSend(); err != nil {
405 // Ok to ignore here, because we landed here due to a problem on the stream
406 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000407 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530408 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530409 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700410 }
411 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
412 return err
413 }
414 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400415 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530416 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400417 // Reset backoff if we have a successful receive
418 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400419 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530420 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000421 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530422 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530423 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400424 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400425 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400426 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700427 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700428 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700429 // Close the send stream
430 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700431
Girish Gowdra3f974912020-03-23 20:35:18 -0700432 return nil
433}
434
435func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
436
437 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
438 if err != nil {
439 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
440 }
441 if indications == nil {
442 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
443 }
444
445 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400446}
447
448// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
449func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
450 switch indication.Data.(type) {
451 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
452 return true
453
454 default:
455 return false
456 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700457}
458
David K. Bainbridge794735f2020-02-11 21:01:37 -0800459func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000460 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000461 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530462 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700463 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530464 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700465 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000466 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000467 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530468 return olterrors.NewErrAdapter("failed-indication", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530469 "device_id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800470 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000471 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800472 }
473 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700474}
475
David K. Bainbridge794735f2020-02-11 21:01:37 -0800476// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530477func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400478 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700479 switch indication.Data.(type) {
480 case *oop.Indication_OltInd:
David K. Bainbridge794735f2020-02-11 21:01:37 -0800481 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400482 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800483 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700484 case *oop.Indication_IntfInd:
485 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800486 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000487 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400488 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800489 }
490 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000491 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700492 case *oop.Indication_IntfOperInd:
493 intfOperInd := indication.GetIntfOperInd()
494 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800495 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000496 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400497 _ = 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 -0800498 }
499 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400500 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
501 logger.Warn(ctx, err)
502 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700503 } else if intfOperInd.GetType() == "pon" {
504 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
505 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800506 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000507 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400508 _ = 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 -0800509 }
510 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000511 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700512 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000513 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530514 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530515 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700516 case *oop.Indication_OnuDiscInd:
517 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000518 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700519 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800520 go func() {
521 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400522 _ = 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 -0800523 }
524 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700525 case *oop.Indication_OnuInd:
526 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000527 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800528 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000529 if err := dh.onuIndication(ctx, onuInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400530 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800531 }
532 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700533 case *oop.Indication_OmciInd:
534 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000535 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 -0800536 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000537 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400538 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800539 }
540 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700541 case *oop.Indication_PktInd:
542 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000543 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700544 "intf-type": pktInd.IntfId,
545 "intf-id": pktInd.IntfId,
546 "gem-port-id": pktInd.GemportId,
547 "port-no": pktInd.PortNo,
548 "device-id": dh.device.Id,
549 })
550
551 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700553 "intf-type": pktInd.IntfId,
554 "intf-id": pktInd.IntfId,
555 "gem-port-id": pktInd.GemportId,
556 "port-no": pktInd.PortNo,
557 "packet": hex.EncodeToString(pktInd.Pkt),
558 "device-id": dh.device.Id,
559 })
560 }
561
David K. Bainbridge794735f2020-02-11 21:01:37 -0800562 go func() {
563 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400564 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800565 }
566 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700567 case *oop.Indication_PortStats:
568 portStats := indication.GetPortStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000569 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.resourceMgr.DevInfo.GetPonPorts())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700570 case *oop.Indication_FlowStats:
571 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000572 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 case *oop.Indication_AlarmInd:
574 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000575 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
576 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700577 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530578}
579
580// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530581func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530582 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000583 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530584
Girish Gowdru0c588b22019-04-23 23:24:56 -0400585 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530586 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400587 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000588 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400589 }
590 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530591}
592
593// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530594func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700595 dh.lockDevice.Lock()
596 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000597 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400598
npujarec5762e2020-01-01 14:08:48 +0530599 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400600 if err != nil || device == nil {
601 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000602 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400603 }
604
605 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400606
607 //Update the device oper state and connection status
608 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400609 dh.device = cloned
610
David K. Bainbridge794735f2020-02-11 21:01:37 -0800611 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000612 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400613 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400614
615 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530616 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400617 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000618 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400619 }
620 for _, onuDevice := range onuDevices.Items {
621
622 // Update onu state as down in onu adapter
623 onuInd := oop.OnuIndication{}
624 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800625 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700626 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800627 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400628 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800629 "source": "openolt",
630 "onu-indicator": onuInd,
631 "device-type": onuDevice.Type,
632 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700633 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700634 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400635 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700636 /* Discovered ONUs entries need to be cleared , since after OLT
637 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530638 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000639 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700640 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530641}
642
643// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530644func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400645 var err error
David K. Bainbridge794735f2020-02-11 21:01:37 -0800646 if dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure(), grpc.WithBlock()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530647 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530648 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000649 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400650 }
651 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530652}
653
654// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530655func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400656 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530657 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400658 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530659}
660
661// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530662func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530663 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000664 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400665
666 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530667 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
668 if err != nil || device == nil {
669 /*TODO: needs to handle error scenarios */
670 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
671 }
672 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000673 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400674
675 cloned := proto.Clone(device).(*voltha.Device)
676 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
677 cloned.OperStatus = voltha.OperStatus_UNKNOWN
678 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530679 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
680 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 -0400681 }
682
Chaitrashree G S44124192019-08-07 20:21:36 -0400683 // 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 +0530684 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400685 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530686 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400687 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400688 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
689 // all the modules initialized and ready to handle incoming ONUs.
690
Thomas Lee S985938d2020-05-04 11:40:41 +0530691 err = dh.initializeDeviceHandlerModules(ctx)
692 if err != nil {
693 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 -0400694 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400695
696 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800697 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530698 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400699 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800700 }
701 }()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400702 return nil
703 }
704
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400705 ports, err := dh.coreProxy.ListDevicePorts(context.TODO(), dh.device.Id)
706 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400707 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400708 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400709 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400710 dh.populateActivePorts(ctx, ports)
711 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
712 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400713 }
714
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400715 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530716 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 -0400717 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530718
cuilin20187b2a8c32019-03-26 19:52:28 -0700719 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800720 go func() {
721 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400722 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800723 }
724 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000725 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000726
727 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000728 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000729 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700730 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530731}
732
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400733func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000734 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400735
736 if err != nil {
737 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
738 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400739 // Instantiate resource manager
Neha Sharma3f221ae2020-04-29 19:02:12 +0000740 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 -0400741 return olterrors.ErrResourceManagerInstantiating
742 }
743
744 // Instantiate flow manager
745 if dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr); dh.flowMgr == nil {
746 return olterrors.ErrResourceManagerInstantiating
747
748 }
749 /* TODO: Instantiate Alarm , stats , BW managers */
750 /* Instantiating Event Manager to handle Alarms and KPIs */
751 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
752
753 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000754 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400755
756 return nil
757
758}
759
Neha Sharma96b7bf22020-06-15 10:37:32 +0000760func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400761 var err error
762 var deviceInfo *oop.DeviceInfo
763
764 deviceInfo, err = dh.Client.GetDeviceInfo(context.Background(), new(oop.Empty))
765
766 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000767 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400768 }
769 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000770 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400771 }
772
Neha Sharma96b7bf22020-06-15 10:37:32 +0000773 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400774 dh.device.Root = true
775 dh.device.Vendor = deviceInfo.Vendor
776 dh.device.Model = deviceInfo.Model
777 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
778 dh.device.HardwareVersion = deviceInfo.HardwareVersion
779 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
780
781 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000782 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400783 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000784 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400785 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000786 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400787 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000788 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400789 dh.device.MacAddress = genmac
790 } else {
791 dh.device.MacAddress = deviceInfo.DeviceId
792 }
793
794 // Synchronous call to update device - this method is run in its own go routine
795 if err := dh.coreProxy.DeviceUpdate(context.TODO(), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000796 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400797 }
798
799 return deviceInfo, nil
800}
801
Neha Sharma96b7bf22020-06-15 10:37:32 +0000802func startCollector(ctx context.Context, dh *DeviceHandler) {
803 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530804 for {
805 select {
806 case <-dh.stopCollector:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000807 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"deviceID:": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530808 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000809 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700810
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400811 ports, err := dh.coreProxy.ListDevicePorts(context.Background(), dh.device.Id)
812 if err != nil {
813 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
814 continue
815 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530816 for _, port := range ports {
817 // NNI Stats
818 if port.Type == voltha.Port_ETHERNET_NNI {
819 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
820 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000821 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
822 go dh.portStats.publishMetrics(ctx, cmnni, port, dh.device.Id, dh.device.Type)
823 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530824 }
825 // PON Stats
826 if port.Type == voltha.Port_PON_OLT {
827 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
828 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
829 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000830 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
831 go dh.portStats.publishMetrics(ctx, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530832 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000833 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Chaitrashree G Sef088112020-02-03 21:39:27 -0500834 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530835 }
836 }
837 }
838}
839
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700840//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530841func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400842 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000843 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530844 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530845
846 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400847 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
848 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530849 }
850
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400851 go startHeartbeatCheck(ctx, dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530852}
853
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700854//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530855func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700856 return &ic.SwitchCapability{
857 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530858 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700859 HwDesc: "open_pon",
860 SwDesc: "open_pon",
861 SerialNum: dh.device.SerialNumber,
862 },
863 SwitchFeatures: &of.OfpSwitchFeatures{
864 NBuffers: 256,
865 NTables: 2,
866 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
867 of.OfpCapabilities_OFPC_TABLE_STATS |
868 of.OfpCapabilities_OFPC_PORT_STATS |
869 of.OfpCapabilities_OFPC_GROUP_STATS),
870 },
871 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530872}
873
Neha Sharma96b7bf22020-06-15 10:37:32 +0000874func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
875 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 -0700876 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700877 var deviceID string
878 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700879
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400880 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700881 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000882 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 -0700883 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
884 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400885
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700886 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530887
888 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
889
Neha Sharma96b7bf22020-06-15 10:37:32 +0000890 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 -0700891 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700892 kwargs := make(map[string]interface{})
893 kwargs["onu_id"] = omciInd.OnuId
894 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700895
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700896 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
897 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530898 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700899 "intf-id": omciInd.IntfId,
900 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700901 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700902 deviceType = onuDevice.Type
903 deviceID = onuDevice.Id
904 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
905 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530906 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700907 } else {
908 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000909 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 +0530910 deviceType = onuInCache.(*OnuDevice).deviceType
911 deviceID = onuInCache.(*OnuDevice).deviceID
912 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700913 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700914
915 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
David K. Bainbridge794735f2020-02-11 21:01:37 -0800916 if err := dh.AdapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
Thomas Lee S985938d2020-05-04 11:40:41 +0530917 ic.InterAdapterMessageType_OMCI_REQUEST, dh.device.Type, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800918 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530919 return olterrors.NewErrCommunication("omci-request", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530920 "source": dh.device.Type,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800921 "destination": deviceType,
922 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +0000923 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700924 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800925 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530926}
927
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700928//ProcessInterAdapterMessage sends the proxied messages to the target device
929// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
930// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +0000931func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
932 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700933 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700934 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700935 fromTopic := msg.Header.FromTopic
936 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700937 toDeviceID := msg.Header.ToDeviceId
938 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700939
Neha Sharma96b7bf22020-06-15 10:37:32 +0000940 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 -0700941
942 msgBody := msg.GetBody()
943
944 omciMsg := &ic.InterAdapterOmciMessage{}
945 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000946 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700947 }
948
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700949 if omciMsg.GetProxyAddress() == nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700950 onuDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, toDeviceID)
951 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530952 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800953 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000954 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700955 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000956 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
957 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530958 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800959 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000960 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800961 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700962 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000963 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
964 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530965 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800966 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000967 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800968 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700969 }
970
971 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +0000972 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -0700973 }
974 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530975}
976
Neha Sharma96b7bf22020-06-15 10:37:32 +0000977func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700978 var intfID uint32
979 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +0000980 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700981 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700982 intfID = onuDevice.ProxyAddress.GetChannelId()
983 onuID = onuDevice.ProxyAddress.GetOnuId()
984 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700985 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700986 intfID = omciMsg.GetProxyAddress().GetChannelId()
987 onuID = omciMsg.GetProxyAddress().GetOnuId()
988 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700989 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700990 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000991 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 -0800992
Thomas Lee S94109f12020-03-03 16:39:29 +0530993 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700994 "intf-id": intfID,
995 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -0700996 }
997
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400998 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
999 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001000 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001001 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1002 hex.Encode(hexPkt, omciMsg.Message)
1003 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1004
1005 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1006 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1007 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001008 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001009 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001010
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001011 _, err := dh.Client.OmciMsgOut(context.Background(), omciMessage)
1012 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301013 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001014 "intf-id": intfID,
1015 "onu-id": onuID,
1016 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001017 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001018 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001019}
1020
David K. Bainbridge794735f2020-02-11 21:01:37 -08001021func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001022 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 +02001023 if err := dh.flowMgr.UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001024 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001025 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001026 // TODO: need resource manager
1027 var pir uint32 = 1000000
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001028 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir}
npujarec5762e2020-01-01 14:08:48 +05301029 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001030 st, _ := status.FromError(err)
1031 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001032 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1033
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001034 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301035 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001036 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001037 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001038 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001039 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001040 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001041}
1042
David K. Bainbridge794735f2020-02-11 21:01:37 -08001043func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001044
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001045 channelID := onuDiscInd.GetIntfId()
1046 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001047
Neha Sharma96b7bf22020-06-15 10:37:32 +00001048 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301049
cuilin20187b2a8c32019-03-26 19:52:28 -07001050 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001051 if sn != "" {
1052 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001053 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001054 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001055 }
1056
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301057 var alarmInd oop.OnuAlarmIndication
1058 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001059 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301060
1061 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1062 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1063 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1064 OnuLosRaise event sent for it */
1065 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1066 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1067 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001068 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301069 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1070 "currentIntfId": onuDiscInd.GetIntfId()})
1071 // TODO:: Should we need to ignore raising OnuLosClear event
1072 // when onu connected to different PON?
1073 }
1074 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1075 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1076 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001077 go func() {
1078 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1079 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1080 }
1081 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301082 }
1083 return true
1084 })
1085
Neha Sharma96b7bf22020-06-15 10:37:32 +00001086 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001087 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001088 }
1089
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001090 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001091
1092 // check the ONU is already know to the OLT
1093 // NOTE the second time the ONU is discovered this should return a device
1094 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1095
1096 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001097 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 -08001098 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001099 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 -08001100 switch e.Code() {
1101 case codes.Internal:
1102 // this probably means NOT FOUND, so just create a new device
1103 onuDevice = nil
1104 case codes.DeadlineExceeded:
1105 // if the call times out, cleanup and exit
1106 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001107 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001108 }
1109 }
1110 }
1111
1112 if onuDevice == nil {
1113 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001114 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001115 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001116 ponintfid := onuDiscInd.GetIntfId()
1117 dh.lockDevice.Lock()
npujarec5762e2020-01-01 14:08:48 +05301118 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Matt Jeanneret53539512019-07-20 14:47:02 -04001119 dh.lockDevice.Unlock()
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001120
Neha Sharma96b7bf22020-06-15 10:37:32 +00001121 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001122
1123 if err != nil {
1124 // if we can't create an ID in resource manager,
1125 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001126 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001127 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001128 "pon-intf-id": ponintfid,
1129 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001130 }
1131
1132 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(context.TODO(), dh.device.Id, int(parentPortNo),
1133 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001134 dh.discOnus.Delete(sn)
1135 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 +05301136 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001137 "pon-intf-id": ponintfid,
1138 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001139 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001140 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1141 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1142 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001143 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301144 log.Fields{"onuDevice": onuDevice,
1145 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001146 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301147 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001148 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001149
1150 // we can now use the existing ONU Id
1151 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001152 //Insert the ONU into cache to use in OnuIndication.
1153 //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 +00001154 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001155 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301156 "intfId": onuDiscInd.GetIntfId(),
1157 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001158 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001159
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301160 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301161 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001162 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301163 log.Fields{"onu": onuDev,
1164 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001165
Kent Hagermane6ff1012020-07-14 15:07:53 -04001166 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301167 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001168 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001169 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001170 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001171 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001172 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301173 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001174 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001175 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001176 }
1177 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001178}
1179
Neha Sharma96b7bf22020-06-15 10:37:32 +00001180func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001181 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1182
1183 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001184 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001185 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001186 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001187 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001188 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301189 log.Fields{"onuId": onuInd.OnuId,
1190 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301191 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001192 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301193
David K. Bainbridge794735f2020-02-11 21:01:37 -08001194 errFields := log.Fields{"device-id": dh.device.Id}
1195
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301196 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1197
Mahir Gunyele77977b2019-06-27 05:36:22 -07001198 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1199 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001200 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001201 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001202 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001203 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1204 if serialNumber != "" {
1205 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001206 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001207 } else {
1208 kwargs["onu_id"] = onuInd.OnuId
1209 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001210 errFields["onu-id"] = onuInd.OnuId
1211 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001212 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001213 onuDevice, err = dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001214 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001215
David K. Bainbridge794735f2020-02-11 21:01:37 -08001216 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001217 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001218 }
1219
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001221 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001222 "previousIntfId": onuDevice.ParentPortNo,
1223 "currentIntfId": ponPort})
1224 }
1225
1226 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001227 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301228 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1229 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301230 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001231 }
1232 if !foundInCache {
1233 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1234
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301235 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 -08001236
1237 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001238 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001239 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001240 }
1241 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001242}
1243
Neha Sharma96b7bf22020-06-15 10:37:32 +00001244func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001245 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 -07001246 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1247 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1248 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1249 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001250 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001251 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1252 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001253 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001254 onuInd.OperState = "down"
1255 }
1256 }
1257
David K. Bainbridge794735f2020-02-11 21:01:37 -08001258 switch onuInd.OperState {
1259 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001260 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 -07001261 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301262 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001263 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1264 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301265 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001266 "onu-indicator": onuInd,
1267 "source": "openolt",
1268 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001269 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001270 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001271 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001272 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 -04001273 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301274 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001275 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1276 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301277 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001278 "onu-indicator": onuInd,
1279 "source": "openolt",
1280 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001281 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001282 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001283 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001284 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001285 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001286 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001287}
1288
cuilin20187b2a8c32019-03-26 19:52:28 -07001289func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1290 if serialNum != nil {
1291 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001292 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001293 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001294}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001295func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1296 decodedStr, err := hex.DecodeString(serialNum[4:])
1297 if err != nil {
1298 return nil, err
1299 }
1300 return &oop.SerialNumber{
1301 VendorId: []byte(serialNum[:4]),
1302 VendorSpecific: []byte(decodedStr),
1303 }, nil
1304}
cuilin20187b2a8c32019-03-26 19:52:28 -07001305
1306func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1307 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001308 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001309 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1310 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1311 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1312 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1313 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1314 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1315 return tmp
1316}
1317
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001318//UpdateFlowsBulk upates the bulk flow
1319func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301320 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001321}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001322
1323//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001324func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1325 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301326 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001327 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301328 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001329 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001330 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001331 kwargs["parent_port_no"] = parentPort
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001332 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001333 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001334 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001335 "intf-id": parentPort,
1336 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001337 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001338 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 -08001339 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301340}
1341
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001342// SendPacketInToCore sends packet-in to core
1343// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1344// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001345func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001346 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001347 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001348 "port": logicalPort,
1349 "packet": hex.EncodeToString(packetPayload),
1350 "device-id": dh.device.Id,
1351 })
1352 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001353 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301354 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001355 "source": "adapter",
1356 "destination": "core",
1357 "device-id": dh.device.Id,
1358 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001359 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001360 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001361 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001362 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001363 "packet": hex.EncodeToString(packetPayload),
1364 "device-id": dh.device.Id,
1365 })
1366 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001367 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001368}
1369
A R Karthick1f85b802019-10-11 05:06:05 +00001370// AddUniPortToOnu adds the uni port to the onu device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001371func (dh *DeviceHandler) AddUniPortToOnu(ctx context.Context, intfID, onuID, uniPort uint32) {
A R Karthick1f85b802019-10-11 05:06:05 +00001372 onuKey := dh.formOnuKey(intfID, onuID)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301373
1374 if onuDevice, ok := dh.onus.Load(onuKey); ok {
A R Karthick1f85b802019-10-11 05:06:05 +00001375 // add it to the uniPort map for the onu device
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301376 if _, ok = onuDevice.(*OnuDevice).uniPorts[uniPort]; !ok {
1377 onuDevice.(*OnuDevice).uniPorts[uniPort] = struct{}{}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001378 logger.Debugw(ctx, "adding-uni-port", log.Fields{"port": uniPort, "intf-id": intfID, "onuId": onuID})
A R Karthick1f85b802019-10-11 05:06:05 +00001379 }
1380 }
1381}
1382
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001383// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001384func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001385
Neha Sharma96b7bf22020-06-15 10:37:32 +00001386 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001387
1388 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1389 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001390 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001391 }
1392
Kent Hagermane6ff1012020-07-14 15:07:53 -04001393 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001394 metrics := dh.metrics.GetSubscriberMetrics()
1395 for _, m := range pmConfigs.Metrics {
1396 metrics[m.Name].Enabled = m.Enabled
1397
1398 }
1399 }
1400}
1401
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001402//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301403func (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 +00001404 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 +01001405
1406 var errorsList []error
1407
Girish Gowdru0c588b22019-04-23 23:24:56 -04001408 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001409 for _, flow := range flows.ToRemove.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001410 dh.incrementActiveFlowRemoveCount(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001411
Neha Sharma96b7bf22020-06-15 10:37:32 +00001412 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301413 log.Fields{"device-id": device.Id,
1414 "flowToRemove": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001415 err := dh.flowMgr.RemoveFlow(ctx, flow)
1416 if err != nil {
1417 errorsList = append(errorsList, err)
1418 }
1419
Neha Sharma96b7bf22020-06-15 10:37:32 +00001420 dh.decrementActiveFlowRemoveCount(ctx, flow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001421 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301422
1423 for _, flow := range flows.ToAdd.Items {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001424 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301425 log.Fields{"device-id": device.Id,
1426 "flowToAdd": flow})
Girish Gowdracefae192020-03-19 18:14:10 -07001427 // If there are active Flow Remove in progress for a given subscriber, wait until it completes
Neha Sharma96b7bf22020-06-15 10:37:32 +00001428 dh.waitForFlowRemoveToFinish(ctx, flow)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001429 err := dh.flowMgr.AddFlow(ctx, flow, flowMetadata)
1430 if err != nil {
1431 errorsList = append(errorsList, err)
1432 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301433 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001434 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001435
Girish Gowdracefae192020-03-19 18:14:10 -07001436 // 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 +00001437 if groups != nil {
1438 for _, group := range groups.ToAdd.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001439 err := dh.flowMgr.AddGroup(ctx, group)
1440 if err != nil {
1441 errorsList = append(errorsList, err)
1442 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001443 }
1444 for _, group := range groups.ToUpdate.Items {
Andrea Campanellac63bba92020-03-10 17:01:04 +01001445 err := dh.flowMgr.ModifyGroup(ctx, group)
1446 if err != nil {
1447 errorsList = append(errorsList, err)
1448 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001449 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001450 for _, group := range groups.ToRemove.Items {
1451 err := dh.flowMgr.DeleteGroup(ctx, group)
1452 if err != nil {
1453 errorsList = append(errorsList, err)
1454 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001455 }
1456 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001457 if len(errorsList) > 0 {
1458 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1459 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001460 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001461 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301462}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001463
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001464//DisableDevice disables the given device
1465//It marks the following for the given device:
1466//Device-Handler Admin-State : down
1467//Device Port-State: UNKNOWN
1468//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001469func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001470 /* On device disable ,admin state update has to be done prior sending request to agent since
1471 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001472 if dh.Client != nil {
1473 if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
1474 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001475 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001476 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001477 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001478 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001479 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001480 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001481 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301482
1483 dh.discOnus = sync.Map{}
1484 dh.onus = sync.Map{}
1485
Thomas Lee S85f37312020-04-03 17:06:12 +05301486 //stopping the stats collector
1487 dh.stopCollector <- true
1488
Neha Sharma96b7bf22020-06-15 10:37:32 +00001489 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001490 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301491 //Update device Admin state
1492 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001493 // 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 -04001494 if err := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
1495 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001496 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001497 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001498 return nil
1499}
1500
Neha Sharma96b7bf22020-06-15 10:37:32 +00001501func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001502
1503 // Update onu state as unreachable in onu adapter
1504 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301505 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001506 //get the child device for the parent device
1507 onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
1508 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001509 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 -04001510 }
1511 if onuDevices != nil {
1512 for _, onuDevice := range onuDevices.Items {
1513 err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1514 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1515 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001516 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
Shrey Baid807a2a02020-04-09 12:52:45 +05301517 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001518 }
1519
1520 }
1521 }
1522
1523}
1524
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001525//ReenableDevice re-enables the olt device after disable
1526//It marks the following for the given device:
1527//Device-Handler Admin-State : up
1528//Device Port-State: ACTIVE
1529//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001530func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301531 if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
1532 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001533 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301534 }
1535 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001536 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001537
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001538 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001539
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001540 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1541 if err != nil {
1542 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device": device.Id}, err)
1543 }
1544 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001545 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001546 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001547 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001548 device.OperStatus = voltha.OperStatus_ACTIVE
1549 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001550
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001551 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301552 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001553 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001554 "connect-status": device.ConnectStatus,
1555 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001556 }
kesavand39e0aa32020-01-28 20:58:50 -05001557
Neha Sharma96b7bf22020-06-15 10:37:32 +00001558 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001559
1560 return nil
1561}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001562
npujarec5762e2020-01-01 14:08:48 +05301563func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001564 var uniID uint32
1565 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301566 for _, port := range onu.UniPorts {
1567 uniID = UniIDFromPortNum(uint32(port))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001568 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001569 /* Delete tech-profile instance from the KV store */
npujarec5762e2020-01-01 14:08:48 +05301570 if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001571 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001572 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001573 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301574 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001575 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301576 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001577 }
npujarec5762e2020-01-01 14:08:48 +05301578 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001579 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301580 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001581 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001582 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001583 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301584 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001586 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001587 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301588 }
npujarec5762e2020-01-01 14:08:48 +05301589 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1590 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001591 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301592 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Esin Karaman7fb80c22020-07-16 14:23:33 +00001594 if err = dh.resourceMgr.DelGemPortPktInOfAllServices(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 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 +00001596 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001597 }
1598 return nil
1599}
1600
npujarec5762e2020-01-01 14:08:48 +05301601func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001602 nniUniID := -1
1603 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301604
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001605 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301606 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001607 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001608 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301609 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301610 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001611 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001612 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001613 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301614 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301615 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +00001616 logger.Debugw(ctx, "current-flow-ids-for-nni", log.Fields{"flow-ids": flowIDs})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301617 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301618 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301619 }
npujarec5762e2020-01-01 14:08:48 +05301620 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001621 }
npujarec5762e2020-01-01 14:08:48 +05301622 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001623 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301624 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001625 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001626}
1627
1628// 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 +05301629func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001630 logger.Debug(ctx, "function-entry-delete-device")
Devmalya Paul495b94a2019-08-27 19:42:00 -04001631 /* Clear the KV store data associated with the all the UNI ports
1632 This clears up flow data and also resource map data for various
1633 other pon resources like alloc_id and gemport_id
1634 */
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001635 go dh.cleanupDeviceResources(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001636 logger.Debug(ctx, "removed-device-from-Resource-manager-KV-store")
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001637 // Stop the Stats collector
1638 dh.stopCollector <- true
1639 // stop the heartbeat check routine
1640 dh.stopHeartbeatCheck <- true
1641 //Reset the state
1642 if dh.Client != nil {
1643 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301644 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001645 }
1646 }
1647 cloned := proto.Clone(device).(*voltha.Device)
1648 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1649 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
1650 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
1651 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
1652 "device-id": device.Id,
1653 "connect-status": cloned.ConnectStatus,
1654 "oper-status": cloned.OperStatus}, err).Log()
1655 }
1656 return nil
1657}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001658func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001659 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301660 noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
1661 var ponPort uint32
1662 for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
1663 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301664 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301665 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001666 _ = olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001667 "device-id": dh.device.Id,
Kent Hagermane6ff1012020-07-14 15:07:53 -04001668 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301669 }
1670 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301671 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001672 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301673 if err = dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001674 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301675 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301676 // Clear flowids for gem cache.
1677 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301678 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301679 }
1680 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301681 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301682 }
npujarec5762e2020-01-01 14:08:48 +05301683 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301684 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301685 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301686 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001687 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001688 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001689 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001690 /* Clear the flows from KV store associated with NNI port.
1691 There are mostly trap rules from NNI port (like LLDP)
1692 */
npujarec5762e2020-01-01 14:08:48 +05301693 if err := dh.clearNNIData(ctx); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001694 logger.Errorw(ctx, "failed-to-clear-data-for-NNI-port", log.Fields{"device-id": dh.device.Id})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001695 }
A R Karthick1f85b802019-10-11 05:06:05 +00001696
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001697 /* Clear the resource pool for each PON port in the background */
Kent Hagermane6ff1012020-07-14 15:07:53 -04001698 go func() {
1699 if err := dh.resourceMgr.Delete(ctx); err != nil {
1700 logger.Debug(ctx, err)
1701 }
1702 }()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001703 }
A R Karthick1f85b802019-10-11 05:06:05 +00001704
Devmalya Paul495b94a2019-08-27 19:42:00 -04001705 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301706 dh.onus.Range(func(key interface{}, value interface{}) bool {
1707 dh.onus.Delete(key)
1708 return true
1709 })
1710
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001711 /*Delete discovered ONU map for the device*/
1712 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1713 dh.discOnus.Delete(key)
1714 return true
1715 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001716}
1717
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001718//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001719func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001720 if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301721 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001722 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001723 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001724 return nil
1725}
1726
David K. Bainbridge794735f2020-02-11 21:01:37 -08001727func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001728 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001729 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001730 "packet-indication": *packetIn,
1731 "device-id": dh.device.Id,
1732 "packet": hex.EncodeToString(packetIn.Pkt),
1733 })
1734 }
npujarec5762e2020-01-01 14:08:48 +05301735 logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001736 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001737 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001738 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001739 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001740 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001741 "logical-port-num": logicalPortNum,
1742 "device-id": dh.device.Id,
1743 "packet": hex.EncodeToString(packetIn.Pkt),
1744 })
1745 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001746
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001747 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301748 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001749 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301750 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001751 "device-id": dh.device.Id,
1752 "packet": hex.EncodeToString(packetIn.Pkt),
1753 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001754 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001755
Matteo Scandolo92186242020-06-12 10:54:18 -07001756 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001757 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001758 "packet": hex.EncodeToString(packetIn.Pkt),
1759 "device-id": dh.device.Id,
1760 })
1761 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001762 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001763}
1764
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001765// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301766func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001767 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001768 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001769 "device-id": dh.device.Id,
1770 "egress-port-no": egressPortNo,
1771 "pkt-length": len(packet.Data),
1772 "packet": hex.EncodeToString(packet.Data),
1773 })
1774 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001775
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001776 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001777 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001778 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1779 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301780 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1781 // Do not packet-out lldp packets on uni port.
1782 // ONOS has no clue about uni/nni ports, it just packets out on all
1783 // available ports on the Logical Switch. It should not be interested
1784 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001785 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001786 "device-id": dh.device.Id,
1787 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301788 return nil
1789 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001790 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1791 if innerEthType == 0x8100 {
1792 // q-in-q 802.1ad or 802.1q double tagged packet.
1793 // slice out the outer tag.
1794 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001795 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001796 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001797 "packet-data": hex.EncodeToString(packet.Data),
1798 "device-id": dh.device.Id,
1799 })
1800 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001801 }
1802 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001803 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1804 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001805 uniID := UniIDFromPortNum(uint32(egressPortNo))
1806
Esin Karaman7fb80c22020-07-16 14:23:33 +00001807 gemPortID, err := dh.flowMgr.GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001808 if err != nil {
1809 // In this case the openolt agent will receive the gemPortID as 0.
1810 // The agent tries to retrieve the gemPortID in this case.
1811 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001812 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001813 "intf-id": intfID,
1814 "onu-id": onuID,
1815 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001816 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301817 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001818 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001819 }
1820
1821 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001822
Matteo Scandolo92186242020-06-12 10:54:18 -07001823 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001824 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001825 "egress-port-no": egressPortNo,
1826 "intf-id": intfID,
1827 "onu-id": onuID,
1828 "uni-id": uniID,
1829 "gem-port-id": gemPortID,
1830 "packet": hex.EncodeToString(packet.Data),
1831 "device-id": dh.device.Id,
1832 })
1833 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001834
npujarec5762e2020-01-01 14:08:48 +05301835 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301836 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001837 "source": "adapter",
1838 "destination": "onu",
1839 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001840 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001841 "oni-id": onuID,
1842 "uni-id": uniID,
1843 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001844 "packet": hex.EncodeToString(packet.Data),
1845 "device-id": dh.device.Id,
1846 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001847 }
1848 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001849 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001850 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001851 return olterrors.NewErrInvalidValue(log.Fields{
1852 "egress-nni-port": egressPortNo,
1853 "device-id": dh.device.Id,
1854 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001855 }
1856 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001857
Matteo Scandolo92186242020-06-12 10:54:18 -07001858 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001859 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001860 "uplink-pkt": uplinkPkt,
1861 "packet": hex.EncodeToString(packet.Data),
1862 "device-id": dh.device.Id,
1863 })
1864 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001865
npujarec5762e2020-01-01 14:08:48 +05301866 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001867 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1868 "packet": hex.EncodeToString(packet.Data),
1869 "device-id": dh.device.Id,
1870 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001871 }
1872 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001873 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301874 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001875 "egressPortType": egressPortType,
1876 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301877 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001878 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001879 }
1880 return nil
1881}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001882
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001883func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1884 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001885}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301886
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001887func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301888 // start the heartbeat check towards the OLT.
1889 var timerCheck *time.Timer
1890
1891 for {
1892 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1893 select {
1894 case <-heartbeatTimer.C:
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001895 ctxWithTimeout, cancel := context.WithTimeout(context.Background(), dh.openOLT.GrpcTimeoutInterval)
1896 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001897 logger.Warnw(ctx, "hearbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301898 if timerCheck == nil {
1899 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001900 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301901 }
1902 } else {
1903 if timerCheck != nil {
1904 if timerCheck.Stop() {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001905 logger.Debugw(ctx, "got-hearbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301906 }
1907 timerCheck = nil
1908 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001909 logger.Debugw(ctx, "hearbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301910 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301911 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301912 }
1913 cancel()
1914 case <-dh.stopHeartbeatCheck:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001915 logger.Debugw(ctx, "stopping-heart-beat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301916 return
1917 }
1918 }
1919}
1920
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001921func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
1922 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
1923 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001924 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001925 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301926
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001927 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
1928 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001929 _ = olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001930 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001931 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001932 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001933 }
1934 go dh.cleanupDeviceResources(ctx)
1935
Girish Gowdra3ab6d212020-03-24 17:33:15 -07001936 dh.lockDevice.RLock()
1937 // Stop the read indication only if it the routine is active
1938 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
1939 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
1940 // on next execution of the readIndication routine.
1941 if dh.isReadIndicationRoutineActive {
1942 dh.stopIndications <- true
1943 }
1944 dh.lockDevice.RUnlock()
1945
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001946 dh.transitionMap.Handle(ctx, DeviceInit)
1947
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301948 }
1949}
kesavand39e0aa32020-01-28 20:58:50 -05001950
1951// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001952func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
1953 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
1954 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001955}
1956
1957// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00001958func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
1959 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
1960 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001961}
1962
kdarapu1afeceb2020-02-12 01:38:09 -05001963//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 +00001964func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
1965 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05001966 if port.GetType() == voltha.Port_ETHERNET_NNI {
1967 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001968 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05301969 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301970 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001971 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00001972 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05001973 }
1974 // fetch interfaceid from PortNo
1975 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1976 ponIntf := &oop.Interface{IntfId: ponID}
1977 var operStatus voltha.OperStatus_Types
1978 if enablePort {
1979 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301980 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001981
1982 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301983 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001984 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001985 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001986 }
1987 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001988 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001989 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05001990 } else {
1991 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05301992 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001993 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301994 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001995 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001996 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05001997 }
1998 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001999 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002000 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002001 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302002 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 +05302003 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302004 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002005 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002006 }
2007 return nil
2008}
2009
kdarapu1afeceb2020-02-12 01:38:09 -05002010//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002011func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002012 // Disable the port and update the oper_port_status to core
2013 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002014 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002015 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002016 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302017 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302018 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002019 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002020 }
2021 }
2022 }
2023 return nil
2024}
2025
2026//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002027func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2028 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2029 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002030 if port.Type == voltha.Port_ETHERNET_NNI {
2031 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002032 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002033 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002034 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002035 }
2036 }
2037 if port.Type == voltha.Port_PON_OLT {
2038 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002039 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002040 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002041 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002042 }
2043 }
2044 }
2045}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002046
2047// ChildDeviceLost deletes ONU and clears pon resources related to it.
2048func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002049 logger.Debugw(ctx, "child-device-lost", log.Fields{"pdeviceID": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002050 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2051 onuKey := dh.formOnuKey(intfID, onuID)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002052 onuDevice, ok := dh.onus.Load(onuKey)
2053 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05302054 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002055 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002056 "device-id": dh.device.Id,
2057 "onu-id": onuID,
2058 "intf-id": intfID}, nil).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002059 }
2060 var sn *oop.SerialNumber
2061 var err error
2062 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302063 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002064 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302065 "devicer-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002066 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
2067 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002068
2069 for uniID := 0; uniID < MaxUnisPerOnu; uniID++ {
2070 var flowRemoveData pendingFlowRemoveData
2071 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uint32(uniID)}
2072 dh.lockDevice.RLock()
2073 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
2074 dh.lockDevice.RUnlock()
2075 continue
2076 }
2077 dh.lockDevice.RUnlock()
2078
2079 log.Debugw("wait-for-flow-remove-complete-before-processing-child-device-lost",
2080 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2081 // Wait for all flow removes to finish first
2082 <-flowRemoveData.allFlowsRemoved
2083 log.Debugw("flow-removes-complete-for-subscriber",
2084 log.Fields{"int-id": intfID, "onu-id": onuID, "uni-id": uniID})
2085 }
2086
2087 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002088 if _, err := dh.Client.DeleteOnu(context.Background(), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302089 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302090 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002091 "onu-id": onuID}, err).Log()
2092 }
2093 //clear PON resources associated with ONU
2094 var onuGemData []rsrcMgr.OnuGemInfo
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002095 if onuMgr, ok := dh.resourceMgr.ResourceMgrs[intfID]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002096 logger.Warnw(ctx, "failed-to-get-resource-manager-for-interface-Id", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002097 "device-id": dh.device.Id,
2098 "intf-id": intfID})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002099 } else {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002100 if err := onuMgr.GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002101 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002102 "device-id": dh.device.Id,
2103 "intf-id": intfID,
2104 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002105 } else {
2106 for i, onu := range onuGemData {
2107 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002108 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002109 if err := dh.clearUNIData(ctx, &onu); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002110 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302111 "device-id": dh.device.Id,
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002112 "onu-device": onu,
2113 "error": err})
2114 }
2115 // Clear flowids for gem cache.
2116 for _, gem := range onu.GemPorts {
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002117 dh.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, gem)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002118 }
2119 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002120 err := onuMgr.AddOnuGemInfo(ctx, intfID, onuGemData)
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002121 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002122 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002123 "intf-id": intfID,
2124 "onu-device": onu,
2125 "onu-gem": onuGemData,
2126 "error": err})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002127 //Not returning error on cleanup.
2128 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002129 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGemData})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002130 dh.resourceMgr.FreeonuID(ctx, intfID, []uint32{onu.OnuID})
Andrea Campanella668ea5f2020-03-31 13:51:06 +02002131 break
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05002132 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002133 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002134 }
2135 }
2136 dh.onus.Delete(onuKey)
2137 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
2138 return nil
2139}
Girish Gowdracefae192020-03-19 18:14:10 -07002140
2141func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
2142 for _, field := range flows.GetOfbFields(flow) {
2143 if field.Type == flows.IN_PORT {
2144 return field.GetPort()
2145 }
2146 }
2147 return InvalidPort
2148}
2149
2150func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
2151 for _, action := range flows.GetActions(flow) {
2152 if action.Type == flows.OUTPUT {
2153 if out := action.GetOutput(); out != nil {
2154 return out.GetPort()
2155 }
2156 }
2157 }
2158 return InvalidPort
2159}
2160
Neha Sharma96b7bf22020-06-15 10:37:32 +00002161func (dh *DeviceHandler) incrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002162 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002163 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 -07002164 if inPort != InvalidPort && outPort != InvalidPort {
2165 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2166 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002167 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 -07002168
2169 dh.lockDevice.Lock()
2170 defer dh.lockDevice.Unlock()
2171 flowRemoveData, ok := dh.pendingFlowRemoveDataPerSubscriber[key]
2172 if !ok {
2173 flowRemoveData = pendingFlowRemoveData{
2174 pendingFlowRemoveCount: 0,
2175 allFlowsRemoved: make(chan struct{}),
2176 }
2177 }
2178 flowRemoveData.pendingFlowRemoveCount++
2179 dh.pendingFlowRemoveDataPerSubscriber[key] = flowRemoveData
2180
Neha Sharma96b7bf22020-06-15 10:37:32 +00002181 logger.Debugw(ctx, "current-flow-remove-count–increment",
Matteo Scandolo92186242020-06-12 10:54:18 -07002182 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002183 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2184 }
2185}
2186
Neha Sharma96b7bf22020-06-15 10:37:32 +00002187func (dh *DeviceHandler) decrementActiveFlowRemoveCount(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002188 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002189 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 -07002190 if inPort != InvalidPort && outPort != InvalidPort {
2191 _, intfID, onuID, uniID := ExtractAccessFromFlow(uint32(inPort), uint32(outPort))
2192 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002193 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 -07002194
2195 dh.lockDevice.Lock()
2196 defer dh.lockDevice.Unlock()
2197 if val, ok := dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002198 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 -07002199 } else {
2200 if val.pendingFlowRemoveCount > 0 {
2201 val.pendingFlowRemoveCount--
2202 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00002203 logger.Debugw(ctx, "current-flow-remove-count-after-decrement",
Matteo Scandolo92186242020-06-12 10:54:18 -07002204 log.Fields{"intf-id": intfID, "onu-id": onuID, "uni-id": uniID,
Girish Gowdracefae192020-03-19 18:14:10 -07002205 "currCnt": dh.pendingFlowRemoveDataPerSubscriber[key].pendingFlowRemoveCount})
2206 // If all flow removes have finished, then close the channel to signal the receiver
2207 // to go ahead with flow adds.
2208 if val.pendingFlowRemoveCount == 0 {
2209 close(val.allFlowsRemoved)
2210 delete(dh.pendingFlowRemoveDataPerSubscriber, key)
2211 return
2212 }
2213 dh.pendingFlowRemoveDataPerSubscriber[key] = val
2214 }
2215 }
2216}
2217
Neha Sharma96b7bf22020-06-15 10:37:32 +00002218func (dh *DeviceHandler) waitForFlowRemoveToFinish(ctx context.Context, flow *of.OfpFlowStats) {
Girish Gowdracefae192020-03-19 18:14:10 -07002219 var flowRemoveData pendingFlowRemoveData
2220 var ok bool
2221 inPort, outPort := getPorts(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002222 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 -07002223 if inPort != InvalidPort && outPort != InvalidPort {
2224 _, intfID, onuID, uniID := ExtractAccessFromFlow(inPort, outPort)
2225 key := pendingFlowRemoveDataKey{intfID: intfID, onuID: onuID, uniID: uniID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00002226 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 -07002227
2228 dh.lockDevice.RLock()
2229 if flowRemoveData, ok = dh.pendingFlowRemoveDataPerSubscriber[key]; !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002230 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 -07002231 dh.lockDevice.RUnlock()
2232 return
2233 }
2234 dh.lockDevice.RUnlock()
2235
2236 // Wait for all flow removes to finish first
2237 <-flowRemoveData.allFlowsRemoved
2238
Neha Sharma96b7bf22020-06-15 10:37:32 +00002239 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 -07002240 }
2241}
2242
2243func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2244 inPort := getInPortFromFlow(flow)
2245 outPort := getOutPortFromFlow(flow)
2246
2247 if inPort == InvalidPort || outPort == InvalidPort {
2248 return inPort, outPort
2249 }
2250
2251 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2252 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2253 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2254 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2255 return uniPort, outPort
2256 }
2257 }
2258 } else {
2259 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2260 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
2261 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2262 return inPort, uniPort
2263 }
2264 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2265 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
2266 if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
2267 return uniPort, outPort
2268 }
2269 }
2270 }
2271
2272 return InvalidPort, InvalidPort
2273}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002274
2275func extractOmciTransactionID(omciPkt []byte) uint16 {
2276 if len(omciPkt) > 3 {
2277 d := omciPkt[0:2]
2278 transid := binary.BigEndian.Uint16(d)
2279 return transid
2280 }
2281 return 0
2282}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002283
2284// StoreOnuDevice stores the onu parameters to the local cache.
2285func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2286 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2287 dh.onus.Store(onuKey, onuDevice)
2288}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002289
2290func (dh *DeviceHandler) getExtValue(device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
2291 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002292 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002293 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002294 resp := new(voltha.ReturnValues)
2295 valueparam := new(oop.ValueParam)
2296 ctx := context.Background()
2297 log.Infow("getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002298 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2299 return nil, err
2300 }
2301 ID = device.ProxyAddress.GetOnuId()
2302 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2303 valueparam.Onu = &Onu
2304 valueparam.Value = value
2305
2306 // This API is unsupported until agent patch is added
2307 resp.Unsupported = uint32(value)
2308 _ = ctx
2309
2310 // Uncomment this code once agent changes are complete and tests
2311 /*
2312 resp, err = dh.Client.GetValue(ctx, valueparam)
2313 if err != nil {
2314 log.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "error": err})
2315 return nil, err
2316 }
2317 */
2318
2319 log.Infow("get-ext-value", log.Fields{"resp": resp, "device-id": dh.device, "onu-id": device.Id, "pon-intf": device.ParentPortNo})
2320 return resp, nil
2321}