blob: 60bd3bd555f9d83e33b4a601e1f3f8b9b30af163 [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 Gowdra4c3d4602021-07-22 16:33:37 -070038 "github.com/opencord/voltha-lib-go/v6/pkg/adapters/adapterif"
39 "github.com/opencord/voltha-lib-go/v6/pkg/config"
40 "github.com/opencord/voltha-lib-go/v6/pkg/events/eventif"
41 flow_utils "github.com/opencord/voltha-lib-go/v6/pkg/flows"
42 "github.com/opencord/voltha-lib-go/v6/pkg/log"
43 "github.com/opencord/voltha-lib-go/v6/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
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070085 resourceMgr []*rsrcMgr.OpenOltResourceMgr
86
87 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +053088
Girish Gowdra3ab6d212020-03-24 17:33:15 -070089 discOnus sync.Map
90 onus sync.Map
91 portStats *OpenOltStatisticsMgr
92 metrics *pmmetrics.PmMetrics
93 stopCollector chan bool
94 stopHeartbeatCheck chan bool
95 activePorts sync.Map
96 stopIndications chan bool
97 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070098
Mahir Gunyelb0046752021-02-26 13:51:05 -080099 totalPonPorts uint32
100 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
101 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800102
103 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
104 // A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
105 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
Gamze Abakac2c32a62021-03-11 11:44:18 +0000106
107 adapterPreviouslyConnected bool
108 agentPreviouslyConnected bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700109}
110
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700111//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700112type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700114 deviceType string
115 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700116 onuID uint32
117 intfID uint32
118 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530119 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400120 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700121}
122
Mahir Gunyelb0046752021-02-26 13:51:05 -0800123type onuIndicationMsg struct {
124 ctx context.Context
125 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800126}
127
128type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800129 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800130 stopChannel chan struct{}
131}
132
Girish Gowdra491a9c62021-01-06 16:43:07 -0800133//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
134//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
135//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
136//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
137type McastFlowOrGroupControlBlock struct {
138 ctx context.Context // Flow/group handler context
139 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
140 flow *voltha.OfpFlowStats // Flow message (can be nil or valid flow)
141 group *voltha.OfpGroupEntry // Group message (can be nil or valid group)
142 errChan *chan error // channel to report the mcast Flow/group handling error
143}
144
Naga Manjunath7615e552019-10-11 22:35:47 +0530145var pmNames = []string{
146 "rx_bytes",
147 "rx_packets",
148 "rx_mcast_packets",
149 "rx_bcast_packets",
150 "tx_bytes",
151 "tx_packets",
152 "tx_mcast_packets",
153 "tx_bcast_packets",
154}
155
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700156//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530157func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700158 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700159 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700160 device.deviceType = deviceTp
161 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700162 device.onuID = onuID
163 device.intfID = intfID
164 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530165 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700166 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530167}
168
169//NewDeviceHandler creates a new device handler
Himani Chawlacd407802020-12-10 12:08:59 +0530170func 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 -0700171 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800172 dh.cm = cm
cuilin20187b2a8c32019-03-26 19:52:28 -0700173 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400174 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400175 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700176 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700177 dh.device = cloned
178 dh.openOLT = adapter
179 dh.exitChannel = make(chan int, 1)
180 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530181 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530182 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530183 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 -0500184 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400185 dh.stopIndications = make(chan bool, 1)
Mahir Gunyelb0046752021-02-26 13:51:05 -0800186 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800187 // Create a slice of buffered channels for handling concurrent mcast flow/group.
188 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
189 for i := range dh.incomingMcastFlowOrGroup {
190 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
191 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
192 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
193 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
194 // for incoming mcast flow/group to be processed serially.
195 go dh.mcastFlowOrGroupChannelHandlerRoutine(dh.incomingMcastFlowOrGroup[i])
196 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700197 //TODO initialize the support classes.
198 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530199}
200
201// start save the device to the data model
202func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700203 dh.lockDevice.Lock()
204 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000205 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700206 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000207 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530208}
209
210// stop stops the device dh. Not much to do for now
211func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700212 dh.lockDevice.Lock()
213 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000214 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700215 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000216 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530217}
218
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400219func macifyIP(ip net.IP) string {
220 if len(ip) > 0 {
221 oct1 := strconv.FormatInt(int64(ip[12]), 16)
222 oct2 := strconv.FormatInt(int64(ip[13]), 16)
223 oct3 := strconv.FormatInt(int64(ip[14]), 16)
224 oct4 := strconv.FormatInt(int64(ip[15]), 16)
225 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
226 }
227 return ""
228}
229
Neha Sharma96b7bf22020-06-15 10:37:32 +0000230func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400231 var genmac string
232 var addr net.IP
233 var ips []string
234 var err error
235
Neha Sharma96b7bf22020-06-15 10:37:32 +0000236 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400237
238 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000239 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400240
241 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000242 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400243 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000244 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400245 }
246 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000247 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530248 log.Fields{"host": ips[0],
249 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400250 return genmac, nil
251 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000252 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400253 }
254
255 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000256 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530257 log.Fields{"host": host,
258 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400259 return genmac, nil
260}
261
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530262func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700263 slist := strings.Split(mac, ":")
264 result := make([]uint32, len(slist))
265 var err error
266 var tmp int64
267 for index, val := range slist {
268 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
269 return []uint32{1, 2, 3, 4, 5, 6}
270 }
271 result[index] = uint32(tmp)
272 }
273 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530274}
275
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700276//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 -0800277func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530278
David K. Bainbridge794735f2020-02-11 21:01:37 -0800279 switch portType {
280 case voltha.Port_ETHERNET_NNI:
281 return fmt.Sprintf("nni-%d", portNum), nil
282 case voltha.Port_PON_OLT:
283 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700284 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800285
Girish Kumarf26e4882020-03-05 06:49:10 +0000286 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530287}
288
Neha Sharma96b7bf22020-06-15 10:37:32 +0000289func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000290 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700291 if state == "up" {
292 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500293 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500294 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700295 } else {
296 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500297 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700298 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700299 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400300 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800301 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000302 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400303 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500304
Neha Sharma8f4e4322020-08-06 10:51:53 +0000305 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 +0000306 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000307 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 -0400308 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
309 "device-id": dh.device.Id,
310 "port-type": portType,
311 "port-number": portNum,
312 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500313 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400314 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500315 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400316 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700317 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400318 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700319 PortNo: portNum,
320 Label: label,
321 Type: portType,
322 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700323 OfpPort: &of.OfpPort{
324 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
325 Config: 0,
326 State: uint32(of.OfpPortState_OFPPS_LIVE),
327 Curr: capacity,
328 Advertised: capacity,
329 Peer: capacity,
330 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
331 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
332 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700333 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000334 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700335 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000336 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000337 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800338 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000339 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400340 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000341 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530342 return nil
343}
344
Kent Hagermane6ff1012020-07-14 15:07:53 -0400345func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000346 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530347 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400348 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
349 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530350 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800351 dh.lockDevice.Lock()
352 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530353 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530354}
355
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700356// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530357// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800358func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000359 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700360 defer func() {
361 dh.lockDevice.Lock()
362 dh.isReadIndicationRoutineActive = false
363 dh.lockDevice.Unlock()
364 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700365 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700366 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700367 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700368 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400369
David Bainbridgef5879ca2019-12-13 21:17:54 +0000370 // Create an exponential backoff around re-enabling indications. The
371 // maximum elapsed time for the back off is set to 0 so that we will
372 // continue to retry. The max interval defaults to 1m, but is set
373 // here for code clarity
374 indicationBackoff := backoff.NewExponentialBackOff()
375 indicationBackoff.MaxElapsedTime = 0
376 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700377
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700378 dh.lockDevice.Lock()
379 dh.isReadIndicationRoutineActive = true
380 dh.lockDevice.Unlock()
381
Girish Gowdra3f974912020-03-23 20:35:18 -0700382Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700383 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400384 select {
385 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000386 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700387 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400388 default:
389 indication, err := indications.Recv()
390 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000391 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530392 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530393 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400394 // Use an exponential back off to prevent getting into a tight loop
395 duration := indicationBackoff.NextBackOff()
396 if duration == backoff.Stop {
397 // If we reach a maximum then warn and reset the backoff
398 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000399 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530400 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530401 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400402 indicationBackoff.Reset()
403 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700404
405 // On failure process a backoff timer while watching for stopIndications
406 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700407 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700408 select {
409 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000410 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700411 if !backoffTimer.Stop() {
412 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700413 }
414 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700415 case <-backoffTimer.C:
416 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700417 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700418 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
419 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400420 }
421 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000422 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530423 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000424 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530425 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530426 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700427 // Close the stream, and re-initialize it
428 if err = indications.CloseSend(); err != nil {
429 // Ok to ignore here, because we landed here due to a problem on the stream
430 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000431 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530432 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530433 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700434 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000435 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700436 return err
437 }
438 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400439 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530440 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400441 // Reset backoff if we have a successful receive
442 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400443 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700444 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000445 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530446 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530447 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400448 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400449 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400450 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700451 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700452 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700453 // Close the send stream
454 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700455
Girish Gowdra3f974912020-03-23 20:35:18 -0700456 return nil
457}
458
459func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700460 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700461 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
462 if err != nil {
463 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
464 }
465 if indications == nil {
466 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
467 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700468 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700469 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400470}
471
472// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
473func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
474 switch indication.Data.(type) {
475 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
476 return true
477
478 default:
479 return false
480 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700481}
482
David K. Bainbridge794735f2020-02-11 21:01:37 -0800483func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700484 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000485 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530486 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700487 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530488 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700489 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000490 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000491 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530492 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000493 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800494 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000495 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800496 }
497 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700498}
499
David K. Bainbridge794735f2020-02-11 21:01:37 -0800500// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530501func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700502 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700503 switch indication.Data.(type) {
504 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000505 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
506 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700507 logger.Infow(ctx, "received olt indication", log.Fields{"device-id": dh.device.Id, "olt-ind": indication.GetOltInd()})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800508 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400509 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800510 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700511 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000512 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
513 defer span.Finish()
514
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800516 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000517 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400518 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800519 }
520 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000521 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700522 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000523 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
524 defer span.Finish()
525
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700526 intfOperInd := indication.GetIntfOperInd()
527 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800528 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000529 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400530 _ = 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 -0800531 }
532 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700533 } else if intfOperInd.GetType() == "pon" {
534 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
535 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800536 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000537 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400538 _ = 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 -0800539 }
540 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000541 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700542 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000543 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530544 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530545 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700546 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000547 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
548 defer span.Finish()
549
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700550 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000551 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800552 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800553 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700554 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000555 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
556 defer span.Finish()
557
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700558 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000559 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800560 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800561 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700562 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000563 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
564 defer span.Finish()
565
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000567 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 -0800568 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000569 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400570 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800571 }
572 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000574 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
575 defer span.Finish()
576
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000578 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700579 "intf-type": pktInd.IntfId,
580 "intf-id": pktInd.IntfId,
581 "gem-port-id": pktInd.GemportId,
582 "port-no": pktInd.PortNo,
583 "device-id": dh.device.Id,
584 })
585
586 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000587 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700588 "intf-type": pktInd.IntfId,
589 "intf-id": pktInd.IntfId,
590 "gem-port-id": pktInd.GemportId,
591 "port-no": pktInd.PortNo,
592 "packet": hex.EncodeToString(pktInd.Pkt),
593 "device-id": dh.device.Id,
594 })
595 }
596
David K. Bainbridge794735f2020-02-11 21:01:37 -0800597 go func() {
598 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400599 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800600 }
601 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700602 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000603 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
604 defer span.Finish()
605
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700606 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700607 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700608 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000609 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
610 defer span.Finish()
611
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700612 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000613 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700614 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000615 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
616 defer span.Finish()
617
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700618 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000619 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
620 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700621 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530622}
623
624// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530625func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530626 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000627 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530628
Girish Gowdru0c588b22019-04-23 23:24:56 -0400629 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530630 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400631 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000632 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400633 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000634
635 //Clear olt communication failure event
636 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
637 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700638 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000639 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
640
Gamze Abakac2c32a62021-03-11 11:44:18 +0000641 //check adapter and agent reconcile status
642 //reboot olt if needed (olt disconnection case)
643 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
644 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
645 log.Fields{
646 "device-id": dh.device.Id,
647 "adapter-status": dh.adapterPreviouslyConnected,
648 "agent-status": dh.agentPreviouslyConnected,
649 })
650 _ = dh.RebootDevice(ctx, dh.device)
651 }
652
Girish Gowdru0c588b22019-04-23 23:24:56 -0400653 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530654}
655
656// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530657func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000658 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400659
npujarec5762e2020-01-01 14:08:48 +0530660 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400661 if err != nil || device == nil {
662 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000663 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400664 }
665
666 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400667
668 //Update the device oper state and connection status
669 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800670 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400671 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800672 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400673
David K. Bainbridge794735f2020-02-11 21:01:37 -0800674 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000675 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400676 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400677
678 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530679 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400680 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000681 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400682 }
683 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400684 // Update onu state as down in onu adapter
685 onuInd := oop.OnuIndication{}
686 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800687 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300688 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800689 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400690 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300691 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800692 "onu-indicator": onuInd,
693 "device-type": onuDevice.Type,
694 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700695 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800696 } else {
697 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 -0700698 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400699 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800700 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700701 /* Discovered ONUs entries need to be cleared , since after OLT
702 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530703 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800704 dh.lockDevice.Unlock()
705
Neha Sharma96b7bf22020-06-15 10:37:32 +0000706 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700707 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530708}
709
710// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530711func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400712 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000713
714 // if the connection is already available, close the previous connection (olt reboot case)
715 if dh.clientCon != nil {
716 if err = dh.clientCon.Close(); err != nil {
717 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
718 } else {
719 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
720 }
721 }
722
723 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000724 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
725 grpc.WithInsecure(),
726 grpc.WithBlock(),
727 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000728 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000729 )),
730 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000731 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000732 )))
733
734 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530735 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530736 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000737 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400738 }
739 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530740}
741
742// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530743func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400744 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530745 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400746 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530747}
748
749// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530750func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530751 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000752 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400753
754 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530755 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
756 if err != nil || device == nil {
757 /*TODO: needs to handle error scenarios */
758 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
759 }
760 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000761 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400762
763 cloned := proto.Clone(device).(*voltha.Device)
764 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
765 cloned.OperStatus = voltha.OperStatus_UNKNOWN
766 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530767 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
768 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 -0400769 }
770
Chaitrashree G S44124192019-08-07 20:21:36 -0400771 // 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 +0530772 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400773 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530774 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400775 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400776 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
777 // all the modules initialized and ready to handle incoming ONUs.
778
Thomas Lee S985938d2020-05-04 11:40:41 +0530779 err = dh.initializeDeviceHandlerModules(ctx)
780 if err != nil {
781 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 -0400782 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400783
784 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800785 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530786 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400787 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800788 }
789 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700790
791 go startHeartbeatCheck(ctx, dh)
792
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400793 return nil
794 }
795
Neha Sharma8f4e4322020-08-06 10:51:53 +0000796 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400797 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400798 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400799 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400800 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400801 dh.populateActivePorts(ctx, ports)
802 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
803 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400804 }
805
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400806 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530807 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 -0400808 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530809
cuilin20187b2a8c32019-03-26 19:52:28 -0700810 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800811 go func() {
812 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400813 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800814 }
815 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000816 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000817
818 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000819 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000820 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700821
822 go startHeartbeatCheck(ctx, dh)
823
cuilin20187b2a8c32019-03-26 19:52:28 -0700824 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530825}
826
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400827func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700828 var err error
829 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400830
831 if err != nil {
832 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
833 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700834 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
835 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700836
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700837 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700838 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700839 var i uint32
840 for i = 0; i < dh.totalPonPorts; i++ {
841 // Instantiate resource manager
842 if dh.resourceMgr[i] = rsrcMgr.NewResourceMgr(ctx, i, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, dh.deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700843 return olterrors.ErrResourceManagerInstantiating
844 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400845 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700846 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
847 // the KV store to manage mcast group data. Provide the first instance (0th index)
848 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
849 return olterrors.ErrGroupManagerInstantiating
850 }
851 for i = 0; i < dh.totalPonPorts; i++ {
852 // Instantiate flow manager
853 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
854 return olterrors.ErrFlowManagerInstantiating
855 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700856 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700857 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400858 /* TODO: Instantiate Alarm , stats , BW managers */
859 /* Instantiating Event Manager to handle Alarms and KPIs */
860 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
861
862 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000863 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400864
865 return nil
866
867}
868
Neha Sharma96b7bf22020-06-15 10:37:32 +0000869func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400870 var err error
871 var deviceInfo *oop.DeviceInfo
872
Neha Sharma8f4e4322020-08-06 10:51:53 +0000873 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400874
875 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000876 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400877 }
878 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000879 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400880 }
881
Neha Sharma96b7bf22020-06-15 10:37:32 +0000882 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400883 dh.device.Root = true
884 dh.device.Vendor = deviceInfo.Vendor
885 dh.device.Model = deviceInfo.Model
886 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
887 dh.device.HardwareVersion = deviceInfo.HardwareVersion
888 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
889
890 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000891 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400892 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000893 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400894 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000895 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400896 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000897 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400898 dh.device.MacAddress = genmac
899 } else {
900 dh.device.MacAddress = deviceInfo.DeviceId
901 }
902
903 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000904 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000905 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400906 }
907
908 return deviceInfo, nil
909}
910
Neha Sharma96b7bf22020-06-15 10:37:32 +0000911func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700912 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530913 for {
914 select {
915 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000916 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530917 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000918 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700919
Neha Sharma8f4e4322020-08-06 10:51:53 +0000920 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400921 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700922 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400923 continue
924 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530925 for _, port := range ports {
926 // NNI Stats
927 if port.Type == voltha.Port_ETHERNET_NNI {
928 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
929 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000930 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000931 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000932 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530933 }
934 // PON Stats
935 if port.Type == voltha.Port_PON_OLT {
936 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
937 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
938 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000939 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000940 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530941 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000942 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000943
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700944 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700945 if len(onuGemInfoLst) > 0 {
946 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000947 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500948 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530949 }
950 }
951 }
952}
953
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700954//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530955func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400956 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000957 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530958 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530959
960 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400961 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
962 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530963 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530964}
965
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700966//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530967func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700968 return &ic.SwitchCapability{
969 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530970 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700971 HwDesc: "open_pon",
972 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700973 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700974 },
975 SwitchFeatures: &of.OfpSwitchFeatures{
976 NBuffers: 256,
977 NTables: 2,
978 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
979 of.OfpCapabilities_OFPC_TABLE_STATS |
980 of.OfpCapabilities_OFPC_PORT_STATS |
981 of.OfpCapabilities_OFPC_GROUP_STATS),
982 },
983 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530984}
985
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700986// GetInterAdapterTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
987func (dh *DeviceHandler) GetInterAdapterTechProfileDownloadMessage(ctx context.Context, tpPath string, ponPortNum uint32, onuID uint32, uniID uint32) *ic.InterAdapterTechProfileDownloadMessage {
988 ifID, err := IntfIDFromPonPortNum(ctx, ponPortNum)
989 if err != nil {
990 return nil
991 }
992 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, tpPath, ifID, onuID, uniID)
993}
994
Neha Sharma96b7bf22020-06-15 10:37:32 +0000995func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
996 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 -0700997 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700998 var deviceID string
999 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -07001000
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001001 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001002 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001003 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 -07001004 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1005 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001006
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001007 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301008
1009 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1010
Neha Sharma96b7bf22020-06-15 10:37:32 +00001011 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 -07001012 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001013 kwargs := make(map[string]interface{})
1014 kwargs["onu_id"] = omciInd.OnuId
1015 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001016
Neha Sharma8f4e4322020-08-06 10:51:53 +00001017 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001018 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301019 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001020 "intf-id": omciInd.IntfId,
1021 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001022 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001023 deviceType = onuDevice.Type
1024 deviceID = onuDevice.Id
1025 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1026 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301027 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001028 } else {
1029 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001030 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 +05301031 deviceType = onuInCache.(*OnuDevice).deviceType
1032 deviceID = onuInCache.(*OnuDevice).deviceID
1033 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001034 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001035
1036 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001037 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001038 ic.InterAdapterMessageType_OMCI_RESPONSE, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001039 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301040 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001041 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001042 "destination": deviceType,
1043 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001044 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001045 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001046 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301047}
1048
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001049//ProcessInterAdapterMessage sends the proxied messages to the target device
1050// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1051// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001052func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1053 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001054 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001055 return dh.handleInterAdapterOmciMsg(ctx, msg)
1056 }
1057 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1058}
cuilin20187b2a8c32019-03-26 19:52:28 -07001059
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001060func (dh *DeviceHandler) handleInterAdapterOmciMsg(ctx context.Context, msg *ic.InterAdapterMessage) error {
1061 msgID := msg.Header.Id
1062 fromTopic := msg.Header.FromTopic
1063 toTopic := msg.Header.ToTopic
1064 toDeviceID := msg.Header.ToDeviceId
1065 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001066
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001067 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 -07001068
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001069 msgBody := msg.GetBody()
1070
1071 omciMsg := &ic.InterAdapterOmciMessage{}
1072 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
1073 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
1074 }
1075
1076 if omciMsg.GetProxyAddress() == nil {
1077 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
1078 if err != nil {
1079 return olterrors.NewErrNotFound("onu", log.Fields{
1080 "device-id": dh.device.Id,
1081 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001082 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001083 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001084 if err := dh.sendProxiedOmciMessage(ctx, onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001085 return olterrors.NewErrCommunication("send-failed", log.Fields{
1086 "device-id": dh.device.Id,
1087 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001088 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001089 } else {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001090 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001091 if err := dh.sendProxiedOmciMessage(ctx, nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001092 return olterrors.NewErrCommunication("send-failed", log.Fields{
1093 "device-id": dh.device.Id,
1094 "onu-device-id": toDeviceID}, err)
1095 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001096 }
1097 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301098}
1099
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001100func (dh *DeviceHandler) sendProxiedOmciMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001101 var intfID uint32
1102 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001103 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001104 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001105 intfID = onuDevice.ProxyAddress.GetChannelId()
1106 onuID = onuDevice.ProxyAddress.GetOnuId()
1107 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001108 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001109 intfID = omciMsg.GetProxyAddress().GetChannelId()
1110 onuID = omciMsg.GetProxyAddress().GetOnuId()
1111 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001112 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001113 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001114 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 -08001115
Thomas Lee S94109f12020-03-03 16:39:29 +05301116 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001117 "intf-id": intfID,
1118 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001119 }
1120
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001121 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1122 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001123 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001124 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1125 hex.Encode(hexPkt, omciMsg.Message)
1126 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1127
1128 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1129 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1130 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001131 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001132 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001133
Neha Sharma8f4e4322020-08-06 10:51:53 +00001134 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001135 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301136 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001137 "intf-id": intfID,
1138 "onu-id": onuID,
1139 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001140 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001141 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001142}
1143
David K. Bainbridge794735f2020-02-11 21:01:37 -08001144func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301145 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 -07001146 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001147 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001148 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001149 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301150 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301151 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001152 st, _ := status.FromError(err)
1153 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001154 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1155
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001156 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301157 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001158 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001159 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001160 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001161 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001162 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001163}
1164
Mahir Gunyelb0046752021-02-26 13:51:05 -08001165func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001166 channelID := onuDiscInd.GetIntfId()
1167 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001168
Mahir Gunyelb0046752021-02-26 13:51:05 -08001169 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301171
cuilin20187b2a8c32019-03-26 19:52:28 -07001172 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001173 if sn != "" {
1174 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001175 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001176 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001177 }
1178
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301179 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001180 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001181 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301182
1183 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1184 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1185 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1186 OnuLosRaise event sent for it */
1187 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1188 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1189 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001190 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301191 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1192 "currentIntfId": onuDiscInd.GetIntfId()})
1193 // TODO:: Should we need to ignore raising OnuLosClear event
1194 // when onu connected to different PON?
1195 }
1196 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1197 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1198 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001199 go func() {
1200 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001201 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001202 }
1203 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301204 }
1205 return true
1206 })
1207
Neha Sharma96b7bf22020-06-15 10:37:32 +00001208 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001209 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001210 }
1211
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001212 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001213
1214 // check the ONU is already know to the OLT
1215 // NOTE the second time the ONU is discovered this should return a device
1216 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1217
1218 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001219 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 -08001220 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001221 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 -08001222 switch e.Code() {
1223 case codes.Internal:
1224 // this probably means NOT FOUND, so just create a new device
1225 onuDevice = nil
1226 case codes.DeadlineExceeded:
1227 // if the call times out, cleanup and exit
1228 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001229 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001230 }
1231 }
1232 }
1233
1234 if onuDevice == nil {
1235 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001236 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001237 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001238 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001239 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001240
Neha Sharma96b7bf22020-06-15 10:37:32 +00001241 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001242
1243 if err != nil {
1244 // if we can't create an ID in resource manager,
1245 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001246 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001247 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001248 "pon-intf-id": ponintfid,
1249 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001250 }
1251
Neha Sharma8f4e4322020-08-06 10:51:53 +00001252 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001253 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001254 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001255 dh.resourceMgr[ponintfid].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 +05301256 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001257 "pon-intf-id": ponintfid,
1258 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001259 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001260 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001261 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001262 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001263 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301264 log.Fields{"onuDevice": onuDevice,
1265 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001266 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301267 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001268 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001269
1270 // we can now use the existing ONU Id
1271 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001272 //Insert the ONU into cache to use in OnuIndication.
1273 //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 +00001274 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001275 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301276 "intfId": onuDiscInd.GetIntfId(),
1277 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001278 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001279
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301280 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301281 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001282 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301283 log.Fields{"onu": onuDev,
1284 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001285
Kent Hagermane6ff1012020-07-14 15:07:53 -04001286 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301287 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001288 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001289 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001290 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001291 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001292 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301293 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001294 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001295 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001296 }
1297 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001298}
1299
Mahir Gunyelb0046752021-02-26 13:51:05 -08001300func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001301
1302 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001303 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001304 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001305 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001306 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001307 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301308 log.Fields{"onuId": onuInd.OnuId,
1309 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301310 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001311 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001312 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301313
David K. Bainbridge794735f2020-02-11 21:01:37 -08001314 errFields := log.Fields{"device-id": dh.device.Id}
1315
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301316 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1317
Mahir Gunyele77977b2019-06-27 05:36:22 -07001318 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1319 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001320 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001321 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001322 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001323 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1324 if serialNumber != "" {
1325 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001326 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001327 } else {
1328 kwargs["onu_id"] = onuInd.OnuId
1329 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001330 errFields["onu-id"] = onuInd.OnuId
1331 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001332 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001333 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001334 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001335
David K. Bainbridge794735f2020-02-11 21:01:37 -08001336 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001337 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001338 }
1339
David K. Bainbridge794735f2020-02-11 21:01:37 -08001340 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001341 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001342 "previousIntfId": onuDevice.ParentPortNo,
1343 "currentIntfId": ponPort})
1344 }
1345
1346 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001347 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301348 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1349 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301350 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001351 }
1352 if !foundInCache {
1353 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1354
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301355 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 -08001356
1357 }
kesavand7cf3a052020-08-28 12:49:18 +05301358 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001359 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001360 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301361 }
1362 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001363 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001364 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001365 }
1366 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001367}
1368
Neha Sharma96b7bf22020-06-15 10:37:32 +00001369func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001370 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 -07001371 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1372 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1373 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1374 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001375 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001376 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1377 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001378 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001379 onuInd.OperState = "down"
1380 }
1381 }
1382
David K. Bainbridge794735f2020-02-11 21:01:37 -08001383 switch onuInd.OperState {
1384 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001385 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 -07001386 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301387 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001388 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001389 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301390 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001391 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001392 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001393 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001394 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001395 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001396 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001397 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 -04001398 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301399 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001400 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001401 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301402 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001403 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001404 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001405 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001406 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001407 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001408 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001409 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001410 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001411 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001412}
1413
cuilin20187b2a8c32019-03-26 19:52:28 -07001414func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1415 if serialNum != nil {
1416 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001417 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001418 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001419}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001420func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1421 decodedStr, err := hex.DecodeString(serialNum[4:])
1422 if err != nil {
1423 return nil, err
1424 }
1425 return &oop.SerialNumber{
1426 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001427 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001428 }, nil
1429}
cuilin20187b2a8c32019-03-26 19:52:28 -07001430
1431func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001432 if len(vendorSpecific) > 3 {
1433 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1434 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1435 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1436 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1437 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1438 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1439 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1440 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1441 return tmp
1442 }
1443 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001444}
1445
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001446//UpdateFlowsBulk upates the bulk flow
1447func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301448 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001449}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001450
1451//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001452func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1453 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301454 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001455 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301456 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001457 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001458 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001459 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001460 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001461 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001462 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001463 "intf-id": parentPort,
1464 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001465 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001466 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 -08001467 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301468}
1469
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001470// SendPacketInToCore sends packet-in to core
1471// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1472// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001473func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001474 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001475 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001476 "port": logicalPort,
1477 "packet": hex.EncodeToString(packetPayload),
1478 "device-id": dh.device.Id,
1479 })
1480 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001481 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 +05301482 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001483 "source": "adapter",
1484 "destination": "core",
1485 "device-id": dh.device.Id,
1486 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001487 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001488 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001489 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001490 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001491 "packet": hex.EncodeToString(packetPayload),
1492 "device-id": dh.device.Id,
1493 })
1494 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001495 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001496}
1497
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001498// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001499func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001500 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001501
1502 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1503 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001504 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001505 }
1506
Kent Hagermane6ff1012020-07-14 15:07:53 -04001507 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001508 metrics := dh.metrics.GetSubscriberMetrics()
1509 for _, m := range pmConfigs.Metrics {
1510 metrics[m.Name].Enabled = m.Enabled
1511
1512 }
1513 }
1514}
1515
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001516//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301517func (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 +00001518 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 +01001519
Girish Gowdra491a9c62021-01-06 16:43:07 -08001520 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001521 var errorsList []error
1522
Girish Gowdru0c588b22019-04-23 23:24:56 -04001523 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001524 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001525 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001526
Neha Sharma96b7bf22020-06-15 10:37:32 +00001527 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301528 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001529 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301530 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001531 if flow_utils.HasGroup(flow) {
1532 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1533 } else {
1534 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1535 }
Girish Gowdracefae192020-03-19 18:14:10 -07001536 if err != nil {
1537 errorsList = append(errorsList, err)
1538 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001539 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301540
1541 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001542 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001543 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301544 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001545 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301546 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001547 if flow_utils.HasGroup(flow) {
1548 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1549 } else {
1550 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1551 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001552 if err != nil {
1553 errorsList = append(errorsList, err)
1554 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301555 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001556 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001557
Girish Gowdracefae192020-03-19 18:14:10 -07001558 // 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 +00001559 if groups != nil {
1560 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001561 // err = dh.groupMgr.AddGroup(ctx, group)
1562 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001563 if err != nil {
1564 errorsList = append(errorsList, err)
1565 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001566 }
1567 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001568 // err = dh.groupMgr.ModifyGroup(ctx, group)
1569 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001570 if err != nil {
1571 errorsList = append(errorsList, err)
1572 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001573 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001574 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001575 // err = dh.groupMgr.DeleteGroup(ctx, group)
1576 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001577 if err != nil {
1578 errorsList = append(errorsList, err)
1579 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001580 }
1581 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001582 if len(errorsList) > 0 {
1583 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1584 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001586 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301587}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001588
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001589//DisableDevice disables the given device
1590//It marks the following for the given device:
1591//Device-Handler Admin-State : down
1592//Device Port-State: UNKNOWN
1593//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001595 /* On device disable ,admin state update has to be done prior sending request to agent since
1596 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001597 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001598 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001599 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001600 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001601 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001602 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001603 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001604 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001605 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001606 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301607
1608 dh.discOnus = sync.Map{}
1609 dh.onus = sync.Map{}
1610
Thomas Lee S85f37312020-04-03 17:06:12 +05301611 //stopping the stats collector
1612 dh.stopCollector <- true
1613
Neha Sharma96b7bf22020-06-15 10:37:32 +00001614 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001615 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301616 //Update device Admin state
1617 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001618 // 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 +00001619 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 -04001620 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001621 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001622 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001623 return nil
1624}
1625
Neha Sharma96b7bf22020-06-15 10:37:32 +00001626func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001627 // Update onu state as unreachable in onu adapter
1628 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301629 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001630 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001631 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001632 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001633 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "err": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001634 }
1635 if onuDevices != nil {
1636 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001637 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001638 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001639 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001640 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001641 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001642 }
1643
1644 }
1645 }
1646
1647}
1648
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001649//ReenableDevice re-enables the olt device after disable
1650//It marks the following for the given device:
1651//Device-Handler Admin-State : up
1652//Device Port-State: ACTIVE
1653//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001654func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001655 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301656 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001657 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301658 }
1659 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001660 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001661
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001662 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001663
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001664 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1665 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001666 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001667 }
1668 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001669 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001670 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001671 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001672 device.OperStatus = voltha.OperStatus_ACTIVE
1673 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001674
Neha Sharma8f4e4322020-08-06 10:51:53 +00001675 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 +05301676 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001677 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001678 "connect-status": device.ConnectStatus,
1679 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001680 }
kesavand39e0aa32020-01-28 20:58:50 -05001681
Neha Sharma96b7bf22020-06-15 10:37:32 +00001682 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001683
1684 return nil
1685}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001686
npujarec5762e2020-01-01 14:08:48 +05301687func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001688 var uniID uint32
1689 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301690 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001691 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001692 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001693 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001694 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001695 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001696 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001697 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001698 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001699 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001700 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001701 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001702 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001703 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001704 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001705 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001706 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001707 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301708 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001709 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1710 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001711 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530