blob: bfdd3ee1b1f13195c97468190da1e5b4d0dbb019 [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"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040026 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070027 "strconv"
28 "strings"
29 "sync"
30 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053031
Elia Battiston599d25f2022-02-16 14:49:08 +010032 "github.com/opencord/voltha-lib-go/v7/pkg/db"
33 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
34
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()
Elia Battiston599d25f2022-02-16 14:49:08 +0100469
470 select {
471 case <-indications.Context().Done():
472 if err != nil {
473 logger.Warnw(ctx, "error-during-enable-indications",
474 log.Fields{"err": err,
475 "device-id": dh.device.Id})
476 }
477
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400478 // Use an exponential back off to prevent getting into a tight loop
479 duration := indicationBackoff.NextBackOff()
Elia Battiston599d25f2022-02-16 14:49:08 +0100480 logger.Infow(ctx, "backing-off-enable-indication", log.Fields{
481 "device-id": dh.device.Id,
482 "duration": duration,
483 })
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400484 if duration == backoff.Stop {
485 // If we reach a maximum then warn and reset the backoff
486 // timer and keep attempting.
Elia Battiston599d25f2022-02-16 14:49:08 +0100487 logger.Warnw(ctx, "maximum-indication-backoff-reached-resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530488 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530489 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400490 indicationBackoff.Reset()
491 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700492
493 // On failure process a backoff timer while watching for stopIndications
494 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700495 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700496 select {
497 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000498 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700499 if !backoffTimer.Stop() {
500 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700501 }
502 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700503 case <-backoffTimer.C:
504 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700505 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700506 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
507 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400508 }
509 continue
Elia Battiston599d25f2022-02-16 14:49:08 +0100510 default:
511 if err != nil {
512 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530513 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530514 "device-id": dh.device.Id})
Elia Battiston599d25f2022-02-16 14:49:08 +0100515 // Close the stream, and re-initialize it
516 if err = indications.CloseSend(); err != nil {
517 // Ok to ignore here, because we landed here due to a problem on the stream
518 // In all probability, the closeSend call may fail
519 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
520 log.Fields{"err": err,
521 "device-id": dh.device.Id})
522 }
523 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
524 return err
525 }
526 // once we re-initialized the indication stream, continue to read indications
527 continue
Girish Gowdra3f974912020-03-23 20:35:18 -0700528 }
Elia Battiston599d25f2022-02-16 14:49:08 +0100529 // Reset backoff if we have a successful receive
530 indicationBackoff.Reset()
531 // When OLT is admin down, ignore all indications.
532 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
533 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
534 log.Fields{"indication": indication,
535 "device-id": dh.device.Id})
536 continue
Girish Gowdra3f974912020-03-23 20:35:18 -0700537 }
Elia Battiston599d25f2022-02-16 14:49:08 +0100538 dh.handleIndication(ctx, indication)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530539 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700540 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700541 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700542 // Close the send stream
543 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700544
Girish Gowdra3f974912020-03-23 20:35:18 -0700545 return nil
546}
547
548func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700549 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700550 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
551 if err != nil {
552 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
553 }
554 if indications == nil {
555 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
556 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700557 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700558 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400559}
560
561// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
562func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
563 switch indication.Data.(type) {
564 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
565 return true
566
567 default:
568 return false
569 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700570}
571
David K. Bainbridge794735f2020-02-11 21:01:37 -0800572func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700573 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000574 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530575 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700576 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530577 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700578 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000579 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000580 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530581 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000582 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800583 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000584 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800585 }
586 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700587}
588
David K. Bainbridge794735f2020-02-11 21:01:37 -0800589// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530590func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700591 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700592 switch indication.Data.(type) {
593 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000594 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
595 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700596 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 -0800597 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400598 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800599 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700600 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000601 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
602 defer span.Finish()
603
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700604 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800605 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100606 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState(), defaultPortSpeedMbps); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400607 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800608 }
609 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000610 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700611 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000612 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
613 defer span.Finish()
614
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700615 intfOperInd := indication.GetIntfOperInd()
616 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800617 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100618 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState(), intfOperInd.GetSpeed()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400619 _ = 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 -0800620 }
621 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700622 } else if intfOperInd.GetType() == "pon" {
623 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
624 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800625 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100626 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState(), defaultPortSpeedMbps); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400627 _ = 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 -0800628 }
629 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700631 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000632 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530633 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530634 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700635 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000636 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
637 defer span.Finish()
638
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700639 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000640 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800641 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800642 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700643 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000644 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
645 defer span.Finish()
646
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700647 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000648 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800649 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800650 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700651 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000652 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
653 defer span.Finish()
654
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700655 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000656 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 -0800657 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000658 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400659 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800660 }
661 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700662 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000663 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
664 defer span.Finish()
665
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700666 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000667 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700668 "intf-type": pktInd.IntfId,
669 "intf-id": pktInd.IntfId,
670 "gem-port-id": pktInd.GemportId,
671 "port-no": pktInd.PortNo,
672 "device-id": dh.device.Id,
673 })
674
675 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000676 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700677 "intf-type": pktInd.IntfId,
678 "intf-id": pktInd.IntfId,
679 "gem-port-id": pktInd.GemportId,
680 "port-no": pktInd.PortNo,
681 "packet": hex.EncodeToString(pktInd.Pkt),
682 "device-id": dh.device.Id,
683 })
684 }
685
David K. Bainbridge794735f2020-02-11 21:01:37 -0800686 go func() {
687 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400688 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800689 }
690 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700691 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000692 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
693 defer span.Finish()
694
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700695 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700696 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700697 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000698 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
699 defer span.Finish()
700
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700701 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000702 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700703 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000704 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
705 defer span.Finish()
706
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700707 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000708 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
709 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700710 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530711}
712
713// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530714func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530715 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000716 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530717
Girish Gowdra618fa572021-09-01 17:19:29 -0700718 // instantiate the mcast handler routines.
719 for i := range dh.incomingMcastFlowOrGroup {
720 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
721 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
722 if !dh.mcastHandlerRoutineActive[i] {
723 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
724 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
725 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
726 // for incoming mcast flow/group to be processed serially.
727 dh.mcastHandlerRoutineActive[i] = true
728 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
729 }
730 }
731
Girish Gowdru0c588b22019-04-23 23:24:56 -0400732 // Synchronous call to update device state - this method is run in its own go routine
khenaidoodc2116e2021-10-19 17:33:19 -0400733 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400734 DeviceId: dh.device.Id,
735 OperStatus: voltha.OperStatus_ACTIVE,
736 ConnStatus: voltha.ConnectStatus_REACHABLE,
737 }); err != nil {
738 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400739 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000740
741 //Clear olt communication failure event
742 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
743 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700744 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000745 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
746
Gamze Abakac2c32a62021-03-11 11:44:18 +0000747 //check adapter and agent reconcile status
748 //reboot olt if needed (olt disconnection case)
749 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
750 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
751 log.Fields{
752 "device-id": dh.device.Id,
753 "adapter-status": dh.adapterPreviouslyConnected,
754 "agent-status": dh.agentPreviouslyConnected,
755 })
756 _ = dh.RebootDevice(ctx, dh.device)
757 }
758
Girish Gowdru0c588b22019-04-23 23:24:56 -0400759 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530760}
761
762// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530763func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000764 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400765
khenaidoo106c61a2021-08-11 18:05:46 -0400766 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400767 if err != nil || device == nil {
768 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000769 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400770 }
771
772 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400773
774 //Update the device oper state and connection status
775 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800776 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400777 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800778 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400779
khenaidoodc2116e2021-10-19 17:33:19 -0400780 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400781 DeviceId: cloned.Id,
782 OperStatus: cloned.OperStatus,
783 ConnStatus: cloned.ConnectStatus,
784 }); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000785 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400786 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400787
788 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -0400789 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400790 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000791 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400792 }
793 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400794 // Update onu state as down in onu adapter
795 onuInd := oop.OnuIndication{}
796 onuInd.OperState = "down"
khenaidoo106c61a2021-08-11 18:05:46 -0400797
798 ogClient, err := dh.getChildAdapterServiceClient(onuDevice.AdapterEndpoint)
799 if err != nil {
800 return err
801 }
802 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
khenaidoodc2116e2021-10-19 17:33:19 -0400803 _, err = ogClient.OnuIndication(subCtx, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -0400804 DeviceId: onuDevice.Id,
805 OnuIndication: &onuInd,
806 })
807 cancel()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800808 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400809 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -0400810 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800811 "onu-indicator": onuInd,
812 "device-type": onuDevice.Type,
813 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700814 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800815 } else {
816 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 -0700817 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400818 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800819 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700820 /* Discovered ONUs entries need to be cleared , since after OLT
821 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530822 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800823 dh.lockDevice.Unlock()
824
Neha Sharma96b7bf22020-06-15 10:37:32 +0000825 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700826 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530827}
828
829// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530830func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400831 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000832
833 // if the connection is already available, close the previous connection (olt reboot case)
834 if dh.clientCon != nil {
835 if err = dh.clientCon.Close(); err != nil {
836 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
837 } else {
838 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
839 }
840 }
841
842 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000843 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
844 grpc.WithInsecure(),
845 grpc.WithBlock(),
846 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000847 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000848 )),
849 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000850 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000851 )))
852
853 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530854 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530855 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000856 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400857 }
858 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530859}
860
861// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530862func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400863 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530864 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400865 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530866}
867
868// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530869func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530870 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000871 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400872
873 // Case where OLT is disabled and then rebooted.
khenaidoo106c61a2021-08-11 18:05:46 -0400874 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Thomas Lee S985938d2020-05-04 11:40:41 +0530875 if err != nil || device == nil {
876 /*TODO: needs to handle error scenarios */
877 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
878 }
879 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000880 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400881
882 cloned := proto.Clone(device).(*voltha.Device)
883 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
884 cloned.OperStatus = voltha.OperStatus_UNKNOWN
885 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -0400886
khenaidoodc2116e2021-10-19 17:33:19 -0400887 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400888 DeviceId: cloned.Id,
889 OperStatus: cloned.OperStatus,
890 ConnStatus: cloned.ConnectStatus,
891 }); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530892 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 -0400893 }
894
Chaitrashree G S44124192019-08-07 20:21:36 -0400895 // 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 +0530896 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400897 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530898 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400899 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400900 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
901 // all the modules initialized and ready to handle incoming ONUs.
902
Thomas Lee S985938d2020-05-04 11:40:41 +0530903 err = dh.initializeDeviceHandlerModules(ctx)
904 if err != nil {
905 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 -0400906 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400907
908 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800909 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530910 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400911 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800912 }
913 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700914
915 go startHeartbeatCheck(ctx, dh)
916
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400917 return nil
918 }
919
khenaidoo106c61a2021-08-11 18:05:46 -0400920 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400921 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400922 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400923 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400924 }
khenaidoo106c61a2021-08-11 18:05:46 -0400925 dh.populateActivePorts(ctx, ports.Items)
926 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400927 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400928 }
929
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400930 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530931 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 -0400932 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530933
cuilin20187b2a8c32019-03-26 19:52:28 -0700934 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800935 go func() {
936 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400937 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800938 }
939 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000940 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000941
942 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000943 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000944 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700945
946 go startHeartbeatCheck(ctx, dh)
947
cuilin20187b2a8c32019-03-26 19:52:28 -0700948 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530949}
950
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400951func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700952 var err error
953 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400954
955 if err != nil {
956 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
957 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700958 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
959 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
yasin saplid0566272021-12-21 09:10:30 +0000960 // +1 is for NNI
961 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts+1)
962 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts+1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700963 var i uint32
yasin saplid0566272021-12-21 09:10:30 +0000964 // Index from 0 to until totalPonPorts ( Ex: 0 .. 15 ) -> PonPort Managers
965 // Index totalPonPorts ( Ex: 16 ) -> NniPort Manager
966 // There is only one NNI manager since multiple NNI is not supported for now
967 for i = 0; i < dh.totalPonPorts+1; i++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700968 // Instantiate resource manager
969 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 -0700970 return olterrors.ErrResourceManagerInstantiating
971 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400972 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700973 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
974 // the KV store to manage mcast group data. Provide the first instance (0th index)
975 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
976 return olterrors.ErrGroupManagerInstantiating
977 }
yasin saplid0566272021-12-21 09:10:30 +0000978 for i = 0; i < dh.totalPonPorts+1; i++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700979 // Instantiate flow manager
980 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
981 return olterrors.ErrFlowManagerInstantiating
982 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700983 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700984 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400985 /* TODO: Instantiate Alarm , stats , BW managers */
986 /* Instantiating Event Manager to handle Alarms and KPIs */
987 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
988
989 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000990 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400991
992 return nil
993
994}
995
Neha Sharma96b7bf22020-06-15 10:37:32 +0000996func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400997 var err error
998 var deviceInfo *oop.DeviceInfo
999
Neha Sharma8f4e4322020-08-06 10:51:53 +00001000 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001001
1002 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001003 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001004 }
1005 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001006 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001007 }
1008
Neha Sharma96b7bf22020-06-15 10:37:32 +00001009 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001010 dh.device.Root = true
1011 dh.device.Vendor = deviceInfo.Vendor
1012 dh.device.Model = deviceInfo.Model
1013 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
1014 dh.device.HardwareVersion = deviceInfo.HardwareVersion
1015 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
1016
1017 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001018 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001019 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +00001020 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001021 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001022 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001023 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001024 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001025 dh.device.MacAddress = genmac
1026 } else {
1027 dh.device.MacAddress = deviceInfo.DeviceId
1028 }
1029
1030 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -04001031 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001032 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001033 }
1034
1035 return deviceInfo, nil
1036}
1037
Neha Sharma96b7bf22020-06-15 10:37:32 +00001038func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001039 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +05301040 for {
1041 select {
1042 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +00001043 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +05301044 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001045 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -07001046
khenaidoo106c61a2021-08-11 18:05:46 -04001047 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001048 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001049 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001050 continue
1051 }
khenaidoo106c61a2021-08-11 18:05:46 -04001052 for _, port := range ports.Items {
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301053 // NNI Stats
1054 if port.Type == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001055 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301056 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001057 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001058 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001059 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301060 }
1061 // PON Stats
1062 if port.Type == voltha.Port_PON_OLT {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001063 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301064 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
1065 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001066 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001067 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301068 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001069 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001070
yasin sapli9e4c5092022-02-01 13:52:33 +00001071 onuGemInfoLst := dh.resourceMgr[intfID].GetOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001072 if len(onuGemInfoLst) > 0 {
1073 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001074 }
Chaitrashree G Sef088112020-02-03 21:39:27 -05001075 }
Naga Manjunath7615e552019-10-11 22:35:47 +05301076 }
1077 }
1078 }
1079}
1080
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001081//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +05301082func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001083 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001084 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +05301085 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +05301086
1087 // Now, set the initial PM configuration for that device
khenaidoo106c61a2021-08-11 18:05:46 -04001088 cgClient, err := dh.coreClient.GetCoreServiceClient()
1089 if err != nil {
1090 logger.Errorw(ctx, "no-core-connection", log.Fields{"device-id": dh.device.Id, "error": err})
1091 return
1092 }
1093
1094 // Now, set the initial PM configuration for that device
1095 if _, err := cgClient.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001096 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +05301097 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301098}
1099
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001100//GetOfpDeviceInfo Gets the Ofp information of the given device
khenaidoodc2116e2021-10-19 17:33:19 -04001101func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ca.SwitchCapability, error) {
1102 return &ca.SwitchCapability{
cuilin20187b2a8c32019-03-26 19:52:28 -07001103 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301104 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001105 HwDesc: "open_pon",
1106 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001107 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001108 },
1109 SwitchFeatures: &of.OfpSwitchFeatures{
1110 NBuffers: 256,
1111 NTables: 2,
1112 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1113 of.OfpCapabilities_OFPC_TABLE_STATS |
1114 of.OfpCapabilities_OFPC_PORT_STATS |
1115 of.OfpCapabilities_OFPC_GROUP_STATS),
1116 },
1117 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301118}
1119
khenaidoo106c61a2021-08-11 18:05:46 -04001120// GetTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
khenaidoodc2116e2021-10-19 17:33:19 -04001121func (dh *DeviceHandler) GetTechProfileDownloadMessage(ctx context.Context, request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001122 ifID, err := plt.IntfIDFromPonPortNum(ctx, request.ParentPonPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001123 if err != nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001124 return nil, err
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001125 }
khenaidoo106c61a2021-08-11 18:05:46 -04001126 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001127}
1128
Neha Sharma96b7bf22020-06-15 10:37:32 +00001129func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001130 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 -07001131 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001132 var deviceID string
1133 var proxyDeviceID string
khenaidoo106c61a2021-08-11 18:05:46 -04001134 var childAdapterEndpoint string
cuilin20187b2a8c32019-03-26 19:52:28 -07001135
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001136 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001137 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001138 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 -07001139 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1140 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001141
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001142 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301143
1144 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1145
Neha Sharma96b7bf22020-06-15 10:37:32 +00001146 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 -07001147 ponPort := plt.IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
cuilin20187b2a8c32019-03-26 19:52:28 -07001148
khenaidoodc2116e2021-10-19 17:33:19 -04001149 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001150 ParentId: dh.device.Id,
1151 OnuId: omciInd.OnuId,
1152 ParentPortNo: ponPort,
1153 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001154 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301155 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001156 "intf-id": omciInd.IntfId,
1157 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001158 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001159 deviceType = onuDevice.Type
1160 deviceID = onuDevice.Id
1161 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
khenaidoo106c61a2021-08-11 18:05:46 -04001162 childAdapterEndpoint = onuDevice.AdapterEndpoint
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001163 //if not exist in cache, then add to cache.
khenaidoo106c61a2021-08-11 18:05:46 -04001164 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false, onuDevice.AdapterEndpoint))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001165 } else {
1166 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001167 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 +05301168 deviceType = onuInCache.(*OnuDevice).deviceType
1169 deviceID = onuInCache.(*OnuDevice).deviceID
1170 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001171 childAdapterEndpoint = onuInCache.(*OnuDevice).adapterEndpoint
cuilin20187b2a8c32019-03-26 19:52:28 -07001172 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001173
khenaidoodc2116e2021-10-19 17:33:19 -04001174 if err := dh.sendOmciIndicationToChildAdapter(ctx, childAdapterEndpoint, &ia.OmciMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001175 ParentDeviceId: proxyDeviceID,
1176 ChildDeviceId: deviceID,
1177 Message: omciInd.Pkt,
1178 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301179 return olterrors.NewErrCommunication("omci-request", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001180 "source": dh.openOLT.config.AdapterEndpoint,
1181 "device-type": deviceType,
1182 "destination": childAdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001183 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001184 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001185 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001186 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301187}
1188
khenaidoo106c61a2021-08-11 18:05:46 -04001189// //ProcessInterAdapterMessage sends the proxied messages to the target device
1190// // If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1191// // is meant, and then send the unmarshalled omci message to this onu
khenaidoodc2116e2021-10-19 17:33:19 -04001192// func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ca.InterAdapterMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001193// logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
khenaidoodc2116e2021-10-19 17:33:19 -04001194// if msg.Header.Type == ca.InterAdapterMessageType_OMCI_REQUEST {
khenaidoo106c61a2021-08-11 18:05:46 -04001195// return dh.handleInterAdapterOmciMsg(ctx, msg)
1196// }
1197// return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1198// }
cuilin20187b2a8c32019-03-26 19:52:28 -07001199
kesavandb9f54fd2021-11-25 20:08:04 +05301200// ProxyOmciRequests sends the proxied OMCI message to the target device
1201func (dh *DeviceHandler) ProxyOmciRequests(ctx context.Context, omciMsgs *ia.OmciMessages) error {
1202 if omciMsgs.GetProxyAddress() == nil {
1203 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsgs.ChildDeviceId)
1204 if err != nil {
1205 return olterrors.NewErrNotFound("onu", log.Fields{
1206 "parent-device-id": dh.device.Id,
1207 "child-device-id": omciMsgs.ChildDeviceId}, err)
1208 }
1209 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1210 if err := dh.sendProxyOmciRequests(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsgs); err != nil {
1211 return olterrors.NewErrCommunication("send-failed", log.Fields{
1212 "parent-device-id": dh.device.Id,
1213 "child-device-id": omciMsgs.ChildDeviceId}, err)
1214 }
1215 } else {
1216 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsgs.ProxyAddress})
1217 if err := dh.sendProxyOmciRequests(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsgs); err != nil {
1218 return olterrors.NewErrCommunication("send-failed", log.Fields{
1219 "parent-device-id": dh.device.Id,
1220 "child-device-id": omciMsgs.ChildDeviceId}, err)
1221 }
1222 }
1223 return nil
1224}
1225
1226func (dh *DeviceHandler) sendProxyOmciRequests(ctx context.Context, onuDevice *voltha.Device, omciMsgs *ia.OmciMessages) error {
1227 var intfID uint32
1228 var onuID uint32
1229 var connectStatus common.ConnectStatus_Types
1230 if onuDevice != nil {
1231 intfID = onuDevice.ProxyAddress.GetChannelId()
1232 onuID = onuDevice.ProxyAddress.GetOnuId()
1233 connectStatus = onuDevice.ConnectStatus
1234 } else {
1235 intfID = omciMsgs.GetProxyAddress().GetChannelId()
1236 onuID = omciMsgs.GetProxyAddress().GetOnuId()
1237 connectStatus = omciMsgs.GetConnectStatus()
1238 }
1239 if connectStatus != voltha.ConnectStatus_REACHABLE {
1240 logger.Debugw(ctx, "onu-not-reachable--cannot-send-omci", log.Fields{"intf-id": intfID, "onu-id": onuID})
1241
1242 return olterrors.NewErrCommunication("unreachable", log.Fields{
1243 "intf-id": intfID,
1244 "onu-id": onuID}, nil)
1245 }
1246
1247 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1248 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
1249
1250 onuSecOmciMsgList := omciMsgs.GetMessages()
1251
1252 for _, onuSecOmciMsg := range onuSecOmciMsgList {
1253
1254 var omciMessage *oop.OmciMsg
1255 hexPkt := make([]byte, hex.EncodedLen(len(onuSecOmciMsg)))
1256 hex.Encode(hexPkt, onuSecOmciMsg)
1257 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1258
1259 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1260 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1261 //https://jira.opencord.org/browse/VOL-4604
1262 transid := extractOmciTransactionID(onuSecOmciMsg)
1263 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
1264 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
1265
1266 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
1267 if err != nil {
1268 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
1269 "intf-id": intfID,
1270 "onu-id": onuID,
1271 "message": omciMessage}, err)
1272 }
1273 }
1274 return nil
1275}
1276
khenaidoo106c61a2021-08-11 18:05:46 -04001277// ProxyOmciMessage sends the proxied OMCI message to the target device
khenaidoodc2116e2021-10-19 17:33:19 -04001278func (dh *DeviceHandler) ProxyOmciMessage(ctx context.Context, omciMsg *ia.OmciMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001279 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 -07001280
1281 if omciMsg.GetProxyAddress() == nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001282 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsg.ChildDeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001283 if err != nil {
1284 return olterrors.NewErrNotFound("onu", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001285 "parent-device-id": dh.device.Id,
1286 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001287 }
khenaidoo106c61a2021-08-11 18:05:46 -04001288 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1289 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001290 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001291 "parent-device-id": dh.device.Id,
1292 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001293 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001294 } else {
khenaidoo106c61a2021-08-11 18:05:46 -04001295 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsg.ProxyAddress})
1296 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001297 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001298 "parent-device-id": dh.device.Id,
1299 "child-device-id": omciMsg.ChildDeviceId}, err)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001300 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001301 }
1302 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301303}
1304
khenaidoodc2116e2021-10-19 17:33:19 -04001305func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ia.OmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001306 var intfID uint32
1307 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001308 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001309 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001310 intfID = onuDevice.ProxyAddress.GetChannelId()
1311 onuID = onuDevice.ProxyAddress.GetOnuId()
1312 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001313 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001314 intfID = omciMsg.GetProxyAddress().GetChannelId()
1315 onuID = omciMsg.GetProxyAddress().GetOnuId()
1316 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001317 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001318 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001319 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 -08001320
Thomas Lee S94109f12020-03-03 16:39:29 +05301321 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001322 "intf-id": intfID,
1323 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001324 }
1325
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001326 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1327 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
kesavandb9f54fd2021-11-25 20:08:04 +05301328 // https://jira.opencord.org/browse/VOL-4604
lcuie24ef182019-04-29 22:58:36 -07001329 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001330 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1331 hex.Encode(hexPkt, omciMsg.Message)
1332 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1333
1334 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1335 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1336 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001337 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001338 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001339
Neha Sharma8f4e4322020-08-06 10:51:53 +00001340 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001341 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301342 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001343 "intf-id": intfID,
1344 "onu-id": onuID,
1345 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001346 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001347 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001348}
1349
David K. Bainbridge794735f2020-02-11 21:01:37 -08001350func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301351 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 +00001352 if err := dh.resourceMgr[intfID].AddNewOnuGemInfoToCacheAndKvStore(ctx, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001353 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001354 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001355 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301356 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301357 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001358 st, _ := status.FromError(err)
1359 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001360 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1361
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001362 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301363 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001364 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001365 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001366 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001367 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001368 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001369}
1370
Mahir Gunyelb0046752021-02-26 13:51:05 -08001371func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001372 channelID := onuDiscInd.GetIntfId()
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001373 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001374
Mahir Gunyelb0046752021-02-26 13:51:05 -08001375 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001376 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301377
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301378 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001379 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001380 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301381
1382 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1383 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1384 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1385 OnuLosRaise event sent for it */
1386 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1387 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1388 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001389 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301390 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1391 "currentIntfId": onuDiscInd.GetIntfId()})
1392 // TODO:: Should we need to ignore raising OnuLosClear event
1393 // when onu connected to different PON?
1394 }
1395 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1396 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1397 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001398 go func() {
1399 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001400 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001401 }
1402 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301403 }
1404 return true
1405 })
1406
Neha Sharma96b7bf22020-06-15 10:37:32 +00001407 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001408 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001409 }
1410
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001411 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001412
1413 // check the ONU is already know to the OLT
1414 // NOTE the second time the ONU is discovered this should return a device
khenaidoodc2116e2021-10-19 17:33:19 -04001415 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001416 ParentId: dh.device.Id,
1417 SerialNumber: sn,
1418 })
Matteo Scandolo945e4012019-12-12 14:16:11 -08001419
1420 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001421 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 -08001422 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001423 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 -08001424 switch e.Code() {
1425 case codes.Internal:
1426 // this probably means NOT FOUND, so just create a new device
1427 onuDevice = nil
1428 case codes.DeadlineExceeded:
1429 // if the call times out, cleanup and exit
1430 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001431 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001432 }
1433 }
1434 }
1435
1436 if onuDevice == nil {
1437 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001438 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001439 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001440 ponintfid := onuDiscInd.GetIntfId()
yasin saplibddc2d72022-02-08 13:10:17 +00001441 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001442
Neha Sharma96b7bf22020-06-15 10:37:32 +00001443 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001444
1445 if err != nil {
1446 // if we can't create an ID in resource manager,
1447 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001448 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001449 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001450 "pon-intf-id": ponintfid,
1451 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001452 }
1453
khenaidoodc2116e2021-10-19 17:33:19 -04001454 if onuDevice, err = dh.sendChildDeviceDetectedToCore(ctx, &ca.DeviceDiscovery{
khenaidoo106c61a2021-08-11 18:05:46 -04001455 ParentId: dh.device.Id,
1456 ParentPortNo: parentPortNo,
1457 ChannelId: channelID,
1458 VendorId: string(onuDiscInd.SerialNumber.GetVendorId()),
1459 SerialNumber: sn,
1460 OnuId: onuID,
1461 }); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001462 dh.discOnus.Delete(sn)
yasin saplibddc2d72022-02-08 13:10:17 +00001463 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 +05301464 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001465 "pon-intf-id": ponintfid,
1466 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001467 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001468 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 -07001469 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001470 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001471 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301472 log.Fields{"onuDevice": onuDevice,
1473 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001474 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301475 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001476 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001477
khenaidoo106c61a2021-08-11 18:05:46 -04001478 // Setup the gRPC connection to the adapter responsible for that onuDevice, if not setup yet
1479 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
1480 err = dh.setupChildInterAdapterClient(subCtx, onuDevice.AdapterEndpoint)
1481 cancel()
1482 if err != nil {
1483 return olterrors.NewErrCommunication("no-connection-to-child-adapter", log.Fields{"device-id": onuDevice.Id}, err)
1484 }
1485
Matteo Scandolo945e4012019-12-12 14:16:11 -08001486 // we can now use the existing ONU Id
1487 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001488 //Insert the ONU into cache to use in OnuIndication.
1489 //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 +00001490 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001491 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301492 "intfId": onuDiscInd.GetIntfId(),
1493 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001494 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001495
khenaidoo106c61a2021-08-11 18:05:46 -04001496 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301497 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001498 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301499 log.Fields{"onu": onuDev,
1500 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001501
khenaidoodc2116e2021-10-19 17:33:19 -04001502 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001503 DeviceId: onuDevice.Id,
1504 ParentDeviceId: dh.device.Id,
1505 OperStatus: common.OperStatus_DISCOVERED,
1506 ConnStatus: common.ConnectStatus_REACHABLE,
1507 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301508 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001509 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001510 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001511 }
khenaidoo106c61a2021-08-11 18:05:46 -04001512
Neha Sharma96b7bf22020-06-15 10:37:32 +00001513 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001514 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301515 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001516 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001517 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001518 }
1519 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001520}
1521
Mahir Gunyelb0046752021-02-26 13:51:05 -08001522func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001523
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001524 ponPort := plt.IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001525 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001526 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001527 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001528 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301529 log.Fields{"onuId": onuInd.OnuId,
1530 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301531 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001532 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001533 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301534
David K. Bainbridge794735f2020-02-11 21:01:37 -08001535 errFields := log.Fields{"device-id": dh.device.Id}
1536
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301537 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1538
Mahir Gunyele77977b2019-06-27 05:36:22 -07001539 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1540 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001541 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001542 onuDevice, err = dh.getDeviceFromCore(ctx, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001543 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001544 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1545 if serialNumber != "" {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001546 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001547 } else {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001548 errFields["onu-id"] = onuInd.OnuId
1549 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001550 }
khenaidoodc2116e2021-10-19 17:33:19 -04001551 onuDevice, err = dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001552 ParentId: dh.device.Id,
1553 SerialNumber: serialNumber,
1554 OnuId: onuInd.OnuId,
1555 ParentPortNo: ponPort,
1556 })
cuilin20187b2a8c32019-03-26 19:52:28 -07001557 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001558
David K. Bainbridge794735f2020-02-11 21:01:37 -08001559 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001560 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001561 }
1562
David K. Bainbridge794735f2020-02-11 21:01:37 -08001563 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001564 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001565 "previousIntfId": onuDevice.ParentPortNo,
1566 "currentIntfId": ponPort})
1567 }
1568
1569 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001570 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301571 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1572 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301573 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001574 }
1575 if !foundInCache {
1576 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1577
khenaidoo106c61a2021-08-11 18:05:46 -04001578 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 -08001579
1580 }
kesavand7cf3a052020-08-28 12:49:18 +05301581 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001582 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001583 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301584 }
1585 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001586 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001587 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001588 }
1589 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001590}
1591
Neha Sharma96b7bf22020-06-15 10:37:32 +00001592func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593 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 -07001594 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1595 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1596 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1597 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001598 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001599 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1600 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001601 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001602 onuInd.OperState = "down"
1603 }
1604 }
1605
David K. Bainbridge794735f2020-02-11 21:01:37 -08001606 switch onuInd.OperState {
khenaidoo106c61a2021-08-11 18:05:46 -04001607 case "up", "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001608 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 -04001609
khenaidoodc2116e2021-10-19 17:33:19 -04001610 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001611 DeviceId: onuDevice.Id,
1612 OnuIndication: onuInd,
1613 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001614 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301615 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001616 "onu-indicator": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001617 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001618 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001619 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001620 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001621 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001622 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001623 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001624 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001625}
1626
cuilin20187b2a8c32019-03-26 19:52:28 -07001627func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1628 if serialNum != nil {
1629 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001630 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001631 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001632}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001633func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1634 decodedStr, err := hex.DecodeString(serialNum[4:])
1635 if err != nil {
1636 return nil, err
1637 }
1638 return &oop.SerialNumber{
1639 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001640 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001641 }, nil
1642}
cuilin20187b2a8c32019-03-26 19:52:28 -07001643
1644func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001645 if len(vendorSpecific) > 3 {
1646 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1647 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1648 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1649 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1650 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1651 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1652 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1653 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1654 return tmp
1655 }
1656 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001657}
1658
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001659//UpdateFlowsBulk upates the bulk flow
1660func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301661 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001662}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001663
1664//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001665func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1666 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301667 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001668 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301669 "device-id": dh.device.Id})
khenaidoo106c61a2021-08-11 18:05:46 -04001670
khenaidoodc2116e2021-10-19 17:33:19 -04001671 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001672 ParentId: dh.device.Id,
1673 OnuId: onuID,
1674 ParentPortNo: parentPort,
1675 })
1676
Girish Gowdru0c588b22019-04-23 23:24:56 -04001677 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001678 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001679 "intf-id": parentPort,
1680 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001681 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001682 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 -08001683 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301684}
1685
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001686// SendPacketInToCore sends packet-in to core
1687// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1688// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001689func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001690 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001691 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001692 "port": logicalPort,
1693 "packet": hex.EncodeToString(packetPayload),
1694 "device-id": dh.device.Id,
1695 })
1696 }
khenaidoo106c61a2021-08-11 18:05:46 -04001697
khenaidoodc2116e2021-10-19 17:33:19 -04001698 if err := dh.sendPacketToCore(ctx, &ca.PacketIn{
khenaidoo106c61a2021-08-11 18:05:46 -04001699 DeviceId: dh.device.Id,
1700 Port: logicalPort,
1701 Packet: packetPayload,
1702 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301703 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001704 "source": "adapter",
1705 "destination": "core",
1706 "device-id": dh.device.Id,
1707 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001708 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001709 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001710 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001711 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001712 "packet": hex.EncodeToString(packetPayload),
1713 "device-id": dh.device.Id,
1714 })
1715 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001716 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001717}
1718
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001719// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001720func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001721 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001722
1723 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1724 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001725 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001726 }
1727
Kent Hagermane6ff1012020-07-14 15:07:53 -04001728 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001729 metrics := dh.metrics.GetSubscriberMetrics()
1730 for _, m := range pmConfigs.Metrics {
1731 metrics[m.Name].Enabled = m.Enabled
1732
1733 }
1734 }
1735}
1736
khenaidoodc2116e2021-10-19 17:33:19 -04001737func (dh *DeviceHandler) handleFlows(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, flowMetadata *of.FlowMetadata) []error {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001738 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001739 var errorsList []error
1740
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001741 if dh.getDeviceDeletionInProgressFlag() {
1742 // The device itself is going to be reset as part of deletion. So nothing to be done.
1743 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1744 return nil
1745 }
1746
Girish Gowdru0c588b22019-04-23 23:24:56 -04001747 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001748 for _, flow := range flows.ToRemove.Items {
yasin saplid0566272021-12-21 09:10:30 +00001749 intfID := dh.getIntfIDFromFlow(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001750
Neha Sharma96b7bf22020-06-15 10:37:32 +00001751 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301752 log.Fields{"device-id": device.Id,
yasin saplid0566272021-12-21 09:10:30 +00001753 "intfId": intfID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301754 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001755 if flow_utils.HasGroup(flow) {
1756 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1757 } else {
yasin saplid0566272021-12-21 09:10:30 +00001758 err = dh.flowMgr[intfID].RouteFlowToOnuChannel(ctx, flow, false, nil)
Girish Gowdra491a9c62021-01-06 16:43:07 -08001759 }
Girish Gowdracefae192020-03-19 18:14:10 -07001760 if err != nil {
Elia Battiston2aaf4342022-02-07 15:16:38 +01001761 if werr, ok := err.(olterrors.WrappedError); ok && status.Code(werr.Unwrap()) == codes.NotFound {
1762 //The flow we want to remove is not there, there is no need to throw an error
1763 logger.Warnw(ctx, "flow-to-remove-not-found",
1764 log.Fields{
1765 "ponIf": intfID,
1766 "flowToRemove": flow,
1767 "error": err,
1768 })
1769 } else {
1770 errorsList = append(errorsList, err)
1771 }
Girish Gowdracefae192020-03-19 18:14:10 -07001772 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001773 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301774
1775 for _, flow := range flows.ToAdd.Items {
yasin saplid0566272021-12-21 09:10:30 +00001776 intfID := dh.getIntfIDFromFlow(ctx, flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001777 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301778 log.Fields{"device-id": device.Id,
yasin saplid0566272021-12-21 09:10:30 +00001779 "ponIf": intfID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301780 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001781 if flow_utils.HasGroup(flow) {
1782 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1783 } else {
yasin saplid0566272021-12-21 09:10:30 +00001784 if dh.flowMgr == nil || dh.flowMgr[intfID] == nil {
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001785 // The flow manager module could be uninitialized if the flow arrives too soon before the device has reconciled fully
1786 logger.Errorw(ctx, "flow-manager-uninitialized", log.Fields{"device-id": device.Id})
1787 err = fmt.Errorf("flow-manager-uninitialized-%v", device.Id)
1788 } else {
yasin saplid0566272021-12-21 09:10:30 +00001789 err = dh.flowMgr[intfID].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001790 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08001791 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001792 if err != nil {
1793 errorsList = append(errorsList, err)
1794 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301795 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001796 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001797
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001798 return errorsList
1799}
1800
1801func (dh *DeviceHandler) handleGroups(ctx context.Context, groups *of.FlowGroupChanges) []error {
1802 var err error
1803 var errorsList []error
1804
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001805 if dh.getDeviceDeletionInProgressFlag() {
1806 // The device itself is going to be reset as part of deletion. So nothing to be done.
1807 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": dh.device.Id})
1808 return nil
1809 }
1810
Girish Gowdracefae192020-03-19 18:14:10 -07001811 // 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 +00001812 if groups != nil {
1813 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001814 // err = dh.groupMgr.AddGroup(ctx, group)
1815 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001816 if err != nil {
1817 errorsList = append(errorsList, err)
1818 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001819 }
1820 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001821 // err = dh.groupMgr.ModifyGroup(ctx, group)
1822 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001823 if err != nil {
1824 errorsList = append(errorsList, err)
1825 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001826 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001827 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001828 // err = dh.groupMgr.DeleteGroup(ctx, group)
1829 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001830 if err != nil {
1831 errorsList = append(errorsList, err)
1832 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001833 }
1834 }
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001835
1836 return errorsList
1837}
1838
1839//UpdateFlowsIncrementally updates the device flow
khenaidoodc2116e2021-10-19 17:33:19 -04001840func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *of.FlowMetadata) error {
Girish Gowdra0fb24a32021-10-27 15:15:27 -0700