blob: ec5bf8434e5110069278ae47c3b10c8fa33f4379 [file] [log] [blame]
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
Phaneendra Manda4c62c802019-03-06 21:37:49 +053019
20import (
cuilin20187b2a8c32019-03-26 19:52:28 -070021 "context"
Matt Jeanneretceea2e02020-03-27 14:19:57 -040022 "encoding/binary"
Matt Jeanneret1359c732019-08-01 21:40:02 -040023 "encoding/hex"
Girish Gowdra491a9c62021-01-06 16:43:07 -080024 "errors"
cuilin20187b2a8c32019-03-26 19:52:28 -070025 "fmt"
26 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040027 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070028 "strconv"
29 "strings"
30 "sync"
31 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053032
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"
Girish Kumar93e91742020-07-27 16:43:19 +000036 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
37 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070038 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080039 "github.com/opencord/voltha-lib-go/v4/pkg/config"
Himani Chawlacd407802020-12-10 12:08:59 +053040 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
Girish Gowdra491a9c62021-01-06 16:43:07 -080041 flow_utils "github.com/opencord/voltha-lib-go/v4/pkg/flows"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070042 "github.com/opencord/voltha-lib-go/v4/pkg/log"
43 "github.com/opencord/voltha-lib-go/v4/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080044
Thomas Lee S94109f12020-03-03 16:39:29 +053045 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080046 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070047 "github.com/opencord/voltha-protos/v4/go/common"
kesavand62126212021-01-12 04:56:06 -050048 "github.com/opencord/voltha-protos/v4/go/extension"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070049 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
50 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
51 oop "github.com/opencord/voltha-protos/v4/go/openolt"
52 "github.com/opencord/voltha-protos/v4/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070053 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040054 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040055 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053056)
57
salmansiddiqui7ac62132019-08-22 03:58:50 +000058// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040059const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080060 InvalidPort = 0xffffffff
61 MaxNumOfGroupHandlerChannels = 256
62
63 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
64 McastFlowOrGroupModify = "McastFlowOrGroupModify"
65 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050066 oltPortInfoTimeout = 3
Manikkaraj kb1d51442019-07-23 10:41:02 -040067)
68
Phaneendra Manda4c62c802019-03-06 21:37:49 +053069//DeviceHandler will interact with the OLT device.
70type DeviceHandler struct {
Matteo Scandolodfa7a972020-11-06 13:03:40 -080071 cm *config.ConfigManager
cuilin20187b2a8c32019-03-26 19:52:28 -070072 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053073 coreProxy adapterif.CoreProxy
74 AdapterProxy adapterif.AdapterProxy
Himani Chawlacd407802020-12-10 12:08:59 +053075 EventProxy eventif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070076 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070077 exitChannel chan int
78 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053079 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070080 transitionMap *TransitionMap
81 clientCon *grpc.ClientConn
Girish Gowdra9602eb42020-09-09 15:50:39 -070082 flowMgr []*OpenOltFlowMgr
83 groupMgr *OpenOltGroupMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040084 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053085 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053086
Girish Gowdra3ab6d212020-03-24 17:33:15 -070087 discOnus sync.Map
88 onus sync.Map
89 portStats *OpenOltStatisticsMgr
90 metrics *pmmetrics.PmMetrics
91 stopCollector chan bool
92 stopHeartbeatCheck chan bool
93 activePorts sync.Map
94 stopIndications chan bool
95 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070096
Mahir Gunyelb0046752021-02-26 13:51:05 -080097 totalPonPorts uint32
98 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
99 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800100
101 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
102 // A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
103 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700104}
105
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700106//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700107type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700108 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700109 deviceType string
110 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700111 onuID uint32
112 intfID uint32
113 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530114 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400115 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700116}
117
Mahir Gunyelb0046752021-02-26 13:51:05 -0800118type onuIndicationMsg struct {
119 ctx context.Context
120 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800121}
122
123type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800124 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800125 stopChannel chan struct{}
126}
127
Girish Gowdra491a9c62021-01-06 16:43:07 -0800128//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
129//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
130//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
131//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
132type McastFlowOrGroupControlBlock struct {
133 ctx context.Context // Flow/group handler context
134 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
135 flow *voltha.OfpFlowStats // Flow message (can be nil or valid flow)
136 group *voltha.OfpGroupEntry // Group message (can be nil or valid group)
137 errChan *chan error // channel to report the mcast Flow/group handling error
138}
139
Naga Manjunath7615e552019-10-11 22:35:47 +0530140var pmNames = []string{
141 "rx_bytes",
142 "rx_packets",
143 "rx_mcast_packets",
144 "rx_bcast_packets",
145 "tx_bytes",
146 "tx_packets",
147 "tx_mcast_packets",
148 "tx_bcast_packets",
149}
150
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700151//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530152func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700153 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700154 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700155 device.deviceType = deviceTp
156 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700157 device.onuID = onuID
158 device.intfID = intfID
159 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530160 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700161 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530162}
163
164//NewDeviceHandler creates a new device handler
Himani Chawlacd407802020-12-10 12:08:59 +0530165func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep eventif.EventProxy, device *voltha.Device, adapter *OpenOLT, cm *config.ConfigManager) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700166 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800167 dh.cm = cm
cuilin20187b2a8c32019-03-26 19:52:28 -0700168 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400169 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400170 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700171 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700172 dh.device = cloned
173 dh.openOLT = adapter
174 dh.exitChannel = make(chan int, 1)
175 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530176 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530177 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530178 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 -0500179 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400180 dh.stopIndications = make(chan bool, 1)
Mahir Gunyelb0046752021-02-26 13:51:05 -0800181 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800182 // Create a slice of buffered channels for handling concurrent mcast flow/group.
183 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
184 for i := range dh.incomingMcastFlowOrGroup {
185 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
186 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
187 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
188 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
189 // for incoming mcast flow/group to be processed serially.
190 go dh.mcastFlowOrGroupChannelHandlerRoutine(dh.incomingMcastFlowOrGroup[i])
191 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700192 //TODO initialize the support classes.
193 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530194}
195
196// start save the device to the data model
197func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700198 dh.lockDevice.Lock()
199 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000200 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700201 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000202 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530203}
204
205// stop stops the device dh. Not much to do for now
206func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700207 dh.lockDevice.Lock()
208 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000209 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700210 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000211 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530212}
213
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400214func macifyIP(ip net.IP) string {
215 if len(ip) > 0 {
216 oct1 := strconv.FormatInt(int64(ip[12]), 16)
217 oct2 := strconv.FormatInt(int64(ip[13]), 16)
218 oct3 := strconv.FormatInt(int64(ip[14]), 16)
219 oct4 := strconv.FormatInt(int64(ip[15]), 16)
220 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
221 }
222 return ""
223}
224
Neha Sharma96b7bf22020-06-15 10:37:32 +0000225func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400226 var genmac string
227 var addr net.IP
228 var ips []string
229 var err error
230
Neha Sharma96b7bf22020-06-15 10:37:32 +0000231 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400232
233 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000234 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400235
236 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000237 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400238 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000239 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400240 }
241 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000242 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530243 log.Fields{"host": ips[0],
244 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400245 return genmac, nil
246 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000247 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400248 }
249
250 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000251 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530252 log.Fields{"host": host,
253 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400254 return genmac, nil
255}
256
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530257func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700258 slist := strings.Split(mac, ":")
259 result := make([]uint32, len(slist))
260 var err error
261 var tmp int64
262 for index, val := range slist {
263 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
264 return []uint32{1, 2, 3, 4, 5, 6}
265 }
266 result[index] = uint32(tmp)
267 }
268 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530269}
270
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700271//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 -0800272func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530273
David K. Bainbridge794735f2020-02-11 21:01:37 -0800274 switch portType {
275 case voltha.Port_ETHERNET_NNI:
276 return fmt.Sprintf("nni-%d", portNum), nil
277 case voltha.Port_PON_OLT:
278 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700279 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800280
Girish Kumarf26e4882020-03-05 06:49:10 +0000281 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530282}
283
Neha Sharma96b7bf22020-06-15 10:37:32 +0000284func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000285 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700286 if state == "up" {
287 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500288 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500289 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700290 } else {
291 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500292 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700293 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700294 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400295 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800296 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000297 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400298 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500299
Neha Sharma8f4e4322020-08-06 10:51:53 +0000300 if port, err := dh.coreProxy.GetDevicePort(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portNum); err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000301 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000302 if err := dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portType, portNum, operStatus); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400303 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
304 "device-id": dh.device.Id,
305 "port-type": portType,
306 "port-number": portNum,
307 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500308 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400309 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500310 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400311 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700312 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400313 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700314 PortNo: portNum,
315 Label: label,
316 Type: portType,
317 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700318 OfpPort: &of.OfpPort{
319 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
320 Config: 0,
321 State: uint32(of.OfpPortState_OFPPS_LIVE),
322 Curr: capacity,
323 Advertised: capacity,
324 Peer: capacity,
325 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
326 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
327 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700328 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000329 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700330 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000331 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000332 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800333 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000334 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400335 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000336 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530337 return nil
338}
339
Kent Hagermane6ff1012020-07-14 15:07:53 -0400340func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000341 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530342 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400343 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
344 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530345 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800346 dh.lockDevice.Lock()
347 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530348 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530349}
350
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700351// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530352// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800353func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000354 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700355 defer func() {
356 dh.lockDevice.Lock()
357 dh.isReadIndicationRoutineActive = false
358 dh.lockDevice.Unlock()
359 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700360 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700361 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700362 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700363 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400364 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530365 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400366 if err != nil || device == nil {
367 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000368 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400369 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400370
David Bainbridgef5879ca2019-12-13 21:17:54 +0000371 // Create an exponential backoff around re-enabling indications. The
372 // maximum elapsed time for the back off is set to 0 so that we will
373 // continue to retry. The max interval defaults to 1m, but is set
374 // here for code clarity
375 indicationBackoff := backoff.NewExponentialBackOff()
376 indicationBackoff.MaxElapsedTime = 0
377 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700378
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700379 dh.lockDevice.Lock()
380 dh.isReadIndicationRoutineActive = true
381 dh.lockDevice.Unlock()
382
Girish Gowdra3f974912020-03-23 20:35:18 -0700383Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700384 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400385 select {
386 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000387 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700388 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400389 default:
390 indication, err := indications.Recv()
391 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000392 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530393 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530394 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400395 // Use an exponential back off to prevent getting into a tight loop
396 duration := indicationBackoff.NextBackOff()
397 if duration == backoff.Stop {
398 // If we reach a maximum then warn and reset the backoff
399 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000400 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530401 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530402 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400403 indicationBackoff.Reset()
404 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700405
406 // On failure process a backoff timer while watching for stopIndications
407 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700408 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700409 select {
410 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000411 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700412 if !backoffTimer.Stop() {
413 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700414 }
415 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700416 case <-backoffTimer.C:
417 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700418 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700419 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
420 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400421 }
422 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000423 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530424 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000425 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530426 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530427 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700428 // Close the stream, and re-initialize it
429 if err = indications.CloseSend(); err != nil {
430 // Ok to ignore here, because we landed here due to a problem on the stream
431 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000432 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530433 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530434 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700435 }
436 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
437 return err
438 }
439 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400440 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530441 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400442 // Reset backoff if we have a successful receive
443 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400444 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530445 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000446 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530447 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530448 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400449 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400450 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400451 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700452 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700453 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700454 // Close the send stream
455 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700456
Girish Gowdra3f974912020-03-23 20:35:18 -0700457 return nil
458}
459
460func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
461
462 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
463 if err != nil {
464 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
465 }
466 if indications == nil {
467 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
468 }
469
470 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400471}
472
473// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
474func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
475 switch indication.Data.(type) {
476 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
477 return true
478
479 default:
480 return false
481 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700482}
483
David K. Bainbridge794735f2020-02-11 21:01:37 -0800484func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000485 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000486 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530487 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700488 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530489 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700490 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000491 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000492 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530493 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000494 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800495 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000496 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800497 }
498 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700499}
500
David K. Bainbridge794735f2020-02-11 21:01:37 -0800501// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530502func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400503 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700504 switch indication.Data.(type) {
505 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000506 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
507 defer span.Finish()
508
David K. Bainbridge794735f2020-02-11 21:01:37 -0800509 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400510 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800511 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700512 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000513 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
514 defer span.Finish()
515
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700516 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800517 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000518 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400519 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800520 }
521 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700523 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000524 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
525 defer span.Finish()
526
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700527 intfOperInd := indication.GetIntfOperInd()
528 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800529 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000530 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400531 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-nni", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800532 }
533 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400534 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
535 logger.Warn(ctx, err)
536 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700537 } else if intfOperInd.GetType() == "pon" {
538 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
539 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800540 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000541 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400542 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-pon", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800543 }
544 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000545 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700546 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000547 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530548 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530549 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700550 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000551 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
552 defer span.Finish()
553
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700554 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000555 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800556 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800557 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700558 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000559 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
560 defer span.Finish()
561
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700562 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000563 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800564 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800565 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000567 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
568 defer span.Finish()
569
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700570 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000571 logger.Debugw(ctx, "received-omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800572 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000573 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400574 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800575 }
576 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000578 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
579 defer span.Finish()
580
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700581 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000582 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700583 "intf-type": pktInd.IntfId,
584 "intf-id": pktInd.IntfId,
585 "gem-port-id": pktInd.GemportId,
586 "port-no": pktInd.PortNo,
587 "device-id": dh.device.Id,
588 })
589
590 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000591 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700592 "intf-type": pktInd.IntfId,
593 "intf-id": pktInd.IntfId,
594 "gem-port-id": pktInd.GemportId,
595 "port-no": pktInd.PortNo,
596 "packet": hex.EncodeToString(pktInd.Pkt),
597 "device-id": dh.device.Id,
598 })
599 }
600
David K. Bainbridge794735f2020-02-11 21:01:37 -0800601 go func() {
602 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400603 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800604 }
605 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700606 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000607 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
608 defer span.Finish()
609
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700610 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700611 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700612 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000613 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
614 defer span.Finish()
615
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700616 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000617 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700618 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000619 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
620 defer span.Finish()
621
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700622 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000623 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
624 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700625 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530626}
627
628// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530629func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530630 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000631 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530632
Girish Gowdru0c588b22019-04-23 23:24:56 -0400633 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530634 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400635 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000636 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400637 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000638
639 //Clear olt communication failure event
640 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
641 dh.device.OperStatus = voltha.OperStatus_ACTIVE
642 raisedTs := time.Now().UnixNano()
643 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
644
Girish Gowdru0c588b22019-04-23 23:24:56 -0400645 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530646}
647
648// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530649func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000650 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400651
npujarec5762e2020-01-01 14:08:48 +0530652 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400653 if err != nil || device == nil {
654 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000655 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400656 }
657
658 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400659
660 //Update the device oper state and connection status
661 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800662 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400663 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800664 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400665
David K. Bainbridge794735f2020-02-11 21:01:37 -0800666 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000667 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400668 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400669
670 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530671 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400672 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000673 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400674 }
675 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400676 // Update onu state as down in onu adapter
677 onuInd := oop.OnuIndication{}
678 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800679 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300680 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800681 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400682 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300683 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800684 "onu-indicator": onuInd,
685 "device-type": onuDevice.Type,
686 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700687 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800688 } else {
689 logger.Debugw(ctx, "sending inter adapter down ind to onu success", log.Fields{"olt-device-id": device.Id, "onu-device-id": onuDevice.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700690 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400691 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800692 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700693 /* Discovered ONUs entries need to be cleared , since after OLT
694 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530695 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800696 dh.lockDevice.Unlock()
697
Neha Sharma96b7bf22020-06-15 10:37:32 +0000698 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700699 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530700}
701
702// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530703func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400704 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000705 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
706 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
707 grpc.WithInsecure(),
708 grpc.WithBlock(),
709 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000710 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000711 )),
712 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000713 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000714 )))
715
716 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530717 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530718 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000719 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400720 }
721 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530722}
723
724// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530725func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400726 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530727 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400728 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530729}
730
731// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530732func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530733 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000734 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400735
736 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530737 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
738 if err != nil || device == nil {
739 /*TODO: needs to handle error scenarios */
740 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
741 }
742 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000743 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400744
745 cloned := proto.Clone(device).(*voltha.Device)
746 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
747 cloned.OperStatus = voltha.OperStatus_UNKNOWN
748 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530749 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
750 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400751 }
752
Chaitrashree G S44124192019-08-07 20:21:36 -0400753 // 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 +0530754 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400755 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530756 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400757 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400758 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
759 // all the modules initialized and ready to handle incoming ONUs.
760
Thomas Lee S985938d2020-05-04 11:40:41 +0530761 err = dh.initializeDeviceHandlerModules(ctx)
762 if err != nil {
763 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400764 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400765
766 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800767 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530768 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400769 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800770 }
771 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700772
773 go startHeartbeatCheck(ctx, dh)
774
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400775 return nil
776 }
777
Neha Sharma8f4e4322020-08-06 10:51:53 +0000778 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400779 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400780 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400781 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400782 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400783 dh.populateActivePorts(ctx, ports)
784 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
785 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400786 }
787
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400788 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530789 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400790 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530791
cuilin20187b2a8c32019-03-26 19:52:28 -0700792 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800793 go func() {
794 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400795 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800796 }
797 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000798 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000799
800 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000801 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000802 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700803
804 go startHeartbeatCheck(ctx, dh)
805
cuilin20187b2a8c32019-03-26 19:52:28 -0700806 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530807}
808
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400809func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000810 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400811
812 if err != nil {
813 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
814 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700815 dh.totalPonPorts = deviceInfo.GetPonPorts()
816
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400817 // Instantiate resource manager
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800818 if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr == nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400819 return olterrors.ErrResourceManagerInstantiating
820 }
821
Girish Gowdra9602eb42020-09-09 15:50:39 -0700822 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400823
Girish Gowdra9602eb42020-09-09 15:50:39 -0700824 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
825 for i := range dh.flowMgr {
826 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700827 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700828 return olterrors.ErrResourceManagerInstantiating
829 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400830 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700831
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400832 /* TODO: Instantiate Alarm , stats , BW managers */
833 /* Instantiating Event Manager to handle Alarms and KPIs */
834 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
835
836 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000837 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400838
839 return nil
840
841}
842
Neha Sharma96b7bf22020-06-15 10:37:32 +0000843func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400844 var err error
845 var deviceInfo *oop.DeviceInfo
846
Neha Sharma8f4e4322020-08-06 10:51:53 +0000847 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400848
849 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000850 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400851 }
852 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000853 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400854 }
855
Neha Sharma96b7bf22020-06-15 10:37:32 +0000856 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400857 dh.device.Root = true
858 dh.device.Vendor = deviceInfo.Vendor
859 dh.device.Model = deviceInfo.Model
860 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
861 dh.device.HardwareVersion = deviceInfo.HardwareVersion
862 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
863
864 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000865 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400866 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000867 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400868 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000869 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400870 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000871 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400872 dh.device.MacAddress = genmac
873 } else {
874 dh.device.MacAddress = deviceInfo.DeviceId
875 }
876
877 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000878 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000879 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400880 }
881
882 return deviceInfo, nil
883}
884
Neha Sharma96b7bf22020-06-15 10:37:32 +0000885func startCollector(ctx context.Context, dh *DeviceHandler) {
886 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530887 for {
888 select {
889 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000890 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530891 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000892 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700893
Neha Sharma8f4e4322020-08-06 10:51:53 +0000894 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400895 if err != nil {
896 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
897 continue
898 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530899 for _, port := range ports {
900 // NNI Stats
901 if port.Type == voltha.Port_ETHERNET_NNI {
902 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
903 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000904 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000905 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000906 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530907 }
908 // PON Stats
909 if port.Type == voltha.Port_PON_OLT {
910 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
911 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
912 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000913 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000914 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530915 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000916 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000917
918 //ONU & Gem Stats
919 onuGemInfo := dh.flowMgr[intfID].onuGemInfo
920 if len(onuGemInfo) != 0 {
921 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfo)
922 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500923 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530924 }
925 }
926 }
927}
928
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700929//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530930func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400931 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000932 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530933 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530934
935 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400936 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
937 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530938 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530939}
940
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700941//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530942func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700943 return &ic.SwitchCapability{
944 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530945 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700946 HwDesc: "open_pon",
947 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700948 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700949 },
950 SwitchFeatures: &of.OfpSwitchFeatures{
951 NBuffers: 256,
952 NTables: 2,
953 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
954 of.OfpCapabilities_OFPC_TABLE_STATS |
955 of.OfpCapabilities_OFPC_PORT_STATS |
956 of.OfpCapabilities_OFPC_GROUP_STATS),
957 },
958 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530959}
960
Neha Sharma96b7bf22020-06-15 10:37:32 +0000961func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
962 logger.Debugw(ctx, "omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700963 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700964 var deviceID string
965 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700966
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400967 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700968 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000969 logger.Debugw(ctx, "recv-omci-msg", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id,
Matteo Scandolo92186242020-06-12 10:54:18 -0700970 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
971 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400972
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700973 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530974
975 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
976
Neha Sharma96b7bf22020-06-15 10:37:32 +0000977 logger.Debugw(ctx, "omci-indication-for-a-device-not-in-cache.", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700978 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700979 kwargs := make(map[string]interface{})
980 kwargs["onu_id"] = omciInd.OnuId
981 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700982
Neha Sharma8f4e4322020-08-06 10:51:53 +0000983 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700984 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530985 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700986 "intf-id": omciInd.IntfId,
987 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700988 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700989 deviceType = onuDevice.Type
990 deviceID = onuDevice.Id
991 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
992 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530993 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700994 } else {
995 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000996 logger.Debugw(ctx, "omci-indication-for-a-device-in-cache.", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530997 deviceType = onuInCache.(*OnuDevice).deviceType
998 deviceID = onuInCache.(*OnuDevice).deviceID
999 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001000 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001001
1002 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001003 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001004 ic.InterAdapterMessageType_OMCI_REQUEST, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001005 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301006 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001007 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001008 "destination": deviceType,
1009 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001010 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001011 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001012 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301013}
1014
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001015//ProcessInterAdapterMessage sends the proxied messages to the target device
1016// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1017// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001018func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1019 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001020 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001021 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -07001022 fromTopic := msg.Header.FromTopic
1023 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001024 toDeviceID := msg.Header.ToDeviceId
1025 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001026
Neha Sharma96b7bf22020-06-15 10:37:32 +00001027 logger.Debugw(ctx, "omci-request-message-header", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
cuilin20187b2a8c32019-03-26 19:52:28 -07001028
1029 msgBody := msg.GetBody()
1030
1031 omciMsg := &ic.InterAdapterOmciMessage{}
1032 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001033 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001034 }
1035
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001036 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001037 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001038 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301039 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001040 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001041 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001042 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001043 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1044 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301045 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001046 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001047 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001048 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001049 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001050 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1051 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301052 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001053 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001054 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001055 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001056 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001057 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001058 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001059 }
1060 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301061}
1062
Neha Sharma96b7bf22020-06-15 10:37:32 +00001063func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001064 var intfID uint32
1065 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001066 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001067 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001068 intfID = onuDevice.ProxyAddress.GetChannelId()
1069 onuID = onuDevice.ProxyAddress.GetOnuId()
1070 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001071 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001072 intfID = omciMsg.GetProxyAddress().GetChannelId()
1073 onuID = omciMsg.GetProxyAddress().GetOnuId()
1074 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001075 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001076 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001077 logger.Debugw(ctx, "onu-not-reachable--cannot-send-omci", log.Fields{"intf-id": intfID, "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001078
Thomas Lee S94109f12020-03-03 16:39:29 +05301079 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001080 "intf-id": intfID,
1081 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001082 }
1083
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001084 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1085 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001086 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001087 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1088 hex.Encode(hexPkt, omciMsg.Message)
1089 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1090
1091 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1092 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1093 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001094 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001095 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001096
Neha Sharma8f4e4322020-08-06 10:51:53 +00001097 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001098 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301099 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001100 "intf-id": intfID,
1101 "onu-id": onuID,
1102 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001103 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001104 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001105}
1106
David K. Bainbridge794735f2020-02-11 21:01:37 -08001107func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301108 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001109 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001110 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001111 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001112 // TODO: need resource manager
1113 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301114 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301115 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001116 st, _ := status.FromError(err)
1117 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001118 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1119
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001120 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301121 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001122 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001123 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001124 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001125 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001126 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001127}
1128
Mahir Gunyelb0046752021-02-26 13:51:05 -08001129func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001130 channelID := onuDiscInd.GetIntfId()
1131 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001132
Mahir Gunyelb0046752021-02-26 13:51:05 -08001133 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001134 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301135
cuilin20187b2a8c32019-03-26 19:52:28 -07001136 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001137 if sn != "" {
1138 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001139 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001140 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001141 }
1142
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301143 var alarmInd oop.OnuAlarmIndication
1144 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001145 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301146
1147 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1148 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1149 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1150 OnuLosRaise event sent for it */
1151 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1152 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1153 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001154 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301155 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1156 "currentIntfId": onuDiscInd.GetIntfId()})
1157 // TODO:: Should we need to ignore raising OnuLosClear event
1158 // when onu connected to different PON?
1159 }
1160 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1161 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1162 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001163 go func() {
1164 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1165 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1166 }
1167 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301168 }
1169 return true
1170 })
1171
Neha Sharma96b7bf22020-06-15 10:37:32 +00001172 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001173 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001174 }
1175
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001176 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001177
1178 // check the ONU is already know to the OLT
1179 // NOTE the second time the ONU is discovered this should return a device
1180 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1181
1182 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001183 logger.Debugw(ctx, "core-proxy-get-child-device-failed", log.Fields{"parentDevice": dh.device.Id, "err": err, "sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001184 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001185 logger.Debugw(ctx, "core-proxy-get-child-device-failed-with-code", log.Fields{"errCode": e.Code(), "sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001186 switch e.Code() {
1187 case codes.Internal:
1188 // this probably means NOT FOUND, so just create a new device
1189 onuDevice = nil
1190 case codes.DeadlineExceeded:
1191 // if the call times out, cleanup and exit
1192 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001193 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001194 }
1195 }
1196 }
1197
1198 if onuDevice == nil {
1199 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001200 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001201 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001202 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301203 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001204
Neha Sharma96b7bf22020-06-15 10:37:32 +00001205 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001206
1207 if err != nil {
1208 // if we can't create an ID in resource manager,
1209 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001210 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001211 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001212 "pon-intf-id": ponintfid,
1213 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001214 }
1215
Neha Sharma8f4e4322020-08-06 10:51:53 +00001216 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001217 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001218 dh.discOnus.Delete(sn)
1219 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 +05301220 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001221 "pon-intf-id": ponintfid,
1222 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001223 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001224 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1225 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1226 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001227 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301228 log.Fields{"onuDevice": onuDevice,
1229 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001230 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301231 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001232 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001233
1234 // we can now use the existing ONU Id
1235 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001236 //Insert the ONU into cache to use in OnuIndication.
1237 //TODO: Do we need to remove this from the cache on ONU change, or wait for overwritten on next discovery.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001238 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001239 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301240 "intfId": onuDiscInd.GetIntfId(),
1241 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001242 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001243
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301244 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301245 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001246 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301247 log.Fields{"onu": onuDev,
1248 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001249
Kent Hagermane6ff1012020-07-14 15:07:53 -04001250 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301251 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001252 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001253 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001254 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001255 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001256 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301257 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001258 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001259 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001260 }
1261 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001262}
1263
Mahir Gunyelb0046752021-02-26 13:51:05 -08001264func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001265
1266 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001267 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001268 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001269 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001270 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001271 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301272 log.Fields{"onuId": onuInd.OnuId,
1273 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301274 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001275 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001276 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301277
David K. Bainbridge794735f2020-02-11 21:01:37 -08001278 errFields := log.Fields{"device-id": dh.device.Id}
1279
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301280 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1281
Mahir Gunyele77977b2019-06-27 05:36:22 -07001282 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1283 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001284 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001285 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001286 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001287 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1288 if serialNumber != "" {
1289 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001290 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001291 } else {
1292 kwargs["onu_id"] = onuInd.OnuId
1293 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001294 errFields["onu-id"] = onuInd.OnuId
1295 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001296 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001297 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001298 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001299
David K. Bainbridge794735f2020-02-11 21:01:37 -08001300 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001301 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001302 }
1303
David K. Bainbridge794735f2020-02-11 21:01:37 -08001304 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001305 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001306 "previousIntfId": onuDevice.ParentPortNo,
1307 "currentIntfId": ponPort})
1308 }
1309
1310 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001311 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301312 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1313 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301314 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001315 }
1316 if !foundInCache {
1317 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1318
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301319 dh.onus.Store(onuKey, NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuInd.GetOnuId(), onuInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001320
1321 }
kesavand7cf3a052020-08-28 12:49:18 +05301322 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1323 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1324 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1325 }
1326 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001327 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001328 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001329 }
1330 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001331}
1332
Neha Sharma96b7bf22020-06-15 10:37:32 +00001333func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001334 logger.Debugw(ctx, "onu-indication-for-state", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Girish Gowdra748de5c2020-07-01 10:27:52 -07001335 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1336 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1337 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1338 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001339 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001340 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1341 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001342 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001343 onuInd.OperState = "down"
1344 }
1345 }
1346
David K. Bainbridge794735f2020-02-11 21:01:37 -08001347 switch onuInd.OperState {
1348 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001349 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001350 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301351 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001352 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001353 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301354 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001355 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001356 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001357 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001358 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001359 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001360 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001361 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Matt Jeanneret53539512019-07-20 14:47:02 -04001362 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301363 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001364 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001365 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301366 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001367 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001368 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001369 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001370 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001371 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001372 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001373 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001374 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001375 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001376}
1377
cuilin20187b2a8c32019-03-26 19:52:28 -07001378func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1379 if serialNum != nil {
1380 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001381 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001382 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001383}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001384func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1385 decodedStr, err := hex.DecodeString(serialNum[4:])
1386 if err != nil {
1387 return nil, err
1388 }
1389 return &oop.SerialNumber{
1390 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001391 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001392 }, nil
1393}
cuilin20187b2a8c32019-03-26 19:52:28 -07001394
1395func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001396 if len(vendorSpecific) > 3 {
1397 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1398 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1399 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1400 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1401 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1402 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1403 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1404 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1405 return tmp
1406 }
1407 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001408}
1409
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001410//UpdateFlowsBulk upates the bulk flow
1411func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301412 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001413}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001414
1415//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001416func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1417 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301418 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001419 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301420 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001421 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001422 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001423 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001424 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001425 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001426 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001427 "intf-id": parentPort,
1428 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001429 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001430 logger.Debugw(ctx, "successfully-received-child-device-from-core", log.Fields{"child-device-id": onuDevice.Id, "child-device-sn": onuDevice.SerialNumber})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001431 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301432}
1433
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001434// SendPacketInToCore sends packet-in to core
1435// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1436// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001437func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001438 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001439 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001440 "port": logicalPort,
1441 "packet": hex.EncodeToString(packetPayload),
1442 "device-id": dh.device.Id,
1443 })
1444 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001445 if err := dh.coreProxy.SendPacketIn(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301446 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001447 "source": "adapter",
1448 "destination": "core",
1449 "device-id": dh.device.Id,
1450 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001451 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001452 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001453 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001454 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001455 "packet": hex.EncodeToString(packetPayload),
1456 "device-id": dh.device.Id,
1457 })
1458 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001459 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001460}
1461
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001462// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001463func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001464 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001465
1466 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1467 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001468 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001469 }
1470
Kent Hagermane6ff1012020-07-14 15:07:53 -04001471 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001472 metrics := dh.metrics.GetSubscriberMetrics()
1473 for _, m := range pmConfigs.Metrics {
1474 metrics[m.Name].Enabled = m.Enabled
1475
1476 }
1477 }
1478}
1479
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001480//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301481func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001482 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
Andrea Campanellac63bba92020-03-10 17:01:04 +01001483
Girish Gowdra491a9c62021-01-06 16:43:07 -08001484 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001485 var errorsList []error
1486
Girish Gowdru0c588b22019-04-23 23:24:56 -04001487 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001488 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001489 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001490
Neha Sharma96b7bf22020-06-15 10:37:32 +00001491 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301492 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001493 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301494 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001495 if flow_utils.HasGroup(flow) {
1496 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1497 } else {
1498 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1499 }
Girish Gowdracefae192020-03-19 18:14:10 -07001500 if err != nil {
1501 errorsList = append(errorsList, err)
1502 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001503 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301504
1505 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001506 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001507 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301508 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001509 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301510 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001511 if flow_utils.HasGroup(flow) {
1512 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1513 } else {
1514 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1515 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001516 if err != nil {
1517 errorsList = append(errorsList, err)
1518 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301519 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001520 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001521
Girish Gowdracefae192020-03-19 18:14:10 -07001522 // Whether we need to synchronize multicast group adds and modifies like flow add and delete needs to be investigated
Esin Karamanccb714b2019-11-29 15:02:06 +00001523 if groups != nil {
1524 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001525 // err = dh.groupMgr.AddGroup(ctx, group)
1526 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001527 if err != nil {
1528 errorsList = append(errorsList, err)
1529 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001530 }
1531 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001532 // err = dh.groupMgr.ModifyGroup(ctx, group)
1533 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001534 if err != nil {
1535 errorsList = append(errorsList, err)
1536 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001537 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001538 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001539 // err = dh.groupMgr.DeleteGroup(ctx, group)
1540 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001541 if err != nil {
1542 errorsList = append(errorsList, err)
1543 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001544 }
1545 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001546 if len(errorsList) > 0 {
1547 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1548 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001549 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001550 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301551}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001552
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001553//DisableDevice disables the given device
1554//It marks the following for the given device:
1555//Device-Handler Admin-State : down
1556//Device Port-State: UNKNOWN
1557//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001558func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001559 /* On device disable ,admin state update has to be done prior sending request to agent since
1560 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001561 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001562 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001563 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001564 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001565 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001566 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001567 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001568 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001569 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001570 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301571
1572 dh.discOnus = sync.Map{}
1573 dh.onus = sync.Map{}
1574
Thomas Lee S85f37312020-04-03 17:06:12 +05301575 //stopping the stats collector
1576 dh.stopCollector <- true
1577
Neha Sharma96b7bf22020-06-15 10:37:32 +00001578 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001579 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301580 //Update device Admin state
1581 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001582 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
Neha Sharma8f4e4322020-08-06 10:51:53 +00001583 if err := dh.coreProxy.PortsStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001584 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001585 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001586 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001587 return nil
1588}
1589
Neha Sharma96b7bf22020-06-15 10:37:32 +00001590func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001591 // Update onu state as unreachable in onu adapter
1592 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301593 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001594 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001595 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001596 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001597 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "error": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001598 }
1599 if onuDevices != nil {
1600 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001601 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001602 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001603 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001604 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001605 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001606 }
1607
1608 }
1609 }
1610
1611}
1612
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001613//ReenableDevice re-enables the olt device after disable
1614//It marks the following for the given device:
1615//Device-Handler Admin-State : up
1616//Device Port-State: ACTIVE
1617//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001618func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001619 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301620 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001621 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301622 }
1623 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001624 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001625
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001626 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001627
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001628 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1629 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001630 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001631 }
1632 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001633 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001634 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001635 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001636 device.OperStatus = voltha.OperStatus_ACTIVE
1637 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001638
Neha Sharma8f4e4322020-08-06 10:51:53 +00001639 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301640 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001641 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001642 "connect-status": device.ConnectStatus,
1643 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001644 }
kesavand39e0aa32020-01-28 20:58:50 -05001645
Neha Sharma96b7bf22020-06-15 10:37:32 +00001646 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001647
1648 return nil
1649}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001650
npujarec5762e2020-01-01 14:08:48 +05301651func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001652 var uniID uint32
1653 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301654 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001655 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001656 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001657 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001658 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001659 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001660 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001661 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301662 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001663 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301664 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001665 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001666 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001667 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301668 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001669 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001670 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301672 }
npujarec5762e2020-01-01 14:08:48 +05301673 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1674 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001675 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301676 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001677 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001678 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001679 logger.Debugw(ctx, "failed-to-remove-gemport-pkt-in", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001680 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001681 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1682 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1683 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001684 }
1685 return nil
1686}
1687
npujarec5762e2020-01-01 14:08:48 +05301688func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001689 nniUniID := -1
1690 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301691
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001692 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301693 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001694 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001695 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +0530