blob: 02bc8950a98581c9b087ba0cb8489f7cfaefaa6d [file] [log] [blame]
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
Phaneendra Manda4c62c802019-03-06 21:37:49 +053019
20import (
cuilin20187b2a8c32019-03-26 19:52:28 -070021 "context"
Matt Jeanneretceea2e02020-03-27 14:19:57 -040022 "encoding/binary"
Matt Jeanneret1359c732019-08-01 21:40:02 -040023 "encoding/hex"
Girish Gowdra491a9c62021-01-06 16:43:07 -080024 "errors"
cuilin20187b2a8c32019-03-26 19:52:28 -070025 "fmt"
26 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040027 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070028 "strconv"
29 "strings"
30 "sync"
31 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053032
khenaidoo106c61a2021-08-11 18:05:46 -040033 "github.com/golang/protobuf/ptypes/empty"
34 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
35 "github.com/opencord/voltha-protos/v5/go/adapter_services"
36
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"
52 "github.com/opencord/voltha-protos/v5/go/extension"
53 ic "github.com/opencord/voltha-protos/v5/go/inter_container"
54 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
55 oop "github.com/opencord/voltha-protos/v5/go/openolt"
56 "github.com/opencord/voltha-protos/v5/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070057 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040058 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040059 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053060)
61
salmansiddiqui7ac62132019-08-22 03:58:50 +000062// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040063const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080064 InvalidPort = 0xffffffff
65 MaxNumOfGroupHandlerChannels = 256
66
67 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
68 McastFlowOrGroupModify = "McastFlowOrGroupModify"
69 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050070 oltPortInfoTimeout = 3
Manikkaraj kb1d51442019-07-23 10:41:02 -040071)
72
Phaneendra Manda4c62c802019-03-06 21:37:49 +053073//DeviceHandler will interact with the OLT device.
74type DeviceHandler struct {
khenaidoo106c61a2021-08-11 18:05:46 -040075 cm *config.ConfigManager
76 device *voltha.Device
77 cfg *conf.AdapterFlags
78 coreClient *vgrpc.Client
79 childAdapterClients map[string]*vgrpc.Client
80 lockChildAdapterClients sync.RWMutex
81 EventProxy eventif.EventProxy
82 openOLT *OpenOLT
83 exitChannel chan int
84 lockDevice sync.RWMutex
85 Client oop.OpenoltClient
86 transitionMap *TransitionMap
87 clientCon *grpc.ClientConn
88 flowMgr []*OpenOltFlowMgr
89 groupMgr *OpenOltGroupMgr
90 eventMgr *OpenOltEventMgr
91 resourceMgr []*rsrcMgr.OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070092
93 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +053094
Girish Gowdra3ab6d212020-03-24 17:33:15 -070095 discOnus sync.Map
96 onus sync.Map
97 portStats *OpenOltStatisticsMgr
98 metrics *pmmetrics.PmMetrics
99 stopCollector chan bool
100 stopHeartbeatCheck chan bool
101 activePorts sync.Map
102 stopIndications chan bool
103 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -0700104
Mahir Gunyelb0046752021-02-26 13:51:05 -0800105 totalPonPorts uint32
106 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
107 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800108
109 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
110 // 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 -0700111 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
112 stopMcastHandlerRoutine []chan bool
113 mcastHandlerRoutineActive []bool
Gamze Abakac2c32a62021-03-11 11:44:18 +0000114
115 adapterPreviouslyConnected bool
116 agentPreviouslyConnected bool
Girish Gowdra950326e2021-11-05 12:43:24 -0700117
118 isDeviceDeletionInProgress bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700119}
120
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700121//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700122type OnuDevice struct {
khenaidoo106c61a2021-08-11 18:05:46 -0400123 deviceID string
124 deviceType string
125 serialNumber string
126 onuID uint32
127 intfID uint32
128 proxyDeviceID string
129 losRaised bool
130 rdiRaised bool
131 adapterEndpoint string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700132}
133
Mahir Gunyelb0046752021-02-26 13:51:05 -0800134type onuIndicationMsg struct {
135 ctx context.Context
136 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800137}
138
139type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800140 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800141 stopChannel chan struct{}
142}
143
Girish Gowdra491a9c62021-01-06 16:43:07 -0800144//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
145//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
146//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
147//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
148type McastFlowOrGroupControlBlock struct {
149 ctx context.Context // Flow/group handler context
150 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
151 flow *voltha.OfpFlowStats // Flow message (can be nil or valid flow)
152 group *voltha.OfpGroupEntry // Group message (can be nil or valid group)
153 errChan *chan error // channel to report the mcast Flow/group handling error
154}
155
Naga Manjunath7615e552019-10-11 22:35:47 +0530156var pmNames = []string{
157 "rx_bytes",
158 "rx_packets",
159 "rx_mcast_packets",
160 "rx_bcast_packets",
161 "tx_bytes",
162 "tx_packets",
163 "tx_mcast_packets",
164 "tx_bcast_packets",
165}
166
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700167//NewOnuDevice creates a new Onu Device
khenaidoo106c61a2021-08-11 18:05:46 -0400168func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool, adapterEndpoint string) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700169 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700170 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700171 device.deviceType = deviceTp
172 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700173 device.onuID = onuID
174 device.intfID = intfID
175 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530176 device.losRaised = losRaised
khenaidoo106c61a2021-08-11 18:05:46 -0400177 device.adapterEndpoint = adapterEndpoint
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700178 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530179}
180
181//NewDeviceHandler creates a new device handler
khenaidoo106c61a2021-08-11 18:05:46 -0400182func 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 -0700183 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800184 dh.cm = cm
khenaidoo106c61a2021-08-11 18:05:46 -0400185 dh.coreClient = cc
Devmalya Paulfb990a52019-07-09 10:01:49 -0400186 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700187 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700188 dh.device = cloned
189 dh.openOLT = adapter
190 dh.exitChannel = make(chan int, 1)
191 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530192 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530193 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530194 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 -0500195 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400196 dh.stopIndications = make(chan bool, 1)
Mahir Gunyelb0046752021-02-26 13:51:05 -0800197 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
khenaidoo106c61a2021-08-11 18:05:46 -0400198 dh.childAdapterClients = make(map[string]*vgrpc.Client)
199 dh.cfg = cfg
Girish Gowdra491a9c62021-01-06 16:43:07 -0800200 // Create a slice of buffered channels for handling concurrent mcast flow/group.
201 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700202 dh.stopMcastHandlerRoutine = make([]chan bool, MaxNumOfGroupHandlerChannels)
203 dh.mcastHandlerRoutineActive = make([]bool, MaxNumOfGroupHandlerChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800204 for i := range dh.incomingMcastFlowOrGroup {
205 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700206 dh.stopMcastHandlerRoutine[i] = make(chan bool, 1)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800207 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
208 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
209 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
210 // for incoming mcast flow/group to be processed serially.
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700211 dh.mcastHandlerRoutineActive[i] = true
212 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
Girish Gowdra491a9c62021-01-06 16:43:07 -0800213 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700214 //TODO initialize the support classes.
215 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530216}
217
218// start save the device to the data model
219func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700220 dh.lockDevice.Lock()
221 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000222 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700223 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000224 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530225}
226
227// stop stops the device dh. Not much to do for now
228func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700229 dh.lockDevice.Lock()
230 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000231 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700232 dh.exitChannel <- 1
khenaidoo106c61a2021-08-11 18:05:46 -0400233
Neha Sharma96b7bf22020-06-15 10:37:32 +0000234 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530235}
236
ssiddiqui04386ee2021-08-23 21:58:25 +0530237func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
238 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
239 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
240 if pooledIntfID == intfID {
241 return resourceRanges.GetTechnology()
242 }
243 }
244 }
245 return ""
246}
247
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400248func macifyIP(ip net.IP) string {
249 if len(ip) > 0 {
250 oct1 := strconv.FormatInt(int64(ip[12]), 16)
251 oct2 := strconv.FormatInt(int64(ip[13]), 16)
252 oct3 := strconv.FormatInt(int64(ip[14]), 16)
253 oct4 := strconv.FormatInt(int64(ip[15]), 16)
254 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
255 }
256 return ""
257}
258
Neha Sharma96b7bf22020-06-15 10:37:32 +0000259func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400260 var genmac string
261 var addr net.IP
262 var ips []string
263 var err error
264
Neha Sharma96b7bf22020-06-15 10:37:32 +0000265 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400266
267 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000268 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400269
270 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000271 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400272 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000273 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400274 }
275 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000276 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530277 log.Fields{"host": ips[0],
278 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400279 return genmac, nil
280 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000281 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400282 }
283
284 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000285 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530286 log.Fields{"host": host,
287 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400288 return genmac, nil
289}
290
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530291func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700292 slist := strings.Split(mac, ":")
293 result := make([]uint32, len(slist))
294 var err error
295 var tmp int64
296 for index, val := range slist {
297 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
298 return []uint32{1, 2, 3, 4, 5, 6}
299 }
300 result[index] = uint32(tmp)
301 }
302 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530303}
304
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700305//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 -0800306func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530307
David K. Bainbridge794735f2020-02-11 21:01:37 -0800308 switch portType {
309 case voltha.Port_ETHERNET_NNI:
310 return fmt.Sprintf("nni-%d", portNum), nil
311 case voltha.Port_PON_OLT:
312 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700313 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800314
Girish Kumarf26e4882020-03-05 06:49:10 +0000315 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530316}
317
Neha Sharma96b7bf22020-06-15 10:37:32 +0000318func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000319 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700320 if state == "up" {
321 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500322 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500323 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700324 } else {
325 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500326 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700327 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700328 portNum := plt.IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400329 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800330 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000331 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400332 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500333
khenaidoo106c61a2021-08-11 18:05:46 -0400334 // Check if port exists
335 port, err := dh.getPortFromCore(ctx, &ic.PortFilter{
336 DeviceId: dh.device.Id,
337 Port: portNum,
338 })
339 if err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000340 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
khenaidoo106c61a2021-08-11 18:05:46 -0400341 err = dh.updatePortStateInCore(ctx, &ic.PortState{
342 DeviceId: dh.device.Id,
343 PortType: portType,
344 PortNo: portNum,
345 OperStatus: operStatus})
346 if err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400347 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
348 "device-id": dh.device.Id,
349 "port-type": portType,
350 "port-number": portNum,
351 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500352 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400353 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500354 }
khenaidoo106c61a2021-08-11 18:05:46 -0400355
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400356 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700357 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
khenaidoo106c61a2021-08-11 18:05:46 -0400358 port = &voltha.Port{
359 DeviceId: dh.device.Id,
cuilin20187b2a8c32019-03-26 19:52:28 -0700360 PortNo: portNum,
361 Label: label,
362 Type: portType,
363 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700364 OfpPort: &of.OfpPort{
365 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
366 Config: 0,
367 State: uint32(of.OfpPortState_OFPPS_LIVE),
368 Curr: capacity,
369 Advertised: capacity,
370 Peer: capacity,
371 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
372 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
373 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700374 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000375 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700376 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400377 err = dh.createPortInCore(ctx, port)
378 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000379 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800380 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000381 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400382 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000383 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530384 return nil
385}
386
Kent Hagermane6ff1012020-07-14 15:07:53 -0400387func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -0400388 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530389 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400390 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
391 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530392 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800393 dh.lockDevice.Lock()
394 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530395 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530396}
397
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700398// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530399// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800400func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000401 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700402 defer func() {
403 dh.lockDevice.Lock()
404 dh.isReadIndicationRoutineActive = false
405 dh.lockDevice.Unlock()
406 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700407 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700408 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700409 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700410 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400411
David Bainbridgef5879ca2019-12-13 21:17:54 +0000412 // Create an exponential backoff around re-enabling indications. The
413 // maximum elapsed time for the back off is set to 0 so that we will
414 // continue to retry. The max interval defaults to 1m, but is set
415 // here for code clarity
416 indicationBackoff := backoff.NewExponentialBackOff()
417 indicationBackoff.MaxElapsedTime = 0
418 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700419
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700420 dh.lockDevice.Lock()
421 dh.isReadIndicationRoutineActive = true
422 dh.lockDevice.Unlock()
423
Girish Gowdra3f974912020-03-23 20:35:18 -0700424Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700425 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400426 select {
427 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000428 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700429 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400430 default:
431 indication, err := indications.Recv()
432 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000433 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530434 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530435 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400436 // Use an exponential back off to prevent getting into a tight loop
437 duration := indicationBackoff.NextBackOff()
438 if duration == backoff.Stop {
439 // If we reach a maximum then warn and reset the backoff
440 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000441 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530442 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530443 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400444 indicationBackoff.Reset()
445 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700446
447 // On failure process a backoff timer while watching for stopIndications
448 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700449 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700450 select {
451 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000452 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700453 if !backoffTimer.Stop() {
454 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700455 }
456 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700457 case <-backoffTimer.C:
458 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700459 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700460 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
461 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400462 }
463 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000464 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530465 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000466 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530467 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530468 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700469 // Close the stream, and re-initialize it
470 if err = indications.CloseSend(); err != nil {
471 // Ok to ignore here, because we landed here due to a problem on the stream
472 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000473 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530474 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530475 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700476 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000477 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700478 return err
479 }
480 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400481 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530482 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400483 // Reset backoff if we have a successful receive
484 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400485 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700486 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000487 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530488 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530489 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400490 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400491 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400492 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700493 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700494 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700495 // Close the send stream
496 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700497
Girish Gowdra3f974912020-03-23 20:35:18 -0700498 return nil
499}
500
501func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700502 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700503 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
504 if err != nil {
505 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
506 }
507 if indications == nil {
508 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
509 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700510 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700511 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400512}
513
514// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
515func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
516 switch indication.Data.(type) {
517 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
518 return true
519
520 default:
521 return false
522 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700523}
524
David K. Bainbridge794735f2020-02-11 21:01:37 -0800525func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700526 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000527 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530528 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700529 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530530 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700531 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000532 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000533 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530534 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000535 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800536 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000537 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800538 }
539 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700540}
541
David K. Bainbridge794735f2020-02-11 21:01:37 -0800542// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530543func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700544 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700545 switch indication.Data.(type) {
546 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000547 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
548 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700549 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 -0800550 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400551 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800552 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700553 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000554 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
555 defer span.Finish()
556
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700557 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800558 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000559 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400560 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800561 }
562 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000563 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700564 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000565 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
566 defer span.Finish()
567
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700568 intfOperInd := indication.GetIntfOperInd()
569 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800570 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000571 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400572 _ = 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 -0800573 }
574 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700575 } else if intfOperInd.GetType() == "pon" {
576 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
577 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800578 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000579 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400580 _ = 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 -0800581 }
582 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000583 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700584 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000585 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530586 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530587 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700588 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000589 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
590 defer span.Finish()
591
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700592 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000593 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800594 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800595 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700596 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000597 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
598 defer span.Finish()
599
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700600 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000601 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800602 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800603 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700604 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000605 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
606 defer span.Finish()
607
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700608 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000609 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 -0800610 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000611 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400612 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800613 }
614 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700615 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000616 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
617 defer span.Finish()
618
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700619 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000620 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700621 "intf-type": pktInd.IntfId,
622 "intf-id": pktInd.IntfId,
623 "gem-port-id": pktInd.GemportId,
624 "port-no": pktInd.PortNo,
625 "device-id": dh.device.Id,
626 })
627
628 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000629 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700630 "intf-type": pktInd.IntfId,
631 "intf-id": pktInd.IntfId,
632 "gem-port-id": pktInd.GemportId,
633 "port-no": pktInd.PortNo,
634 "packet": hex.EncodeToString(pktInd.Pkt),
635 "device-id": dh.device.Id,
636 })
637 }
638
David K. Bainbridge794735f2020-02-11 21:01:37 -0800639 go func() {
640 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400641 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800642 }
643 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700644 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000645 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
646 defer span.Finish()
647
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700648 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700649 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700650 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000651 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
652 defer span.Finish()
653
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700654 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000655 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700656 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000657 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
658 defer span.Finish()
659
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700660 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000661 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
662 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700663 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530664}
665
666// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530667func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530668 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000669 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530670
Girish Gowdra618fa572021-09-01 17:19:29 -0700671 // instantiate the mcast handler routines.
672 for i := range dh.incomingMcastFlowOrGroup {
673 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
674 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
675 if !dh.mcastHandlerRoutineActive[i] {
676 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
677 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
678 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
679 // for incoming mcast flow/group to be processed serially.
680 dh.mcastHandlerRoutineActive[i] = true
681 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
682 }
683 }
684
Girish Gowdru0c588b22019-04-23 23:24:56 -0400685 // Synchronous call to update device state - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400686 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
687 DeviceId: dh.device.Id,
688 OperStatus: voltha.OperStatus_ACTIVE,
689 ConnStatus: voltha.ConnectStatus_REACHABLE,
690 }); err != nil {
691 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400692 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000693
694 //Clear olt communication failure event
695 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
696 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700697 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000698 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
699
Gamze Abakac2c32a62021-03-11 11:44:18 +0000700 //check adapter and agent reconcile status
701 //reboot olt if needed (olt disconnection case)
702 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
703 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
704 log.Fields{
705 "device-id": dh.device.Id,
706 "adapter-status": dh.adapterPreviouslyConnected,
707 "agent-status": dh.agentPreviouslyConnected,
708 })
709 _ = dh.RebootDevice(ctx, dh.device)
710 }
711
Girish Gowdru0c588b22019-04-23 23:24:56 -0400712 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530713}
714
715// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530716func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000717 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400718
khenaidoo106c61a2021-08-11 18:05:46 -0400719 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400720 if err != nil || device == nil {
721 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000722 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400723 }
724
725 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400726
727 //Update the device oper state and connection status
728 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800729 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400730 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800731 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400732
khenaidoo106c61a2021-08-11 18:05:46 -0400733 if err = dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
734 DeviceId: cloned.Id,
735 OperStatus: cloned.OperStatus,
736 ConnStatus: cloned.ConnectStatus,
737 }); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000738 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400739 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400740
741 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -0400742 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400743 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000744 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400745 }
746 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400747 // Update onu state as down in onu adapter
748 onuInd := oop.OnuIndication{}
749 onuInd.OperState = "down"
khenaidoo106c61a2021-08-11 18:05:46 -0400750
751 ogClient, err := dh.getChildAdapterServiceClient(onuDevice.AdapterEndpoint)
752 if err != nil {
753 return err
754 }
755 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
756 _, err = ogClient.OnuIndication(subCtx, &ic.OnuIndicationMessage{
757 DeviceId: onuDevice.Id,
758 OnuIndication: &onuInd,
759 })
760 cancel()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800761 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400762 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -0400763 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800764 "onu-indicator": onuInd,
765 "device-type": onuDevice.Type,
766 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700767 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800768 } else {
769 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 -0700770 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400771 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800772 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700773 /* Discovered ONUs entries need to be cleared , since after OLT
774 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530775 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800776 dh.lockDevice.Unlock()
777
Neha Sharma96b7bf22020-06-15 10:37:32 +0000778 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700779 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530780}
781
782// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530783func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400784 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000785
786 // if the connection is already available, close the previous connection (olt reboot case)
787 if dh.clientCon != nil {
788 if err = dh.clientCon.Close(); err != nil {
789 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
790 } else {
791 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
792 }
793 }
794
795 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000796 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
797 grpc.WithInsecure(),
798 grpc.WithBlock(),
799 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000800 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000801 )),
802 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000803 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000804 )))
805
806 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530807 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530808 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000809 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400810 }
811 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530812}
813
814// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530815func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400816 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530817 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400818 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530819}
820
821// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530822func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530823 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000824 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400825
826 // Case where OLT is disabled and then rebooted.
khenaidoo106c61a2021-08-11 18:05:46 -0400827 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Thomas Lee S985938d2020-05-04 11:40:41 +0530828 if err != nil || device == nil {
829 /*TODO: needs to handle error scenarios */
830 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
831 }
832 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000833 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400834
835 cloned := proto.Clone(device).(*voltha.Device)
836 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
837 cloned.OperStatus = voltha.OperStatus_UNKNOWN
838 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -0400839
840 if err = dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
841 DeviceId: cloned.Id,
842 OperStatus: cloned.OperStatus,
843 ConnStatus: cloned.ConnectStatus,
844 }); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530845 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 -0400846 }
847
Chaitrashree G S44124192019-08-07 20:21:36 -0400848 // 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 +0530849 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400850 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530851 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400852 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400853 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
854 // all the modules initialized and ready to handle incoming ONUs.
855
Thomas Lee S985938d2020-05-04 11:40:41 +0530856 err = dh.initializeDeviceHandlerModules(ctx)
857 if err != nil {
858 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 -0400859 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400860
861 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800862 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530863 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400864 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800865 }
866 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700867
868 go startHeartbeatCheck(ctx, dh)
869
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400870 return nil
871 }
872
khenaidoo106c61a2021-08-11 18:05:46 -0400873 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400874 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400875 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400876 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400877 }
khenaidoo106c61a2021-08-11 18:05:46 -0400878 dh.populateActivePorts(ctx, ports.Items)
879 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400880 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400881 }
882
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400883 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530884 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 -0400885 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530886
cuilin20187b2a8c32019-03-26 19:52:28 -0700887 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800888 go func() {
889 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400890 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800891 }
892 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000893 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000894
895 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000896 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000897 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700898
899 go startHeartbeatCheck(ctx, dh)
900
cuilin20187b2a8c32019-03-26 19:52:28 -0700901 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530902}
903
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400904func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700905 var err error
906 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400907
908 if err != nil {
909 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
910 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700911 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
912 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700913
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700914 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700915 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700916 var i uint32
917 for i = 0; i < dh.totalPonPorts; i++ {
918 // Instantiate resource manager
919 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 -0700920 return olterrors.ErrResourceManagerInstantiating
921 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400922 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700923 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
924 // the KV store to manage mcast group data. Provide the first instance (0th index)
925 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
926 return olterrors.ErrGroupManagerInstantiating
927 }
928 for i = 0; i < dh.totalPonPorts; i++ {
929 // Instantiate flow manager
930 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
931 return olterrors.ErrFlowManagerInstantiating
932 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700933 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700934 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400935 /* TODO: Instantiate Alarm , stats , BW managers */
936 /* Instantiating Event Manager to handle Alarms and KPIs */
937 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
938
939 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000940 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400941
942 return nil
943
944}
945
Neha Sharma96b7bf22020-06-15 10:37:32 +0000946func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400947 var err error
948 var deviceInfo *oop.DeviceInfo
949
Neha Sharma8f4e4322020-08-06 10:51:53 +0000950 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400951
952 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000953 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400954 }
955 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000956 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400957 }
958
Neha Sharma96b7bf22020-06-15 10:37:32 +0000959 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400960 dh.device.Root = true
961 dh.device.Vendor = deviceInfo.Vendor
962 dh.device.Model = deviceInfo.Model
963 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
964 dh.device.HardwareVersion = deviceInfo.HardwareVersion
965 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
966
967 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000968 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400969 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000970 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400971 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000972 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400973 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000974 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400975 dh.device.MacAddress = genmac
976 } else {
977 dh.device.MacAddress = deviceInfo.DeviceId
978 }
979
980 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400981 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000982 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400983 }
984
985 return deviceInfo, nil
986}
987
Neha Sharma96b7bf22020-06-15 10:37:32 +0000988func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700989 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530990 for {
991 select {
992 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000993 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530994 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000995 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700996
khenaidoo106c61a2021-08-11 18:05:46 -0400997 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400998 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700999 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001000 continue
1001 }
khenaidoo106c61a2021-08-11 18:05:46 -04001002 for _, port := range ports.Items {
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301003 // NNI Stats
1004 if port.Type == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001005 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301006 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001007 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001008 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001009 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301010 }
1011 // PON Stats
1012 if port.Type == voltha.Port_PON_OLT {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001013 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301014 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
1015 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001016 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001017 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301018 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001019 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001020
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001021 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001022 if len(onuGemInfoLst) > 0 {
1023 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001024 }
Chaitrashree G Sef088112020-02-03 21:39:27 -05001025 }
Naga Manjunath7615e552019-10-11 22:35:47 +05301026 }
1027 }
1028 }
1029}
1030
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001031//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +05301032func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001033 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001034 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +05301035 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +05301036
1037 // Now, set the initial PM configuration for that device
khenaidoo106c61a2021-08-11 18:05:46 -04001038 cgClient, err := dh.coreClient.GetCoreServiceClient()
1039 if err != nil {
1040 logger.Errorw(ctx, "no-core-connection", log.Fields{"device-id": dh.device.Id, "error": err})
1041 return
1042 }
1043
1044 // Now, set the initial PM configuration for that device
1045 if _, err := cgClient.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001046 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +05301047 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301048}
1049
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001050//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301051func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -07001052 return &ic.SwitchCapability{
1053 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301054 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001055 HwDesc: "open_pon",
1056 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001057 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001058 },
1059 SwitchFeatures: &of.OfpSwitchFeatures{
1060 NBuffers: 256,
1061 NTables: 2,
1062 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1063 of.OfpCapabilities_OFPC_TABLE_STATS |
1064 of.OfpCapabilities_OFPC_PORT_STATS |
1065 of.OfpCapabilities_OFPC_GROUP_STATS),
1066 },
1067 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301068}
1069
khenaidoo106c61a2021-08-11 18:05:46 -04001070// GetTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
1071func (dh *DeviceHandler) GetTechProfileDownloadMessage(ctx context.Context, request *ic.TechProfileInstanceRequestMessage) (*ic.TechProfileDownloadMessage, error) {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001072 ifID, err := plt.IntfIDFromPonPortNum(ctx, request.ParentPonPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001073 if err != nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001074 return nil, err
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001075 }
khenaidoo106c61a2021-08-11 18:05:46 -04001076 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001077}
1078
Neha Sharma96b7bf22020-06-15 10:37:32 +00001079func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001080 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 -07001081 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001082 var deviceID string
1083 var proxyDeviceID string
khenaidoo106c61a2021-08-11 18:05:46 -04001084 var childAdapterEndpoint string
cuilin20187b2a8c32019-03-26 19:52:28 -07001085
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001086 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001087 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001088 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 -07001089 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1090 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001091
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001092 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301093
1094 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1095
Neha Sharma96b7bf22020-06-15 10:37:32 +00001096 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 -07001097 ponPort := plt.IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
cuilin20187b2a8c32019-03-26 19:52:28 -07001098
khenaidoo106c61a2021-08-11 18:05:46 -04001099 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1100 ParentId: dh.device.Id,
1101 OnuId: omciInd.OnuId,
1102 ParentPortNo: ponPort,
1103 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001104 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301105 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001106 "intf-id": omciInd.IntfId,
1107 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001108 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001109 deviceType = onuDevice.Type
1110 deviceID = onuDevice.Id
1111 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
khenaidoo106c61a2021-08-11 18:05:46 -04001112 childAdapterEndpoint = onuDevice.AdapterEndpoint
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001113 //if not exist in cache, then add to cache.
khenaidoo106c61a2021-08-11 18:05:46 -04001114 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false, onuDevice.AdapterEndpoint))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001115 } else {
1116 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001117 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 +05301118 deviceType = onuInCache.(*OnuDevice).deviceType
1119 deviceID = onuInCache.(*OnuDevice).deviceID
1120 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001121 childAdapterEndpoint = onuInCache.(*OnuDevice).adapterEndpoint
cuilin20187b2a8c32019-03-26 19:52:28 -07001122 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001123
khenaidoo106c61a2021-08-11 18:05:46 -04001124 if err := dh.sendOmciIndicationToChildAdapter(ctx, childAdapterEndpoint, &ic.OmciMessage{
1125 ParentDeviceId: proxyDeviceID,
1126 ChildDeviceId: deviceID,
1127 Message: omciInd.Pkt,
1128 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301129 return olterrors.NewErrCommunication("omci-request", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001130 "source": dh.openOLT.config.AdapterEndpoint,
1131 "device-type": deviceType,
1132 "destination": childAdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001133 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001134 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001135 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001136 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301137}
1138
khenaidoo106c61a2021-08-11 18:05:46 -04001139// //ProcessInterAdapterMessage sends the proxied messages to the target device
1140// // If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1141// // is meant, and then send the unmarshalled omci message to this onu
1142// func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1143// logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
1144// if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
1145// return dh.handleInterAdapterOmciMsg(ctx, msg)
1146// }
1147// return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1148// }
cuilin20187b2a8c32019-03-26 19:52:28 -07001149
khenaidoo106c61a2021-08-11 18:05:46 -04001150// ProxyOmciMessage sends the proxied OMCI message to the target device
1151func (dh *DeviceHandler) ProxyOmciMessage(ctx context.Context, omciMsg *ic.OmciMessage) error {
1152 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 -07001153
1154 if omciMsg.GetProxyAddress() == nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001155 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsg.ChildDeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001156 if err != nil {
1157 return olterrors.NewErrNotFound("onu", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001158 "parent-device-id": dh.device.Id,
1159 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001160 }
khenaidoo106c61a2021-08-11 18:05:46 -04001161 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1162 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001163 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001164 "parent-device-id": dh.device.Id,
1165 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001166 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001167 } else {
khenaidoo106c61a2021-08-11 18:05:46 -04001168 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsg.ProxyAddress})
1169 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001170 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001171 "parent-device-id": dh.device.Id,
1172 "child-device-id": omciMsg.ChildDeviceId}, err)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001173 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001174 }
1175 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301176}
1177
khenaidoo106c61a2021-08-11 18:05:46 -04001178func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.OmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001179 var intfID uint32
1180 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001181 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001182 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001183 intfID = onuDevice.ProxyAddress.GetChannelId()
1184 onuID = onuDevice.ProxyAddress.GetOnuId()
1185 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001186 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001187 intfID = omciMsg.GetProxyAddress().GetChannelId()
1188 onuID = omciMsg.GetProxyAddress().GetOnuId()
1189 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001190 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001191 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001192 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 -08001193
Thomas Lee S94109f12020-03-03 16:39:29 +05301194 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001195 "intf-id": intfID,
1196 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001197 }
1198
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001199 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1200 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001201 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001202 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1203 hex.Encode(hexPkt, omciMsg.Message)
1204 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1205
1206 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1207 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1208 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001209 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001210 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001211
Neha Sharma8f4e4322020-08-06 10:51:53 +00001212 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001213 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301214 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001215 "intf-id": intfID,
1216 "onu-id": onuID,
1217 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001218 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001219 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001220}
1221
David K. Bainbridge794735f2020-02-11 21:01:37 -08001222func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301223 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra197acc12021-08-16 10:59:45 -07001224 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001225 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001226 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001227 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301228 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301229 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001230 st, _ := status.FromError(err)
1231 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001232 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1233
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001234 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301235 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001236 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001237 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001238 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001239 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001240 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001241}
1242
Mahir Gunyelb0046752021-02-26 13:51:05 -08001243func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001244 channelID := onuDiscInd.GetIntfId()
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001245 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001246
Mahir Gunyelb0046752021-02-26 13:51:05 -08001247 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001248 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301249
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301250 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001251 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001252 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301253
1254 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1255 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1256 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1257 OnuLosRaise event sent for it */
1258 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1259 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1260 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001261 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301262 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1263 "currentIntfId": onuDiscInd.GetIntfId()})
1264 // TODO:: Should we need to ignore raising OnuLosClear event
1265 // when onu connected to different PON?
1266 }
1267 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1268 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1269 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001270 go func() {
1271 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001272 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001273 }
1274 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301275 }
1276 return true
1277 })
1278
Neha Sharma96b7bf22020-06-15 10:37:32 +00001279 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001280 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001281 }
1282
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001283 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001284
1285 // check the ONU is already know to the OLT
1286 // NOTE the second time the ONU is discovered this should return a device
khenaidoo106c61a2021-08-11 18:05:46 -04001287 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1288 ParentId: dh.device.Id,
1289 SerialNumber: sn,
1290 })
Matteo Scandolo945e4012019-12-12 14:16:11 -08001291
1292 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001293 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 -08001294 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001295 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 -08001296 switch e.Code() {
1297 case codes.Internal:
1298 // this probably means NOT FOUND, so just create a new device
1299 onuDevice = nil
1300 case codes.DeadlineExceeded:
1301 // if the call times out, cleanup and exit
1302 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001303 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001304 }
1305 }
1306 }
1307
1308 if onuDevice == nil {
1309 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001310 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001311 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001312 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001313 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001314
Neha Sharma96b7bf22020-06-15 10:37:32 +00001315 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001316
1317 if err != nil {
1318 // if we can't create an ID in resource manager,
1319 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001320 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001321 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001322 "pon-intf-id": ponintfid,
1323 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001324 }
1325
khenaidoo106c61a2021-08-11 18:05:46 -04001326 if onuDevice, err = dh.sendChildDeviceDetectedToCore(ctx, &ic.DeviceDiscovery{
1327 ParentId: dh.device.Id,
1328 ParentPortNo: parentPortNo,
1329 ChannelId: channelID,
1330 VendorId: string(onuDiscInd.SerialNumber.GetVendorId()),
1331 SerialNumber: sn,
1332 OnuId: onuID,
1333 }); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001334 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001335 dh.resourceMgr[ponintfid].FreeonuID(ctx, ponintfid, []uint32{onuID}) // NOTE I'm not sure this method is actually cleaning up the right thing
Thomas Lee S94109f12020-03-03 16:39:29 +05301336 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001337 "pon-intf-id": ponintfid,
1338 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001339 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001340 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 -07001341 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001342 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001343 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301344 log.Fields{"onuDevice": onuDevice,
1345 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001346 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301347 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001348 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001349
khenaidoo106c61a2021-08-11 18:05:46 -04001350 // Setup the gRPC connection to the adapter responsible for that onuDevice, if not setup yet
1351 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
1352 err = dh.setupChildInterAdapterClient(subCtx, onuDevice.AdapterEndpoint)
1353 cancel()
1354 if err != nil {
1355 return olterrors.NewErrCommunication("no-connection-to-child-adapter", log.Fields{"device-id": onuDevice.Id}, err)
1356 }
1357
Matteo Scandolo945e4012019-12-12 14:16:11 -08001358 // we can now use the existing ONU Id
1359 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001360 //Insert the ONU into cache to use in OnuIndication.
1361 //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 +00001362 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001363 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301364 "intfId": onuDiscInd.GetIntfId(),
1365 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001366 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001367
khenaidoo106c61a2021-08-11 18:05:46 -04001368 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301369 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001370 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301371 log.Fields{"onu": onuDev,
1372 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001373
khenaidoo106c61a2021-08-11 18:05:46 -04001374 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1375 DeviceId: onuDevice.Id,
1376 ParentDeviceId: dh.device.Id,
1377 OperStatus: common.OperStatus_DISCOVERED,
1378 ConnStatus: common.ConnectStatus_REACHABLE,
1379 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301380 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001381 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001382 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001383 }
khenaidoo106c61a2021-08-11 18:05:46 -04001384
Neha Sharma96b7bf22020-06-15 10:37:32 +00001385 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001386 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301387 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001388 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001389 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001390 }
1391 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001392}
1393
Mahir Gunyelb0046752021-02-26 13:51:05 -08001394func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001395
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001396 ponPort := plt.IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001397 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001398 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001399 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001400 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301401 log.Fields{"onuId": onuInd.OnuId,
1402 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301403 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001404 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001405 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301406
David K. Bainbridge794735f2020-02-11 21:01:37 -08001407 errFields := log.Fields{"device-id": dh.device.Id}
1408
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301409 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1410
Mahir Gunyele77977b2019-06-27 05:36:22 -07001411 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1412 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001413 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001414 onuDevice, err = dh.getDeviceFromCore(ctx, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001415 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001416 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1417 if serialNumber != "" {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001418 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001419 } else {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001420 errFields["onu-id"] = onuInd.OnuId
1421 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001422 }
khenaidoo106c61a2021-08-11 18:05:46 -04001423 onuDevice, err = dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1424 ParentId: dh.device.Id,
1425 SerialNumber: serialNumber,
1426 OnuId: onuInd.OnuId,
1427 ParentPortNo: ponPort,
1428 })
cuilin20187b2a8c32019-03-26 19:52:28 -07001429 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001430
David K. Bainbridge794735f2020-02-11 21:01:37 -08001431 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001432 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001433 }
1434
David K. Bainbridge794735f2020-02-11 21:01:37 -08001435 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001436 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001437 "previousIntfId": onuDevice.ParentPortNo,
1438 "currentIntfId": ponPort})
1439 }
1440
1441 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001442 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301443 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1444 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301445 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001446 }
1447 if !foundInCache {
1448 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1449
khenaidoo106c61a2021-08-11 18:05:46 -04001450 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 -08001451
1452 }
kesavand7cf3a052020-08-28 12:49:18 +05301453 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001454 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001455 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301456 }
1457 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001458 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001459 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001460 }
1461 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001462}
1463
Neha Sharma96b7bf22020-06-15 10:37:32 +00001464func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001465 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 -07001466 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1467 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1468 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1469 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001470 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001471 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1472 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001473 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001474 onuInd.OperState = "down"
1475 }
1476 }
1477
David K. Bainbridge794735f2020-02-11 21:01:37 -08001478 switch onuInd.OperState {
khenaidoo106c61a2021-08-11 18:05:46 -04001479 case "up", "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001480 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 -04001481
1482 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ic.OnuIndicationMessage{
1483 DeviceId: onuDevice.Id,
1484 OnuIndication: onuInd,
1485 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001486 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301487 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001488 "onu-indicator": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001489 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001490 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001491 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001492 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001493 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001494 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001495 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001496 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001497}
1498
cuilin20187b2a8c32019-03-26 19:52:28 -07001499func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1500 if serialNum != nil {
1501 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001502 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001503 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001504}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001505func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1506 decodedStr, err := hex.DecodeString(serialNum[4:])
1507 if err != nil {
1508 return nil, err
1509 }
1510 return &oop.SerialNumber{
1511 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001512 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001513 }, nil
1514}
cuilin20187b2a8c32019-03-26 19:52:28 -07001515
1516func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001517 if len(vendorSpecific) > 3 {
1518 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1519 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1520 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1521 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1522 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1523 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1524 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1525 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1526 return tmp
1527 }
1528 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001529}
1530
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001531//UpdateFlowsBulk upates the bulk flow
1532func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301533 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001534}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001535
1536//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001537func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1538 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301539 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001540 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301541 "device-id": dh.device.Id})
khenaidoo106c61a2021-08-11 18:05:46 -04001542
1543 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1544 ParentId: dh.device.Id,
1545 OnuId: onuID,
1546 ParentPortNo: parentPort,
1547 })
1548
Girish Gowdru0c588b22019-04-23 23:24:56 -04001549 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001550 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001551 "intf-id": parentPort,
1552 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001553 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001554 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 -08001555 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301556}
1557
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001558// SendPacketInToCore sends packet-in to core
1559// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1560// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001561func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001562 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001563 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001564 "port": logicalPort,
1565 "packet": hex.EncodeToString(packetPayload),
1566 "device-id": dh.device.Id,
1567 })
1568 }
khenaidoo106c61a2021-08-11 18:05:46 -04001569
1570 if err := dh.sendPacketToCore(ctx, &ic.PacketIn{
1571 DeviceId: dh.device.Id,
1572 Port: logicalPort,
1573 Packet: packetPayload,
1574 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301575 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001576 "source": "adapter",
1577 "destination": "core",
1578 "device-id": dh.device.Id,
1579 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001580 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001581 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001582 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001583 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001584 "packet": hex.EncodeToString(packetPayload),
1585 "device-id": dh.device.Id,
1586 })
1587 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001588 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001589}
1590
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001591// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001592func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001594
1595 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1596 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001597 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001598 }
1599
Kent Hagermane6ff1012020-07-14 15:07:53 -04001600 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001601 metrics := dh.metrics.GetSubscriberMetrics()
1602 for _, m := range pmConfigs.Metrics {
1603 metrics[m.Name].Enabled = m.Enabled
1604
1605 }
1606 }
1607}
1608
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001609func (dh *DeviceHandler) handleFlows(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, flowMetadata *voltha.FlowMetadata) []error {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001610 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001611 var errorsList []error
1612
Girish Gowdru0c588b22019-04-23 23:24:56 -04001613 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001614 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001615 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001616
Neha Sharma96b7bf22020-06-15 10:37:32 +00001617 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301618 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001619 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301620 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001621 if flow_utils.HasGroup(flow) {
1622 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1623 } else {
1624 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1625 }
Girish Gowdracefae192020-03-19 18:14:10 -07001626 if err != nil {
1627 errorsList = append(errorsList, err)
1628 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001629 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301630
1631 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001632 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001633 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301634 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001635 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301636 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001637 if flow_utils.HasGroup(flow) {
1638 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1639 } else {
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001640 if dh.flowMgr == nil || dh.flowMgr[ponIf] == nil {
1641 // The flow manager module could be uninitialized if the flow arrives too soon before the device has reconciled fully
1642 logger.Errorw(ctx, "flow-manager-uninitialized", log.Fields{"device-id": device.Id})
1643 err = fmt.Errorf("flow-manager-uninitialized-%v", device.Id)
1644 } else {
1645 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1646 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08001647 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001648 if err != nil {
1649 errorsList = append(errorsList, err)
1650 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301651 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001652 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001653
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001654 return errorsList
1655}
1656
1657func (dh *DeviceHandler) handleGroups(ctx context.Context, groups *of.FlowGroupChanges) []error {
1658 var err error
1659 var errorsList []error
1660
Girish Gowdracefae192020-03-19 18:14:10 -07001661 // 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 +00001662 if groups != nil {
1663 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001664 // err = dh.groupMgr.AddGroup(ctx, group)
1665 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001666 if err != nil {
1667 errorsList = append(errorsList, err)
1668 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001669 }
1670 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001671 // err = dh.groupMgr.ModifyGroup(ctx, group)
1672 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001673 if err != nil {
1674 errorsList = append(errorsList, err)
1675 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001676 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001677 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001678 // err = dh.groupMgr.DeleteGroup(ctx, group)
1679 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001680 if err != nil {
1681 errorsList = append(errorsList, err)
1682 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001683 }
1684 }
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001685
1686 return errorsList
1687}
1688
1689//UpdateFlowsIncrementally updates the device flow
1690func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
1691
1692 var errorsList []error
Girish Gowdra950326e2021-11-05 12:43:24 -07001693
1694 if dh.getDeviceDeletionInProgressFlag() {
1695 // The device itself is going to be reset as part of deletion. So nothing to be done.
1696 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1697 return nil
1698 }
1699
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001700 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
1701 errorsList = append(errorsList, dh.handleFlows(ctx, device, flows, flowMetadata)...)
1702 errorsList = append(errorsList, dh.handleGroups(ctx, groups)...)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001703 if len(errorsList) > 0 {
1704 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1705 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001706 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001707 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301708}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001709
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001710//DisableDevice disables the given device
1711//It marks the following for the given device:
1712//Device-Handler Admin-State : down
1713//Device Port-State: UNKNOWN
1714//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001715func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001716 /* On device disable ,admin state update has to be done prior sending request to agent since
1717 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001718 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001719 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001720 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001721 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001722 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001723 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001724 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001725 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001726 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001727 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301728
1729 dh.discOnus = sync.Map{}
1730 dh.onus = sync.Map{}
1731
Thomas Lee S85f37312020-04-03 17:06:12 +05301732 //stopping the stats collector
1733 dh.stopCollector <- true
1734
Neha Sharma96b7bf22020-06-15 10:37:32 +00001735 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001736 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301737 //Update device Admin state
1738 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -04001739
kdarapu1afeceb2020-02-12 01:38:09 -05001740 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
khenaidoo106c61a2021-08-11 18:05:46 -04001741 if err := dh.updatePortsStateInCore(ctx, &ic.PortStateFilter{
1742 DeviceId: cloned.Id,
1743 PortTypeFilter: ^uint32(1 << voltha.Port_PON_OLT),
1744 OperStatus: voltha.OperStatus_UNKNOWN,
1745 }); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001746 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001747 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001748 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001749 return nil
1750}
1751
Neha Sharma96b7bf22020-06-15 10:37:32 +00001752func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001753 // Update onu state as unreachable in onu adapter
1754 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301755 onuInd.OperState = state
khenaidoo106c61a2021-08-11 18:05:46 -04001756
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001757 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -04001758 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001759 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001760 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "err": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001761 }
1762 if onuDevices != nil {
1763 for _, onuDevice := range onuDevices.Items {
khenaidoo106c61a2021-08-11 18:05:46 -04001764 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ic.OnuIndicationMessage{
1765 DeviceId: onuDevice.Id,
1766 OnuIndication: &onuInd,
1767 })
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001768 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001769 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001770 "From Adapter": dh.openOLT.config.AdapterEndpoint, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001771 }
1772
1773 }
1774 }
1775
1776}
1777
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001778//ReenableDevice re-enables the olt device after disable
1779//It marks the following for the given device:
1780//Device-Handler Admin-State : up
1781//Device Port-State: ACTIVE
1782//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001783func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001784 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301785 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001786 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301787 }
1788 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001789 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001790
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001791 // Update the all ports state on that device to enable
khenaidoo106c61a2021-08-11 18:05:46 -04001792 ports, err := dh.listDevicePortsFromCore(ctx, device.Id)
Mahir Gunyele5e807a2021-10-22 11:33:25 -07001793 var retError error
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001794 if err != nil {
Mahir Gunyele5e807a2021-10-22 11:33:25 -07001795 retError = olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
1796 } else {
1797 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
1798 retError = olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
1799 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001800 }
Mahir Gunyele5e807a2021-10-22 11:33:25 -07001801 if retError == nil {
1802 //Update the device oper status as ACTIVE
1803 device.OperStatus = voltha.OperStatus_ACTIVE
1804 } else {
1805 //Update the device oper status as FAILED
1806 device.OperStatus = voltha.OperStatus_FAILED
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001807 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001808 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001809
khenaidoo106c61a2021-08-11 18:05:46 -04001810 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1811 DeviceId: device.Id,
1812 OperStatus: device.OperStatus,
1813 ConnStatus: device.ConnectStatus,
1814 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301815 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001816 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001817 "connect-status": device.ConnectStatus,
1818 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001819 }
kesavand39e0aa32020-01-28 20:58:50 -05001820
Neha Sharma96b7bf22020-06-15 10:37:32 +00001821 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001822
Mahir Gunyele5e807a2021-10-22 11:33:25 -07001823 return retError
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001824}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001825
npujarec5762e2020-01-01 14:08:48 +05301826func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001827 var uniID uint32
1828 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301829 for _, port := range onu.UniPorts {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001830 uniID = plt.UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001831 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001832 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001833 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001834 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001835 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001836 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001837 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001838 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001839 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001840 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001841 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001842 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001843 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001844 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001845 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001846 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301847 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001848 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1849 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001850 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301851 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001852 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001853 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001854 logger.Debugw(ctx, "failed-to-remove-gemport-pkt-in", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001855 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001856 }
1857 return nil
1858}
1859
Devmalya Paul495b94a2019-08-27 19:42:00 -04001860// DeleteDevice deletes the device instance from openolt handler array. Also clears allocated resource manager resources. Also reboots the OLT hardware!
npujarec5762e2020-01-01 14:08:48 +05301861func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001862 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001863 /* Clear the KV store data associated with the all the UNI ports
1864 This clears up flow data and also resource map data for various
1865 other pon resources like alloc_id and gemport_id
1866 */
Girish Gowdra950326e2021-11-05 12:43:24 -07001867
1868 dh.setDeviceDeletionInProgressFlag(true)
1869
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001870 dh.cleanupDeviceResources(ctx)
1871 logger.Debugw(ctx, "removed-device-from-Resource-manager-KV-store", log.Fields{"device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001872 // Stop the Stats collector
1873 dh.stopCollector <- true
1874 // stop the heartbeat check routine
1875 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301876 dh.lockDevice.RLock()
1877 // Stop the read indication only if it the routine is active
1878 if dh.isReadIndicationRoutineActive {
1879 dh.stopIndications <- true
1880 }
1881 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001882 dh.removeOnuIndicationChannels(ctx)
Girish Gowdra4736e5c2021-08-25 15:19:10 -07001883 go dh.StopAllMcastHandlerRoutines(ctx)
1884 for _, flMgr := range dh.flowMgr {
1885 go flMgr.StopAllFlowHandlerRoutines(ctx)
1886 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001887 //Reset the state
1888 if dh.Client != nil {
1889 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301890 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001891 }
1892 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001893 // There is no need to update the core about operation status and connection status of the OLT.
1894 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1895 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1896 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001897
khenaidoo7eb2d672021-10-22 19:08:50 -04001898 // Stop the adapter grpc clients for that parent device
1899 dh.deleteAdapterClients(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001900 return nil
1901}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001902func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001903
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001904 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301905 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001906 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001907 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001908 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001909 for i, onu := range onuGemData {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001910 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001911 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001912 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301913 }
1914 }
Girish Gowdra950326e2021-11-05 12:43:24 -07001915 _ = dh.resourceMgr[ponPort].DeleteAllFlowIDsForGemForIntf(ctx, ponPort)
1916 _ = dh.resourceMgr[ponPort].DeleteAllOnuGemInfoForIntf(ctx, ponPort)
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001917 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1918 logger.Debug(ctx, err)
1919 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001920 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001921 }
A R Karthick1f85b802019-10-11 05:06:05 +00001922
Devmalya Paul495b94a2019-08-27 19:42:00 -04001923 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301924 dh.onus.Range(func(key interface{}, value interface{}) bool {
1925 dh.onus.Delete(key)
1926 return true
1927 })
1928
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001929 /*Delete discovered ONU map for the device*/
1930 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1931 dh.discOnus.Delete(key)
1932 return true
1933 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001934}
1935
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001936//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001937func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001938 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301939 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001940 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001941 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001942 return nil
1943}
1944
David K. Bainbridge794735f2020-02-11 21:01:37 -08001945func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001946 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001947 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001948 "packet-indication": *packetIn,
1949 "device-id": dh.device.Id,
1950 "packet": hex.EncodeToString(packetIn.Pkt),
1951 })
1952 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001953 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001954 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001955 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001956 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001957 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001958 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001959 "logical-port-num": logicalPortNum,
1960 "device-id": dh.device.Id,
1961 "packet": hex.EncodeToString(packetIn.Pkt),
1962 })
1963 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001964
khenaidoo106c61a2021-08-11 18:05:46 -04001965 if err := dh.sendPacketToCore(ctx, &ic.PacketIn{
1966 DeviceId: dh.device.Id,
1967 Port: logicalPortNum,
1968 Packet: packetIn.Pkt,
1969 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301970 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001971 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301972 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001973 "device-id": dh.device.Id,
1974 "packet": hex.EncodeToString(packetIn.Pkt),
1975 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001976 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001977
Matteo Scandolo92186242020-06-12 10:54:18 -07001978 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001979 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001980 "packet": hex.EncodeToString(packetIn.Pkt),
1981 "device-id": dh.device.Id,
1982 })
1983 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001984 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001985}
1986
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001987// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
khenaidoo106c61a2021-08-11 18:05:46 -04001988func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo uint32, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001989 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001990 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001991 "device-id": dh.device.Id,
1992 "egress-port-no": egressPortNo,
1993 "pkt-length": len(packet.Data),
1994 "packet": hex.EncodeToString(packet.Data),
1995 })
1996 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001997
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001998 egressPortType := plt.IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001999 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04002000 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
2001 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05302002 if outerEthType == 0x8942 || outerEthType == 0x88cc {
2003 // Do not packet-out lldp packets on uni port.
2004 // ONOS has no clue about uni/nni ports, it just packets out on all
2005 // available ports on the Logical Switch. It should not be interested
2006 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002007 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002008 "device-id": dh.device.Id,
2009 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05302010 return nil
2011 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04002012 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
2013 if innerEthType == 0x8100 {
2014 // q-in-q 802.1ad or 802.1q double tagged packet.
2015 // slice out the outer tag.
2016 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07002017 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002018 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002019 "packet-data": hex.EncodeToString(packet.Data),
2020 "device-id": dh.device.Id,
2021 })
2022 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04002023 }
2024 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002025 intfID := plt.IntfIDFromUniPortNum(uint32(egressPortNo))
2026 onuID := plt.OnuIDFromPortNum(uint32(egressPortNo))
2027 uniID := plt.UniIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04002028
Girish Gowdra9602eb42020-09-09 15:50:39 -07002029 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04002030 if err != nil {
2031 // In this case the openolt agent will receive the gemPortID as 0.
2032 // The agent tries to retrieve the gemPortID in this case.
2033 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002034 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002035 "intf-id": intfID,
2036 "onu-id": onuID,
2037 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002038 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05302039 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08002040 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04002041 }
2042
2043 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07002044 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002045 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002046 "egress-port-no": egressPortNo,
2047 "intf-id": intfID,
2048 "onu-id": onuID,
2049 "uni-id": uniID,
2050 "gem-port-id": gemPortID,
2051 "packet": hex.EncodeToString(packet.Data),
2052 "device-id": dh.device.Id,
2053 })
2054 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04002055
npujarec5762e2020-01-01 14:08:48 +05302056 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302057 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002058 "source": "adapter",
2059 "destination": "onu",
2060 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07002061 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08002062 "oni-id": onuID,
2063 "uni-id": uniID,
2064 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002065 "packet": hex.EncodeToString(packet.Data),
2066 "device-id": dh.device.Id,
2067 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04002068 }
2069 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002070 nniIntfID, err := plt.IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08002071 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002072 return olterrors.NewErrInvalidValue(log.Fields{
2073 "egress-nni-port": egressPortNo,
2074 "device-id": dh.device.Id,
2075 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08002076 }
2077 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04002078
Matteo Scandolo92186242020-06-12 10:54:18 -07002079 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002080 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002081 "uplink-pkt": uplinkPkt,
2082 "packet": hex.EncodeToString(packet.Data),
2083 "device-id": dh.device.Id,
2084 })
2085 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04002086
npujarec5762e2020-01-01 14:08:48 +05302087 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002088 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
2089 "packet": hex.EncodeToString(packet.Data),
2090 "device-id": dh.device.Id,
2091 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04002092 }
2093 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002094 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05302095 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08002096 "egressPortType": egressPortType,
2097 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05302098 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08002099 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04002100 }
2101 return nil
2102}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07002103
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07002104func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
2105 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07002106}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302107
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002108func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00002109
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302110 // start the heartbeat check towards the OLT.
2111 var timerCheck *time.Timer
2112
2113 for {
2114 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
2115 select {
2116 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00002117 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002118 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002119 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302120 if timerCheck == nil {
2121 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002122 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302123 }
2124 } else {
2125 if timerCheck != nil {
2126 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002127 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302128 }
2129 timerCheck = nil
2130 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002131 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05302132 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302133 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302134 }
2135 cancel()
2136 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002137 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302138 return
2139 }
2140 }
2141}
2142
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002143func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -04002144 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002145 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002146 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2147 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2148 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2149 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2150 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002151 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002152 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2153 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002154 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302155
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002156 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2157 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002158 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
khenaidoo106c61a2021-08-11 18:05:46 -04002159 if err = dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
2160 DeviceId: dh.device.Id,
2161 OperStatus: voltha.OperStatus_UNKNOWN,
2162 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2163 }); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002164 _ = olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002165 }
khenaidoo106c61a2021-08-11 18:05:46 -04002166
2167 if err = dh.updatePortsStateInCore(ctx, &ic.PortStateFilter{
2168 DeviceId: dh.device.Id,
2169 PortTypeFilter: 0,
2170 OperStatus: voltha.OperStatus_UNKNOWN,
2171 }); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002172 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002173 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002174
2175 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002176 raisedTs := time.Now().Unix()
khenaidoo106c61a2021-08-11 18:05:46 -04002177 cloned := proto.Clone(device).(*voltha.Device)
2178 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2179 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2180 dh.device = cloned // update local copy of the device
2181 go dh.eventMgr.oltCommunicationEvent(ctx, cloned, raisedTs)
Gamze Abaka07868a52020-12-17 14:19:28 +00002182
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002183 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002184 // Stop the Stats collector
2185 dh.stopCollector <- true
2186 // stop the heartbeat check routine
2187 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002188
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002189 dh.lockDevice.RLock()
2190 // Stop the read indication only if it the routine is active
2191 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2192 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2193 // on next execution of the readIndication routine.
2194 if dh.isReadIndicationRoutineActive {
2195 dh.stopIndications <- true
2196 }
2197 dh.lockDevice.RUnlock()
2198
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002199 go dh.StopAllMcastHandlerRoutines(ctx)
2200 for _, flMgr := range dh.flowMgr {
2201 go flMgr.StopAllFlowHandlerRoutines(ctx)
2202 }
2203
Gamze Abakac2c32a62021-03-11 11:44:18 +00002204 //reset adapter reconcile flag
2205 dh.adapterPreviouslyConnected = false
2206
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002207 dh.transitionMap.Handle(ctx, DeviceInit)
2208
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302209 }
2210}
kesavand39e0aa32020-01-28 20:58:50 -05002211
2212// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002213func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2214 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2215 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002216}
2217
2218// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002219func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2220 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2221 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002222}
2223
kdarapu1afeceb2020-02-12 01:38:09 -05002224//modifyPhyPort is common function to enable and disable the port. parm :enablePort, true to enablePort and false to disablePort.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002225func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2226 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002227 if port.GetType() == voltha.Port_ETHERNET_NNI {
2228 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002229 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302230 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302231 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002232 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002233 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002234 }
2235 // fetch interfaceid from PortNo
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002236 ponID := plt.PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
kesavand39e0aa32020-01-28 20:58:50 -05002237 ponIntf := &oop.Interface{IntfId: ponID}
2238 var operStatus voltha.OperStatus_Types
2239 if enablePort {
2240 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302241 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002242
2243 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302244 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002245 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002246 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002247 }
2248 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002249 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002250 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002251 } else {
2252 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302253 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002254 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302255 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002256 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002257 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002258 }
2259 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002260 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002261 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002262 }
khenaidoo106c61a2021-08-11 18:05:46 -04002263 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
2264 DeviceId: dh.device.Id,
2265 PortType: voltha.Port_PON_OLT,
2266 PortNo: port.PortNo,
2267 OperStatus: operStatus,
2268 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302269 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302270 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002271 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002272 }
2273 return nil
2274}
2275
kdarapu1afeceb2020-02-12 01:38:09 -05002276//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002277func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002278 // Disable the port and update the oper_port_status to core
2279 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002280 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002281 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002282 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302283 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302284 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002285 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002286 }
2287 }
2288 }
2289 return nil
2290}
2291
2292//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002293func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2294 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2295 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002296 if port.Type == voltha.Port_ETHERNET_NNI {
2297 if port.OperStatus == voltha.OperStatus_ACTIVE {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002298 dh.activePorts.Store(plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002299 } else {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002300 dh.activePorts.Store(plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002301 }
2302 }
2303 if port.Type == voltha.Port_PON_OLT {
2304 if port.OperStatus == voltha.OperStatus_ACTIVE {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002305 dh.activePorts.Store(plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002306 } else {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002307 dh.activePorts.Store(plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002308 }
2309 }
2310 }
2311}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002312
2313// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002314func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002315 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002316 intfID := plt.PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002317 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002318
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002319 var sn *oop.SerialNumber
2320 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002321 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302322 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002323 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302324 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002325 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002326 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002327
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002328 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002329 //clear PON resources associated with ONU
2330 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2331 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2332 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2333 "device-id": dh.device.Id,
2334 "intf-id": intfID,
2335 "onuID": onuID,
2336 "err": err})
2337 } else {
2338 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2339 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2340 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2341 "device-id": dh.device.Id,
2342 "onu-device": onu,
2343 "err": err})
2344 }
2345 // Clear flowids for gem cache.
2346 for _, gem := range onuGem.GemPorts {
2347 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2348 }
Girish Gowdra197acc12021-08-16 10:59:45 -07002349 if err := dh.flowMgr[intfID].RemoveOnuInfoFromFlowMgrCacheAndKvStore(ctx, intfID, onuID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002350 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2351 "intf-id": intfID,
2352 "onu-device": onu,
2353 "onu-gem": onuGem,
2354 "err": err})
2355 //Not returning error on cleanup.
2356 }
2357 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
Himani Chawlabcc95852021-10-27 10:55:40 +05302358
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002359 }
Himani Chawlabcc95852021-10-27 10:55:40 +05302360 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002361 dh.onus.Delete(onuKey)
2362 dh.discOnus.Delete(onuSn)
2363
2364 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002365 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302366 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302367 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002368 "onu-id": onuID}, err).Log()
2369 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002370
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002371 return nil
2372}
Girish Gowdracefae192020-03-19 18:14:10 -07002373
2374func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002375 for _, field := range flow_utils.GetOfbFields(flow) {
2376 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002377 return field.GetPort()
2378 }
2379 }
2380 return InvalidPort
2381}
2382
2383func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002384 for _, action := range flow_utils.GetActions(flow) {
2385 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002386 if out := action.GetOutput(); out != nil {
2387 return out.GetPort()
2388 }
2389 }
2390 }
2391 return InvalidPort
2392}
2393
Girish Gowdracefae192020-03-19 18:14:10 -07002394func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2395 inPort := getInPortFromFlow(flow)
2396 outPort := getOutPortFromFlow(flow)
2397
2398 if inPort == InvalidPort || outPort == InvalidPort {
2399 return inPort, outPort
2400 }
2401
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002402 if isControllerFlow := plt.IsControllerBoundFlow(outPort); isControllerFlow {
Girish Gowdracefae192020-03-19 18:14:10 -07002403 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002404 if portType := plt.IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002405 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002406 return uniPort, outPort
2407 }
2408 }
2409 } else {
2410 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002411 if portType := plt.IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002412 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002413 return inPort, uniPort
2414 }
2415 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002416 } else if portType := plt.IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002417 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002418 return uniPort, outPort
2419 }
2420 }
2421 }
2422
2423 return InvalidPort, InvalidPort
2424}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002425
2426func extractOmciTransactionID(omciPkt []byte) uint16 {
2427 if len(omciPkt) > 3 {
2428 d := omciPkt[0:2]
2429 transid := binary.BigEndian.Uint16(d)
2430 return transid
2431 }
2432 return 0
2433}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002434
2435// StoreOnuDevice stores the onu parameters to the local cache.
2436func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2437 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2438 dh.onus.Store(onuKey, onuDevice)
2439}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002440
Neha Sharma8f4e4322020-08-06 10:51:53 +00002441func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002442 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002443 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002444 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002445 resp := new(voltha.ReturnValues)
2446 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002447 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002448 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002449 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2450 return nil, err
2451 }
2452 ID = device.ProxyAddress.GetOnuId()
2453 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2454 valueparam.Onu = &Onu
2455 valueparam.Value = value
2456
2457 // This API is unsupported until agent patch is added
2458 resp.Unsupported = uint32(value)
2459 _ = ctx
2460
2461 // Uncomment this code once agent changes are complete and tests
2462 /*
2463 resp, err = dh.Client.GetValue(ctx, valueparam)
2464 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002465 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002466 return nil, err
2467 }
2468 */
2469
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002470 logger.Infow(ctx, "get-ext-value", log.Fields{"resp": resp, "device-id": dh.device, "onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002471 return resp, nil
2472}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002473
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002474func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002475 // Default to PON0
2476 var intfID uint32
2477 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002478 if inPort != InvalidPort && outPort != InvalidPort {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002479 _, intfID, _, _ = plt.ExtractAccessFromFlow(inPort, outPort)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002480 }
2481 return intfID
2482}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002483
Mahir Gunyelb0046752021-02-26 13:51:05 -08002484func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2485 dh.perPonOnuIndicationChannelLock.Lock()
2486 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2487 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002488 return ch.indicationChannel
2489 }
2490 channels := onuIndicationChannels{
2491 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002492 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002493 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002494 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002495 stopChannel: make(chan struct{}),
2496 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002497 dh.perPonOnuIndicationChannel[intfID] = channels
2498 dh.perPonOnuIndicationChannelLock.Unlock()
2499 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002500 return channels.indicationChannel
2501
2502}
2503
Mahir Gunyelb0046752021-02-26 13:51:05 -08002504func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2505 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2506 dh.perPonOnuIndicationChannelLock.Lock()
2507 defer dh.perPonOnuIndicationChannelLock.Unlock()
2508 for _, v := range dh.perPonOnuIndicationChannel {
2509 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002510 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002511 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002512}
2513
Mahir Gunyelb0046752021-02-26 13:51:05 -08002514func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2515 ind := onuIndicationMsg{
2516 ctx: ctx,
2517 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002518 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002519 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002520 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002521 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002522}
2523
Mahir Gunyelb0046752021-02-26 13:51:05 -08002524func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002525 for {
2526 select {
2527 // process one indication per onu, before proceeding to the next one
2528 case onuInd := <-onuChannels.indicationChannel:
2529 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002530 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002531 switch onuInd.indication.Data.(type) {
2532 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002533 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002534 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2535 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002536 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002537 }
2538 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002539 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002540 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2541 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002542 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002543 }
2544 }
2545 case <-onuChannels.stopChannel:
2546 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2547 close(onuChannels.indicationChannel)
2548 return
2549 }
2550 }
2551}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002552
2553// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2554// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2555func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2556 // Step1 : Fill McastFlowOrGroupControlBlock
2557 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2558 // Step3 : Wait on response channel for response
2559 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002560 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002561 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2562 errChan := make(chan error)
2563 var groupID uint32
2564 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2565 ctx: ctx,
2566 flowOrGroupAction: action,
2567 flow: flow,
2568 group: group,
2569 errChan: &errChan,
2570 }
2571 if flow != nil {
2572 groupID = flow_utils.GetGroup(flow)
2573 } else if group != nil {
2574 groupID = group.Desc.GroupId
2575 } else {
2576 return errors.New("flow-and-group-both-nil")
2577 }
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002578 mcastRoutineIdx := groupID % MaxNumOfGroupHandlerChannels
2579 if dh.mcastHandlerRoutineActive[mcastRoutineIdx] {
2580 // Derive the appropriate go routine to handle the request by a simple module operation.
2581 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2582 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2583 // Wait for handler to return error value
2584 err := <-errChan
2585 logger.Debugw(ctx, "process-flow-or-group--received-resp", log.Fields{"err": err, "totalTimeInSeconds": time.Since(startTime).Milliseconds()})
2586 return err
2587 }
2588 logger.Errorw(ctx, "mcast handler routine not active for onu", log.Fields{"mcastRoutineIdx": mcastRoutineIdx})
2589 return fmt.Errorf("mcast-handler-routine-not-active-for-index-%v", mcastRoutineIdx)
Girish Gowdra491a9c62021-01-06 16:43:07 -08002590}
2591
2592// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002593func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(routineIndex int, mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock, stopHandler chan bool) {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002594 for {
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002595 select {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002596 // block on the channel to receive an incoming mcast flow/group
2597 // process the flow completely before proceeding to handle the next flow
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002598 case mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel:
2599 if mcastFlowOrGroupCb.flow != nil {
2600 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2601 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2602 log.Fields{"device-id": dh.device.Id,
2603 "flowToAdd": mcastFlowOrGroupCb.flow})
2604 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2605 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2606 // Pass the return value over the return channel
2607 *mcastFlowOrGroupCb.errChan <- err
2608 } else { // flow remove
2609 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2610 log.Fields{"device-id": dh.device.Id,
2611 "flowToRemove": mcastFlowOrGroupCb.flow})
2612 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2613 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2614 // Pass the return value over the return channel
2615 *mcastFlowOrGroupCb.errChan <- err
2616 }
2617 } else { // mcast group
2618 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2619 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2620 log.Fields{"device-id": dh.device.Id,
2621 "groupToAdd": mcastFlowOrGroupCb.group})
2622 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2623 // Pass the return value over the return channel
2624 *mcastFlowOrGroupCb.errChan <- err
2625 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2626 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2627 log.Fields{"device-id": dh.device.Id,
2628 "groupToModify": mcastFlowOrGroupCb.group})
2629 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2630 // Pass the return value over the return channel
2631 *mcastFlowOrGroupCb.errChan <- err
2632 } else { // group remove
2633 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2634 log.Fields{"device-id": dh.device.Id,
2635 "groupToRemove": mcastFlowOrGroupCb.group})
2636 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2637 // Pass the return value over the return channel
2638 *mcastFlowOrGroupCb.errChan <- err
2639 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08002640 }
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002641 case <-stopHandler:
2642 dh.mcastHandlerRoutineActive[routineIndex] = false
2643 return
Girish Gowdra491a9c62021-01-06 16:43:07 -08002644 }
2645 }
2646}
kesavand62126212021-01-12 04:56:06 -05002647
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002648// StopAllMcastHandlerRoutines stops all flow handler routines. Call this when device is being rebooted or deleted
2649func (dh *DeviceHandler) StopAllMcastHandlerRoutines(ctx context.Context) {
2650 for i, v := range dh.stopMcastHandlerRoutine {
2651 if dh.mcastHandlerRoutineActive[i] {
2652 v <- true
2653 }
2654 }
2655 logger.Debug(ctx, "stopped all mcast handler routines")
2656}
2657
kesavand62126212021-01-12 04:56:06 -05002658func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2659
2660 singleValResp := extension.SingleGetValueResponse{
2661 Response: &extension.GetValueResponse{
2662 Response: &extension.GetValueResponse_PortCoutners{
2663 PortCoutners: &extension.GetOltPortCountersResponse{},
2664 },
2665 },
2666 }
2667
2668 errResp := func(status extension.GetValueResponse_Status,
2669 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2670 return &extension.SingleGetValueResponse{
2671 Response: &extension.GetValueResponse{
2672 Status: status,
2673 ErrReason: reason,
2674 },
2675 }
2676 }
2677
2678 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2679 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2680 //send error response
2681 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2682 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2683 }
2684 statIndChn := make(chan bool, 1)
2685 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2686 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2687 //request openOlt agent to send the the port statistics indication
2688
2689 go func() {
2690 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2691 if err != nil {
2692 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2693 }
2694 }()
2695 select {
2696 case <-statIndChn:
2697 //indication received for ports stats
2698 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2699 case <-time.After(oltPortInfoTimeout * time.Second):
2700 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2701 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2702 case <-ctx.Done():
2703 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2704 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2705 }
2706 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2707 //get nni stats
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002708 intfID := plt.PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
kesavand62126212021-01-12 04:56:06 -05002709 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2710 cmnni := dh.portStats.collectNNIMetrics(intfID)
2711 if cmnni == nil {
2712 //TODO define the error reason
2713 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2714 }
2715 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2716 return &singleValResp
2717
2718 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2719 // get pon stats
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002720 intfID := plt.PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
kesavand62126212021-01-12 04:56:06 -05002721 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2722 cmpon := dh.portStats.collectPONMetrics(intfID)
2723 if cmpon == nil {
2724 //TODO define the error reason
2725 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2726 }
2727 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2728 return &singleValResp
2729 }
2730 }
2731 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2732}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302733
2734func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2735
2736 singleValResp := extension.SingleGetValueResponse{
2737 Response: &extension.GetValueResponse{
2738 Response: &extension.GetValueResponse_OnuPonCounters{
2739 OnuPonCounters: &extension.GetOnuCountersResponse{},
2740 },
2741 },
2742 }
2743
2744 errResp := func(status extension.GetValueResponse_Status,
2745 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2746 return &extension.SingleGetValueResponse{
2747 Response: &extension.GetValueResponse{
2748 Status: status,
2749 ErrReason: reason,
2750 },
2751 }
2752 }
2753 intfID := onuPonInfo.IntfId
2754 onuID := onuPonInfo.OnuId
2755 onuKey := dh.formOnuKey(intfID, onuID)
2756
2757 if _, ok := dh.onus.Load(onuKey); !ok {
2758 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2759 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2760 }
2761 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2762 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2763 if cmnni == nil {
2764 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2765 }
2766 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2767 return &singleValResp
2768
2769}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002770
2771func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2772
2773 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2774 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2775 if err != nil {
2776 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2777 return generateSingleGetValueErrorResponse(err)
2778 }
2779 return &extension.SingleGetValueResponse{
2780 Response: &extension.GetValueResponse{
2781 Status: extension.GetValueResponse_OK,
2782 Response: &extension.GetValueResponse_RxPower{
2783 RxPower: &extension.GetRxPowerResponse{
2784 IntfId: rxPowerRequest.IntfId,
2785 OnuId: rxPowerRequest.OnuId,
2786 Status: rxPower.Status,
2787 FailReason: rxPower.FailReason.String(),
2788 RxPower: rxPower.RxPowerMeanDbm,
2789 },
2790 },
2791 },
2792 }
2793}
2794
2795func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2796 errResp := func(status extension.GetValueResponse_Status,
2797 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2798 return &extension.SingleGetValueResponse{
2799 Response: &extension.GetValueResponse{
2800 Status: status,
2801 ErrReason: reason,
2802 },
2803 }
2804 }
2805
2806 if err != nil {
2807 if e, ok := status.FromError(err); ok {
2808 switch e.Code() {
2809 case codes.Internal:
2810 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2811 case codes.DeadlineExceeded:
2812 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2813 case codes.Unimplemented:
2814 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2815 case codes.NotFound:
2816 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2817 }
2818 }
2819 }
2820
2821 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2822}
khenaidoo106c61a2021-08-11 18:05:46 -04002823
2824/*
2825Helper functions to communicate with Core
2826*/
2827
2828func (dh *DeviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
2829 cClient, err := dh.coreClient.GetCoreServiceClient()
2830 if err != nil || cClient == nil {
2831 return nil, err
2832 }
2833 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2834 defer cancel()
2835 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
2836}
2837
2838func (dh *DeviceHandler) getChildDeviceFromCore(ctx context.Context, childDeviceFilter *ic.ChildDeviceFilter) (*voltha.Device, error) {
2839 cClient, err := dh.coreClient.GetCoreServiceClient()
2840 if err != nil || cClient == nil {
2841 return nil, err
2842 }
2843 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2844 defer cancel()
2845 return cClient.GetChildDevice(subCtx, childDeviceFilter)
2846}
2847
2848func (dh *DeviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ic.DeviceStateFilter) error {
2849 cClient, err := dh.coreClient.GetCoreServiceClient()
2850 if err != nil || cClient == nil {
2851 return err
2852 }
2853 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2854 defer cancel()
2855 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
2856 return err
2857}
2858
2859func (dh *DeviceHandler) getChildDevicesFromCore(ctx context.Context, deviceID string) (*voltha.Devices, error) {
2860 cClient, err := dh.coreClient.GetCoreServiceClient()
2861 if err != nil || cClient == nil {
2862 return nil, err
2863 }
2864 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2865 defer cancel()
2866 return cClient.GetChildDevices(subCtx, &common.ID{Id: deviceID})
2867}
2868
2869func (dh *DeviceHandler) listDevicePortsFromCore(ctx context.Context, deviceID string) (*voltha.Ports, error) {
2870 cClient, err := dh.coreClient.GetCoreServiceClient()
2871 if err != nil || cClient == nil {
2872 return nil, err
2873 }
2874 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2875 defer cancel()
2876 return cClient.ListDevicePorts(subCtx, &common.ID{Id: deviceID})
2877}
2878
2879func (dh *DeviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
2880 cClient, err := dh.coreClient.GetCoreServiceClient()
2881 if err != nil || cClient == nil {
2882 return err
2883 }
2884 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2885 defer cancel()
2886 _, err = cClient.DeviceUpdate(subCtx, device)
2887 return err
2888}
2889
2890func (dh *DeviceHandler) sendChildDeviceDetectedToCore(ctx context.Context, deviceDiscoveryInfo *ic.DeviceDiscovery) (*voltha.Device, error) {
2891 cClient, err := dh.coreClient.GetCoreServiceClient()
2892 if err != nil || cClient == nil {
2893 return nil, err
2894 }
2895 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2896 defer cancel()
2897 return cClient.ChildDeviceDetected(subCtx, deviceDiscoveryInfo)
2898}
2899
2900func (dh *DeviceHandler) sendPacketToCore(ctx context.Context, pkt *ic.PacketIn) error {
2901 cClient, err := dh.coreClient.GetCoreServiceClient()
2902 if err != nil || cClient == nil {
2903 return err
2904 }
2905 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2906 defer cancel()
2907 _, err = cClient.SendPacketIn(subCtx, pkt)
2908 return err
2909}
2910
2911func (dh *DeviceHandler) createPortInCore(ctx context.Context, port *voltha.Port) error {
2912 cClient, err := dh.coreClient.GetCoreServiceClient()
2913 if err != nil || cClient == nil {
2914 return err
2915 }
2916 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2917 defer cancel()
2918 _, err = cClient.PortCreated(subCtx, port)
2919 return err
2920}
2921
2922func (dh *DeviceHandler) updatePortsStateInCore(ctx context.Context, portFilter *ic.PortStateFilter) error {
2923 cClient, err := dh.coreClient.GetCoreServiceClient()
2924 if err != nil || cClient == nil {
2925 return err
2926 }
2927 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2928 defer cancel()
2929 _, err = cClient.PortsStateUpdate(subCtx, portFilter)
2930 return err
2931}
2932
2933func (dh *DeviceHandler) updatePortStateInCore(ctx context.Context, portState *ic.PortState) error {
2934 cClient, err := dh.coreClient.GetCoreServiceClient()
2935 if err != nil || cClient == nil {
2936 return err
2937 }
2938 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2939 defer cancel()
2940 _, err = cClient.PortStateUpdate(subCtx, portState)
2941 return err
2942}
2943
2944func (dh *DeviceHandler) getPortFromCore(ctx context.Context, portFilter *ic.PortFilter) (*voltha.Port, error) {
2945 cClient, err := dh.coreClient.GetCoreServiceClient()
2946 if err != nil || cClient == nil {
2947 return nil, err
2948 }
2949 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2950 defer cancel()
2951 return cClient.GetDevicePort(subCtx, portFilter)
2952}
2953
2954/*
2955Helper functions to communicate with child adapter
2956*/
2957
2958func (dh *DeviceHandler) sendOmciIndicationToChildAdapter(ctx context.Context, childEndpoint string, response *ic.OmciMessage) error {
2959 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2960 if err != nil || aClient == nil {
2961 return err
2962 }
2963 logger.Debugw(ctx, "sending-omci-response", log.Fields{"response": response, "child-endpoint": childEndpoint})
2964 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2965 defer cancel()
2966 _, err = aClient.OmciIndication(subCtx, response)
2967 return err
2968}
2969
2970func (dh *DeviceHandler) sendOnuIndicationToChildAdapter(ctx context.Context, childEndpoint string, onuInd *ic.OnuIndicationMessage) error {
2971 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2972 if err != nil || aClient == nil {
2973 return err
2974 }
2975 logger.Debugw(ctx, "sending-onu-indication", log.Fields{"onu-indication": onuInd, "child-endpoint": childEndpoint})
2976 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2977 defer cancel()
2978 _, err = aClient.OnuIndication(subCtx, onuInd)
2979 return err
2980}
2981
2982func (dh *DeviceHandler) sendDeleteTContToChildAdapter(ctx context.Context, childEndpoint string, tContInfo *ic.DeleteTcontMessage) error {
2983 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2984 if err != nil || aClient == nil {
2985 return err
2986 }
2987 logger.Debugw(ctx, "sending-delete-tcont", log.Fields{"tcont": tContInfo, "child-endpoint": childEndpoint})
2988 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2989 defer cancel()
2990 _, err = aClient.DeleteTCont(subCtx, tContInfo)
2991 return err
2992}
2993
2994func (dh *DeviceHandler) sendDeleteGemPortToChildAdapter(ctx context.Context, childEndpoint string, gemPortInfo *ic.DeleteGemPortMessage) error {
2995 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2996 if err != nil || aClient == nil {
2997 return err
2998 }
2999 logger.Debugw(ctx, "sending-delete-gem-port", log.Fields{"gem-port-info": gemPortInfo, "child-endpoint": childEndpoint})
3000 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
3001 defer cancel()
3002 _, err = aClient.DeleteGemPort(subCtx, gemPortInfo)
3003 return err
3004}
3005
3006func (dh *DeviceHandler) sendDownloadTechProfileToChildAdapter(ctx context.Context, childEndpoint string, tpDownloadInfo *ic.TechProfileDownloadMessage) error {
3007 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
3008 if err != nil || aClient == nil {
3009 return err
3010 }
3011 logger.Debugw(ctx, "sending-tech-profile-download", log.Fields{"tp-download-info": tpDownloadInfo, "child-endpoint": childEndpoint})
3012 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
3013 defer cancel()
3014 _, err = aClient.DownloadTechProfile(subCtx, tpDownloadInfo)
3015 return err
3016}
3017
3018/*
3019Helper functions for remote communication
3020*/
3021
3022// TODO: Use a connection tracker such that the adapter connection is stopped when the last device that adapter
3023// supports is deleted
3024func (dh *DeviceHandler) setupChildInterAdapterClient(ctx context.Context, endpoint string) error {
3025 logger.Infow(ctx, "setting-child-adapter-connection", log.Fields{"child-endpoint": endpoint})
3026
3027 dh.lockChildAdapterClients.Lock()
3028 defer dh.lockChildAdapterClients.Unlock()
3029 if _, ok := dh.childAdapterClients[endpoint]; ok {
3030 // Already set
3031 return nil
3032 }
3033
3034 // Setup child's adapter grpc connection
3035 var err error
3036 if dh.childAdapterClients[endpoint], err = vgrpc.NewClient(endpoint,
3037 dh.onuAdapterRestarted,
3038 vgrpc.ActivityCheck(true)); err != nil {
3039 logger.Errorw(ctx, "grpc-client-not-created", log.Fields{"error": err, "endpoint": endpoint})
3040 return err
3041 }
3042 go dh.childAdapterClients[endpoint].Start(log.WithSpanFromContext(context.TODO(), ctx), setAndTestAdapterServiceHandler)
3043
3044 // Wait until we have a connection to the child adapter.
3045 // Unlimited retries or until context expires
3046 subCtx := log.WithSpanFromContext(context.TODO(), ctx)
3047 backoff := vgrpc.NewBackoff(dh.cfg.MinBackoffRetryDelay, dh.cfg.MaxBackoffRetryDelay, 0)
3048 for {
3049 client, err := dh.childAdapterClients[endpoint].GetOnuInterAdapterServiceClient()
3050 if err == nil && client != nil {
3051 logger.Infow(subCtx, "connected-to-child-adapter", log.Fields{"child-endpoint": endpoint})
3052 break
3053 }
3054 logger.Warnw(subCtx, "connection-to-child-adapter-not-ready", log.Fields{"error": err, "child-endpoint": endpoint})
3055 // Backoff
3056 if err = backoff.Backoff(subCtx); err != nil {
3057 logger.Errorw(subCtx, "received-error-on-backoff", log.Fields{"error": err, "child-endpoint": endpoint})
3058 break
3059 }
3060 }
3061 return nil
3062}
3063
3064// func (dh *DeviceHandler) getChildAdapterServiceClient(endpoint string) (adapter_services.OnuInterAdapterServiceClient, error) {
3065// dh.lockChildAdapterClients.RLock()
3066// defer dh.lockChildAdapterClients.RUnlock()
3067// if cgClient, ok := dh.childAdapterClients[endpoint]; ok {
3068// return cgClient.GetOnuInterAdapterServiceClient()
3069// }
3070// return nil, fmt.Errorf("no-client-for-endpoint-%s", endpoint)
3071// }
3072
3073func (dh *DeviceHandler) getChildAdapterServiceClient(endpoint string) (adapter_services.OnuInterAdapterServiceClient, error) {
3074
3075 // First check from cache
3076 dh.lockChildAdapterClients.RLock()
3077 if cgClient, ok := dh.childAdapterClients[endpoint]; ok {
3078 dh.lockChildAdapterClients.RUnlock()
3079 return cgClient.GetOnuInterAdapterServiceClient()
3080 }
3081 dh.lockChildAdapterClients.RUnlock()
3082
3083 // Set the child connection - can occur on restarts
3084 ctx, cancel := context.WithTimeout(context.Background(), dh.cfg.RPCTimeout)
3085 err := dh.setupChildInterAdapterClient(ctx, endpoint)
3086 cancel()
3087 if err != nil {
3088 return nil, err
3089 }
3090
3091 // Get the child client now
3092 dh.lockChildAdapterClients.RLock()
3093 defer dh.lockChildAdapterClients.RUnlock()
3094 if cgClient, ok := dh.childAdapterClients[endpoint]; ok {
3095 return cgClient.GetOnuInterAdapterServiceClient()
3096 }
3097 return nil, fmt.Errorf("no-client-for-endpoint-%s", endpoint)
3098}
3099
3100func (dh *DeviceHandler) deleteAdapterClients(ctx context.Context) {
3101 dh.lockChildAdapterClients.Lock()
3102 defer dh.lockChildAdapterClients.Unlock()
3103 for key, client := range dh.childAdapterClients {
3104 client.Stop(ctx)
3105 delete(dh.childAdapterClients, key)
3106 }
3107}
3108
3109// TODO: Any action the adapter needs to do following a onu adapter restart?
3110func (dh *DeviceHandler) onuAdapterRestarted(ctx context.Context, endPoint string) error {
khenaidoo7eb2d672021-10-22 19:08:50 -04003111 logger.Warnw(ctx, "onu-adapter-reconnected", log.Fields{"endpoint": endPoint})
khenaidoo106c61a2021-08-11 18:05:46 -04003112 return nil
3113}
3114
3115// setAndTestAdapterServiceHandler is used to test whether the remote gRPC service is up
3116func setAndTestAdapterServiceHandler(ctx context.Context, conn *grpc.ClientConn) interface{} {
3117 svc := adapter_services.NewOnuInterAdapterServiceClient(conn)
3118 if h, err := svc.GetHealthStatus(ctx, &empty.Empty{}); err != nil || h.State != voltha.HealthStatus_HEALTHY {
3119 return nil
3120 }
3121 return svc
3122}
Girish Gowdra950326e2021-11-05 12:43:24 -07003123
3124func (dh *DeviceHandler) setDeviceDeletionInProgressFlag(flag bool) {
3125 dh.lockDevice.Lock()
3126 defer dh.lockDevice.Unlock()
3127 dh.isDeviceDeletionInProgress = flag
3128}
3129
3130func (dh *DeviceHandler) getDeviceDeletionInProgressFlag() bool {
3131 dh.lockDevice.RLock()
3132 defer dh.lockDevice.RUnlock()
3133 return dh.isDeviceDeletionInProgress
3134}