blob: 8b01c34423748bab1d6fe920061dbfc42546cc1a [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 Jeanneret1359c732019-08-01 21:40:02 -040022 "encoding/hex"
cuilin20187b2a8c32019-03-26 19:52:28 -070023 "fmt"
24 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040025 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070026 "strconv"
27 "strings"
28 "sync"
29 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053030
Chaitrashree G Sb2b62dd2019-07-24 21:47:04 -040031 "google.golang.org/grpc/codes"
32
Matteo Scandolo945e4012019-12-12 14:16:11 -080033 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070034 "github.com/gogo/protobuf/proto"
35 "github.com/golang/protobuf/ptypes"
Esin Karamanccb714b2019-11-29 15:02:06 +000036 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
37 "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"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040047 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053048)
49
salmansiddiqui7ac62132019-08-22 03:58:50 +000050// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040051const (
salmansiddiqui7ac62132019-08-22 03:58:50 +000052 MaxRetry = 10
53 MaxTimeOutInMs = 500
Manikkaraj kb1d51442019-07-23 10:41:02 -040054)
55
Phaneendra Manda4c62c802019-03-06 21:37:49 +053056//DeviceHandler will interact with the OLT device.
57type DeviceHandler struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070058 deviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -070059 deviceType string
Girish Gowdru5ba46c92019-04-25 05:00:05 -040060 adminState string
cuilin20187b2a8c32019-03-26 19:52:28 -070061 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053062 coreProxy adapterif.CoreProxy
63 AdapterProxy adapterif.AdapterProxy
64 EventProxy adapterif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070065 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070066 exitChannel chan int
67 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053068 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070069 transitionMap *TransitionMap
70 clientCon *grpc.ClientConn
manikkaraj kbf256be2019-03-25 00:13:48 +053071 flowMgr *OpenOltFlowMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040072 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053073 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053074
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +053075 discOnus sync.Map
76 onus sync.Map
77 portStats *OpenOltStatisticsMgr
78 metrics *pmmetrics.PmMetrics
79 stopCollector chan bool
80 stopHeartbeatCheck chan bool
Chaitrashree G Sef088112020-02-03 21:39:27 -050081 activePorts sync.Map
Mahir Gunyela3f9add2019-06-06 15:13:19 -070082}
83
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070084//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -070085type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070086 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -070087 deviceType string
88 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070089 onuID uint32
90 intfID uint32
91 proxyDeviceID string
A R Karthick1f85b802019-10-11 05:06:05 +000092 uniPorts map[uint32]struct{}
Mahir Gunyela3f9add2019-06-06 15:13:19 -070093}
94
Naga Manjunath7615e552019-10-11 22:35:47 +053095var pmNames = []string{
96 "rx_bytes",
97 "rx_packets",
98 "rx_mcast_packets",
99 "rx_bcast_packets",
100 "tx_bytes",
101 "tx_packets",
102 "tx_mcast_packets",
103 "tx_bcast_packets",
104}
105
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700106//NewOnuDevice creates a new Onu Device
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700107func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700108 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700109 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700110 device.deviceType = deviceTp
111 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700112 device.onuID = onuID
113 device.intfID = intfID
114 device.proxyDeviceID = proxyDevID
A R Karthick1f85b802019-10-11 05:06:05 +0000115 device.uniPorts = make(map[uint32]struct{})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700116 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530117}
118
119//NewDeviceHandler creates a new device handler
kdarapu381c6902019-07-31 18:23:16 +0530120func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700121 var dh DeviceHandler
122 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400123 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400124 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700125 cloned := (proto.Clone(device)).(*voltha.Device)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700126 dh.deviceID = cloned.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700127 dh.deviceType = cloned.Type
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400128 dh.adminState = "up"
cuilin20187b2a8c32019-03-26 19:52:28 -0700129 dh.device = cloned
130 dh.openOLT = adapter
131 dh.exitChannel = make(chan int, 1)
132 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530133 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530134 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530135 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 -0500136 dh.activePorts = sync.Map{}
cuilin20187b2a8c32019-03-26 19:52:28 -0700137 //TODO initialize the support classes.
138 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530139}
140
141// start save the device to the data model
142func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700143 dh.lockDevice.Lock()
144 defer dh.lockDevice.Unlock()
145 log.Debugw("starting-device-agent", log.Fields{"device": dh.device})
146 // Add the initial device to the local model
147 log.Debug("device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530148}
149
150// stop stops the device dh. Not much to do for now
151func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700152 dh.lockDevice.Lock()
153 defer dh.lockDevice.Unlock()
154 log.Debug("stopping-device-agent")
155 dh.exitChannel <- 1
156 log.Debug("device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530157}
158
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400159func macifyIP(ip net.IP) string {
160 if len(ip) > 0 {
161 oct1 := strconv.FormatInt(int64(ip[12]), 16)
162 oct2 := strconv.FormatInt(int64(ip[13]), 16)
163 oct3 := strconv.FormatInt(int64(ip[14]), 16)
164 oct4 := strconv.FormatInt(int64(ip[15]), 16)
165 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
166 }
167 return ""
168}
169
170func generateMacFromHost(host string) (string, error) {
171 var genmac string
172 var addr net.IP
173 var ips []string
174 var err error
175
176 log.Debugw("generating-mac-from-host", log.Fields{"host": host})
177
178 if addr = net.ParseIP(host); addr == nil {
179 log.Debugw("looking-up-hostname", log.Fields{"host": host})
180
181 if ips, err = net.LookupHost(host); err == nil {
182 log.Debugw("dns-result-ips", log.Fields{"ips": ips})
183 if addr = net.ParseIP(ips[0]); addr == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530184 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil).Log()
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400185 }
186 genmac = macifyIP(addr)
187 log.Debugw("using-ip-as-mac", log.Fields{"host": ips[0], "mac": genmac})
188 return genmac, nil
189 }
Thomas Lee S94109f12020-03-03 16:39:29 +0530190 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", nil, err).Log()
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400191 }
192
193 genmac = macifyIP(addr)
194 log.Debugw("using-ip-as-mac", log.Fields{"host": host, "mac": genmac})
195 return genmac, nil
196}
197
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530198func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700199 slist := strings.Split(mac, ":")
200 result := make([]uint32, len(slist))
201 var err error
202 var tmp int64
203 for index, val := range slist {
204 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
205 return []uint32{1, 2, 3, 4, 5, 6}
206 }
207 result[index] = uint32(tmp)
208 }
209 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530210}
211
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700212//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 -0800213func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530214
David K. Bainbridge794735f2020-02-11 21:01:37 -0800215 switch portType {
216 case voltha.Port_ETHERNET_NNI:
217 return fmt.Sprintf("nni-%d", portNum), nil
218 case voltha.Port_PON_OLT:
219 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700220 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800221
Thomas Lee S94109f12020-03-03 16:39:29 +0530222 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil).Log()
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530223}
224
David K. Bainbridge794735f2020-02-11 21:01:37 -0800225func (dh *DeviceHandler) addPort(intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000226 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700227 if state == "up" {
228 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500229 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500230 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700231 } else {
232 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500233 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700234 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700235 portNum := IntfIDToPortNo(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800236 label, err := GetportLabel(portNum, portType)
237 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530238 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, nil).Log()
Girish Gowdru0c588b22019-04-23 23:24:56 -0400239 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500240
241 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
242 if err != nil || device == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530243 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500244 }
245 if device.Ports != nil {
246 for _, dPort := range device.Ports {
247 if dPort.Type == portType && dPort.PortNo == portNum {
248 log.Debug("port-already-exists-updating-oper-status-of-port")
249 if err := dh.coreProxy.PortStateUpdate(context.TODO(), dh.device.Id, portType, portNum, operStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530250 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800251 "device-id": dh.device.Id,
252 "port-type": portType,
253 "port-number": portNum,
254 "oper-status": operStatus}, err).Log()
255
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500256 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800257 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500258 }
259 }
260 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400261 // Now create Port
262 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700263 PortNo: portNum,
264 Label: label,
265 Type: portType,
266 OperStatus: operStatus,
267 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500268 log.Debugw("Sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700269 // Synchronous call to update device - this method is run in its own go routine
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700270 if err := dh.coreProxy.PortCreated(context.TODO(), dh.device.Id, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530271 return olterrors.NewErrAdapter("Error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800272 "device-id": dh.device.Id,
273 "port-type": portType}, err).Log()
Girish Gowdru1110ef22019-06-24 11:17:59 -0400274 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800275 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530276}
277
278// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800279func (dh *DeviceHandler) readIndications(ctx context.Context) error {
280 defer log.Debugw("indications-ended", log.Fields{"device-id": dh.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530281 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
cuilin20187b2a8c32019-03-26 19:52:28 -0700282 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530283 return olterrors.NewErrCommunication("fail-to-read-indications", log.Fields{"device-id": dh.device.Id}, err).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -0700284 }
285 if indications == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530286 return olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -0700287 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400288 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530289 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400290 if err != nil || device == nil {
291 /*TODO: needs to handle error scenarios */
Thomas Lee S94109f12020-03-03 16:39:29 +0530292 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400293 }
294 // When the device is in DISABLED and Adapter container restarts, we need to
295 // rebuild the locally maintained admin state.
296 if device.AdminState == voltha.AdminState_DISABLED {
297 dh.lockDevice.Lock()
298 dh.adminState = "down"
299 dh.lockDevice.Unlock()
300 }
301
David Bainbridgef5879ca2019-12-13 21:17:54 +0000302 // Create an exponential backoff around re-enabling indications. The
303 // maximum elapsed time for the back off is set to 0 so that we will
304 // continue to retry. The max interval defaults to 1m, but is set
305 // here for code clarity
306 indicationBackoff := backoff.NewExponentialBackOff()
307 indicationBackoff.MaxElapsedTime = 0
308 indicationBackoff.MaxInterval = 1 * time.Minute
cuilin20187b2a8c32019-03-26 19:52:28 -0700309 for {
310 indication, err := indications.Recv()
311 if err == io.EOF {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530312 log.Infow("EOF for indications", log.Fields{"err": err})
David Bainbridgef5879ca2019-12-13 21:17:54 +0000313 // Use an exponential back off to prevent getting into a tight loop
314 duration := indicationBackoff.NextBackOff()
315 if duration == backoff.Stop {
316 // If we reach a maximum then warn and reset the backoff
317 // timer and keep attempting.
318 log.Warnw("Maximum indication backoff reached, resetting backoff timer",
319 log.Fields{"max_indication_backoff": indicationBackoff.MaxElapsedTime})
320 indicationBackoff.Reset()
321 }
322 time.Sleep(indicationBackoff.NextBackOff())
npujarec5762e2020-01-01 14:08:48 +0530323 indications, err = dh.Client.EnableIndication(ctx, new(oop.Empty))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530324 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530325 return olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530326 }
327 continue
cuilin20187b2a8c32019-03-26 19:52:28 -0700328 }
329 if err != nil {
330 log.Infow("Failed to read from indications", log.Fields{"err": err})
Devmalya Paul495b94a2019-08-27 19:42:00 -0400331 if dh.adminState == "deleted" {
332 log.Debug("Device deleted stoping the read indication thread")
333 break
334 }
npujarec5762e2020-01-01 14:08:48 +0530335 dh.transitionMap.Handle(ctx, DeviceDownInd)
336 dh.transitionMap.Handle(ctx, DeviceInit)
Thomas Lee S94109f12020-03-03 16:39:29 +0530337 return olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -0700338 }
David Bainbridgef5879ca2019-12-13 21:17:54 +0000339 // Reset backoff if we have a successful receive
340 indicationBackoff.Reset()
Chaitrashree G S44124192019-08-07 20:21:36 -0400341 dh.lockDevice.RLock()
342 adminState := dh.adminState
343 dh.lockDevice.RUnlock()
Chaitrashree G S3b4c0352019-09-09 20:59:29 -0400344 // When OLT is admin down, ignore all indications.
Chaitrashree G S44124192019-08-07 20:21:36 -0400345 if adminState == "down" {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530346
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +0530347 log.Infow("olt is admin down, ignore indication", log.Fields{"indication": indication})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -0400348 continue
349 }
npujarec5762e2020-01-01 14:08:48 +0530350 dh.handleIndication(ctx, indication)
manikkaraj kbf256be2019-03-25 00:13:48 +0530351
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700352 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800353 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700354}
355
David K. Bainbridge794735f2020-02-11 21:01:37 -0800356func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000357 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000358 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530359 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700360 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530361 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700362 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000363 // Send or clear Alarm
David K. Bainbridge794735f2020-02-11 21:01:37 -0800364 if err := dh.eventMgr.oltUpDownIndication(oltIndication, dh.deviceID, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530365 return olterrors.NewErrAdapter("failed-indication", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800366 "device_id": dh.deviceID,
367 "indication": oltIndication,
368 "timestamp": raisedTs}, err).Log()
369 }
370 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700371}
372
David K. Bainbridge794735f2020-02-11 21:01:37 -0800373// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530374func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400375 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700376 switch indication.Data.(type) {
377 case *oop.Indication_OltInd:
David K. Bainbridge794735f2020-02-11 21:01:37 -0800378 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530379 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt"}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800380 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700381 case *oop.Indication_IntfInd:
382 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800383 go func() {
384 if err := dh.addPort(intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530385 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface"}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800386 }
387 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700388 log.Infow("Received interface indication ", log.Fields{"InterfaceInd": intfInd})
389 case *oop.Indication_IntfOperInd:
390 intfOperInd := indication.GetIntfOperInd()
391 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800392 go func() {
393 if err := dh.addPort(intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530394 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-nni"}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800395 }
396 }()
npujarec5762e2020-01-01 14:08:48 +0530397 dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700398 } else if intfOperInd.GetType() == "pon" {
399 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
400 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800401 go func() {
402 if err := dh.addPort(intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530403 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-pon"}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800404 }
405 }()
kesavand39e0aa32020-01-28 20:58:50 -0500406 go dh.eventMgr.oltIntfOperIndication(indication.GetIntfOperInd(), dh.deviceID, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700407 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700408 log.Infow("Received interface oper indication ", log.Fields{"InterfaceOperInd": intfOperInd})
409 case *oop.Indication_OnuDiscInd:
410 onuDiscInd := indication.GetOnuDiscInd()
411 log.Infow("Received Onu discovery indication ", log.Fields{"OnuDiscInd": onuDiscInd})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700412 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800413 go func() {
414 if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530415 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu-discovery"}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800416 }
417 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700418 case *oop.Indication_OnuInd:
419 onuInd := indication.GetOnuInd()
420 log.Infow("Received Onu indication ", log.Fields{"OnuInd": onuInd})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800421 go func() {
422 if err := dh.onuIndication(onuInd); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530423 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "onu"}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800424 }
425 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700426 case *oop.Indication_OmciInd:
427 omciInd := indication.GetOmciInd()
lcuie24ef182019-04-29 22:58:36 -0700428 log.Debugw("Received Omci indication ", log.Fields{"IntfId": omciInd.IntfId, "OnuId": omciInd.OnuId, "pkt": hex.EncodeToString(omciInd.Pkt)})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800429 go func() {
430 if err := dh.omciIndication(omciInd); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530431 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci"}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800432 }
433 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700434 case *oop.Indication_PktInd:
435 pktInd := indication.GetPktInd()
436 log.Infow("Received pakcet indication ", log.Fields{"PktInd": pktInd})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800437 go func() {
438 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530439 olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet"}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800440 }
441 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700442 case *oop.Indication_PortStats:
443 portStats := indication.GetPortStats()
Naga Manjunath7615e552019-10-11 22:35:47 +0530444 go dh.portStats.PortStatisticsIndication(portStats, dh.resourceMgr.DevInfo.GetPonPorts())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700445 case *oop.Indication_FlowStats:
446 flowStats := indication.GetFlowStats()
447 log.Infow("Received flow stats", log.Fields{"FlowStats": flowStats})
448 case *oop.Indication_AlarmInd:
449 alarmInd := indication.GetAlarmInd()
450 log.Infow("Received alarm indication ", log.Fields{"AlarmInd": alarmInd})
Naga Manjunath7615e552019-10-11 22:35:47 +0530451 go dh.eventMgr.ProcessEvents(alarmInd, dh.deviceID, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700452 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530453}
454
455// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530456func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400457 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530458 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400459 voltha.OperStatus_ACTIVE); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530460 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdru0c588b22019-04-23 23:24:56 -0400461 }
462 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530463}
464
465// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530466func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700467 dh.lockDevice.Lock()
468 defer dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400469 log.Debug("do-state-down-start")
470
npujarec5762e2020-01-01 14:08:48 +0530471 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400472 if err != nil || device == nil {
473 /*TODO: needs to handle error scenarios */
Thomas Lee S94109f12020-03-03 16:39:29 +0530474 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrud4245152019-05-10 00:47:31 -0400475 }
476
477 cloned := proto.Clone(device).(*voltha.Device)
478 // Update the all ports state on that device to disable
David K. Bainbridge794735f2020-02-11 21:01:37 -0800479 if err = dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530480 return olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": device.Id}, err).Log()
Girish Gowdrud4245152019-05-10 00:47:31 -0400481 }
482
483 //Update the device oper state and connection status
484 cloned.OperStatus = voltha.OperStatus_UNKNOWN
485 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
486 dh.device = cloned
487
David K. Bainbridge794735f2020-02-11 21:01:37 -0800488 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530489 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err).Log()
Girish Gowdrud4245152019-05-10 00:47:31 -0400490 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400491
492 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530493 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400494 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530495 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400496 }
497 for _, onuDevice := range onuDevices.Items {
498
499 // Update onu state as down in onu adapter
500 onuInd := oop.OnuIndication{}
501 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800502 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700503 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800504 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530505 olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800506 "source": "openolt",
507 "onu-indicator": onuInd,
508 "device-type": onuDevice.Type,
509 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700510 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700511 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400512 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700513 /* Discovered ONUs entries need to be cleared , since after OLT
514 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530515 dh.discOnus = sync.Map{}
David K. Bainbridge794735f2020-02-11 21:01:37 -0800516 log.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700517 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530518}
519
520// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530521func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400522 var err error
David K. Bainbridge794735f2020-02-11 21:01:37 -0800523 if dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure(), grpc.WithBlock()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530524 return olterrors.NewErrCommunication("dial-failure", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800525 "device-id": dh.deviceID,
526 "host-and-port": dh.device.GetHostAndPort()}, err).Log()
Girish Gowdru0c588b22019-04-23 23:24:56 -0400527 }
528 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530529}
530
531// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530532func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400533 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530534 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400535 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530536}
537
538// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530539func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400540 log.Debug("OLT device has been connected")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400541
542 // Case where OLT is disabled and then rebooted.
543 if dh.adminState == "down" {
544 log.Debugln("do-state-connected--device-admin-state-down")
npujarec5762e2020-01-01 14:08:48 +0530545 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400546 if err != nil || device == nil {
547 /*TODO: needs to handle error scenarios */
Thomas Lee S94109f12020-03-03 16:39:29 +0530548 olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400549 }
550
551 cloned := proto.Clone(device).(*voltha.Device)
552 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
553 cloned.OperStatus = voltha.OperStatus_UNKNOWN
554 dh.device = cloned
npujarec5762e2020-01-01 14:08:48 +0530555 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530556 olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400557 }
558
Chaitrashree G S44124192019-08-07 20:21:36 -0400559 // 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 +0530560 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400561 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530562 olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400563 }
564
565 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800566 go func() {
567 if err := dh.readIndications(ctx); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530568 olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800569 }
570 }()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400571 return nil
572 }
573
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400574 deviceInfo, err := dh.populateDeviceInfo()
cuilin20187b2a8c32019-03-26 19:52:28 -0700575 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530576 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -0700577 }
Girish Gowdrud4245152019-05-10 00:47:31 -0400578
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700579 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400580 if err != nil || device == nil {
581 /*TODO: needs to handle error scenarios */
Thomas Lee S94109f12020-03-03 16:39:29 +0530582 return olterrors.NewErrAdapter("fetch-device-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrud4245152019-05-10 00:47:31 -0400583 }
kesavand39e0aa32020-01-28 20:58:50 -0500584 dh.populateActivePorts(device)
kdarapu1afeceb2020-02-12 01:38:09 -0500585 if err := dh.disableAdminDownPorts(device); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530586 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"device": device}, err).Log()
Girish Gowdrud4245152019-05-10 00:47:31 -0400587 }
588
Girish Gowdru0c588b22019-04-23 23:24:56 -0400589 KVStoreHostPort := fmt.Sprintf("%s:%d", dh.openOLT.KVStoreHost, dh.openOLT.KVStorePort)
590 // Instantiate resource manager
npujarec5762e2020-01-01 14:08:48 +0530591 if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.deviceID, KVStoreHostPort, dh.openOLT.KVStoreType, dh.deviceType, deviceInfo); dh.resourceMgr == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530592 return olterrors.ErrResourceManagerInstantiating.Log()
Girish Gowdru0c588b22019-04-23 23:24:56 -0400593 }
594 // Instantiate flow manager
npujarec5762e2020-01-01 14:08:48 +0530595 if dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr); dh.flowMgr == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530596 return olterrors.ErrResourceManagerInstantiating.Log()
Girish Gowdru0c588b22019-04-23 23:24:56 -0400597 }
598 /* TODO: Instantiate Alarm , stats , BW managers */
Devmalya Paulfb990a52019-07-09 10:01:49 -0400599 /* Instantiating Event Manager to handle Alarms and KPIs */
Devmalya Paul90ca3012019-09-02 21:55:45 -0400600 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
Naga Manjunath7615e552019-10-11 22:35:47 +0530601 // Stats config for new device
602 dh.portStats = NewOpenOltStatsMgr(dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530603
cuilin20187b2a8c32019-03-26 19:52:28 -0700604 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800605 go func() {
606 if err := dh.readIndications(ctx); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530607 olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800608 }
609 }()
cuilin20187b2a8c32019-03-26 19:52:28 -0700610 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530611}
612
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400613func (dh *DeviceHandler) populateDeviceInfo() (*oop.DeviceInfo, error) {
614 var err error
615 var deviceInfo *oop.DeviceInfo
616
617 deviceInfo, err = dh.Client.GetDeviceInfo(context.Background(), new(oop.Empty))
618
619 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530620 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err).Log()
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400621 }
622 if deviceInfo == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530623 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil).Log()
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400624 }
625
626 log.Debugw("Fetched device info", log.Fields{"deviceInfo": deviceInfo})
627 dh.device.Root = true
628 dh.device.Vendor = deviceInfo.Vendor
629 dh.device.Model = deviceInfo.Model
630 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
631 dh.device.HardwareVersion = deviceInfo.HardwareVersion
632 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
633
634 if deviceInfo.DeviceId == "" {
635 log.Warnw("no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
636 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
637 genmac, err := generateMacFromHost(host)
638 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530639 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err).Log()
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400640 }
641 log.Debugw("using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
642 dh.device.MacAddress = genmac
643 } else {
644 dh.device.MacAddress = deviceInfo.DeviceId
645 }
646
647 // Synchronous call to update device - this method is run in its own go routine
648 if err := dh.coreProxy.DeviceUpdate(context.TODO(), dh.device); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530649 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400650 }
651
652 return deviceInfo, nil
653}
654
Naga Manjunath7615e552019-10-11 22:35:47 +0530655func startCollector(dh *DeviceHandler) {
656 // Initial delay for OLT initialization
657 time.Sleep(1 * time.Minute)
658 log.Debugf("Starting-Collector")
659 context := make(map[string]string)
660 for {
661 select {
662 case <-dh.stopCollector:
663 log.Debugw("Stopping-Collector-for-OLT", log.Fields{"deviceID:": dh.deviceID})
664 return
665 default:
666 freq := dh.metrics.ToPmConfigs().DefaultFreq
667 time.Sleep(time.Duration(freq) * time.Second)
668 context["oltid"] = dh.deviceID
669 context["devicetype"] = dh.deviceType
670 // NNI Stats
671 cmnni := dh.portStats.collectNNIMetrics(uint32(0))
672 log.Debugf("Collect-NNI-Metrics %v", cmnni)
673 go dh.portStats.publishMetrics("NNIStats", cmnni, uint32(0), context, dh.deviceID)
674 log.Debugf("Publish-NNI-Metrics")
675 // PON Stats
676 NumPonPORTS := dh.resourceMgr.DevInfo.GetPonPorts()
Chaitrashree G Sef088112020-02-03 21:39:27 -0500677 for i := uint32(0); i < NumPonPORTS; i++ {
678 if val, ok := dh.activePorts.Load(i); ok && val == true {
679 cmpon := dh.portStats.collectPONMetrics(i)
680 log.Debugf("Collect-PON-Metrics %v", cmpon)
Naga Manjunath7615e552019-10-11 22:35:47 +0530681
Chaitrashree G Sef088112020-02-03 21:39:27 -0500682 go dh.portStats.publishMetrics("PONStats", cmpon, i, context, dh.deviceID)
683 log.Debugf("Publish-PON-Metrics")
684 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530685 }
686 }
687 }
688}
689
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700690//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530691func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400692 dh.transitionMap = NewTransitionMap(dh)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700693 log.Infow("Adopt_device", log.Fields{"deviceID": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530694 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530695
696 // Now, set the initial PM configuration for that device
697 if err := dh.coreProxy.DevicePMConfigUpdate(nil, dh.metrics.ToPmConfigs()); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530698 olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530699 }
700
701 go startCollector(dh)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530702 go startHeartbeatCheck(dh)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530703}
704
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700705//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530706func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700707 return &ic.SwitchCapability{
708 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530709 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700710 HwDesc: "open_pon",
711 SwDesc: "open_pon",
712 SerialNum: dh.device.SerialNumber,
713 },
714 SwitchFeatures: &of.OfpSwitchFeatures{
715 NBuffers: 256,
716 NTables: 2,
717 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
718 of.OfpCapabilities_OFPC_TABLE_STATS |
719 of.OfpCapabilities_OFPC_PORT_STATS |
720 of.OfpCapabilities_OFPC_GROUP_STATS),
721 },
722 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530723}
724
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700725//GetOfpPortInfo Get Ofp port information
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530726func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device, portNo int64) (*ic.PortCapability, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700727 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
cuilin20187b2a8c32019-03-26 19:52:28 -0700728 return &ic.PortCapability{
729 Port: &voltha.LogicalPort{
730 OfpPort: &of.OfpPort{
731 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
732 Config: 0,
733 State: uint32(of.OfpPortState_OFPPS_LIVE),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700734 Curr: capacity,
735 Advertised: capacity,
736 Peer: capacity,
cuilin20187b2a8c32019-03-26 19:52:28 -0700737 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
738 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
739 },
740 DeviceId: dh.device.Id,
741 DevicePortNo: uint32(portNo),
742 },
743 }, nil
744}
745
David K. Bainbridge794735f2020-02-11 21:01:37 -0800746func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700747 log.Debugw("omci indication", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700748 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700749 var deviceID string
750 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700751
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700752 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530753
754 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
755
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700756 log.Debugw("omci indication for a device not in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
757 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700758 kwargs := make(map[string]interface{})
759 kwargs["onu_id"] = omciInd.OnuId
760 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700761
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700762 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
763 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530764 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800765 "interface-id": omciInd.IntfId,
766 "onu-id": omciInd.OnuId}, err).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -0700767 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700768 deviceType = onuDevice.Type
769 deviceID = onuDevice.Id
770 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
771 //if not exist in cache, then add to cache.
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530772 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700773 } else {
774 //found in cache
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700775 log.Debugw("omci indication for a device in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530776 deviceType = onuInCache.(*OnuDevice).deviceType
777 deviceID = onuInCache.(*OnuDevice).deviceID
778 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700779 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700780
781 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
David K. Bainbridge794735f2020-02-11 21:01:37 -0800782 if err := dh.AdapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700783 ic.InterAdapterMessageType_OMCI_REQUEST, dh.deviceType, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800784 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530785 return olterrors.NewErrCommunication("omci-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800786 "source": dh.deviceType,
787 "destination": deviceType,
788 "onu-id": deviceID,
789 "proxy-device-id": proxyDeviceID}, err).Log()
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700790 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800791 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530792}
793
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700794//ProcessInterAdapterMessage sends the proxied messages to the target device
795// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
796// is meant, and then send the unmarshalled omci message to this onu
797func (dh *DeviceHandler) ProcessInterAdapterMessage(msg *ic.InterAdapterMessage) error {
798 log.Debugw("Process_inter_adapter_message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700799 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700800 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700801 fromTopic := msg.Header.FromTopic
802 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700803 toDeviceID := msg.Header.ToDeviceId
804 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700805
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700806 log.Debugw("omci request message header", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
cuilin20187b2a8c32019-03-26 19:52:28 -0700807
808 msgBody := msg.GetBody()
809
810 omciMsg := &ic.InterAdapterOmciMessage{}
811 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
812 log.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{"error": err})
813 return err
814 }
815
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700816 if omciMsg.GetProxyAddress() == nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700817 onuDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, toDeviceID)
818 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530819 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800820 "device-id": dh.device.Id,
821 "onu-device-id": toDeviceID}, err).Log()
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700822 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700823 log.Debugw("device retrieved from core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800824 if err := dh.sendProxiedMessage(onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530825 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800826 "device-id": dh.device.Id,
827 "onu-device-id": toDeviceID}, err).Log()
828 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700829 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700830 log.Debugw("Proxy Address found in omci message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800831 if err := dh.sendProxiedMessage(nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530832 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800833 "device-id": dh.device.Id,
834 "onu-device-id": toDeviceID}, err).Log()
835 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700836 }
837
838 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530839 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -0700840 }
841 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530842}
843
David K. Bainbridge794735f2020-02-11 21:01:37 -0800844func (dh *DeviceHandler) sendProxiedMessage(onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700845 var intfID uint32
846 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +0000847 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700848 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700849 intfID = onuDevice.ProxyAddress.GetChannelId()
850 onuID = onuDevice.ProxyAddress.GetOnuId()
851 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700852 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700853 intfID = omciMsg.GetProxyAddress().GetChannelId()
854 onuID = omciMsg.GetProxyAddress().GetOnuId()
855 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700856 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700857 if connectStatus != voltha.ConnectStatus_REACHABLE {
858 log.Debugw("ONU is not reachable, cannot send OMCI", log.Fields{"intfID": intfID, "onuID": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800859
Thomas Lee S94109f12020-03-03 16:39:29 +0530860 return olterrors.NewErrCommunication("unreachable", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800861 "interface-id": intfID,
862 "onu-id": onuID}, nil).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -0700863 }
864
lcuie24ef182019-04-29 22:58:36 -0700865 // TODO: Once we are sure openonu/openomci is sending only binary in omciMsg.Message, we can remove this check
866 isHexString := false
867 _, decodeerr := hex.DecodeString(string(omciMsg.Message))
868 if decodeerr == nil {
869 isHexString = true
870 }
871
872 // TODO: OpenOLT Agent expects a hex string for OMCI packets rather than binary. Fix this in the agent and then we can pass binary Pkt: omciMsg.Message.
873 var omciMessage *oop.OmciMsg
874 if isHexString {
875 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: omciMsg.Message}
876 } else {
877 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
878 hex.Encode(hexPkt, omciMsg.Message)
879 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
880 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700881
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700882 _, err := dh.Client.OmciMsgOut(context.Background(), omciMessage)
883 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530884 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800885 "interface-id": intfID,
886 "onu-id": onuID,
887 "message": omciMessage}, err).Log()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700888 }
lcuie24ef182019-04-29 22:58:36 -0700889 log.Debugw("Sent Omci message", log.Fields{"intfID": intfID, "onuID": onuID, "omciMsg": hex.EncodeToString(omciMsg.Message)})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800890 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700891}
892
David K. Bainbridge794735f2020-02-11 21:01:37 -0800893func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700894 log.Debugw("activate-onu", log.Fields{"intfID": intfID, "onuID": onuID, "serialNum": serialNum, "serialNumber": serialNumber})
npujarec5762e2020-01-01 14:08:48 +0530895 dh.flowMgr.UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber)
cuilin20187b2a8c32019-03-26 19:52:28 -0700896 // TODO: need resource manager
897 var pir uint32 = 1000000
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700898 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir}
npujarec5762e2020-01-01 14:08:48 +0530899 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400900 st, _ := status.FromError(err)
901 if st.Code() == codes.AlreadyExists {
902 log.Debug("ONU activation is in progress", log.Fields{"SerialNumber": serialNumber})
903 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530904 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu}, err).Log()
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400905 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700906 } else {
907 log.Infow("activated-onu", log.Fields{"SerialNumber": serialNumber})
908 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800909 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700910}
911
David K. Bainbridge794735f2020-02-11 21:01:37 -0800912func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Matteo Scandolo945e4012019-12-12 14:16:11 -0800913
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700914 channelID := onuDiscInd.GetIntfId()
915 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -0400916
Matteo Scandolo945e4012019-12-12 14:16:11 -0800917 log.Infow("new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530918
cuilin20187b2a8c32019-03-26 19:52:28 -0700919 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400920 if sn != "" {
921 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -0400922 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530923 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil).Log()
Chaitrashree G S35b5d802019-07-08 23:12:03 -0400924 }
925
Amit Ghoshe5c6a852020-02-10 15:09:46 +0000926 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
927 log.Warnw("onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800928 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +0000929 }
930
Chaitrashree G S35b5d802019-07-08 23:12:03 -0400931 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -0800932
933 // check the ONU is already know to the OLT
934 // NOTE the second time the ONU is discovered this should return a device
935 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
936
937 if err != nil {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800938 log.Warnw("core-proxy-get-child-device-failed", log.Fields{"parentDevice": dh.device.Id, "err": err, "sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -0800939 if e, ok := status.FromError(err); ok {
940 log.Warnw("core-proxy-get-child-device-failed-with-code", log.Fields{"errCode": e.Code(), "sn": sn})
941 switch e.Code() {
942 case codes.Internal:
943 // this probably means NOT FOUND, so just create a new device
944 onuDevice = nil
945 case codes.DeadlineExceeded:
946 // if the call times out, cleanup and exit
947 dh.discOnus.Delete(sn)
Thomas Lee S94109f12020-03-03 16:39:29 +0530948 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err).Log()
Matteo Scandolo945e4012019-12-12 14:16:11 -0800949 }
950 }
951 }
952
953 if onuDevice == nil {
954 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
955 log.Infow("creating-new-onu", log.Fields{"sn": sn})
956 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -0400957 ponintfid := onuDiscInd.GetIntfId()
958 dh.lockDevice.Lock()
npujarec5762e2020-01-01 14:08:48 +0530959 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Matt Jeanneret53539512019-07-20 14:47:02 -0400960 dh.lockDevice.Unlock()
Chaitrashree G S35b5d802019-07-08 23:12:03 -0400961
Matteo Scandolo945e4012019-12-12 14:16:11 -0800962 log.Infow("creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
963
964 if err != nil {
965 // if we can't create an ID in resource manager,
966 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -0800967 dh.discOnus.Delete(sn)
Thomas Lee S94109f12020-03-03 16:39:29 +0530968 return olterrors.NewErrAdapter("resource-manage-get-onu-id-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800969 "pon-interface-id": ponintfid,
970 "serial-number": sn}, err).Log()
Matteo Scandolo945e4012019-12-12 14:16:11 -0800971 }
972
973 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(context.TODO(), dh.device.Id, int(parentPortNo),
974 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -0800975 dh.discOnus.Delete(sn)
976 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 +0530977 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800978 "pon-interface-id": ponintfid,
979 "serial-number": sn}, err).Log()
Matteo Scandolo945e4012019-12-12 14:16:11 -0800980 }
981
982 log.Infow("onu-child-device-added", log.Fields{"onuDevice": onuDevice, "sn": sn})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400983 }
Matteo Scandolo945e4012019-12-12 14:16:11 -0800984
985 // we can now use the existing ONU Id
986 onuID = onuDevice.ProxyAddress.OnuId
987
Mahir Gunyele77977b2019-06-27 05:36:22 -0700988 //Insert the ONU into cache to use in OnuIndication.
989 //TODO: Do we need to remove this from the cache on ONU change, or wait for overwritten on next discovery.
Matteo Scandolo945e4012019-12-12 14:16:11 -0800990 log.Debugw("onu-discovery-indication-key-create", log.Fields{"onuID": onuID,
991 "intfId": onuDiscInd.GetIntfId(), "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -0700992 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -0400993
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530994 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId)
995 dh.onus.Store(onuKey, onuDev)
Matteo Scandolo945e4012019-12-12 14:16:11 -0800996 log.Debugw("new-onu-device-discovered", log.Fields{"onu": onuDev, "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -0400997
David K. Bainbridge794735f2020-02-11 21:01:37 -0800998 if err = dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530999 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001000 "device-id": onuDevice.Id,
1001 "serial-number": sn}, err).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -07001002 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001003 log.Infow("onu-discovered-reachable", log.Fields{"deviceId": onuDevice.Id, "sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001004 if err = dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301005 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001006 "device-id": onuDevice.Id,
1007 "serial-number": sn}, err).Log()
1008 }
1009 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001010}
1011
David K. Bainbridge794735f2020-02-11 21:01:37 -08001012func (dh *DeviceHandler) onuIndication(onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001013 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
1014
1015 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001016 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001017 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001018 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001019 foundInCache := false
Scott Baker7eb0a932019-07-26 10:33:22 -07001020 log.Debugw("ONU indication key create", log.Fields{"onuId": onuInd.OnuId,
1021 "intfId": onuInd.GetIntfId()})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001022 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301023
David K. Bainbridge794735f2020-02-11 21:01:37 -08001024 errFields := log.Fields{"device-id": dh.device.Id}
1025
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301026 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1027
Mahir Gunyele77977b2019-06-27 05:36:22 -07001028 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1029 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001030 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
1031 onuDevice, err = dh.coreProxy.GetDevice(nil, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001032 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001033 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1034 if serialNumber != "" {
1035 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001036 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001037 } else {
1038 kwargs["onu_id"] = onuInd.OnuId
1039 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001040 errFields["onu-id"] = onuInd.OnuId
1041 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001042 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001043 onuDevice, err = dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001044 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001045
David K. Bainbridge794735f2020-02-11 21:01:37 -08001046 if err != nil || onuDevice == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301047 return olterrors.NewErrNotFound("onu-device", errFields, err).Log()
cuilin20187b2a8c32019-03-26 19:52:28 -07001048 }
1049
David K. Bainbridge794735f2020-02-11 21:01:37 -08001050 if onuDevice.ParentPortNo != ponPort {
1051 log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{
1052 "previousIntfId": onuDevice.ParentPortNo,
1053 "currentIntfId": ponPort})
1054 }
1055
1056 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
1057 log.Warnw("ONU-id-mismatch, can happen if both voltha and the olt rebooted", log.Fields{
1058 "expected_onu_id": onuDevice.ProxyAddress.OnuId,
1059 "received_onu_id": onuInd.OnuId})
1060 }
1061 if !foundInCache {
1062 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1063
1064 dh.onus.Store(onuKey, NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuInd.GetOnuId(), onuInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId))
1065
1066 }
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001067 if err := dh.updateOnuStates(onuDevice, onuInd); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301068 return olterrors.NewErrCommunication("state-update-failed", errFields, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001069 }
1070 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001071}
1072
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001073func (dh *DeviceHandler) updateOnuStates(onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
npujarec5762e2020-01-01 14:08:48 +05301074 ctx := context.TODO()
Matt Jeanneret53539512019-07-20 14:47:02 -04001075 log.Debugw("onu-indication-for-state", log.Fields{"onuIndication": onuInd, "DeviceId": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001076 if onuInd.AdminState == "down" {
1077 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1078 if onuInd.OperState != "down" {
1079 log.Warnw("ONU-admin-state-down", log.Fields{"operState": onuInd.OperState})
1080 onuInd.OperState = "down"
1081 }
1082 }
1083
David K. Bainbridge794735f2020-02-11 21:01:37 -08001084 switch onuInd.OperState {
1085 case "down":
Matt Jeanneret53539512019-07-20 14:47:02 -04001086 log.Debugw("sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "DeviceId": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001087 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301088 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001089 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1090 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301091 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001092 "onu-indicator": onuInd,
1093 "source": "openolt",
1094 "device-type": onuDevice.Type,
1095 "device-id": onuDevice.Id}, err).Log()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001096 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001097 case "up":
Matt Jeanneret53539512019-07-20 14:47:02 -04001098 log.Debugw("sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "DeviceId": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
1099 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301100 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001101 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1102 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301103 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001104 "onu-indicator": onuInd,
1105 "source": "openolt",
1106 "device-type": onuDevice.Type,
1107 "device-id": onuDevice.Id}, err).Log()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001108 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001109 default:
Thomas Lee S94109f12020-03-03 16:39:29 +05301110 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil).Log()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001111 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001112 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001113}
1114
cuilin20187b2a8c32019-03-26 19:52:28 -07001115func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1116 if serialNum != nil {
1117 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001118 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001119 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001120}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001121func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1122 decodedStr, err := hex.DecodeString(serialNum[4:])
1123 if err != nil {
1124 return nil, err
1125 }
1126 return &oop.SerialNumber{
1127 VendorId: []byte(serialNum[:4]),
1128 VendorSpecific: []byte(decodedStr),
1129 }, nil
1130}
cuilin20187b2a8c32019-03-26 19:52:28 -07001131
1132func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1133 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001134 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001135 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1136 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1137 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1138 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1139 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1140 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1141 return tmp
1142}
1143
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001144//UpdateFlowsBulk upates the bulk flow
1145func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301146 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001147}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001148
1149//GetChildDevice returns the child device for given parent port and onu id
David K. Bainbridge794735f2020-02-11 21:01:37 -08001150func (dh *DeviceHandler) GetChildDevice(parentPort, onuID uint32) (*voltha.Device, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001151 log.Debugw("GetChildDevice", log.Fields{"pon port": parentPort, "onuID": onuID})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001152 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001153 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001154 kwargs["parent_port_no"] = parentPort
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001155 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001156 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301157 return nil, olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001158 "interface-id": parentPort,
1159 "onu-id": onuID}, err).Log()
Girish Gowdru0c588b22019-04-23 23:24:56 -04001160 }
1161 log.Debugw("Successfully received child device from core", log.Fields{"child_device": *onuDevice})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001162 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301163}
1164
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001165// SendPacketInToCore sends packet-in to core
1166// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1167// The adapter handling the device creates a device specific topic
David K. Bainbridge794735f2020-02-11 21:01:37 -08001168func (dh *DeviceHandler) SendPacketInToCore(logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo6056e822019-11-13 14:05:29 -08001169 log.Debugw("send-packet-in-to-core", log.Fields{
1170 "port": logicalPort,
1171 "packet": hex.EncodeToString(packetPayload),
1172 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001173 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301174 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001175 "source": "adapter",
1176 "destination": "core",
1177 "device-id": dh.device.Id,
1178 "logical-port": logicalPort,
1179 "packet": hex.EncodeToString(packetPayload)}, err).Log()
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001180 }
Matteo Scandolo6056e822019-11-13 14:05:29 -08001181 log.Debugw("Sent packet-in to core successfully", log.Fields{
1182 "packet": hex.EncodeToString(packetPayload),
1183 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001184 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001185}
1186
A R Karthick1f85b802019-10-11 05:06:05 +00001187// AddUniPortToOnu adds the uni port to the onu device
1188func (dh *DeviceHandler) AddUniPortToOnu(intfID, onuID, uniPort uint32) {
1189 onuKey := dh.formOnuKey(intfID, onuID)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301190
1191 if onuDevice, ok := dh.onus.Load(onuKey); ok {
A R Karthick1f85b802019-10-11 05:06:05 +00001192 // add it to the uniPort map for the onu device
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301193 if _, ok = onuDevice.(*OnuDevice).uniPorts[uniPort]; !ok {
1194 onuDevice.(*OnuDevice).uniPorts[uniPort] = struct{}{}
A R Karthick1f85b802019-10-11 05:06:05 +00001195 log.Debugw("adding-uni-port", log.Fields{"port": uniPort, "intfID": intfID, "onuId": onuID})
1196 }
1197 }
1198}
1199
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001200//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301201func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -04001202 log.Debugw("Received-incremental-flowupdate-in-device-handler", log.Fields{"deviceID": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001203 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001204 for _, flow := range flows.ToRemove.Items {
1205 log.Debug("Removing flow", log.Fields{"deviceId": device.Id, "flowToRemove": flow})
npujarec5762e2020-01-01 14:08:48 +05301206 dh.flowMgr.RemoveFlow(ctx, flow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001207 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301208
1209 for _, flow := range flows.ToAdd.Items {
1210 log.Debug("Adding flow", log.Fields{"deviceId": device.Id, "flowToAdd": flow})
npujarec5762e2020-01-01 14:08:48 +05301211 dh.flowMgr.AddFlow(ctx, flow, flowMetadata)
Girish Gowdra3d633032019-12-10 16:37:05 +05301212 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001213 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001214 if groups != nil && flows != nil {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001215 for _, flow := range flows.ToRemove.Items {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001216 log.Debug("Removing flow", log.Fields{"deviceID": device.Id, "flowToRemove": flow})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001217 // dh.flowMgr.RemoveFlow(flow)
1218 }
1219 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001220
1221 if groups != nil {
1222 for _, group := range groups.ToAdd.Items {
npujarec5762e2020-01-01 14:08:48 +05301223 dh.flowMgr.AddGroup(ctx, group)
Esin Karamanccb714b2019-11-29 15:02:06 +00001224 }
1225 for _, group := range groups.ToUpdate.Items {
npujarec5762e2020-01-01 14:08:48 +05301226 dh.flowMgr.ModifyGroup(ctx, group)
Esin Karamanccb714b2019-11-29 15:02:06 +00001227 }
1228 if len(groups.ToRemove.Items) != 0 {
1229 log.Debug("Group delete operation is not supported for now")
1230 }
1231 }
Manikkaraj kb1d51442019-07-23 10:41:02 -04001232 log.Debug("UpdateFlowsIncrementally done successfully")
Girish Gowdru0c588b22019-04-23 23:24:56 -04001233 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301234}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001235
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001236//DisableDevice disables the given device
1237//It marks the following for the given device:
1238//Device-Handler Admin-State : down
1239//Device Port-State: UNKNOWN
1240//Device Oper-State: UNKNOWN
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001241func (dh *DeviceHandler) DisableDevice(device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001242 /* On device disable ,admin state update has to be done prior sending request to agent since
1243 the indication thread may processes invalid indications of ONU and OLT*/
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001244 dh.lockDevice.Lock()
1245 dh.adminState = "down"
1246 dh.lockDevice.Unlock()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001247 if dh.Client != nil {
1248 if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
1249 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001250 dh.lockDevice.Lock()
1251 dh.adminState = "up"
1252 dh.lockDevice.Unlock()
Thomas Lee S94109f12020-03-03 16:39:29 +05301253 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err).Log()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001254 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001255 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001256 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001257 log.Debugw("olt-disabled", log.Fields{"deviceID": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001258 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001259 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301260
1261 dh.discOnus = sync.Map{}
1262 dh.onus = sync.Map{}
1263
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301264 go dh.notifyChildDevices("unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001265 cloned := proto.Clone(device).(*voltha.Device)
kdarapu1afeceb2020-02-12 01:38:09 -05001266 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
1267 for _, port := range cloned.Ports {
1268 if port.GetType() == voltha.Port_PON_OLT {
1269 if err := dh.coreProxy.PortStateUpdate(context.TODO(), cloned.Id,
1270 voltha.Port_PON_OLT, port.GetPortNo(), voltha.OperStatus_UNKNOWN); err != nil {
1271 return err
1272 }
1273 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001274 }
1275
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001276 log.Debugw("disable-device-end", log.Fields{"deviceID": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001277 return nil
1278}
1279
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301280func (dh *DeviceHandler) notifyChildDevices(state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001281
1282 // Update onu state as unreachable in onu adapter
1283 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301284 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001285 //get the child device for the parent device
1286 onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
1287 if err != nil {
1288 log.Errorw("failed-to-get-child-devices-information", log.Fields{"deviceID": dh.device.Id, "error": err})
1289 }
1290 if onuDevices != nil {
1291 for _, onuDevice := range onuDevices.Items {
1292 err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1293 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1294 if err != nil {
1295 log.Errorw("failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
1296 "From Adapter": "openolt", "DeviceType": onuDevice.Type, "DeviceID": onuDevice.Id})
1297 }
1298
1299 }
1300 }
1301
1302}
1303
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001304//ReenableDevice re-enables the olt device after disable
1305//It marks the following for the given device:
1306//Device-Handler Admin-State : up
1307//Device Port-State: ACTIVE
1308//Device Oper-State: ACTIVE
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001309func (dh *DeviceHandler) ReenableDevice(device *voltha.Device) error {
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001310 dh.lockDevice.Lock()
1311 dh.adminState = "up"
1312 dh.lockDevice.Unlock()
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301313
1314 if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
1315 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301316 dh.lockDevice.Lock()
1317 dh.adminState = "down"
1318 dh.lockDevice.Unlock()
Thomas Lee S94109f12020-03-03 16:39:29 +05301319 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301320 }
1321 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001322 log.Debug("olt-reenabled")
1323
1324 cloned := proto.Clone(device).(*voltha.Device)
1325 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001326
kdarapu1afeceb2020-02-12 01:38:09 -05001327 if err := dh.disableAdminDownPorts(device); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301328 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err).Log()
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001329 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001330 //Update the device oper status as ACTIVE
1331 cloned.OperStatus = voltha.OperStatus_ACTIVE
1332 dh.device = cloned
1333
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001334 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301335 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001336 "device-id": device.Id,
1337 "connect-status": cloned.ConnectStatus,
1338 "oper-status": cloned.OperStatus}, err).Log()
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001339 }
kesavand39e0aa32020-01-28 20:58:50 -05001340
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001341 log.Debugw("ReEnableDevice-end", log.Fields{"deviceID": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001342
1343 return nil
1344}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001345
npujarec5762e2020-01-01 14:08:48 +05301346func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001347 var uniID uint32
1348 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301349 for _, port := range onu.UniPorts {
1350 uniID = UniIDFromPortNum(uint32(port))
A R Karthick1f85b802019-10-11 05:06:05 +00001351 log.Debugw("clearing-resource-data-for-uni-port", log.Fields{"port": port, "uniID": uniID})
1352 /* Delete tech-profile instance from the KV store */
npujarec5762e2020-01-01 14:08:48 +05301353 if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301354 log.Debugw("Failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001355 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301356 log.Debugw("Deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301357 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
A R Karthick1f85b802019-10-11 05:06:05 +00001358 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301359 dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
A R Karthick1f85b802019-10-11 05:06:05 +00001360 }
npujarec5762e2020-01-01 14:08:48 +05301361 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001362 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301363 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301364 log.Debugw("Failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001365 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301366 log.Debugw("Removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301367 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301368 log.Debugw("Failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001369 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301370 log.Debugw("Removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
1371 }
npujarec5762e2020-01-01 14:08:48 +05301372 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1373 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301374 log.Debugw("Failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
1375 }
1376 log.Debugw("Removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301377 if err = dh.resourceMgr.DelGemPortPktIn(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301378 log.Debugw("Failed-to-remove-gemport-pkt-in", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001379 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001380 }
1381 return nil
1382}
1383
npujarec5762e2020-01-01 14:08:48 +05301384func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001385 nniUniID := -1
1386 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301387
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001388 if dh.resourceMgr == nil {
1389 return fmt.Errorf("no resource manager for deviceID %s", dh.deviceID)
1390 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001391 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301392 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301393 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301394 return olterrors.NewErrPersistence("get", "nni", 0, nil, err).Log()
Devmalya Paul495b94a2019-08-27 19:42:00 -04001395 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301396 log.Debugw("NNI are ", log.Fields{"nni": nni})
1397 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301398 flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301399 log.Debugw("Current flow ids for nni", log.Fields{"flow-ids": flowIDs})
1400 for _, flowID := range flowIDs {
npujarec5762e2020-01-01 14:08:48 +05301401 dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301402 }
npujarec5762e2020-01-01 14:08:48 +05301403 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Devmalya Paul495b94a2019-08-27 19:42:00 -04001404 }
npujarec5762e2020-01-01 14:08:48 +05301405 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301406 return olterrors.NewErrPersistence("clear", "nni", 0, nil, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301407 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001408 return nil
Devmalya Paul495b94a2019-08-27 19:42:00 -04001409}
1410
1411// 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 +05301412func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001413 log.Debug("Function entry delete device")
1414 dh.lockDevice.Lock()
A R Karthick1f85b802019-10-11 05:06:05 +00001415 if dh.adminState == "deleted" {
1416 dh.lockDevice.Unlock()
1417 return nil
1418 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001419 dh.adminState = "deleted"
1420 dh.lockDevice.Unlock()
1421 /* Clear the KV store data associated with the all the UNI ports
1422 This clears up flow data and also resource map data for various
1423 other pon resources like alloc_id and gemport_id
1424 */
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001425 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301426 noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
1427 var ponPort uint32
1428 for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
1429 var onuGemData []rsrcMgr.OnuGemInfo
npujarec5762e2020-01-01 14:08:48 +05301430 err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301431 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301432 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001433 "device-id": dh.device.Id,
1434 "pon-port": ponPort}, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301435 }
1436 for _, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301437 onuID := make([]uint32, 1)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301438 log.Debugw("onu data ", log.Fields{"onu": onu})
npujarec5762e2020-01-01 14:08:48 +05301439 if err = dh.clearUNIData(ctx, &onu); err != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301440 log.Errorw("Failed to clear data for onu", log.Fields{"onu-device": onu})
1441 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301442 // Clear flowids for gem cache.
1443 for _, gem := range onu.GemPorts {
npujarec5762e2020-01-01 14:08:48 +05301444 dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301445 }
1446 onuID[0] = onu.OnuID
npujarec5762e2020-01-01 14:08:48 +05301447 dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301448 }
npujarec5762e2020-01-01 14:08:48 +05301449 dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301450 onuGemData = nil
npujarec5762e2020-01-01 14:08:48 +05301451 err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301452 if err != nil {
1453 log.Errorw("Failed to update onugem info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001454 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001455 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001456 /* Clear the flows from KV store associated with NNI port.
1457 There are mostly trap rules from NNI port (like LLDP)
1458 */
npujarec5762e2020-01-01 14:08:48 +05301459 if err := dh.clearNNIData(ctx); err != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301460 log.Errorw("Failed to clear data for NNI port", log.Fields{"device-id": dh.deviceID})
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001461 }
A R Karthick1f85b802019-10-11 05:06:05 +00001462
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001463 /* Clear the resource pool for each PON port in the background */
npujarec5762e2020-01-01 14:08:48 +05301464 go dh.resourceMgr.Delete(ctx)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001465 }
A R Karthick1f85b802019-10-11 05:06:05 +00001466
Devmalya Paul495b94a2019-08-27 19:42:00 -04001467 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301468 dh.onus.Range(func(key interface{}, value interface{}) bool {
1469 dh.onus.Delete(key)
1470 return true
1471 })
1472
Devmalya Paul495b94a2019-08-27 19:42:00 -04001473 log.Debug("Removed-device-from-Resource-manager-KV-store")
Naga Manjunath7615e552019-10-11 22:35:47 +05301474 // Stop the Stats collector
1475 dh.stopCollector <- true
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301476 // stop the heartbeat check routine
1477 dh.stopHeartbeatCheck <- true
Devmalya Paul495b94a2019-08-27 19:42:00 -04001478 //Reset the state
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001479 if dh.Client != nil {
npujarec5762e2020-01-01 14:08:48 +05301480 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301481 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.deviceID}, err).Log()
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001482 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001483 }
1484 cloned := proto.Clone(device).(*voltha.Device)
1485 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1486 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
npujarec5762e2020-01-01 14:08:48 +05301487 if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301488 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001489 "device-id": device.Id,
1490 "connect-status": cloned.ConnectStatus,
1491 "oper-status": cloned.OperStatus}, err).Log()
Devmalya Paul495b94a2019-08-27 19:42:00 -04001492 }
1493 return nil
1494}
1495
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001496//RebootDevice reboots the given device
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001497func (dh *DeviceHandler) RebootDevice(device *voltha.Device) error {
1498 if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301499 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.deviceID}, err).Log()
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001500 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001501 log.Debugw("rebooted-device-successfully", log.Fields{"deviceID": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001502 return nil
1503}
1504
David K. Bainbridge794735f2020-02-11 21:01:37 -08001505func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo6056e822019-11-13 14:05:29 -08001506 log.Debugw("Received packet-in", log.Fields{
1507 "packet-indication": *packetIn,
1508 "packet": hex.EncodeToString(packetIn.Pkt),
1509 })
npujarec5762e2020-01-01 14:08:48 +05301510 logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001511 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301512 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err).Log()
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001513 }
Matteo Scandolo6056e822019-11-13 14:05:29 -08001514 log.Debugw("sending packet-in to core", log.Fields{
1515 "logicalPortNum": logicalPortNum,
1516 "packet": hex.EncodeToString(packetIn.Pkt),
1517 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001518 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301519 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001520 "destination": "core",
1521 "source": dh.deviceType,
1522 "packet": hex.EncodeToString(packetIn.Pkt)}, err).Log()
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001523 }
Matteo Scandolo6056e822019-11-13 14:05:29 -08001524 log.Debugw("Success sending packet-in to core!", log.Fields{
1525 "packet": hex.EncodeToString(packetIn.Pkt),
1526 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001527 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001528}
1529
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001530// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301531func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo6056e822019-11-13 14:05:29 -08001532 log.Debugw("incoming-packet-out", log.Fields{
1533 "deviceID": dh.deviceID,
1534 "egress_port_no": egressPortNo,
1535 "pkt-length": len(packet.Data),
1536 "packet": hex.EncodeToString(packet.Data),
1537 })
Matt Jeanneret1359c732019-08-01 21:40:02 -04001538
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001539 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001540 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001541 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1542 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301543 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1544 // Do not packet-out lldp packets on uni port.
1545 // ONOS has no clue about uni/nni ports, it just packets out on all
1546 // available ports on the Logical Switch. It should not be interested
1547 // in the UNI links.
1548 log.Debug("dropping-lldp-packet-out-on-uni")
1549 return nil
1550 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001551 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1552 if innerEthType == 0x8100 {
1553 // q-in-q 802.1ad or 802.1q double tagged packet.
1554 // slice out the outer tag.
1555 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
1556 log.Debugw("packet-now-single-tagged", log.Fields{"packetData": hex.EncodeToString(packet.Data)})
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001557 }
1558 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001559 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1560 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001561 uniID := UniIDFromPortNum(uint32(egressPortNo))
1562
npujarec5762e2020-01-01 14:08:48 +05301563 gemPortID, err := dh.flowMgr.GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001564 if err != nil {
1565 // In this case the openolt agent will receive the gemPortID as 0.
1566 // The agent tries to retrieve the gemPortID in this case.
1567 // This may not always succeed at the agent and packetOut may fail.
Matteo Scandolo6056e822019-11-13 14:05:29 -08001568 log.Errorw("failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
1569 "packet": hex.EncodeToString(packet.Data),
1570 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001571 }
1572
1573 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001574
Matteo Scandolo6056e822019-11-13 14:05:29 -08001575 log.Debugw("sending-packet-to-onu", log.Fields{
1576 "egress_port_no": egressPortNo,
1577 "IntfId": intfID,
1578 "onuID": onuID,
1579 "uniID": uniID,
1580 "gemPortID": gemPortID,
1581 "packet": hex.EncodeToString(packet.Data),
1582 })
Matt Jeanneret1359c732019-08-01 21:40:02 -04001583
npujarec5762e2020-01-01 14:08:48 +05301584 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301585 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001586 "source": "adapter",
1587 "destination": "onu",
1588 "egress-port-number": egressPortNo,
1589 "interface-id": intfID,
1590 "oni-id": onuID,
1591 "uni-id": uniID,
1592 "gem-port-id": gemPortID,
1593 "packet": hex.EncodeToString(packet.Data)}, err).Log()
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001594 }
1595 } else if egressPortType == voltha.Port_ETHERNET_NNI {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001596 nniIntfID, err := IntfIDFromNniPortNum(uint32(egressPortNo))
1597 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301598 return olterrors.NewErrInvalidValue(log.Fields{"egress-nni-port": egressPortNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001599 }
1600 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001601
Matteo Scandolo6056e822019-11-13 14:05:29 -08001602 log.Debugw("sending-packet-to-nni", log.Fields{
1603 "uplink_pkt": uplinkPkt,
1604 "packet": hex.EncodeToString(packet.Data),
1605 })
Matt Jeanneret1359c732019-08-01 21:40:02 -04001606
npujarec5762e2020-01-01 14:08:48 +05301607 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301608 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{"packet": hex.EncodeToString(packet.Data)}, err).Log()
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001609 }
1610 } else {
Matteo Scandolo6056e822019-11-13 14:05:29 -08001611 log.Warnw("Packet-out-to-this-interface-type-not-implemented", log.Fields{
1612 "egress_port_no": egressPortNo,
1613 "egressPortType": egressPortType,
1614 "packet": hex.EncodeToString(packet.Data),
1615 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001616 }
1617 return nil
1618}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001619
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001620func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1621 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001622}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301623
1624func startHeartbeatCheck(dh *DeviceHandler) {
1625 // start the heartbeat check towards the OLT.
1626 var timerCheck *time.Timer
1627
1628 for {
1629 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1630 select {
1631 case <-heartbeatTimer.C:
1632 ctx, cancel := context.WithTimeout(context.Background(), dh.openOLT.GrpcTimeoutInterval)
1633 if heartBeat, err := dh.Client.HeartbeatCheck(ctx, new(oop.Empty)); err != nil {
1634 log.Error("Hearbeat failed")
1635 if timerCheck == nil {
1636 // start a after func, when expired will update the state to the core
1637 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, dh.updateStateUnreachable)
1638 }
1639 } else {
1640 if timerCheck != nil {
1641 if timerCheck.Stop() {
1642 log.Debug("We got hearbeat within the timeout")
1643 } else {
1644
1645 log.Debug("We got hearbeat after the timeout expired, changing the states")
1646 go dh.notifyChildDevices("up")
npujarec5762e2020-01-01 14:08:48 +05301647 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301648 voltha.OperStatus_ACTIVE); err != nil {
1649 log.Errorw("Failed to update device state", log.Fields{"deviceID": dh.device.Id, "error": err})
1650 }
1651 }
1652 timerCheck = nil
1653 }
1654 log.Debugw("Hearbeat", log.Fields{"signature": heartBeat})
1655 }
1656 cancel()
1657 case <-dh.stopHeartbeatCheck:
1658 log.Debug("Stopping heart beat check")
1659 return
1660 }
1661 }
1662}
1663
1664func (dh *DeviceHandler) updateStateUnreachable() {
1665
1666 go dh.notifyChildDevices("unreachable")
1667 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301668 olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301669 }
1670}
kesavand39e0aa32020-01-28 20:58:50 -05001671
1672// EnablePort to enable Pon interface
1673func (dh *DeviceHandler) EnablePort(port *voltha.Port) error {
1674 log.Debugw("enable-port", log.Fields{"Device": dh.device, "port": port})
kdarapu1afeceb2020-02-12 01:38:09 -05001675 return dh.modifyPhyPort(port, true)
kesavand39e0aa32020-01-28 20:58:50 -05001676}
1677
1678// DisablePort to disable pon interface
1679func (dh *DeviceHandler) DisablePort(port *voltha.Port) error {
1680 log.Debugw("disable-port", log.Fields{"Device": dh.device, "port": port})
kdarapu1afeceb2020-02-12 01:38:09 -05001681 return dh.modifyPhyPort(port, false)
kesavand39e0aa32020-01-28 20:58:50 -05001682}
1683
kdarapu1afeceb2020-02-12 01:38:09 -05001684//modifyPhyPort is common function to enable and disable the port. parm :enablePort, true to enablePort and false to disablePort.
1685func (dh *DeviceHandler) modifyPhyPort(port *voltha.Port, enablePort bool) error {
npujarec5762e2020-01-01 14:08:48 +05301686 ctx := context.Background()
kdarapu1afeceb2020-02-12 01:38:09 -05001687 log.Infow("modifyPhyPort", log.Fields{"port": port, "Enable": enablePort})
kesavand39e0aa32020-01-28 20:58:50 -05001688 if port.GetType() == voltha.Port_ETHERNET_NNI {
1689 // Bug is opened for VOL-2505 to support NNI disable feature.
1690 log.Infow("voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
1691 log.Fields{"Device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05301692 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001693 "port-type": port.GetType,
1694 "enable-state": enablePort}, nil).Log()
kesavand39e0aa32020-01-28 20:58:50 -05001695 }
1696 // fetch interfaceid from PortNo
1697 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
1698 ponIntf := &oop.Interface{IntfId: ponID}
1699 var operStatus voltha.OperStatus_Types
1700 if enablePort {
1701 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05301702 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001703
1704 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301705 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001706 "device-id": dh.device.Id,
1707 "port": port}, err).Log()
kesavand39e0aa32020-01-28 20:58:50 -05001708 }
1709 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001710 dh.activePorts.Store(ponID, true)
kesavand39e0aa32020-01-28 20:58:50 -05001711 log.Infow("enabled-pon-port", log.Fields{"out": out, "DeviceID": dh.device, "Port": port})
1712 } else {
1713 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05301714 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05001715 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301716 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001717 "device-id": dh.device.Id,
1718 "port": port}, err).Log()
kesavand39e0aa32020-01-28 20:58:50 -05001719 }
1720 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05001721 dh.activePorts.Store(ponID, false)
kesavand39e0aa32020-01-28 20:58:50 -05001722 log.Infow("disabled-pon-port", log.Fields{"out": out, "DeviceID": dh.device, "Port": port})
1723 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001724 if err := dh.coreProxy.PortStateUpdate(ctx, dh.deviceID, voltha.Port_PON_OLT, port.PortNo, operStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301725 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001726 "device-id": dh.deviceID,
1727 "port": port.PortNo}, err).Log()
kesavand39e0aa32020-01-28 20:58:50 -05001728 }
1729 return nil
1730}
1731
kdarapu1afeceb2020-02-12 01:38:09 -05001732//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
1733func (dh *DeviceHandler) disableAdminDownPorts(device *voltha.Device) error {
kesavand39e0aa32020-01-28 20:58:50 -05001734 cloned := proto.Clone(device).(*voltha.Device)
1735 // Disable the port and update the oper_port_status to core
1736 // if the Admin state of the port is disabled on reboot and re-enable device.
1737 for _, port := range cloned.Ports {
1738 if port.AdminState == common.AdminState_DISABLED {
kdarapu1afeceb2020-02-12 01:38:09 -05001739 if err := dh.DisablePort(port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301740 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001741 "device-id": dh.deviceID,
1742 "port": port}, err).Log()
kesavand39e0aa32020-01-28 20:58:50 -05001743 }
1744 }
1745 }
1746 return nil
1747}
1748
1749//populateActivePorts to populate activePorts map
1750func (dh *DeviceHandler) populateActivePorts(device *voltha.Device) {
1751 log.Info("populateActiveports", log.Fields{"Device": device})
1752 for _, port := range device.Ports {
1753 if port.Type == voltha.Port_ETHERNET_NNI {
1754 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05001755 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05001756 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05001757 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05001758 }
1759 }
1760 if port.Type == voltha.Port_PON_OLT {
1761 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05001762 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05001763 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05001764 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05001765 }
1766 }
1767 }
1768}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001769
1770// ChildDeviceLost deletes ONU and clears pon resources related to it.
1771func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
1772 log.Debugw("child-device-lost", log.Fields{"pdeviceID": dh.device.Id})
1773 IntfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
1774 onuKey := dh.formOnuKey(IntfID, onuID)
1775 onuDevice, ok := dh.onus.Load(onuKey)
1776 if !ok {
Thomas Lee S94109f12020-03-03 16:39:29 +05301777 return olterrors.NewErrAdapter("failed-to-load-onu-details",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001778 log.Fields{
1779 "device-id": dh.deviceID,
1780 "onu-id": onuID,
1781 "interface-id": IntfID}, nil).Log()
1782 }
1783 var sn *oop.SerialNumber
1784 var err error
1785 if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301786 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001787 log.Fields{
1788 "devicer-id": dh.deviceID,
1789 "serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
1790 }
1791 onu := &oop.Onu{IntfId: IntfID, OnuId: onuID, SerialNumber: sn}
1792 if _, err := dh.Client.DeleteOnu(context.Background(), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301793 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001794 "device-id": dh.deviceID,
1795 "onu-id": onuID}, err).Log()
1796 }
1797 //clear PON resources associated with ONU
1798 var onuGemData []rsrcMgr.OnuGemInfo
1799 if err := dh.resourceMgr.ResourceMgrs[IntfID].GetOnuGemInfo(ctx, IntfID, &onuGemData); err != nil {
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05001800 log.Warnw("Failed-to-get-onu-info-for-pon-port ", log.Fields{
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001801 "device-id": dh.deviceID,
1802 "interface-id": IntfID,
1803 "error": err})
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05001804 } else {
1805 for i, onu := range onuGemData {
1806 if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
1807 log.Debugw("onu-data ", log.Fields{"onu": onu})
1808 if err := dh.clearUNIData(ctx, &onu); err != nil {
1809 log.Warnw("Failed-to-clear-uni-data-for-onu", log.Fields{
1810 "device-id": dh.deviceID,
1811 "onu-device": onu,
1812 "error": err})
1813 }
1814 // Clear flowids for gem cache.
1815 for _, gem := range onu.GemPorts {
1816 dh.resourceMgr.DeleteFlowIDsForGem(ctx, IntfID, gem)
1817 }
1818 onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
1819 dh.resourceMgr.UpdateOnuGemInfo(ctx, IntfID, onuGemData)
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001820
Chaitrashree G Se420b5f2020-02-23 21:34:54 -05001821 dh.resourceMgr.FreeonuID(ctx, IntfID, []uint32{onu.OnuID})
1822 break
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001823 }
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001824 }
1825 }
1826 dh.onus.Delete(onuKey)
1827 dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
1828 return nil
1829}