blob: 8248278e2b1f08644f84e5fbc8bd25c0ee015d6f [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"
Girish Gowdra0f3190e2022-02-11 14:18:28 -080026 "github.com/opencord/voltha-lib-go/v7/pkg/db"
27 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
cuilin20187b2a8c32019-03-26 19:52:28 -070028 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040029 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070030 "strconv"
31 "strings"
32 "sync"
33 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053034
khenaidoo106c61a2021-08-11 18:05:46 -040035 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
khenaidoo106c61a2021-08-11 18:05:46 -040036
Matteo Scandolo945e4012019-12-12 14:16:11 -080037 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070038 "github.com/gogo/protobuf/proto"
Girish Kumar93e91742020-07-27 16:43:19 +000039 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
40 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
khenaidoo106c61a2021-08-11 18:05:46 -040041 "github.com/opencord/voltha-lib-go/v7/pkg/config"
42 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
43 flow_utils "github.com/opencord/voltha-lib-go/v7/pkg/flows"
44 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyel85f61c12021-10-06 11:53:45 -070045 plt "github.com/opencord/voltha-lib-go/v7/pkg/platform"
khenaidoo106c61a2021-08-11 18:05:46 -040046 "github.com/opencord/voltha-lib-go/v7/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080047
khenaidoo106c61a2021-08-11 18:05:46 -040048 conf "github.com/opencord/voltha-openolt-adapter/internal/pkg/config"
Thomas Lee S94109f12020-03-03 16:39:29 +053049 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080050 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
khenaidoo106c61a2021-08-11 18:05:46 -040051 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoodc2116e2021-10-19 17:33:19 -040052 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo106c61a2021-08-11 18:05:46 -040053 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoodc2116e2021-10-19 17:33:19 -040054 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
55 "github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service"
khenaidoo106c61a2021-08-11 18:05:46 -040056 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
57 oop "github.com/opencord/voltha-protos/v5/go/openolt"
58 "github.com/opencord/voltha-protos/v5/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070059 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040060 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040061 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053062)
63
salmansiddiqui7ac62132019-08-22 03:58:50 +000064// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040065const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080066 InvalidPort = 0xffffffff
67 MaxNumOfGroupHandlerChannels = 256
68
69 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
70 McastFlowOrGroupModify = "McastFlowOrGroupModify"
71 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050072 oltPortInfoTimeout = 3
Elia Battiston596406d2022-02-02 12:19:00 +010073
74 defaultPortSpeedMbps = 1000
Manikkaraj kb1d51442019-07-23 10:41:02 -040075)
76
Phaneendra Manda4c62c802019-03-06 21:37:49 +053077//DeviceHandler will interact with the OLT device.
78type DeviceHandler struct {
khenaidoo106c61a2021-08-11 18:05:46 -040079 cm *config.ConfigManager
80 device *voltha.Device
81 cfg *conf.AdapterFlags
82 coreClient *vgrpc.Client
83 childAdapterClients map[string]*vgrpc.Client
84 lockChildAdapterClients sync.RWMutex
85 EventProxy eventif.EventProxy
86 openOLT *OpenOLT
khenaidooefff76e2021-12-15 16:51:30 -050087 exitChannel chan struct{}
khenaidoo106c61a2021-08-11 18:05:46 -040088 lockDevice sync.RWMutex
89 Client oop.OpenoltClient
90 transitionMap *TransitionMap
91 clientCon *grpc.ClientConn
92 flowMgr []*OpenOltFlowMgr
93 groupMgr *OpenOltGroupMgr
94 eventMgr *OpenOltEventMgr
95 resourceMgr []*rsrcMgr.OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070096
97 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +053098
Girish Gowdra3ab6d212020-03-24 17:33:15 -070099 discOnus sync.Map
100 onus sync.Map
101 portStats *OpenOltStatisticsMgr
102 metrics *pmmetrics.PmMetrics
103 stopCollector chan bool
104 stopHeartbeatCheck chan bool
105 activePorts sync.Map
106 stopIndications chan bool
107 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -0700108
Mahir Gunyelb0046752021-02-26 13:51:05 -0800109 totalPonPorts uint32
110 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
111 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800112
113 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
114 // 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 -0700115 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
116 stopMcastHandlerRoutine []chan bool
117 mcastHandlerRoutineActive []bool
Gamze Abakac2c32a62021-03-11 11:44:18 +0000118
119 adapterPreviouslyConnected bool
120 agentPreviouslyConnected bool
Girish Gowdra950326e2021-11-05 12:43:24 -0700121
122 isDeviceDeletionInProgress bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700123}
124
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700125//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700126type OnuDevice struct {
khenaidoo106c61a2021-08-11 18:05:46 -0400127 deviceID string
128 deviceType string
129 serialNumber string
130 onuID uint32
131 intfID uint32
132 proxyDeviceID string
133 losRaised bool
134 rdiRaised bool
135 adapterEndpoint string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700136}
137
Mahir Gunyelb0046752021-02-26 13:51:05 -0800138type onuIndicationMsg struct {
139 ctx context.Context
140 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800141}
142
143type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800144 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800145 stopChannel chan struct{}
146}
147
Girish Gowdra491a9c62021-01-06 16:43:07 -0800148//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
149//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
150//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
151//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
152type McastFlowOrGroupControlBlock struct {
khenaidoodc2116e2021-10-19 17:33:19 -0400153 ctx context.Context // Flow/group handler context
154 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
155 flow *of.OfpFlowStats // Flow message (can be nil or valid flow)
156 group *of.OfpGroupEntry // Group message (can be nil or valid group)
157 errChan *chan error // channel to report the mcast Flow/group handling error
Girish Gowdra491a9c62021-01-06 16:43:07 -0800158}
159
Naga Manjunath7615e552019-10-11 22:35:47 +0530160var pmNames = []string{
161 "rx_bytes",
162 "rx_packets",
163 "rx_mcast_packets",
164 "rx_bcast_packets",
165 "tx_bytes",
166 "tx_packets",
167 "tx_mcast_packets",
168 "tx_bcast_packets",
169}
170
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700171//NewOnuDevice creates a new Onu Device
khenaidoo106c61a2021-08-11 18:05:46 -0400172func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool, adapterEndpoint string) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700173 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700174 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700175 device.deviceType = deviceTp
176 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700177 device.onuID = onuID
178 device.intfID = intfID
179 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530180 device.losRaised = losRaised
khenaidoo106c61a2021-08-11 18:05:46 -0400181 device.adapterEndpoint = adapterEndpoint
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700182 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530183}
184
185//NewDeviceHandler creates a new device handler
khenaidoo106c61a2021-08-11 18:05:46 -0400186func 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 -0700187 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800188 dh.cm = cm
khenaidoo106c61a2021-08-11 18:05:46 -0400189 dh.coreClient = cc
Devmalya Paulfb990a52019-07-09 10:01:49 -0400190 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700191 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700192 dh.device = cloned
193 dh.openOLT = adapter
khenaidooefff76e2021-12-15 16:51:30 -0500194 dh.exitChannel = make(chan struct{})
cuilin20187b2a8c32019-03-26 19:52:28 -0700195 dh.lockDevice = sync.RWMutex{}
Girish Gowdraae56c722021-11-22 14:31:11 -0800196 dh.stopCollector = make(chan bool, 2) // TODO: Why buffered?
197 dh.stopHeartbeatCheck = make(chan bool, 2) // TODO: Why buffered?
Naga Manjunath7615e552019-10-11 22:35:47 +0530198 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 -0500199 dh.activePorts = sync.Map{}
Girish Gowdraae56c722021-11-22 14:31:11 -0800200 dh.stopIndications = make(chan bool, 1) // TODO: Why buffered?
Mahir Gunyelb0046752021-02-26 13:51:05 -0800201 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
khenaidoo106c61a2021-08-11 18:05:46 -0400202 dh.childAdapterClients = make(map[string]*vgrpc.Client)
203 dh.cfg = cfg
Girish Gowdra491a9c62021-01-06 16:43:07 -0800204 // Create a slice of buffered channels for handling concurrent mcast flow/group.
205 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700206 dh.stopMcastHandlerRoutine = make([]chan bool, MaxNumOfGroupHandlerChannels)
207 dh.mcastHandlerRoutineActive = make([]bool, MaxNumOfGroupHandlerChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800208 for i := range dh.incomingMcastFlowOrGroup {
209 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdraae56c722021-11-22 14:31:11 -0800210 dh.stopMcastHandlerRoutine[i] = make(chan bool)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800211 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
212 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
213 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
214 // for incoming mcast flow/group to be processed serially.
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700215 dh.mcastHandlerRoutineActive[i] = true
216 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
Girish Gowdra491a9c62021-01-06 16:43:07 -0800217 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700218 //TODO initialize the support classes.
219 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530220}
221
222// start save the device to the data model
223func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700224 dh.lockDevice.Lock()
225 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000226 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700227 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000228 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530229}
230
khenaidooefff76e2021-12-15 16:51:30 -0500231// Stop stops the device handler
232func (dh *DeviceHandler) Stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700233 dh.lockDevice.Lock()
234 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000235 logger.Debug(ctx, "stopping-device-agent")
khenaidooefff76e2021-12-15 16:51:30 -0500236 close(dh.exitChannel)
khenaidoo106c61a2021-08-11 18:05:46 -0400237
khenaidooefff76e2021-12-15 16:51:30 -0500238 // Delete (which will stop also) all grpc connections to the child adapters
239 dh.deleteAdapterClients(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000240 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530241}
242
ssiddiqui04386ee2021-08-23 21:58:25 +0530243func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
244 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
245 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
246 if pooledIntfID == intfID {
247 return resourceRanges.GetTechnology()
248 }
249 }
250 }
251 return ""
252}
253
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400254func macifyIP(ip net.IP) string {
255 if len(ip) > 0 {
256 oct1 := strconv.FormatInt(int64(ip[12]), 16)
257 oct2 := strconv.FormatInt(int64(ip[13]), 16)
258 oct3 := strconv.FormatInt(int64(ip[14]), 16)
259 oct4 := strconv.FormatInt(int64(ip[15]), 16)
260 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
261 }
262 return ""
263}
264
Neha Sharma96b7bf22020-06-15 10:37:32 +0000265func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400266 var genmac string
267 var addr net.IP
268 var ips []string
269 var err error
270
Neha Sharma96b7bf22020-06-15 10:37:32 +0000271 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400272
273 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000274 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400275
276 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000277 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400278 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000279 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400280 }
281 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000282 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530283 log.Fields{"host": ips[0],
284 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400285 return genmac, nil
286 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000287 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400288 }
289
290 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000291 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530292 log.Fields{"host": host,
293 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400294 return genmac, nil
295}
296
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530297func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700298 slist := strings.Split(mac, ":")
299 result := make([]uint32, len(slist))
300 var err error
301 var tmp int64
302 for index, val := range slist {
303 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
304 return []uint32{1, 2, 3, 4, 5, 6}
305 }
306 result[index] = uint32(tmp)
307 }
308 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530309}
310
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700311//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 -0800312func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530313
David K. Bainbridge794735f2020-02-11 21:01:37 -0800314 switch portType {
315 case voltha.Port_ETHERNET_NNI:
316 return fmt.Sprintf("nni-%d", portNum), nil
317 case voltha.Port_PON_OLT:
318 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700319 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800320
Girish Kumarf26e4882020-03-05 06:49:10 +0000321 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530322}
323
Elia Battiston596406d2022-02-02 12:19:00 +0100324func makeOfpPort(macAddress string, speedMbps uint32) *of.OfpPort {
325 if speedMbps == 0 {
326 //In case it was not set in the indication
327 //and no other value was provided
328 speedMbps = defaultPortSpeedMbps
329 }
330
331 ofpPortSpeed := of.OfpPortFeatures_OFPPF_OTHER
332 switch speedMbps {
333 case 1000000:
334 ofpPortSpeed = of.OfpPortFeatures_OFPPF_1TB_FD
335 case 100000:
336 ofpPortSpeed = of.OfpPortFeatures_OFPPF_100GB_FD
337 case 40000:
338 ofpPortSpeed = of.OfpPortFeatures_OFPPF_40GB_FD
339 case 10000:
340 ofpPortSpeed = of.OfpPortFeatures_OFPPF_10GB_FD
341 case 1000:
342 ofpPortSpeed = of.OfpPortFeatures_OFPPF_1GB_FD
343 case 100:
344 ofpPortSpeed = of.OfpPortFeatures_OFPPF_100MB_FD
345 case 10:
346 ofpPortSpeed = of.OfpPortFeatures_OFPPF_10MB_FD
347 }
348
349 capacity := uint32(ofpPortSpeed | of.OfpPortFeatures_OFPPF_FIBER)
350
351 port := &of.OfpPort{
352 HwAddr: macAddressToUint32Array(macAddress),
353 Config: 0,
354 State: uint32(of.OfpPortState_OFPPS_LIVE),
355 Curr: capacity,
356 Advertised: capacity,
357 Peer: capacity,
358 CurrSpeed: speedMbps * 1000, //kbps
359 MaxSpeed: speedMbps * 1000, //kbps
360 }
361
362 return port
363}
364
365func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string, speedMbps uint32) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000366 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700367 if state == "up" {
368 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500369 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500370 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700371 } else {
372 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500373 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700374 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700375 portNum := plt.IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400376 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800377 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000378 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400379 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500380
khenaidoo106c61a2021-08-11 18:05:46 -0400381 // Check if port exists
khenaidoodc2116e2021-10-19 17:33:19 -0400382 port, err := dh.getPortFromCore(ctx, &ca.PortFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400383 DeviceId: dh.device.Id,
384 Port: portNum,
385 })
386 if err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000387 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
khenaidoodc2116e2021-10-19 17:33:19 -0400388 err = dh.updatePortStateInCore(ctx, &ca.PortState{
khenaidoo106c61a2021-08-11 18:05:46 -0400389 DeviceId: dh.device.Id,
390 PortType: portType,
391 PortNo: portNum,
392 OperStatus: operStatus})
393 if err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400394 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
395 "device-id": dh.device.Id,
396 "port-type": portType,
397 "port-number": portNum,
398 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500399 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400400 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500401 }
khenaidoo106c61a2021-08-11 18:05:46 -0400402
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400403 // Now create Port
khenaidoo106c61a2021-08-11 18:05:46 -0400404 port = &voltha.Port{
405 DeviceId: dh.device.Id,
cuilin20187b2a8c32019-03-26 19:52:28 -0700406 PortNo: portNum,
407 Label: label,
408 Type: portType,
409 OperStatus: operStatus,
Elia Battiston596406d2022-02-02 12:19:00 +0100410 OfpPort: makeOfpPort(dh.device.MacAddress, speedMbps),
cuilin20187b2a8c32019-03-26 19:52:28 -0700411 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000412 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700413 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400414 err = dh.createPortInCore(ctx, port)
415 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000416 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800417 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000418 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400419 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000420 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530421 return nil
422}
423
Kent Hagermane6ff1012020-07-14 15:07:53 -0400424func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -0400425 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530426 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400427 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
428 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530429 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800430 dh.lockDevice.Lock()
431 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530432 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530433}
434
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700435// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530436// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800437func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000438 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700439 defer func() {
440 dh.lockDevice.Lock()
441 dh.isReadIndicationRoutineActive = false
442 dh.lockDevice.Unlock()
443 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700444 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700445 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700446 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700447 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400448
David Bainbridgef5879ca2019-12-13 21:17:54 +0000449 // Create an exponential backoff around re-enabling indications. The
450 // maximum elapsed time for the back off is set to 0 so that we will
451 // continue to retry. The max interval defaults to 1m, but is set
452 // here for code clarity
453 indicationBackoff := backoff.NewExponentialBackOff()
454 indicationBackoff.MaxElapsedTime = 0
455 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700456
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700457 dh.lockDevice.Lock()
458 dh.isReadIndicationRoutineActive = true
459 dh.lockDevice.Unlock()
460
Girish Gowdra3f974912020-03-23 20:35:18 -0700461Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700462 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400463 select {
464 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000465 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700466 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400467 default:
468 indication, err := indications.Recv()
469 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000470 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530471 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530472 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400473 // Use an exponential back off to prevent getting into a tight loop
474 duration := indicationBackoff.NextBackOff()
475 if duration == backoff.Stop {
476 // If we reach a maximum then warn and reset the backoff
477 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000478 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530479 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530480 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400481 indicationBackoff.Reset()
482 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700483
484 // On failure process a backoff timer while watching for stopIndications
485 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700486 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700487 select {
488 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000489 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700490 if !backoffTimer.Stop() {
491 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700492 }
493 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700494 case <-backoffTimer.C:
495 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700496 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700497 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
498 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400499 }
500 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000501 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530502 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000503 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530504 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530505 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700506 // Close the stream, and re-initialize it
507 if err = indications.CloseSend(); err != nil {
508 // Ok to ignore here, because we landed here due to a problem on the stream
509 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000510 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530511 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530512 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700513 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000514 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700515 return err
516 }
517 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400518 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530519 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400520 // Reset backoff if we have a successful receive
521 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400522 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700523 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000524 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530525 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530526 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400527 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400528 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400529 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700530 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700531 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700532 // Close the send stream
533 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700534
Girish Gowdra3f974912020-03-23 20:35:18 -0700535 return nil
536}
537
538func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700539 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700540 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
541 if err != nil {
542 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
543 }
544 if indications == nil {
545 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
546 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700547 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700548 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400549}
550
551// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
552func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
553 switch indication.Data.(type) {
554 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
555 return true
556
557 default:
558 return false
559 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700560}
561
David K. Bainbridge794735f2020-02-11 21:01:37 -0800562func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700563 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000564 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530565 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530567 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700568 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000569 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000570 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530571 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000572 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800573 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000574 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800575 }
576 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577}
578
David K. Bainbridge794735f2020-02-11 21:01:37 -0800579// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530580func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700581 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700582 switch indication.Data.(type) {
583 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000584 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
585 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700586 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 -0800587 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400588 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800589 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700590 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000591 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
592 defer span.Finish()
593
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700594 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800595 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100596 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState(), defaultPortSpeedMbps); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400597 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800598 }
599 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000600 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700601 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000602 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
603 defer span.Finish()
604
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700605 intfOperInd := indication.GetIntfOperInd()
606 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800607 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100608 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState(), intfOperInd.GetSpeed()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400609 _ = 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 -0800610 }
611 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700612 } else if intfOperInd.GetType() == "pon" {
613 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
614 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800615 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100616 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState(), defaultPortSpeedMbps); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400617 _ = 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 -0800618 }
619 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000620 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700621 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000622 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530623 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530624 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700625 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000626 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
627 defer span.Finish()
628
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700629 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800631 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800632 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700633 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000634 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
635 defer span.Finish()
636
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700637 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000638 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800639 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800640 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700641 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000642 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
643 defer span.Finish()
644
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700645 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000646 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 -0800647 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000648 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400649 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800650 }
651 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700652 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000653 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
654 defer span.Finish()
655
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700656 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000657 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700658 "intf-type": pktInd.IntfId,
659 "intf-id": pktInd.IntfId,
660 "gem-port-id": pktInd.GemportId,
661 "port-no": pktInd.PortNo,
662 "device-id": dh.device.Id,
663 })
664
665 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000666 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700667 "intf-type": pktInd.IntfId,
668 "intf-id": pktInd.IntfId,
669 "gem-port-id": pktInd.GemportId,
670 "port-no": pktInd.PortNo,
671 "packet": hex.EncodeToString(pktInd.Pkt),
672 "device-id": dh.device.Id,
673 })
674 }
675
David K. Bainbridge794735f2020-02-11 21:01:37 -0800676 go func() {
677 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400678 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800679 }
680 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700681 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000682 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
683 defer span.Finish()
684
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700685 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700686 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700687 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000688 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
689 defer span.Finish()
690
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700691 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000692 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700693 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000694 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
695 defer span.Finish()
696
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700697 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000698 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
699 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700700 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530701}
702
703// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530704func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530705 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000706 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530707
Girish Gowdra618fa572021-09-01 17:19:29 -0700708 // instantiate the mcast handler routines.
709 for i := range dh.incomingMcastFlowOrGroup {
710 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
711 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
712 if !dh.mcastHandlerRoutineActive[i] {
713 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
714 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
715 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
716 // for incoming mcast flow/group to be processed serially.
717 dh.mcastHandlerRoutineActive[i] = true
718 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
719 }
720 }
721
Girish Gowdru0c588b22019-04-23 23:24:56 -0400722 // Synchronous call to update device state - this method is run in its own go routine
khenaidoodc2116e2021-10-19 17:33:19 -0400723 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400724 DeviceId: dh.device.Id,
725 OperStatus: voltha.OperStatus_ACTIVE,
726 ConnStatus: voltha.ConnectStatus_REACHABLE,
727 }); err != nil {
728 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400729 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000730
731 //Clear olt communication failure event
732 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
733 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700734 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000735 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
736
Gamze Abakac2c32a62021-03-11 11:44:18 +0000737 //check adapter and agent reconcile status
738 //reboot olt if needed (olt disconnection case)
739 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
740 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
741 log.Fields{
742 "device-id": dh.device.Id,
743 "adapter-status": dh.adapterPreviouslyConnected,
744 "agent-status": dh.agentPreviouslyConnected,
745 })
746 _ = dh.RebootDevice(ctx, dh.device)
747 }
748
Girish Gowdru0c588b22019-04-23 23:24:56 -0400749 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530750}
751
752// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530753func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000754 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400755
khenaidoo106c61a2021-08-11 18:05:46 -0400756 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400757 if err != nil || device == nil {
758 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000759 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400760 }
761
762 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400763
764 //Update the device oper state and connection status
765 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800766 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400767 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800768 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400769
khenaidoodc2116e2021-10-19 17:33:19 -0400770 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400771 DeviceId: cloned.Id,
772 OperStatus: cloned.OperStatus,
773 ConnStatus: cloned.ConnectStatus,
774 }); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000775 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400776 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400777
778 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -0400779 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400780 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000781 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400782 }
783 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400784 // Update onu state as down in onu adapter
785 onuInd := oop.OnuIndication{}
786 onuInd.OperState = "down"
khenaidoo106c61a2021-08-11 18:05:46 -0400787
788 ogClient, err := dh.getChildAdapterServiceClient(onuDevice.AdapterEndpoint)
789 if err != nil {
790 return err
791 }
792 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
khenaidoodc2116e2021-10-19 17:33:19 -0400793 _, err = ogClient.OnuIndication(subCtx, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -0400794 DeviceId: onuDevice.Id,
795 OnuIndication: &onuInd,
796 })
797 cancel()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800798 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400799 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -0400800 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800801 "onu-indicator": onuInd,
802 "device-type": onuDevice.Type,
803 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700804 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800805 } else {
806 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 -0700807 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400808 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800809 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700810 /* Discovered ONUs entries need to be cleared , since after OLT
811 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530812 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800813 dh.lockDevice.Unlock()
814
Neha Sharma96b7bf22020-06-15 10:37:32 +0000815 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700816 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530817}
818
819// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530820func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400821 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000822
823 // if the connection is already available, close the previous connection (olt reboot case)
824 if dh.clientCon != nil {
825 if err = dh.clientCon.Close(); err != nil {
826 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
827 } else {
828 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
829 }
830 }
831
832 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000833 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
834 grpc.WithInsecure(),
835 grpc.WithBlock(),
836 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000837 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000838 )),
839 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000840 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000841 )))
842
843 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530844 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530845 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000846 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400847 }
848 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530849}
850
851// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530852func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400853 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530854 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400855 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530856}
857
858// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530859func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530860 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000861 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400862
863 // Case where OLT is disabled and then rebooted.
khenaidoo106c61a2021-08-11 18:05:46 -0400864 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Thomas Lee S985938d2020-05-04 11:40:41 +0530865 if err != nil || device == nil {
866 /*TODO: needs to handle error scenarios */
867 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
868 }
869 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000870 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400871
872 cloned := proto.Clone(device).(*voltha.Device)
873 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
874 cloned.OperStatus = voltha.OperStatus_UNKNOWN
875 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -0400876
khenaidoodc2116e2021-10-19 17:33:19 -0400877 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400878 DeviceId: cloned.Id,
879 OperStatus: cloned.OperStatus,
880 ConnStatus: cloned.ConnectStatus,
881 }); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530882 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 -0400883 }
884
Chaitrashree G S44124192019-08-07 20:21:36 -0400885 // 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 +0530886 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400887 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530888 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400889 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400890 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
891 // all the modules initialized and ready to handle incoming ONUs.
892
Thomas Lee S985938d2020-05-04 11:40:41 +0530893 err = dh.initializeDeviceHandlerModules(ctx)
894 if err != nil {
895 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 -0400896 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400897
898 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800899 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530900 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400901 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800902 }
903 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700904
905 go startHeartbeatCheck(ctx, dh)
906
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400907 return nil
908 }
909
khenaidoo106c61a2021-08-11 18:05:46 -0400910 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400911 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400912 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400913 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400914 }
khenaidoo106c61a2021-08-11 18:05:46 -0400915 dh.populateActivePorts(ctx, ports.Items)
916 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400917 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400918 }
919
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400920 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530921 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 -0400922 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530923
cuilin20187b2a8c32019-03-26 19:52:28 -0700924 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800925 go func() {
926 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400927 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800928 }
929 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000930 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000931
932 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000933 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000934 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700935
936 go startHeartbeatCheck(ctx, dh)
937
cuilin20187b2a8c32019-03-26 19:52:28 -0700938 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530939}
940
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400941func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700942 var err error
943 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400944
945 if err != nil {
946 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
947 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700948 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
949 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
yasin saplid0566272021-12-21 09:10:30 +0000950 // +1 is for NNI
951 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts+1)
952 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts+1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700953 var i uint32
yasin saplid0566272021-12-21 09:10:30 +0000954 // Index from 0 to until totalPonPorts ( Ex: 0 .. 15 ) -> PonPort Managers
955 // Index totalPonPorts ( Ex: 16 ) -> NniPort Manager
956 // There is only one NNI manager since multiple NNI is not supported for now
957 for i = 0; i < dh.totalPonPorts+1; i++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700958 // Instantiate resource manager
959 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 -0700960 return olterrors.ErrResourceManagerInstantiating
961 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400962 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700963 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
964 // the KV store to manage mcast group data. Provide the first instance (0th index)
965 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
966 return olterrors.ErrGroupManagerInstantiating
967 }
yasin saplid0566272021-12-21 09:10:30 +0000968 for i = 0; i < dh.totalPonPorts+1; i++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700969 // Instantiate flow manager
970 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
971 return olterrors.ErrFlowManagerInstantiating
972 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700973 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700974 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400975 /* TODO: Instantiate Alarm , stats , BW managers */
976 /* Instantiating Event Manager to handle Alarms and KPIs */
977 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
978
979 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000980 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400981
982 return nil
983
984}
985
Neha Sharma96b7bf22020-06-15 10:37:32 +0000986func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400987 var err error
988 var deviceInfo *oop.DeviceInfo
989
Neha Sharma8f4e4322020-08-06 10:51:53 +0000990 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400991
992 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000993 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400994 }
995 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000996 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400997 }
998
Neha Sharma96b7bf22020-06-15 10:37:32 +0000999 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001000 dh.device.Root = true
1001 dh.device.Vendor = deviceInfo.Vendor
1002 dh.device.Model = deviceInfo.Model
1003 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
1004 dh.device.HardwareVersion = deviceInfo.HardwareVersion
1005 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
1006
1007 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001008 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001009 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +00001010 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001011 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001012 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001013 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001014 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001015 dh.device.MacAddress = genmac
1016 } else {
1017 dh.device.MacAddress = deviceInfo.DeviceId
1018 }
1019
1020 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -04001021 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001022 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001023 }
1024
1025 return deviceInfo, nil
1026}
1027
Neha Sharma96b7bf22020-06-15 10:37:32 +00001028func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001029 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +05301030 for {
1031 select {
1032 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +00001033 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +05301034 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001035 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -07001036
khenaidoo106c61a2021-08-11 18:05:46 -04001037 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001038 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001039 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001040 continue
1041 }
khenaidoo106c61a2021-08-11 18:05:46 -04001042 for _, port := range ports.Items {
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301043 // NNI Stats
1044 if port.Type == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001045 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301046 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001047 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001048 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001049 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301050 }
1051 // PON Stats
1052 if port.Type == voltha.Port_PON_OLT {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001053 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301054 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
1055 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001056 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001057 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301058 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001059 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001060
yasin sapli9e4c5092022-02-01 13:52:33 +00001061 onuGemInfoLst := dh.resourceMgr[intfID].GetOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001062 if len(onuGemInfoLst) > 0 {
1063 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001064 }
Chaitrashree G Sef088112020-02-03 21:39:27 -05001065 }
Naga Manjunath7615e552019-10-11 22:35:47 +05301066 }
1067 }
1068 }
1069}
1070
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001071//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +05301072func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001073 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001074 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +05301075 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +05301076
1077 // Now, set the initial PM configuration for that device
khenaidoo106c61a2021-08-11 18:05:46 -04001078 cgClient, err := dh.coreClient.GetCoreServiceClient()
1079 if err != nil {
1080 logger.Errorw(ctx, "no-core-connection", log.Fields{"device-id": dh.device.Id, "error": err})
1081 return
1082 }
1083
1084 // Now, set the initial PM configuration for that device
1085 if _, err := cgClient.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001086 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +05301087 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301088}
1089
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001090//GetOfpDeviceInfo Gets the Ofp information of the given device
khenaidoodc2116e2021-10-19 17:33:19 -04001091func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ca.SwitchCapability, error) {
1092 return &ca.SwitchCapability{
cuilin20187b2a8c32019-03-26 19:52:28 -07001093 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301094 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001095 HwDesc: "open_pon",
1096 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001097 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001098 },
1099 SwitchFeatures: &of.OfpSwitchFeatures{
1100 NBuffers: 256,
1101 NTables: 2,
1102 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1103 of.OfpCapabilities_OFPC_TABLE_STATS |
1104 of.OfpCapabilities_OFPC_PORT_STATS |
1105 of.OfpCapabilities_OFPC_GROUP_STATS),
1106 },
1107 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301108}
1109
khenaidoo106c61a2021-08-11 18:05:46 -04001110// GetTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
khenaidoodc2116e2021-10-19 17:33:19 -04001111func (dh *DeviceHandler) GetTechProfileDownloadMessage(ctx context.Context, request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001112 ifID, err := plt.IntfIDFromPonPortNum(ctx, request.ParentPonPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001113 if err != nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001114 return nil, err
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001115 }
khenaidoo106c61a2021-08-11 18:05:46 -04001116 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001117}
1118
Neha Sharma96b7bf22020-06-15 10:37:32 +00001119func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001120 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 -07001121 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001122 var deviceID string
1123 var proxyDeviceID string
khenaidoo106c61a2021-08-11 18:05:46 -04001124 var childAdapterEndpoint string
cuilin20187b2a8c32019-03-26 19:52:28 -07001125
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001126 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001127 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001128 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 -07001129 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1130 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001131
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001132 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301133
1134 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1135
Neha Sharma96b7bf22020-06-15 10:37:32 +00001136 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 -07001137 ponPort := plt.IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
cuilin20187b2a8c32019-03-26 19:52:28 -07001138
khenaidoodc2116e2021-10-19 17:33:19 -04001139 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001140 ParentId: dh.device.Id,
1141 OnuId: omciInd.OnuId,
1142 ParentPortNo: ponPort,
1143 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001144 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301145 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001146 "intf-id": omciInd.IntfId,
1147 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001148 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001149 deviceType = onuDevice.Type
1150 deviceID = onuDevice.Id
1151 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
khenaidoo106c61a2021-08-11 18:05:46 -04001152 childAdapterEndpoint = onuDevice.AdapterEndpoint
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001153 //if not exist in cache, then add to cache.
khenaidoo106c61a2021-08-11 18:05:46 -04001154 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false, onuDevice.AdapterEndpoint))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001155 } else {
1156 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001157 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 +05301158 deviceType = onuInCache.(*OnuDevice).deviceType
1159 deviceID = onuInCache.(*OnuDevice).deviceID
1160 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001161 childAdapterEndpoint = onuInCache.(*OnuDevice).adapterEndpoint
cuilin20187b2a8c32019-03-26 19:52:28 -07001162 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001163
khenaidoodc2116e2021-10-19 17:33:19 -04001164 if err := dh.sendOmciIndicationToChildAdapter(ctx, childAdapterEndpoint, &ia.OmciMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001165 ParentDeviceId: proxyDeviceID,
1166 ChildDeviceId: deviceID,
1167 Message: omciInd.Pkt,
1168 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301169 return olterrors.NewErrCommunication("omci-request", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001170 "source": dh.openOLT.config.AdapterEndpoint,
1171 "device-type": deviceType,
1172 "destination": childAdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001173 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001174 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001175 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001176 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301177}
1178
khenaidoo106c61a2021-08-11 18:05:46 -04001179// //ProcessInterAdapterMessage sends the proxied messages to the target device
1180// // If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1181// // is meant, and then send the unmarshalled omci message to this onu
khenaidoodc2116e2021-10-19 17:33:19 -04001182// func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ca.InterAdapterMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001183// logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
khenaidoodc2116e2021-10-19 17:33:19 -04001184// if msg.Header.Type == ca.InterAdapterMessageType_OMCI_REQUEST {
khenaidoo106c61a2021-08-11 18:05:46 -04001185// return dh.handleInterAdapterOmciMsg(ctx, msg)
1186// }
1187// return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1188// }
cuilin20187b2a8c32019-03-26 19:52:28 -07001189
kesavandb9f54fd2021-11-25 20:08:04 +05301190// ProxyOmciRequests sends the proxied OMCI message to the target device
1191func (dh *DeviceHandler) ProxyOmciRequests(ctx context.Context, omciMsgs *ia.OmciMessages) error {
1192 if omciMsgs.GetProxyAddress() == nil {
1193 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsgs.ChildDeviceId)
1194 if err != nil {
1195 return olterrors.NewErrNotFound("onu", log.Fields{
1196 "parent-device-id": dh.device.Id,
1197 "child-device-id": omciMsgs.ChildDeviceId}, err)
1198 }
1199 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1200 if err := dh.sendProxyOmciRequests(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsgs); err != nil {
1201 return olterrors.NewErrCommunication("send-failed", log.Fields{
1202 "parent-device-id": dh.device.Id,
1203 "child-device-id": omciMsgs.ChildDeviceId}, err)
1204 }
1205 } else {
1206 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsgs.ProxyAddress})
1207 if err := dh.sendProxyOmciRequests(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsgs); err != nil {
1208 return olterrors.NewErrCommunication("send-failed", log.Fields{
1209 "parent-device-id": dh.device.Id,
1210 "child-device-id": omciMsgs.ChildDeviceId}, err)
1211 }
1212 }
1213 return nil
1214}
1215
1216func (dh *DeviceHandler) sendProxyOmciRequests(ctx context.Context, onuDevice *voltha.Device, omciMsgs *ia.OmciMessages) error {
1217 var intfID uint32
1218 var onuID uint32
1219 var connectStatus common.ConnectStatus_Types
1220 if onuDevice != nil {
1221 intfID = onuDevice.ProxyAddress.GetChannelId()
1222 onuID = onuDevice.ProxyAddress.GetOnuId()
1223 connectStatus = onuDevice.ConnectStatus
1224 } else {
1225 intfID = omciMsgs.GetProxyAddress().GetChannelId()
1226 onuID = omciMsgs.GetProxyAddress().GetOnuId()
1227 connectStatus = omciMsgs.GetConnectStatus()
1228 }
1229 if connectStatus != voltha.ConnectStatus_REACHABLE {
1230 logger.Debugw(ctx, "onu-not-reachable--cannot-send-omci", log.Fields{"intf-id": intfID, "onu-id": onuID})
1231
1232 return olterrors.NewErrCommunication("unreachable", log.Fields{
1233 "intf-id": intfID,
1234 "onu-id": onuID}, nil)
1235 }
1236
1237 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1238 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
1239
1240 onuSecOmciMsgList := omciMsgs.GetMessages()
1241
1242 for _, onuSecOmciMsg := range onuSecOmciMsgList {
1243
1244 var omciMessage *oop.OmciMsg
1245 hexPkt := make([]byte, hex.EncodedLen(len(onuSecOmciMsg)))
1246 hex.Encode(hexPkt, onuSecOmciMsg)
1247 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1248
1249 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1250 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1251 //https://jira.opencord.org/browse/VOL-4604
1252 transid := extractOmciTransactionID(onuSecOmciMsg)
1253 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
1254 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
1255
1256 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
1257 if err != nil {
1258 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
1259 "intf-id": intfID,
1260 "onu-id": onuID,
1261 "message": omciMessage}, err)
1262 }
1263 }
1264 return nil
1265}
1266
khenaidoo106c61a2021-08-11 18:05:46 -04001267// ProxyOmciMessage sends the proxied OMCI message to the target device
khenaidoodc2116e2021-10-19 17:33:19 -04001268func (dh *DeviceHandler) ProxyOmciMessage(ctx context.Context, omciMsg *ia.OmciMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001269 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 -07001270
1271 if omciMsg.GetProxyAddress() == nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001272 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsg.ChildDeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001273 if err != nil {
1274 return olterrors.NewErrNotFound("onu", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001275 "parent-device-id": dh.device.Id,
1276 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001277 }
khenaidoo106c61a2021-08-11 18:05:46 -04001278 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1279 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001280 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001281 "parent-device-id": dh.device.Id,
1282 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001283 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001284 } else {
khenaidoo106c61a2021-08-11 18:05:46 -04001285 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsg.ProxyAddress})
1286 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001287 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001288 "parent-device-id": dh.device.Id,
1289 "child-device-id": omciMsg.ChildDeviceId}, err)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001290 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001291 }
1292 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301293}
1294
khenaidoodc2116e2021-10-19 17:33:19 -04001295func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ia.OmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001296 var intfID uint32
1297 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001298 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001299 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001300 intfID = onuDevice.ProxyAddress.GetChannelId()
1301 onuID = onuDevice.ProxyAddress.GetOnuId()
1302 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001303 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001304 intfID = omciMsg.GetProxyAddress().GetChannelId()
1305 onuID = omciMsg.GetProxyAddress().GetOnuId()
1306 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001307 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001308 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001309 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 -08001310
Thomas Lee S94109f12020-03-03 16:39:29 +05301311 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001312 "intf-id": intfID,
1313 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001314 }
1315
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001316 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1317 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
kesavandb9f54fd2021-11-25 20:08:04 +05301318 // https://jira.opencord.org/browse/VOL-4604
lcuie24ef182019-04-29 22:58:36 -07001319 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001320 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1321 hex.Encode(hexPkt, omciMsg.Message)
1322 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1323
1324 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1325 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1326 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001327 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001328 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001329
Neha Sharma8f4e4322020-08-06 10:51:53 +00001330 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001331 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301332 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001333 "intf-id": intfID,
1334 "onu-id": onuID,
1335 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001336 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001337 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001338}
1339
David K. Bainbridge794735f2020-02-11 21:01:37 -08001340func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301341 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})
yasin saplibddc2d72022-02-08 13:10:17 +00001342 if err := dh.resourceMgr[intfID].AddNewOnuGemInfoToCacheAndKvStore(ctx, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001343 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001344 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001345 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301346 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301347 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001348 st, _ := status.FromError(err)
1349 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001350 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1351
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001352 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301353 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001354 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001355 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001356 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001357 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001358 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001359}
1360
Mahir Gunyelb0046752021-02-26 13:51:05 -08001361func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001362 channelID := onuDiscInd.GetIntfId()
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001363 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001364
Mahir Gunyelb0046752021-02-26 13:51:05 -08001365 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001366 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301367
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301368 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001369 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001370 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301371
1372 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1373 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1374 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1375 OnuLosRaise event sent for it */
1376 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1377 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1378 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001379 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301380 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1381 "currentIntfId": onuDiscInd.GetIntfId()})
1382 // TODO:: Should we need to ignore raising OnuLosClear event
1383 // when onu connected to different PON?
1384 }
1385 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1386 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1387 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001388 go func() {
1389 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001390 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001391 }
1392 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301393 }
1394 return true
1395 })
1396
Neha Sharma96b7bf22020-06-15 10:37:32 +00001397 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001398 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001399 }
1400
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001401 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001402
1403 // check the ONU is already know to the OLT
1404 // NOTE the second time the ONU is discovered this should return a device
khenaidoodc2116e2021-10-19 17:33:19 -04001405 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001406 ParentId: dh.device.Id,
1407 SerialNumber: sn,
1408 })
Matteo Scandolo945e4012019-12-12 14:16:11 -08001409
1410 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001411 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 -08001412 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001413 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 -08001414 switch e.Code() {
1415 case codes.Internal:
1416 // this probably means NOT FOUND, so just create a new device
1417 onuDevice = nil
1418 case codes.DeadlineExceeded:
1419 // if the call times out, cleanup and exit
1420 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001421 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001422 }
1423 }
1424 }
1425
1426 if onuDevice == nil {
1427 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001428 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001429 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001430 ponintfid := onuDiscInd.GetIntfId()
yasin saplibddc2d72022-02-08 13:10:17 +00001431 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001432
Neha Sharma96b7bf22020-06-15 10:37:32 +00001433 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001434
1435 if err != nil {
1436 // if we can't create an ID in resource manager,
1437 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001438 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001439 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001440 "pon-intf-id": ponintfid,
1441 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001442 }
1443
khenaidoodc2116e2021-10-19 17:33:19 -04001444 if onuDevice, err = dh.sendChildDeviceDetectedToCore(ctx, &ca.DeviceDiscovery{
khenaidoo106c61a2021-08-11 18:05:46 -04001445 ParentId: dh.device.Id,
1446 ParentPortNo: parentPortNo,
1447 ChannelId: channelID,
1448 VendorId: string(onuDiscInd.SerialNumber.GetVendorId()),
1449 SerialNumber: sn,
1450 OnuId: onuID,
1451 }); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001452 dh.discOnus.Delete(sn)
yasin saplibddc2d72022-02-08 13:10:17 +00001453 dh.resourceMgr[ponintfid].FreeonuID(ctx, []uint32{onuID}) // NOTE I'm not sure this method is actually cleaning up the right thing
Thomas Lee S94109f12020-03-03 16:39:29 +05301454 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001455 "pon-intf-id": ponintfid,
1456 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001457 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001458 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 -07001459 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001460 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001461 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301462 log.Fields{"onuDevice": onuDevice,
1463 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001464 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301465 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001466 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001467
khenaidoo106c61a2021-08-11 18:05:46 -04001468 // Setup the gRPC connection to the adapter responsible for that onuDevice, if not setup yet
1469 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
1470 err = dh.setupChildInterAdapterClient(subCtx, onuDevice.AdapterEndpoint)
1471 cancel()
1472 if err != nil {
1473 return olterrors.NewErrCommunication("no-connection-to-child-adapter", log.Fields{"device-id": onuDevice.Id}, err)
1474 }
1475
Matteo Scandolo945e4012019-12-12 14:16:11 -08001476 // we can now use the existing ONU Id
1477 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001478 //Insert the ONU into cache to use in OnuIndication.
1479 //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 +00001480 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001481 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301482 "intfId": onuDiscInd.GetIntfId(),
1483 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001484 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001485
khenaidoo106c61a2021-08-11 18:05:46 -04001486 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301487 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001488 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301489 log.Fields{"onu": onuDev,
1490 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001491
khenaidoodc2116e2021-10-19 17:33:19 -04001492 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001493 DeviceId: onuDevice.Id,
1494 ParentDeviceId: dh.device.Id,
1495 OperStatus: common.OperStatus_DISCOVERED,
1496 ConnStatus: common.ConnectStatus_REACHABLE,
1497 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301498 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001499 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001500 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001501 }
khenaidoo106c61a2021-08-11 18:05:46 -04001502
Neha Sharma96b7bf22020-06-15 10:37:32 +00001503 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001504 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301505 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001506 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001507 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001508 }
1509 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001510}
1511
Mahir Gunyelb0046752021-02-26 13:51:05 -08001512func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001513
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001514 ponPort := plt.IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001515 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001516 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001517 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001518 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301519 log.Fields{"onuId": onuInd.OnuId,
1520 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301521 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001522 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001523 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301524
David K. Bainbridge794735f2020-02-11 21:01:37 -08001525 errFields := log.Fields{"device-id": dh.device.Id}
1526
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301527 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1528
Mahir Gunyele77977b2019-06-27 05:36:22 -07001529 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1530 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001531 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001532 onuDevice, err = dh.getDeviceFromCore(ctx, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001533 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001534 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1535 if serialNumber != "" {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001536 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001537 } else {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001538 errFields["onu-id"] = onuInd.OnuId
1539 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001540 }
khenaidoodc2116e2021-10-19 17:33:19 -04001541 onuDevice, err = dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001542 ParentId: dh.device.Id,
1543 SerialNumber: serialNumber,
1544 OnuId: onuInd.OnuId,
1545 ParentPortNo: ponPort,
1546 })
cuilin20187b2a8c32019-03-26 19:52:28 -07001547 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001548
David K. Bainbridge794735f2020-02-11 21:01:37 -08001549 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001550 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001551 }
1552
David K. Bainbridge794735f2020-02-11 21:01:37 -08001553 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001554 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001555 "previousIntfId": onuDevice.ParentPortNo,
1556 "currentIntfId": ponPort})
1557 }
1558
1559 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001560 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301561 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1562 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301563 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001564 }
1565 if !foundInCache {
1566 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1567
khenaidoo106c61a2021-08-11 18:05:46 -04001568 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 -08001569
1570 }
kesavand7cf3a052020-08-28 12:49:18 +05301571 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001572 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001573 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301574 }
1575 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001576 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001577 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001578 }
1579 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001580}
1581
Neha Sharma96b7bf22020-06-15 10:37:32 +00001582func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001583 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 -07001584 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1585 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1586 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1587 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001588 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001589 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1590 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001591 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001592 onuInd.OperState = "down"
1593 }
1594 }
1595
David K. Bainbridge794735f2020-02-11 21:01:37 -08001596 switch onuInd.OperState {
khenaidoo106c61a2021-08-11 18:05:46 -04001597 case "up", "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001598 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 -04001599
khenaidoodc2116e2021-10-19 17:33:19 -04001600 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001601 DeviceId: onuDevice.Id,
1602 OnuIndication: onuInd,
1603 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001604 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301605 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001606 "onu-indicator": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001607 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001608 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001609 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001610 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001611 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001612 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001613 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001614 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001615}
1616
cuilin20187b2a8c32019-03-26 19:52:28 -07001617func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1618 if serialNum != nil {
1619 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001620 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001621 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001622}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001623func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1624 decodedStr, err := hex.DecodeString(serialNum[4:])
1625 if err != nil {
1626 return nil, err
1627 }
1628 return &oop.SerialNumber{
1629 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001630 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001631 }, nil
1632}
cuilin20187b2a8c32019-03-26 19:52:28 -07001633
1634func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001635 if len(vendorSpecific) > 3 {
1636 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1637 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1638 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1639 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1640 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1641 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1642 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1643 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1644 return tmp
1645 }
1646 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001647}
1648
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001649//UpdateFlowsBulk upates the bulk flow
1650func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301651 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001652}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001653
1654//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001655func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1656 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301657 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001658 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301659 "device-id": dh.device.Id})
khenaidoo106c61a2021-08-11 18:05:46 -04001660
khenaidoodc2116e2021-10-19 17:33:19 -04001661 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001662 ParentId: dh.device.Id,
1663 OnuId: onuID,
1664 ParentPortNo: parentPort,
1665 })
1666
Girish Gowdru0c588b22019-04-23 23:24:56 -04001667 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001668 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001669 "intf-id": parentPort,
1670 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001671 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001672 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 -08001673 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301674}
1675
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001676// SendPacketInToCore sends packet-in to core
1677// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1678// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001679func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001680 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001681 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001682 "port": logicalPort,
1683 "packet": hex.EncodeToString(packetPayload),
1684 "device-id": dh.device.Id,
1685 })
1686 }
khenaidoo106c61a2021-08-11 18:05:46 -04001687
khenaidoodc2116e2021-10-19 17:33:19 -04001688 if err := dh.sendPacketToCore(ctx, &ca.PacketIn{
khenaidoo106c61a2021-08-11 18:05:46 -04001689 DeviceId: dh.device.Id,
1690 Port: logicalPort,
1691 Packet: packetPayload,
1692 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301693 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001694 "source": "adapter",
1695 "destination": "core",
1696 "device-id": dh.device.Id,
1697 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001698 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001699 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001700 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001701 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001702 "packet": hex.EncodeToString(packetPayload),
1703 "device-id": dh.device.Id,
1704 })
1705 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001706 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001707}
1708
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001709// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001710func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001711 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001712
1713 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1714 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001715 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001716 }
1717
Kent Hagermane6ff1012020-07-14 15:07:53 -04001718 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001719 metrics := dh.metrics.GetSubscriberMetrics()
1720 for _, m := range pmConfigs.Metrics {
1721 metrics[m.Name].Enabled = m.Enabled
1722
1723 }
1724 }
1725}
1726
khenaidoodc2116e2021-10-19 17:33:19 -04001727func (dh *DeviceHandler) handleFlows(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, flowMetadata *of.FlowMetadata) []error {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001728 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001729 var errorsList []error
1730
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001731 if dh.getDeviceDeletionInProgressFlag() {
1732 // The device itself is going to be reset as part of deletion. So nothing to be done.
1733 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1734 return nil
1735 }
1736
Girish Gowdru0c588b22019-04-23 23:24:56 -04001737 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001738 for _, flow := range flows.ToRemove.Items {
yasin saplid0566272021-12-21 09:10:30 +00001739 intfID := dh.getIntfIDFromFlow(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001740
Neha Sharma96b7bf22020-06-15 10:37:32 +00001741 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301742 log.Fields{"device-id": device.Id,
yasin saplid0566272021-12-21 09:10:30 +00001743 "intfId": intfID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301744 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001745 if flow_utils.HasGroup(flow) {
1746 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1747 } else {
yasin saplid0566272021-12-21 09:10:30 +00001748 err = dh.flowMgr[intfID].RouteFlowToOnuChannel(ctx, flow, false, nil)
Girish Gowdra491a9c62021-01-06 16:43:07 -08001749 }
Girish Gowdracefae192020-03-19 18:14:10 -07001750 if err != nil {
Elia Battiston2aaf4342022-02-07 15:16:38 +01001751 if werr, ok := err.(olterrors.WrappedError); ok && status.Code(werr.Unwrap()) == codes.NotFound {
1752 //The flow we want to remove is not there, there is no need to throw an error
1753 logger.Warnw(ctx, "flow-to-remove-not-found",
1754 log.Fields{
1755 "ponIf": intfID,
1756 "flowToRemove": flow,
1757 "error": err,
1758 })
1759 } else {
1760 errorsList = append(errorsList, err)
1761 }
Girish Gowdracefae192020-03-19 18:14:10 -07001762 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001763 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301764
1765 for _, flow := range flows.ToAdd.Items {
yasin saplid0566272021-12-21 09:10:30 +00001766 intfID := dh.getIntfIDFromFlow(ctx, flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001767 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301768 log.Fields{"device-id": device.Id,
yasin saplid0566272021-12-21 09:10:30 +00001769 "ponIf": intfID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301770 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001771 if flow_utils.HasGroup(flow) {
1772 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1773 } else {
yasin saplid0566272021-12-21 09:10:30 +00001774 if dh.flowMgr == nil || dh.flowMgr[intfID] == nil {
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001775 // The flow manager module could be uninitialized if the flow arrives too soon before the device has reconciled fully
1776 logger.Errorw(ctx, "flow-manager-uninitialized", log.Fields{"device-id": device.Id})
1777 err = fmt.Errorf("flow-manager-uninitialized-%v", device.Id)
1778 } else {
yasin saplid0566272021-12-21 09:10:30 +00001779 err = dh.flowMgr[intfID].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001780 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08001781 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001782 if err != nil {
1783 errorsList = append(errorsList, err)
1784 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301785 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001786 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001787
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001788 return errorsList
1789}
1790
1791func (dh *DeviceHandler) handleGroups(ctx context.Context, groups *of.FlowGroupChanges) []error {
1792 var err error
1793 var errorsList []error
1794
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001795 if dh.getDeviceDeletionInProgressFlag() {
1796 // The device itself is going to be reset as part of deletion. So nothing to be done.
1797 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": dh.device.Id})
1798 return nil
1799 }
1800
Girish Gowdracefae192020-03-19 18:14:10 -07001801 // 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 +00001802 if groups != nil {
1803 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001804 // err = dh.groupMgr.AddGroup(ctx, group)
1805 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001806 if err != nil {
1807 errorsList = append(errorsList, err)
1808 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001809 }
1810 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001811 // err = dh.groupMgr.ModifyGroup(ctx, group)
1812 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001813 if err != nil {
1814 errorsList = append(errorsList, err)
1815 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001816 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001817 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001818 // err = dh.groupMgr.DeleteGroup(ctx, group)