blob: 2bdbbb1ae8475b6b336a9d0cd4717b9373394289 [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
khenaidoo106c61a2021-08-11 18:05:46 -040033 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
khenaidoo106c61a2021-08-11 18:05:46 -040034
Matteo Scandolo945e4012019-12-12 14:16:11 -080035 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070036 "github.com/gogo/protobuf/proto"
Girish Kumar93e91742020-07-27 16:43:19 +000037 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
38 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
khenaidoo106c61a2021-08-11 18:05:46 -040039 "github.com/opencord/voltha-lib-go/v7/pkg/config"
40 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
41 flow_utils "github.com/opencord/voltha-lib-go/v7/pkg/flows"
42 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyel85f61c12021-10-06 11:53:45 -070043 plt "github.com/opencord/voltha-lib-go/v7/pkg/platform"
khenaidoo106c61a2021-08-11 18:05:46 -040044 "github.com/opencord/voltha-lib-go/v7/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080045
khenaidoo106c61a2021-08-11 18:05:46 -040046 conf "github.com/opencord/voltha-openolt-adapter/internal/pkg/config"
Thomas Lee S94109f12020-03-03 16:39:29 +053047 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080048 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
khenaidoo106c61a2021-08-11 18:05:46 -040049 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoodc2116e2021-10-19 17:33:19 -040050 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo106c61a2021-08-11 18:05:46 -040051 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoodc2116e2021-10-19 17:33:19 -040052 "github.com/opencord/voltha-protos/v5/go/health"
53 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
54 "github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service"
khenaidoo106c61a2021-08-11 18:05:46 -040055 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
56 oop "github.com/opencord/voltha-protos/v5/go/openolt"
57 "github.com/opencord/voltha-protos/v5/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070058 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040059 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040060 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053061)
62
salmansiddiqui7ac62132019-08-22 03:58:50 +000063// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040064const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080065 InvalidPort = 0xffffffff
66 MaxNumOfGroupHandlerChannels = 256
67
68 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
69 McastFlowOrGroupModify = "McastFlowOrGroupModify"
70 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050071 oltPortInfoTimeout = 3
Manikkaraj kb1d51442019-07-23 10:41:02 -040072)
73
Phaneendra Manda4c62c802019-03-06 21:37:49 +053074//DeviceHandler will interact with the OLT device.
75type DeviceHandler struct {
khenaidoo106c61a2021-08-11 18:05:46 -040076 cm *config.ConfigManager
77 device *voltha.Device
78 cfg *conf.AdapterFlags
79 coreClient *vgrpc.Client
80 childAdapterClients map[string]*vgrpc.Client
81 lockChildAdapterClients sync.RWMutex
82 EventProxy eventif.EventProxy
83 openOLT *OpenOLT
84 exitChannel chan int
85 lockDevice sync.RWMutex
86 Client oop.OpenoltClient
87 transitionMap *TransitionMap
88 clientCon *grpc.ClientConn
89 flowMgr []*OpenOltFlowMgr
90 groupMgr *OpenOltGroupMgr
91 eventMgr *OpenOltEventMgr
92 resourceMgr []*rsrcMgr.OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070093
94 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +053095
Girish Gowdra3ab6d212020-03-24 17:33:15 -070096 discOnus sync.Map
97 onus sync.Map
98 portStats *OpenOltStatisticsMgr
99 metrics *pmmetrics.PmMetrics
100 stopCollector chan bool
101 stopHeartbeatCheck chan bool
102 activePorts sync.Map
103 stopIndications chan bool
104 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -0700105
Mahir Gunyelb0046752021-02-26 13:51:05 -0800106 totalPonPorts uint32
107 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
108 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800109
110 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
111 // A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700112 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
113 stopMcastHandlerRoutine []chan bool
114 mcastHandlerRoutineActive []bool
Gamze Abakac2c32a62021-03-11 11:44:18 +0000115
116 adapterPreviouslyConnected bool
117 agentPreviouslyConnected bool
Girish Gowdra950326e2021-11-05 12:43:24 -0700118
119 isDeviceDeletionInProgress bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700120}
121
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700122//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700123type OnuDevice struct {
khenaidoo106c61a2021-08-11 18:05:46 -0400124 deviceID string
125 deviceType string
126 serialNumber string
127 onuID uint32
128 intfID uint32
129 proxyDeviceID string
130 losRaised bool
131 rdiRaised bool
132 adapterEndpoint string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700133}
134
Mahir Gunyelb0046752021-02-26 13:51:05 -0800135type onuIndicationMsg struct {
136 ctx context.Context
137 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800138}
139
140type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800141 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800142 stopChannel chan struct{}
143}
144
Girish Gowdra491a9c62021-01-06 16:43:07 -0800145//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
146//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
147//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
148//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
149type McastFlowOrGroupControlBlock struct {
khenaidoodc2116e2021-10-19 17:33:19 -0400150 ctx context.Context // Flow/group handler context
151 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
152 flow *of.OfpFlowStats // Flow message (can be nil or valid flow)
153 group *of.OfpGroupEntry // Group message (can be nil or valid group)
154 errChan *chan error // channel to report the mcast Flow/group handling error
Girish Gowdra491a9c62021-01-06 16:43:07 -0800155}
156
Naga Manjunath7615e552019-10-11 22:35:47 +0530157var pmNames = []string{
158 "rx_bytes",
159 "rx_packets",
160 "rx_mcast_packets",
161 "rx_bcast_packets",
162 "tx_bytes",
163 "tx_packets",
164 "tx_mcast_packets",
165 "tx_bcast_packets",
166}
167
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700168//NewOnuDevice creates a new Onu Device
khenaidoo106c61a2021-08-11 18:05:46 -0400169func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool, adapterEndpoint string) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700170 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700171 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700172 device.deviceType = deviceTp
173 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700174 device.onuID = onuID
175 device.intfID = intfID
176 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530177 device.losRaised = losRaised
khenaidoo106c61a2021-08-11 18:05:46 -0400178 device.adapterEndpoint = adapterEndpoint
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700179 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530180}
181
182//NewDeviceHandler creates a new device handler
khenaidoo106c61a2021-08-11 18:05:46 -0400183func NewDeviceHandler(cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenOLT, cm *config.ConfigManager, cfg *conf.AdapterFlags) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700184 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800185 dh.cm = cm
khenaidoo106c61a2021-08-11 18:05:46 -0400186 dh.coreClient = cc
Devmalya Paulfb990a52019-07-09 10:01:49 -0400187 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700188 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700189 dh.device = cloned
190 dh.openOLT = adapter
Girish Gowdraae56c722021-11-22 14:31:11 -0800191 dh.exitChannel = make(chan int, 1) // TODO: Why buffered?
cuilin20187b2a8c32019-03-26 19:52:28 -0700192 dh.lockDevice = sync.RWMutex{}
Girish Gowdraae56c722021-11-22 14:31:11 -0800193 dh.stopCollector = make(chan bool, 2) // TODO: Why buffered?
194 dh.stopHeartbeatCheck = make(chan bool, 2) // TODO: Why buffered?
Naga Manjunath7615e552019-10-11 22:35:47 +0530195 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 -0500196 dh.activePorts = sync.Map{}
Girish Gowdraae56c722021-11-22 14:31:11 -0800197 dh.stopIndications = make(chan bool, 1) // TODO: Why buffered?
Mahir Gunyelb0046752021-02-26 13:51:05 -0800198 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
khenaidoo106c61a2021-08-11 18:05:46 -0400199 dh.childAdapterClients = make(map[string]*vgrpc.Client)
200 dh.cfg = cfg
Girish Gowdra491a9c62021-01-06 16:43:07 -0800201 // Create a slice of buffered channels for handling concurrent mcast flow/group.
202 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700203 dh.stopMcastHandlerRoutine = make([]chan bool, MaxNumOfGroupHandlerChannels)
204 dh.mcastHandlerRoutineActive = make([]bool, MaxNumOfGroupHandlerChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800205 for i := range dh.incomingMcastFlowOrGroup {
206 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdraae56c722021-11-22 14:31:11 -0800207 dh.stopMcastHandlerRoutine[i] = make(chan bool)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800208 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
209 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
210 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
211 // for incoming mcast flow/group to be processed serially.
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700212 dh.mcastHandlerRoutineActive[i] = true
213 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
Girish Gowdra491a9c62021-01-06 16:43:07 -0800214 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700215 //TODO initialize the support classes.
216 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530217}
218
219// start save the device to the data model
220func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700221 dh.lockDevice.Lock()
222 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000223 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700224 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000225 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530226}
227
228// stop stops the device dh. Not much to do for now
229func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700230 dh.lockDevice.Lock()
231 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000232 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700233 dh.exitChannel <- 1
khenaidoo106c61a2021-08-11 18:05:46 -0400234
Neha Sharma96b7bf22020-06-15 10:37:32 +0000235 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530236}
237
ssiddiqui04386ee2021-08-23 21:58:25 +0530238func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
239 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
240 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
241 if pooledIntfID == intfID {
242 return resourceRanges.GetTechnology()
243 }
244 }
245 }
246 return ""
247}
248
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400249func macifyIP(ip net.IP) string {
250 if len(ip) > 0 {
251 oct1 := strconv.FormatInt(int64(ip[12]), 16)
252 oct2 := strconv.FormatInt(int64(ip[13]), 16)
253 oct3 := strconv.FormatInt(int64(ip[14]), 16)
254 oct4 := strconv.FormatInt(int64(ip[15]), 16)
255 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
256 }
257 return ""
258}
259
Neha Sharma96b7bf22020-06-15 10:37:32 +0000260func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400261 var genmac string
262 var addr net.IP
263 var ips []string
264 var err error
265
Neha Sharma96b7bf22020-06-15 10:37:32 +0000266 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400267
268 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000269 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400270
271 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000272 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400273 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000274 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400275 }
276 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000277 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530278 log.Fields{"host": ips[0],
279 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400280 return genmac, nil
281 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000282 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400283 }
284
285 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000286 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530287 log.Fields{"host": host,
288 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400289 return genmac, nil
290}
291
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530292func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700293 slist := strings.Split(mac, ":")
294 result := make([]uint32, len(slist))
295 var err error
296 var tmp int64
297 for index, val := range slist {
298 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
299 return []uint32{1, 2, 3, 4, 5, 6}
300 }
301 result[index] = uint32(tmp)
302 }
303 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530304}
305
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700306//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 -0800307func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530308
David K. Bainbridge794735f2020-02-11 21:01:37 -0800309 switch portType {
310 case voltha.Port_ETHERNET_NNI:
311 return fmt.Sprintf("nni-%d", portNum), nil
312 case voltha.Port_PON_OLT:
313 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700314 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800315
Girish Kumarf26e4882020-03-05 06:49:10 +0000316 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530317}
318
Neha Sharma96b7bf22020-06-15 10:37:32 +0000319func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000320 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700321 if state == "up" {
322 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500323 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500324 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700325 } else {
326 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500327 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700328 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700329 portNum := plt.IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400330 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800331 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000332 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400333 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500334
khenaidoo106c61a2021-08-11 18:05:46 -0400335 // Check if port exists
khenaidoodc2116e2021-10-19 17:33:19 -0400336 port, err := dh.getPortFromCore(ctx, &ca.PortFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400337 DeviceId: dh.device.Id,
338 Port: portNum,
339 })
340 if err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000341 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
khenaidoodc2116e2021-10-19 17:33:19 -0400342 err = dh.updatePortStateInCore(ctx, &ca.PortState{
khenaidoo106c61a2021-08-11 18:05:46 -0400343 DeviceId: dh.device.Id,
344 PortType: portType,
345 PortNo: portNum,
346 OperStatus: operStatus})
347 if err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400348 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
349 "device-id": dh.device.Id,
350 "port-type": portType,
351 "port-number": portNum,
352 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500353 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400354 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500355 }
khenaidoo106c61a2021-08-11 18:05:46 -0400356
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400357 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700358 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
khenaidoo106c61a2021-08-11 18:05:46 -0400359 port = &voltha.Port{
360 DeviceId: dh.device.Id,
cuilin20187b2a8c32019-03-26 19:52:28 -0700361 PortNo: portNum,
362 Label: label,
363 Type: portType,
364 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700365 OfpPort: &of.OfpPort{
366 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
367 Config: 0,
368 State: uint32(of.OfpPortState_OFPPS_LIVE),
369 Curr: capacity,
370 Advertised: capacity,
371 Peer: capacity,
372 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
373 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
374 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700375 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000376 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700377 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400378 err = dh.createPortInCore(ctx, port)
379 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000380 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800381 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000382 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400383 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000384 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530385 return nil
386}
387
Kent Hagermane6ff1012020-07-14 15:07:53 -0400388func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -0400389 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530390 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400391 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
392 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530393 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800394 dh.lockDevice.Lock()
395 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530396 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530397}
398
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700399// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530400// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800401func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000402 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700403 defer func() {
404 dh.lockDevice.Lock()
405 dh.isReadIndicationRoutineActive = false
406 dh.lockDevice.Unlock()
407 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700408 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700409 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700410 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700411 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400412
David Bainbridgef5879ca2019-12-13 21:17:54 +0000413 // Create an exponential backoff around re-enabling indications. The
414 // maximum elapsed time for the back off is set to 0 so that we will
415 // continue to retry. The max interval defaults to 1m, but is set
416 // here for code clarity
417 indicationBackoff := backoff.NewExponentialBackOff()
418 indicationBackoff.MaxElapsedTime = 0
419 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700420
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700421 dh.lockDevice.Lock()
422 dh.isReadIndicationRoutineActive = true
423 dh.lockDevice.Unlock()
424
Girish Gowdra3f974912020-03-23 20:35:18 -0700425Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700426 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400427 select {
428 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000429 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700430 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400431 default:
432 indication, err := indications.Recv()
433 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000434 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530435 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530436 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400437 // Use an exponential back off to prevent getting into a tight loop
438 duration := indicationBackoff.NextBackOff()
439 if duration == backoff.Stop {
440 // If we reach a maximum then warn and reset the backoff
441 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000442 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530443 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530444 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400445 indicationBackoff.Reset()
446 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700447
448 // On failure process a backoff timer while watching for stopIndications
449 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700450 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700451 select {
452 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000453 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700454 if !backoffTimer.Stop() {
455 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700456 }
457 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700458 case <-backoffTimer.C:
459 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700460 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700461 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
462 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400463 }
464 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000465 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530466 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000467 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530468 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530469 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700470 // Close the stream, and re-initialize it
471 if err = indications.CloseSend(); err != nil {
472 // Ok to ignore here, because we landed here due to a problem on the stream
473 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000474 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530475 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530476 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700477 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000478 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700479 return err
480 }
481 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400482 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530483 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400484 // Reset backoff if we have a successful receive
485 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400486 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700487 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000488 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530489 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530490 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400491 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400492 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400493 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700494 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700495 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700496 // Close the send stream
497 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700498
Girish Gowdra3f974912020-03-23 20:35:18 -0700499 return nil
500}
501
502func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700503 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700504 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
505 if err != nil {
506 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
507 }
508 if indications == nil {
509 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
510 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700511 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700512 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400513}
514
515// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
516func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
517 switch indication.Data.(type) {
518 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
519 return true
520
521 default:
522 return false
523 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700524}
525
David K. Bainbridge794735f2020-02-11 21:01:37 -0800526func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700527 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000528 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530529 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700530 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530531 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700532 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000533 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000534 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530535 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000536 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800537 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000538 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800539 }
540 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700541}
542
David K. Bainbridge794735f2020-02-11 21:01:37 -0800543// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530544func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700545 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700546 switch indication.Data.(type) {
547 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000548 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
549 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700550 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 -0800551 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400552 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800553 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700554 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000555 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
556 defer span.Finish()
557
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700558 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800559 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000560 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400561 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800562 }
563 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000564 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700565 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000566 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
567 defer span.Finish()
568
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700569 intfOperInd := indication.GetIntfOperInd()
570 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800571 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000572 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400573 _ = 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 -0800574 }
575 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700576 } else if intfOperInd.GetType() == "pon" {
577 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
578 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800579 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000580 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400581 _ = 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 -0800582 }
583 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000584 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700585 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000586 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530587 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530588 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700589 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000590 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
591 defer span.Finish()
592
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700593 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000594 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800595 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800596 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700597 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000598 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
599 defer span.Finish()
600
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700601 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000602 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800603 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800604 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700605 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000606 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
607 defer span.Finish()
608
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700609 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000610 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 -0800611 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000612 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400613 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800614 }
615 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700616 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000617 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
618 defer span.Finish()
619
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700620 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000621 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700622 "intf-type": pktInd.IntfId,
623 "intf-id": pktInd.IntfId,
624 "gem-port-id": pktInd.GemportId,
625 "port-no": pktInd.PortNo,
626 "device-id": dh.device.Id,
627 })
628
629 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700631 "intf-type": pktInd.IntfId,
632 "intf-id": pktInd.IntfId,
633 "gem-port-id": pktInd.GemportId,
634 "port-no": pktInd.PortNo,
635 "packet": hex.EncodeToString(pktInd.Pkt),
636 "device-id": dh.device.Id,
637 })
638 }
639
David K. Bainbridge794735f2020-02-11 21:01:37 -0800640 go func() {
641 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400642 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800643 }
644 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700645 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000646 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
647 defer span.Finish()
648
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700649 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700650 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700651 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000652 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
653 defer span.Finish()
654
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700655 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000656 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700657 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000658 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
659 defer span.Finish()
660
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700661 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000662 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
663 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700664 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530665}
666
667// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530668func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530669 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000670 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530671
Girish Gowdra618fa572021-09-01 17:19:29 -0700672 // instantiate the mcast handler routines.
673 for i := range dh.incomingMcastFlowOrGroup {
674 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
675 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
676 if !dh.mcastHandlerRoutineActive[i] {
677 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
678 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
679 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
680 // for incoming mcast flow/group to be processed serially.
681 dh.mcastHandlerRoutineActive[i] = true
682 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
683 }
684 }
685
Girish Gowdru0c588b22019-04-23 23:24:56 -0400686 // Synchronous call to update device state - this method is run in its own go routine
khenaidoodc2116e2021-10-19 17:33:19 -0400687 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400688 DeviceId: dh.device.Id,
689 OperStatus: voltha.OperStatus_ACTIVE,
690 ConnStatus: voltha.ConnectStatus_REACHABLE,
691 }); err != nil {
692 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400693 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000694
695 //Clear olt communication failure event
696 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
697 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700698 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000699 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
700
Gamze Abakac2c32a62021-03-11 11:44:18 +0000701 //check adapter and agent reconcile status
702 //reboot olt if needed (olt disconnection case)
703 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
704 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
705 log.Fields{
706 "device-id": dh.device.Id,
707 "adapter-status": dh.adapterPreviouslyConnected,
708 "agent-status": dh.agentPreviouslyConnected,
709 })
710 _ = dh.RebootDevice(ctx, dh.device)
711 }
712
Girish Gowdru0c588b22019-04-23 23:24:56 -0400713 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530714}
715
716// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530717func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000718 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400719
khenaidoo106c61a2021-08-11 18:05:46 -0400720 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400721 if err != nil || device == nil {
722 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000723 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400724 }
725
726 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400727
728 //Update the device oper state and connection status
729 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800730 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400731 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800732 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400733
khenaidoodc2116e2021-10-19 17:33:19 -0400734 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400735 DeviceId: cloned.Id,
736 OperStatus: cloned.OperStatus,
737 ConnStatus: cloned.ConnectStatus,
738 }); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000739 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400740 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400741
742 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -0400743 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400744 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000745 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400746 }
747 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400748 // Update onu state as down in onu adapter
749 onuInd := oop.OnuIndication{}
750 onuInd.OperState = "down"
khenaidoo106c61a2021-08-11 18:05:46 -0400751
752 ogClient, err := dh.getChildAdapterServiceClient(onuDevice.AdapterEndpoint)
753 if err != nil {
754 return err
755 }
756 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
khenaidoodc2116e2021-10-19 17:33:19 -0400757 _, err = ogClient.OnuIndication(subCtx, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -0400758 DeviceId: onuDevice.Id,
759 OnuIndication: &onuInd,
760 })
761 cancel()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800762 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400763 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -0400764 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800765 "onu-indicator": onuInd,
766 "device-type": onuDevice.Type,
767 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700768 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800769 } else {
770 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 -0700771 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400772 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800773 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700774 /* Discovered ONUs entries need to be cleared , since after OLT
775 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530776 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800777 dh.lockDevice.Unlock()
778
Neha Sharma96b7bf22020-06-15 10:37:32 +0000779 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700780 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530781}
782
783// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530784func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400785 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000786
787 // if the connection is already available, close the previous connection (olt reboot case)
788 if dh.clientCon != nil {
789 if err = dh.clientCon.Close(); err != nil {
790 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
791 } else {
792 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
793 }
794 }
795
796 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000797 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
798 grpc.WithInsecure(),
799 grpc.WithBlock(),
800 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000801 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000802 )),
803 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000804 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000805 )))
806
807 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530808 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530809 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000810 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400811 }
812 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530813}
814
815// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530816func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400817 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530818 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400819 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530820}
821
822// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530823func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530824 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000825 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400826
827 // Case where OLT is disabled and then rebooted.
khenaidoo106c61a2021-08-11 18:05:46 -0400828 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Thomas Lee S985938d2020-05-04 11:40:41 +0530829 if err != nil || device == nil {
830 /*TODO: needs to handle error scenarios */
831 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
832 }
833 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000834 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400835
836 cloned := proto.Clone(device).(*voltha.Device)
837 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
838 cloned.OperStatus = voltha.OperStatus_UNKNOWN
839 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -0400840
khenaidoodc2116e2021-10-19 17:33:19 -0400841 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400842 DeviceId: cloned.Id,
843 OperStatus: cloned.OperStatus,
844 ConnStatus: cloned.ConnectStatus,
845 }); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530846 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 -0400847 }
848
Chaitrashree G S44124192019-08-07 20:21:36 -0400849 // 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 +0530850 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400851 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530852 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400853 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400854 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
855 // all the modules initialized and ready to handle incoming ONUs.
856
Thomas Lee S985938d2020-05-04 11:40:41 +0530857 err = dh.initializeDeviceHandlerModules(ctx)
858 if err != nil {
859 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 -0400860 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400861
862 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800863 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530864 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400865 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800866 }
867 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700868
869 go startHeartbeatCheck(ctx, dh)
870
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400871 return nil
872 }
873
khenaidoo106c61a2021-08-11 18:05:46 -0400874 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400875 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400876 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400877 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400878 }
khenaidoo106c61a2021-08-11 18:05:46 -0400879 dh.populateActivePorts(ctx, ports.Items)
880 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400881 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400882 }
883
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400884 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530885 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 -0400886 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530887
cuilin20187b2a8c32019-03-26 19:52:28 -0700888 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800889 go func() {
890 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400891 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800892 }
893 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000894 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000895
896 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000897 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000898 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700899
900 go startHeartbeatCheck(ctx, dh)
901
cuilin20187b2a8c32019-03-26 19:52:28 -0700902 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530903}
904
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400905func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700906 var err error
907 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400908
909 if err != nil {
910 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
911 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700912 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
913 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700914
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700915 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700916 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700917 var i uint32
918 for i = 0; i < dh.totalPonPorts; i++ {
919 // Instantiate resource manager
920 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 -0700921 return olterrors.ErrResourceManagerInstantiating
922 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400923 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700924 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
925 // the KV store to manage mcast group data. Provide the first instance (0th index)
926 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
927 return olterrors.ErrGroupManagerInstantiating
928 }
929 for i = 0; i < dh.totalPonPorts; i++ {
930 // Instantiate flow manager
931 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
932 return olterrors.ErrFlowManagerInstantiating
933 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700934 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700935 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400936 /* TODO: Instantiate Alarm , stats , BW managers */
937 /* Instantiating Event Manager to handle Alarms and KPIs */
938 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
939
940 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000941 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400942
943 return nil
944
945}
946
Neha Sharma96b7bf22020-06-15 10:37:32 +0000947func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400948 var err error
949 var deviceInfo *oop.DeviceInfo
950
Neha Sharma8f4e4322020-08-06 10:51:53 +0000951 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400952
953 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000954 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400955 }
956 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000957 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400958 }
959
Neha Sharma96b7bf22020-06-15 10:37:32 +0000960 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400961 dh.device.Root = true
962 dh.device.Vendor = deviceInfo.Vendor
963 dh.device.Model = deviceInfo.Model
964 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
965 dh.device.HardwareVersion = deviceInfo.HardwareVersion
966 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
967
968 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000969 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400970 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000971 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400972 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000973 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400974 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000975 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400976 dh.device.MacAddress = genmac
977 } else {
978 dh.device.MacAddress = deviceInfo.DeviceId
979 }
980
981 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400982 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000983 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400984 }
985
986 return deviceInfo, nil
987}
988
Neha Sharma96b7bf22020-06-15 10:37:32 +0000989func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700990 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530991 for {
992 select {
993 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000994 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530995 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000996 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700997
khenaidoo106c61a2021-08-11 18:05:46 -0400998 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400999 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001000 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001001 continue
1002 }
khenaidoo106c61a2021-08-11 18:05:46 -04001003 for _, port := range ports.Items {
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301004 // NNI Stats
1005 if port.Type == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001006 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301007 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001008 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001009 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001010 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301011 }
1012 // PON Stats
1013 if port.Type == voltha.Port_PON_OLT {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001014 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301015 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
1016 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001017 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001018 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301019 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001020 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001021
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001022 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001023 if len(onuGemInfoLst) > 0 {
1024 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001025 }
Chaitrashree G Sef088112020-02-03 21:39:27 -05001026 }
Naga Manjunath7615e552019-10-11 22:35:47 +05301027 }
1028 }
1029 }
1030}
1031
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001032//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +05301033func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001034 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001035 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +05301036 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +05301037
1038 // Now, set the initial PM configuration for that device
khenaidoo106c61a2021-08-11 18:05:46 -04001039 cgClient, err := dh.coreClient.GetCoreServiceClient()
1040 if err != nil {
1041 logger.Errorw(ctx, "no-core-connection", log.Fields{"device-id": dh.device.Id, "error": err})
1042 return
1043 }
1044
1045 // Now, set the initial PM configuration for that device
1046 if _, err := cgClient.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001047 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +05301048 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301049}
1050
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001051//GetOfpDeviceInfo Gets the Ofp information of the given device
khenaidoodc2116e2021-10-19 17:33:19 -04001052func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ca.SwitchCapability, error) {
1053 return &ca.SwitchCapability{
cuilin20187b2a8c32019-03-26 19:52:28 -07001054 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301055 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001056 HwDesc: "open_pon",
1057 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001058 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001059 },
1060 SwitchFeatures: &of.OfpSwitchFeatures{
1061 NBuffers: 256,
1062 NTables: 2,
1063 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1064 of.OfpCapabilities_OFPC_TABLE_STATS |
1065 of.OfpCapabilities_OFPC_PORT_STATS |
1066 of.OfpCapabilities_OFPC_GROUP_STATS),
1067 },
1068 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301069}
1070
khenaidoo106c61a2021-08-11 18:05:46 -04001071// GetTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
khenaidoodc2116e2021-10-19 17:33:19 -04001072func (dh *DeviceHandler) GetTechProfileDownloadMessage(ctx context.Context, request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001073 ifID, err := plt.IntfIDFromPonPortNum(ctx, request.ParentPonPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001074 if err != nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001075 return nil, err
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001076 }
khenaidoo106c61a2021-08-11 18:05:46 -04001077 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001078}
1079
Neha Sharma96b7bf22020-06-15 10:37:32 +00001080func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001081 logger.Debugw(ctx, "omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "parent-device-id": dh.device.Id})
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001082 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001083 var deviceID string
1084 var proxyDeviceID string
khenaidoo106c61a2021-08-11 18:05:46 -04001085 var childAdapterEndpoint string
cuilin20187b2a8c32019-03-26 19:52:28 -07001086
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001087 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001088 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001089 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 -07001090 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1091 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001092
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001093 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301094
1095 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1096
Neha Sharma96b7bf22020-06-15 10:37:32 +00001097 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})
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001098 ponPort := plt.IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
cuilin20187b2a8c32019-03-26 19:52:28 -07001099
khenaidoodc2116e2021-10-19 17:33:19 -04001100 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001101 ParentId: dh.device.Id,
1102 OnuId: omciInd.OnuId,
1103 ParentPortNo: ponPort,
1104 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001105 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301106 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001107 "intf-id": omciInd.IntfId,
1108 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001109 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001110 deviceType = onuDevice.Type
1111 deviceID = onuDevice.Id
1112 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
khenaidoo106c61a2021-08-11 18:05:46 -04001113 childAdapterEndpoint = onuDevice.AdapterEndpoint
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001114 //if not exist in cache, then add to cache.
khenaidoo106c61a2021-08-11 18:05:46 -04001115 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false, onuDevice.AdapterEndpoint))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001116 } else {
1117 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001118 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 +05301119 deviceType = onuInCache.(*OnuDevice).deviceType
1120 deviceID = onuInCache.(*OnuDevice).deviceID
1121 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001122 childAdapterEndpoint = onuInCache.(*OnuDevice).adapterEndpoint
cuilin20187b2a8c32019-03-26 19:52:28 -07001123 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001124
khenaidoodc2116e2021-10-19 17:33:19 -04001125 if err := dh.sendOmciIndicationToChildAdapter(ctx, childAdapterEndpoint, &ia.OmciMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001126 ParentDeviceId: proxyDeviceID,
1127 ChildDeviceId: deviceID,
1128 Message: omciInd.Pkt,
1129 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301130 return olterrors.NewErrCommunication("omci-request", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001131 "source": dh.openOLT.config.AdapterEndpoint,
1132 "device-type": deviceType,
1133 "destination": childAdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001134 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001135 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001136 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001137 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301138}
1139
khenaidoo106c61a2021-08-11 18:05:46 -04001140// //ProcessInterAdapterMessage sends the proxied messages to the target device
1141// // If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1142// // is meant, and then send the unmarshalled omci message to this onu
khenaidoodc2116e2021-10-19 17:33:19 -04001143// func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ca.InterAdapterMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001144// logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
khenaidoodc2116e2021-10-19 17:33:19 -04001145// if msg.Header.Type == ca.InterAdapterMessageType_OMCI_REQUEST {
khenaidoo106c61a2021-08-11 18:05:46 -04001146// return dh.handleInterAdapterOmciMsg(ctx, msg)
1147// }
1148// return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1149// }
cuilin20187b2a8c32019-03-26 19:52:28 -07001150
kesavandb9f54fd2021-11-25 20:08:04 +05301151// ProxyOmciRequests sends the proxied OMCI message to the target device
1152func (dh *DeviceHandler) ProxyOmciRequests(ctx context.Context, omciMsgs *ia.OmciMessages) error {
1153 if omciMsgs.GetProxyAddress() == nil {
1154 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsgs.ChildDeviceId)
1155 if err != nil {
1156 return olterrors.NewErrNotFound("onu", log.Fields{
1157 "parent-device-id": dh.device.Id,
1158 "child-device-id": omciMsgs.ChildDeviceId}, err)
1159 }
1160 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1161 if err := dh.sendProxyOmciRequests(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsgs); err != nil {
1162 return olterrors.NewErrCommunication("send-failed", log.Fields{
1163 "parent-device-id": dh.device.Id,
1164 "child-device-id": omciMsgs.ChildDeviceId}, err)
1165 }
1166 } else {
1167 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsgs.ProxyAddress})
1168 if err := dh.sendProxyOmciRequests(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsgs); err != nil {
1169 return olterrors.NewErrCommunication("send-failed", log.Fields{
1170 "parent-device-id": dh.device.Id,
1171 "child-device-id": omciMsgs.ChildDeviceId}, err)
1172 }
1173 }
1174 return nil
1175}
1176
1177func (dh *DeviceHandler) sendProxyOmciRequests(ctx context.Context, onuDevice *voltha.Device, omciMsgs *ia.OmciMessages) error {
1178 var intfID uint32
1179 var onuID uint32
1180 var connectStatus common.ConnectStatus_Types
1181 if onuDevice != nil {
1182 intfID = onuDevice.ProxyAddress.GetChannelId()
1183 onuID = onuDevice.ProxyAddress.GetOnuId()
1184 connectStatus = onuDevice.ConnectStatus
1185 } else {
1186 intfID = omciMsgs.GetProxyAddress().GetChannelId()
1187 onuID = omciMsgs.GetProxyAddress().GetOnuId()
1188 connectStatus = omciMsgs.GetConnectStatus()
1189 }
1190 if connectStatus != voltha.ConnectStatus_REACHABLE {
1191 logger.Debugw(ctx, "onu-not-reachable--cannot-send-omci", log.Fields{"intf-id": intfID, "onu-id": onuID})
1192
1193 return olterrors.NewErrCommunication("unreachable", log.Fields{
1194 "intf-id": intfID,
1195 "onu-id": onuID}, nil)
1196 }
1197
1198 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1199 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
1200
1201 onuSecOmciMsgList := omciMsgs.GetMessages()
1202
1203 for _, onuSecOmciMsg := range onuSecOmciMsgList {
1204
1205 var omciMessage *oop.OmciMsg
1206 hexPkt := make([]byte, hex.EncodedLen(len(onuSecOmciMsg)))
1207 hex.Encode(hexPkt, onuSecOmciMsg)
1208 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1209
1210 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1211 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1212 //https://jira.opencord.org/browse/VOL-4604
1213 transid := extractOmciTransactionID(onuSecOmciMsg)
1214 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
1215 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
1216
1217 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
1218 if err != nil {
1219 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
1220 "intf-id": intfID,
1221 "onu-id": onuID,
1222 "message": omciMessage}, err)
1223 }
1224 }
1225 return nil
1226}
1227
khenaidoo106c61a2021-08-11 18:05:46 -04001228// ProxyOmciMessage sends the proxied OMCI message to the target device
khenaidoodc2116e2021-10-19 17:33:19 -04001229func (dh *DeviceHandler) ProxyOmciMessage(ctx context.Context, omciMsg *ia.OmciMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001230 logger.Debugw(ctx, "proxy-omci-message", log.Fields{"parent-device-id": omciMsg.ParentDeviceId, "child-device-id": omciMsg.ChildDeviceId, "proxy-address": omciMsg.ProxyAddress, "connect-status": omciMsg.ConnectStatus})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001231
1232 if omciMsg.GetProxyAddress() == nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001233 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsg.ChildDeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001234 if err != nil {
1235 return olterrors.NewErrNotFound("onu", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001236 "parent-device-id": dh.device.Id,
1237 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001238 }
khenaidoo106c61a2021-08-11 18:05:46 -04001239 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1240 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001241 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001242 "parent-device-id": dh.device.Id,
1243 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001244 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001245 } else {
khenaidoo106c61a2021-08-11 18:05:46 -04001246 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsg.ProxyAddress})
1247 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001248 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001249 "parent-device-id": dh.device.Id,
1250 "child-device-id": omciMsg.ChildDeviceId}, err)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001251 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001252 }
1253 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301254}
1255
khenaidoodc2116e2021-10-19 17:33:19 -04001256func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ia.OmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001257 var intfID uint32
1258 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001259 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001260 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001261 intfID = onuDevice.ProxyAddress.GetChannelId()
1262 onuID = onuDevice.ProxyAddress.GetOnuId()
1263 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001264 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001265 intfID = omciMsg.GetProxyAddress().GetChannelId()
1266 onuID = omciMsg.GetProxyAddress().GetOnuId()
1267 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001268 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001269 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001270 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 -08001271
Thomas Lee S94109f12020-03-03 16:39:29 +05301272 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001273 "intf-id": intfID,
1274 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001275 }
1276
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001277 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1278 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
kesavandb9f54fd2021-11-25 20:08:04 +05301279 // https://jira.opencord.org/browse/VOL-4604
lcuie24ef182019-04-29 22:58:36 -07001280 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001281 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1282 hex.Encode(hexPkt, omciMsg.Message)
1283 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1284
1285 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1286 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1287 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001288 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001289 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001290
Neha Sharma8f4e4322020-08-06 10:51:53 +00001291 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001292 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301293 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001294 "intf-id": intfID,
1295 "onu-id": onuID,
1296 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001297 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001298 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001299}
1300
David K. Bainbridge794735f2020-02-11 21:01:37 -08001301func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301302 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 Gowdra197acc12021-08-16 10:59:45 -07001303 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001304 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001305 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001306 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301307 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301308 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001309 st, _ := status.FromError(err)
1310 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001311 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1312
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001313 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301314 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001315 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001316 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001317 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001318 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001319 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001320}
1321
Mahir Gunyelb0046752021-02-26 13:51:05 -08001322func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001323 channelID := onuDiscInd.GetIntfId()
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001324 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001325
Mahir Gunyelb0046752021-02-26 13:51:05 -08001326 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001327 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301328
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301329 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001330 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001331 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301332
1333 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1334 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1335 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1336 OnuLosRaise event sent for it */
1337 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1338 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1339 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001340 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301341 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1342 "currentIntfId": onuDiscInd.GetIntfId()})
1343 // TODO:: Should we need to ignore raising OnuLosClear event
1344 // when onu connected to different PON?
1345 }
1346 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1347 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1348 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001349 go func() {
1350 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001351 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001352 }
1353 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301354 }
1355 return true
1356 })
1357
Neha Sharma96b7bf22020-06-15 10:37:32 +00001358 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001359 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001360 }
1361
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001362 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001363
1364 // check the ONU is already know to the OLT
1365 // NOTE the second time the ONU is discovered this should return a device
khenaidoodc2116e2021-10-19 17:33:19 -04001366 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001367 ParentId: dh.device.Id,
1368 SerialNumber: sn,
1369 })
Matteo Scandolo945e4012019-12-12 14:16:11 -08001370
1371 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001372 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 -08001373 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001374 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 -08001375 switch e.Code() {
1376 case codes.Internal:
1377 // this probably means NOT FOUND, so just create a new device
1378 onuDevice = nil
1379 case codes.DeadlineExceeded:
1380 // if the call times out, cleanup and exit
1381 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001382 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001383 }
1384 }
1385 }
1386
1387 if onuDevice == nil {
1388 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001389 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001390 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001391 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001392 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001393
Neha Sharma96b7bf22020-06-15 10:37:32 +00001394 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001395
1396 if err != nil {
1397 // if we can't create an ID in resource manager,
1398 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001399 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001400 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001401 "pon-intf-id": ponintfid,
1402 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001403 }
1404
khenaidoodc2116e2021-10-19 17:33:19 -04001405 if onuDevice, err = dh.sendChildDeviceDetectedToCore(ctx, &ca.DeviceDiscovery{
khenaidoo106c61a2021-08-11 18:05:46 -04001406 ParentId: dh.device.Id,
1407 ParentPortNo: parentPortNo,
1408 ChannelId: channelID,
1409 VendorId: string(onuDiscInd.SerialNumber.GetVendorId()),
1410 SerialNumber: sn,
1411 OnuId: onuID,
1412 }); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001413 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001414 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 +05301415 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001416 "pon-intf-id": ponintfid,
1417 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001418 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001419 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 -07001420 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001421 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001422 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301423 log.Fields{"onuDevice": onuDevice,
1424 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001425 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301426 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001427 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001428
khenaidoo106c61a2021-08-11 18:05:46 -04001429 // Setup the gRPC connection to the adapter responsible for that onuDevice, if not setup yet
1430 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
1431 err = dh.setupChildInterAdapterClient(subCtx, onuDevice.AdapterEndpoint)
1432 cancel()
1433 if err != nil {
1434 return olterrors.NewErrCommunication("no-connection-to-child-adapter", log.Fields{"device-id": onuDevice.Id}, err)
1435 }
1436
Matteo Scandolo945e4012019-12-12 14:16:11 -08001437 // we can now use the existing ONU Id
1438 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001439 //Insert the ONU into cache to use in OnuIndication.
1440 //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 +00001441 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001442 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301443 "intfId": onuDiscInd.GetIntfId(),
1444 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001445 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001446
khenaidoo106c61a2021-08-11 18:05:46 -04001447 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301448 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001449 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301450 log.Fields{"onu": onuDev,
1451 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001452
khenaidoodc2116e2021-10-19 17:33:19 -04001453 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001454 DeviceId: onuDevice.Id,
1455 ParentDeviceId: dh.device.Id,
1456 OperStatus: common.OperStatus_DISCOVERED,
1457 ConnStatus: common.ConnectStatus_REACHABLE,
1458 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301459 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001460 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001461 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001462 }
khenaidoo106c61a2021-08-11 18:05:46 -04001463
Neha Sharma96b7bf22020-06-15 10:37:32 +00001464 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001465 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301466 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001467 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001468 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001469 }
1470 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001471}
1472
Mahir Gunyelb0046752021-02-26 13:51:05 -08001473func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001474
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001475 ponPort := plt.IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001476 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001477 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001478 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001479 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301480 log.Fields{"onuId": onuInd.OnuId,
1481 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301482 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001483 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001484 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301485
David K. Bainbridge794735f2020-02-11 21:01:37 -08001486 errFields := log.Fields{"device-id": dh.device.Id}
1487
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301488 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1489
Mahir Gunyele77977b2019-06-27 05:36:22 -07001490 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1491 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001492 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001493 onuDevice, err = dh.getDeviceFromCore(ctx, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001494 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001495 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1496 if serialNumber != "" {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001497 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001498 } else {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001499 errFields["onu-id"] = onuInd.OnuId
1500 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001501 }
khenaidoodc2116e2021-10-19 17:33:19 -04001502 onuDevice, err = dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001503 ParentId: dh.device.Id,
1504 SerialNumber: serialNumber,
1505 OnuId: onuInd.OnuId,
1506 ParentPortNo: ponPort,
1507 })
cuilin20187b2a8c32019-03-26 19:52:28 -07001508 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001509
David K. Bainbridge794735f2020-02-11 21:01:37 -08001510 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001511 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001512 }
1513
David K. Bainbridge794735f2020-02-11 21:01:37 -08001514 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001515 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001516 "previousIntfId": onuDevice.ParentPortNo,
1517 "currentIntfId": ponPort})
1518 }
1519
1520 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001521 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301522 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1523 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301524 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001525 }
1526 if !foundInCache {
1527 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1528
khenaidoo106c61a2021-08-11 18:05:46 -04001529 dh.onus.Store(onuKey, NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuInd.GetOnuId(), onuInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001530
1531 }
kesavand7cf3a052020-08-28 12:49:18 +05301532 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001533 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001534 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301535 }
1536 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001537 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001538 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001539 }
1540 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001541}
1542
Neha Sharma96b7bf22020-06-15 10:37:32 +00001543func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001544 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 -07001545 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1546 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1547 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1548 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001549 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001550 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1551 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001552 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001553 onuInd.OperState = "down"
1554 }
1555 }
1556
David K. Bainbridge794735f2020-02-11 21:01:37 -08001557 switch onuInd.OperState {
khenaidoo106c61a2021-08-11 18:05:46 -04001558 case "up", "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001559 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
khenaidoo106c61a2021-08-11 18:05:46 -04001560
khenaidoodc2116e2021-10-19 17:33:19 -04001561 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001562 DeviceId: onuDevice.Id,
1563 OnuIndication: onuInd,
1564 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001565 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301566 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001567 "onu-indicator": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001568 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001569 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001570 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001571 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001572 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001573 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001574 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001575 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001576}
1577
cuilin20187b2a8c32019-03-26 19:52:28 -07001578func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1579 if serialNum != nil {
1580 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001581 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001582 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001583}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001584func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1585 decodedStr, err := hex.DecodeString(serialNum[4:])
1586 if err != nil {
1587 return nil, err
1588 }
1589 return &oop.SerialNumber{
1590 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001591 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001592 }, nil
1593}
cuilin20187b2a8c32019-03-26 19:52:28 -07001594
1595func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001596 if len(vendorSpecific) > 3 {
1597 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1598 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1599 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1600 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1601 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1602 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1603 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1604 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1605 return tmp
1606 }
1607 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001608}
1609
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001610//UpdateFlowsBulk upates the bulk flow
1611func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301612 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001613}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001614
1615//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001616func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1617 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301618 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001619 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301620 "device-id": dh.device.Id})
khenaidoo106c61a2021-08-11 18:05:46 -04001621
khenaidoodc2116e2021-10-19 17:33:19 -04001622 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001623 ParentId: dh.device.Id,
1624 OnuId: onuID,
1625 ParentPortNo: parentPort,
1626 })
1627
Girish Gowdru0c588b22019-04-23 23:24:56 -04001628 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001629 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001630 "intf-id": parentPort,
1631 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001632 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001633 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 -08001634 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301635}
1636
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001637// SendPacketInToCore sends packet-in to core
1638// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1639// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001640func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001641 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001642 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001643 "port": logicalPort,
1644 "packet": hex.EncodeToString(packetPayload),
1645 "device-id": dh.device.Id,
1646 })
1647 }
khenaidoo106c61a2021-08-11 18:05:46 -04001648
khenaidoodc2116e2021-10-19 17:33:19 -04001649 if err := dh.sendPacketToCore(ctx, &ca.PacketIn{
khenaidoo106c61a2021-08-11 18:05:46 -04001650 DeviceId: dh.device.Id,
1651 Port: logicalPort,
1652 Packet: packetPayload,
1653 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301654 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001655 "source": "adapter",
1656 "destination": "core",
1657 "device-id": dh.device.Id,
1658 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001659 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001660 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001661 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001662 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001663 "packet": hex.EncodeToString(packetPayload),
1664 "device-id": dh.device.Id,
1665 })
1666 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001667 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001668}
1669
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001670// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001672 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001673
1674 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1675 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001676 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001677 }
1678
Kent Hagermane6ff1012020-07-14 15:07:53 -04001679 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001680 metrics := dh.metrics.GetSubscriberMetrics()
1681 for _, m := range pmConfigs.Metrics {
1682 metrics[m.Name].Enabled = m.Enabled
1683
1684 }
1685 }
1686}
1687
khenaidoodc2116e2021-10-19 17:33:19 -04001688func (dh *DeviceHandler) handleFlows(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, flowMetadata *of.FlowMetadata) []error {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001689 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001690 var errorsList []error
1691
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001692 if dh.getDeviceDeletionInProgressFlag() {
1693 // The device itself is going to be reset as part of deletion. So nothing to be done.
1694 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1695 return nil
1696 }
1697
Girish Gowdru0c588b22019-04-23 23:24:56 -04001698 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001699 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001700 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001701
Neha Sharma96b7bf22020-06-15 10:37:32 +00001702 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301703 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001704 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301705 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001706 if flow_utils.HasGroup(flow) {
1707 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1708 } else {
1709 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1710 }
Girish Gowdracefae192020-03-19 18:14:10 -07001711 if err != nil {
1712 errorsList = append(errorsList, err)
1713 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001714 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301715
1716 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001717 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001718 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301719 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001720 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301721 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001722 if flow_utils.HasGroup(flow) {
1723 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1724 } else {
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001725 if dh.flowMgr == nil || dh.flowMgr[ponIf] == nil {
1726 // The flow manager module could be uninitialized if the flow arrives too soon before the device has reconciled fully
1727 logger.Errorw(ctx, "flow-manager-uninitialized", log.Fields{"device-id": device.Id})
1728 err = fmt.Errorf("flow-manager-uninitialized-%v", device.Id)
1729 } else {
1730 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1731 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08001732 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001733 if err != nil {
1734 errorsList = append(errorsList, err)
1735 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301736 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001737 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001738
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001739 return errorsList
1740}
1741
1742func (dh *DeviceHandler) handleGroups(ctx context.Context, groups *of.FlowGroupChanges) []error {
1743 var err error
1744 var errorsList []error
1745
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001746 if dh.getDeviceDeletionInProgressFlag() {
1747 // The device itself is going to be reset as part of deletion. So nothing to be done.
1748 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": dh.device.Id})
1749 return nil
1750 }
1751
Girish Gowdracefae192020-03-19 18:14:10 -07001752 // 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 +00001753 if groups != nil {
1754 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001755 // err = dh.groupMgr.AddGroup(ctx, group)
1756 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001757 if err != nil {
1758 errorsList = append(errorsList, err)
1759 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001760 }
1761 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001762 // err = dh.groupMgr.ModifyGroup(ctx, group)
1763 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001764 if err != nil {
1765 errorsList = append(errorsList, err)
1766 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001767 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001768 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001769 // err = dh.groupMgr.DeleteGroup(ctx, group)
1770 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001771 if err != nil {
1772 errorsList = append(errorsList, err)
1773 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001774 }
1775 }
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001776
1777 return errorsList
1778}
1779
1780//UpdateFlowsIncrementally updates the device flow
khenaidoodc2116e2021-10-19 17:33:19 -04001781func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *of.FlowMetadata) error {
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001782
1783 var errorsList []error
Girish Gowdra950326e2021-11-05 12:43:24 -07001784
1785 if dh.getDeviceDeletionInProgressFlag() {
1786 // The device itself is going to be reset as part of deletion. So nothing to be done.
1787 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1788 return nil
1789 }
1790
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001791 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
1792 errorsList = append(errorsList, dh.handleFlows(ctx, device, flows, flowMetadata)...)
1793 errorsList = append(errorsList, dh.handleGroups(ctx, groups)...)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001794 if len(errorsList) > 0 {
1795 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1796 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001797 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001798 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301799}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001800
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001801//DisableDevice disables the given device
1802//It marks the following for the given device:
1803//Device-Handler Admin-State : down
1804//Device Port-State: UNKNOWN
1805//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001806func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001807 /* On device disable ,admin state update has to be done prior sending request to agent since
1808 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001809 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001810 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -0700