blob: 33e2f5aa66cb2dd1fcdbe145ed9e1cd68c6dc0d3 [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
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700117}
118
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700119//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700120type OnuDevice struct {
khenaidoo106c61a2021-08-11 18:05:46 -0400121 deviceID string
122 deviceType string
123 serialNumber string
124 onuID uint32
125 intfID uint32
126 proxyDeviceID string
127 losRaised bool
128 rdiRaised bool
129 adapterEndpoint string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700130}
131
Mahir Gunyelb0046752021-02-26 13:51:05 -0800132type onuIndicationMsg struct {
133 ctx context.Context
134 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800135}
136
137type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800138 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800139 stopChannel chan struct{}
140}
141
Girish Gowdra491a9c62021-01-06 16:43:07 -0800142//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
143//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
144//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
145//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
146type McastFlowOrGroupControlBlock struct {
147 ctx context.Context // Flow/group handler context
148 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
149 flow *voltha.OfpFlowStats // Flow message (can be nil or valid flow)
150 group *voltha.OfpGroupEntry // Group message (can be nil or valid group)
151 errChan *chan error // channel to report the mcast Flow/group handling error
152}
153
Naga Manjunath7615e552019-10-11 22:35:47 +0530154var pmNames = []string{
155 "rx_bytes",
156 "rx_packets",
157 "rx_mcast_packets",
158 "rx_bcast_packets",
159 "tx_bytes",
160 "tx_packets",
161 "tx_mcast_packets",
162 "tx_bcast_packets",
163}
164
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700165//NewOnuDevice creates a new Onu Device
khenaidoo106c61a2021-08-11 18:05:46 -0400166func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool, adapterEndpoint string) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700167 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700168 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700169 device.deviceType = deviceTp
170 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700171 device.onuID = onuID
172 device.intfID = intfID
173 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530174 device.losRaised = losRaised
khenaidoo106c61a2021-08-11 18:05:46 -0400175 device.adapterEndpoint = adapterEndpoint
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700176 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530177}
178
179//NewDeviceHandler creates a new device handler
khenaidoo106c61a2021-08-11 18:05:46 -0400180func 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 -0700181 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800182 dh.cm = cm
khenaidoo106c61a2021-08-11 18:05:46 -0400183 dh.coreClient = cc
Devmalya Paulfb990a52019-07-09 10:01:49 -0400184 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700185 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700186 dh.device = cloned
187 dh.openOLT = adapter
188 dh.exitChannel = make(chan int, 1)
189 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530190 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530191 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530192 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 -0500193 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400194 dh.stopIndications = make(chan bool, 1)
Mahir Gunyelb0046752021-02-26 13:51:05 -0800195 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
khenaidoo106c61a2021-08-11 18:05:46 -0400196 dh.childAdapterClients = make(map[string]*vgrpc.Client)
197 dh.cfg = cfg
Girish Gowdra491a9c62021-01-06 16:43:07 -0800198 // Create a slice of buffered channels for handling concurrent mcast flow/group.
199 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700200 dh.stopMcastHandlerRoutine = make([]chan bool, MaxNumOfGroupHandlerChannels)
201 dh.mcastHandlerRoutineActive = make([]bool, MaxNumOfGroupHandlerChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800202 for i := range dh.incomingMcastFlowOrGroup {
203 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700204 dh.stopMcastHandlerRoutine[i] = make(chan bool, 1)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800205 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
206 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
207 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
208 // for incoming mcast flow/group to be processed serially.
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700209 dh.mcastHandlerRoutineActive[i] = true
210 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
Girish Gowdra491a9c62021-01-06 16:43:07 -0800211 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700212 //TODO initialize the support classes.
213 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530214}
215
216// start save the device to the data model
217func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700218 dh.lockDevice.Lock()
219 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000220 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700221 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000222 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530223}
224
225// stop stops the device dh. Not much to do for now
226func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700227 dh.lockDevice.Lock()
228 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000229 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700230 dh.exitChannel <- 1
khenaidoo106c61a2021-08-11 18:05:46 -0400231
Neha Sharma96b7bf22020-06-15 10:37:32 +0000232 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530233}
234
ssiddiqui04386ee2021-08-23 21:58:25 +0530235func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
236 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
237 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
238 if pooledIntfID == intfID {
239 return resourceRanges.GetTechnology()
240 }
241 }
242 }
243 return ""
244}
245
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400246func macifyIP(ip net.IP) string {
247 if len(ip) > 0 {
248 oct1 := strconv.FormatInt(int64(ip[12]), 16)
249 oct2 := strconv.FormatInt(int64(ip[13]), 16)
250 oct3 := strconv.FormatInt(int64(ip[14]), 16)
251 oct4 := strconv.FormatInt(int64(ip[15]), 16)
252 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
253 }
254 return ""
255}
256
Neha Sharma96b7bf22020-06-15 10:37:32 +0000257func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400258 var genmac string
259 var addr net.IP
260 var ips []string
261 var err error
262
Neha Sharma96b7bf22020-06-15 10:37:32 +0000263 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400264
265 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000266 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400267
268 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000269 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400270 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000271 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400272 }
273 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000274 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530275 log.Fields{"host": ips[0],
276 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400277 return genmac, nil
278 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000279 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400280 }
281
282 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000283 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530284 log.Fields{"host": host,
285 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400286 return genmac, nil
287}
288
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530289func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700290 slist := strings.Split(mac, ":")
291 result := make([]uint32, len(slist))
292 var err error
293 var tmp int64
294 for index, val := range slist {
295 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
296 return []uint32{1, 2, 3, 4, 5, 6}
297 }
298 result[index] = uint32(tmp)
299 }
300 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530301}
302
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700303//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 -0800304func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530305
David K. Bainbridge794735f2020-02-11 21:01:37 -0800306 switch portType {
307 case voltha.Port_ETHERNET_NNI:
308 return fmt.Sprintf("nni-%d", portNum), nil
309 case voltha.Port_PON_OLT:
310 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700311 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800312
Girish Kumarf26e4882020-03-05 06:49:10 +0000313 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530314}
315
Neha Sharma96b7bf22020-06-15 10:37:32 +0000316func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000317 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700318 if state == "up" {
319 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500320 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500321 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700322 } else {
323 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500324 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700325 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700326 portNum := plt.IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400327 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800328 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000329 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400330 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500331
khenaidoo106c61a2021-08-11 18:05:46 -0400332 // Check if port exists
333 port, err := dh.getPortFromCore(ctx, &ic.PortFilter{
334 DeviceId: dh.device.Id,
335 Port: portNum,
336 })
337 if err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000338 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
khenaidoo106c61a2021-08-11 18:05:46 -0400339 err = dh.updatePortStateInCore(ctx, &ic.PortState{
340 DeviceId: dh.device.Id,
341 PortType: portType,
342 PortNo: portNum,
343 OperStatus: operStatus})
344 if err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400345 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
346 "device-id": dh.device.Id,
347 "port-type": portType,
348 "port-number": portNum,
349 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500350 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400351 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500352 }
khenaidoo106c61a2021-08-11 18:05:46 -0400353
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400354 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700355 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
khenaidoo106c61a2021-08-11 18:05:46 -0400356 port = &voltha.Port{
357 DeviceId: dh.device.Id,
cuilin20187b2a8c32019-03-26 19:52:28 -0700358 PortNo: portNum,
359 Label: label,
360 Type: portType,
361 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700362 OfpPort: &of.OfpPort{
363 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
364 Config: 0,
365 State: uint32(of.OfpPortState_OFPPS_LIVE),
366 Curr: capacity,
367 Advertised: capacity,
368 Peer: capacity,
369 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
370 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
371 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700372 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000373 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700374 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400375 err = dh.createPortInCore(ctx, port)
376 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000377 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800378 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000379 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400380 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000381 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530382 return nil
383}
384
Kent Hagermane6ff1012020-07-14 15:07:53 -0400385func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -0400386 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530387 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400388 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
389 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530390 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800391 dh.lockDevice.Lock()
392 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530393 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530394}
395
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700396// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530397// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800398func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000399 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700400 defer func() {
401 dh.lockDevice.Lock()
402 dh.isReadIndicationRoutineActive = false
403 dh.lockDevice.Unlock()
404 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700405 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700406 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700407 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700408 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400409
David Bainbridgef5879ca2019-12-13 21:17:54 +0000410 // Create an exponential backoff around re-enabling indications. The
411 // maximum elapsed time for the back off is set to 0 so that we will
412 // continue to retry. The max interval defaults to 1m, but is set
413 // here for code clarity
414 indicationBackoff := backoff.NewExponentialBackOff()
415 indicationBackoff.MaxElapsedTime = 0
416 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700417
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700418 dh.lockDevice.Lock()
419 dh.isReadIndicationRoutineActive = true
420 dh.lockDevice.Unlock()
421
Girish Gowdra3f974912020-03-23 20:35:18 -0700422Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700423 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400424 select {
425 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000426 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700427 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400428 default:
429 indication, err := indications.Recv()
430 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000431 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530432 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530433 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400434 // Use an exponential back off to prevent getting into a tight loop
435 duration := indicationBackoff.NextBackOff()
436 if duration == backoff.Stop {
437 // If we reach a maximum then warn and reset the backoff
438 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000439 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530440 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530441 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400442 indicationBackoff.Reset()
443 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700444
445 // On failure process a backoff timer while watching for stopIndications
446 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700447 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700448 select {
449 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000450 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700451 if !backoffTimer.Stop() {
452 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700453 }
454 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700455 case <-backoffTimer.C:
456 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700457 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700458 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
459 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400460 }
461 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000462 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530463 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000464 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530465 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530466 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700467 // Close the stream, and re-initialize it
468 if err = indications.CloseSend(); err != nil {
469 // Ok to ignore here, because we landed here due to a problem on the stream
470 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000471 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530472 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530473 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700474 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000475 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700476 return err
477 }
478 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400479 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530480 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400481 // Reset backoff if we have a successful receive
482 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400483 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700484 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000485 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530486 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530487 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400488 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400489 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400490 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700491 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700492 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700493 // Close the send stream
494 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700495
Girish Gowdra3f974912020-03-23 20:35:18 -0700496 return nil
497}
498
499func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700500 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700501 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
502 if err != nil {
503 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
504 }
505 if indications == nil {
506 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
507 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700508 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700509 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400510}
511
512// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
513func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
514 switch indication.Data.(type) {
515 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
516 return true
517
518 default:
519 return false
520 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700521}
522
David K. Bainbridge794735f2020-02-11 21:01:37 -0800523func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700524 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000525 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530526 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700527 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530528 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700529 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000530 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000531 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530532 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000533 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800534 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000535 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800536 }
537 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700538}
539
David K. Bainbridge794735f2020-02-11 21:01:37 -0800540// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530541func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700542 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700543 switch indication.Data.(type) {
544 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000545 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
546 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700547 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 -0800548 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400549 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800550 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700551 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000552 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
553 defer span.Finish()
554
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700555 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800556 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000557 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400558 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800559 }
560 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000561 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700562 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000563 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
564 defer span.Finish()
565
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 intfOperInd := indication.GetIntfOperInd()
567 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800568 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000569 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400570 _ = 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 -0800571 }
572 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 } else if intfOperInd.GetType() == "pon" {
574 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
575 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800576 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000577 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400578 _ = 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 -0800579 }
580 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000581 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700582 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000583 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530584 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530585 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700586 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000587 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
588 defer span.Finish()
589
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700590 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000591 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800592 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800593 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700594 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000595 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
596 defer span.Finish()
597
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700598 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000599 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800600 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800601 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700602 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000603 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
604 defer span.Finish()
605
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700606 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000607 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 -0800608 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000609 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400610 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800611 }
612 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700613 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000614 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
615 defer span.Finish()
616
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700617 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000618 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700619 "intf-type": pktInd.IntfId,
620 "intf-id": pktInd.IntfId,
621 "gem-port-id": pktInd.GemportId,
622 "port-no": pktInd.PortNo,
623 "device-id": dh.device.Id,
624 })
625
626 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000627 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700628 "intf-type": pktInd.IntfId,
629 "intf-id": pktInd.IntfId,
630 "gem-port-id": pktInd.GemportId,
631 "port-no": pktInd.PortNo,
632 "packet": hex.EncodeToString(pktInd.Pkt),
633 "device-id": dh.device.Id,
634 })
635 }
636
David K. Bainbridge794735f2020-02-11 21:01:37 -0800637 go func() {
638 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400639 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800640 }
641 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700642 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000643 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
644 defer span.Finish()
645
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700646 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700647 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700648 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000649 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
650 defer span.Finish()
651
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700652 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000653 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700654 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000655 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
656 defer span.Finish()
657
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700658 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000659 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
660 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700661 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530662}
663
664// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530665func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530666 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000667 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530668
Girish Gowdra618fa572021-09-01 17:19:29 -0700669 // instantiate the mcast handler routines.
670 for i := range dh.incomingMcastFlowOrGroup {
671 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
672 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
673 if !dh.mcastHandlerRoutineActive[i] {
674 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
675 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
676 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
677 // for incoming mcast flow/group to be processed serially.
678 dh.mcastHandlerRoutineActive[i] = true
679 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
680 }
681 }
682
Girish Gowdru0c588b22019-04-23 23:24:56 -0400683 // Synchronous call to update device state - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400684 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
685 DeviceId: dh.device.Id,
686 OperStatus: voltha.OperStatus_ACTIVE,
687 ConnStatus: voltha.ConnectStatus_REACHABLE,
688 }); err != nil {
689 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400690 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000691
692 //Clear olt communication failure event
693 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
694 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700695 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000696 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
697
Gamze Abakac2c32a62021-03-11 11:44:18 +0000698 //check adapter and agent reconcile status
699 //reboot olt if needed (olt disconnection case)
700 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
701 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
702 log.Fields{
703 "device-id": dh.device.Id,
704 "adapter-status": dh.adapterPreviouslyConnected,
705 "agent-status": dh.agentPreviouslyConnected,
706 })
707 _ = dh.RebootDevice(ctx, dh.device)
708 }
709
Girish Gowdru0c588b22019-04-23 23:24:56 -0400710 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530711}
712
713// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530714func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000715 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400716
khenaidoo106c61a2021-08-11 18:05:46 -0400717 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400718 if err != nil || device == nil {
719 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000720 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400721 }
722
723 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400724
725 //Update the device oper state and connection status
726 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800727 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400728 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800729 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400730
khenaidoo106c61a2021-08-11 18:05:46 -0400731 if err = dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
732 DeviceId: cloned.Id,
733 OperStatus: cloned.OperStatus,
734 ConnStatus: cloned.ConnectStatus,
735 }); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000736 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400737 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400738
739 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -0400740 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400741 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000742 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400743 }
744 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400745 // Update onu state as down in onu adapter
746 onuInd := oop.OnuIndication{}
747 onuInd.OperState = "down"
khenaidoo106c61a2021-08-11 18:05:46 -0400748
749 ogClient, err := dh.getChildAdapterServiceClient(onuDevice.AdapterEndpoint)
750 if err != nil {
751 return err
752 }
753 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
754 _, err = ogClient.OnuIndication(subCtx, &ic.OnuIndicationMessage{
755 DeviceId: onuDevice.Id,
756 OnuIndication: &onuInd,
757 })
758 cancel()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800759 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400760 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -0400761 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800762 "onu-indicator": onuInd,
763 "device-type": onuDevice.Type,
764 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700765 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800766 } else {
767 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 -0700768 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400769 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800770 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700771 /* Discovered ONUs entries need to be cleared , since after OLT
772 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530773 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800774 dh.lockDevice.Unlock()
775
Neha Sharma96b7bf22020-06-15 10:37:32 +0000776 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700777 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530778}
779
780// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530781func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400782 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000783
784 // if the connection is already available, close the previous connection (olt reboot case)
785 if dh.clientCon != nil {
786 if err = dh.clientCon.Close(); err != nil {
787 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
788 } else {
789 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
790 }
791 }
792
793 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000794 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
795 grpc.WithInsecure(),
796 grpc.WithBlock(),
797 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000798 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000799 )),
800 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000801 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000802 )))
803
804 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530805 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530806 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000807 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400808 }
809 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530810}
811
812// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530813func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400814 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530815 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400816 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530817}
818
819// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530820func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530821 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000822 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400823
824 // Case where OLT is disabled and then rebooted.
khenaidoo106c61a2021-08-11 18:05:46 -0400825 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Thomas Lee S985938d2020-05-04 11:40:41 +0530826 if err != nil || device == nil {
827 /*TODO: needs to handle error scenarios */
828 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
829 }
830 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000831 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400832
833 cloned := proto.Clone(device).(*voltha.Device)
834 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
835 cloned.OperStatus = voltha.OperStatus_UNKNOWN
836 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -0400837
838 if err = dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
839 DeviceId: cloned.Id,
840 OperStatus: cloned.OperStatus,
841 ConnStatus: cloned.ConnectStatus,
842 }); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530843 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 -0400844 }
845
Chaitrashree G S44124192019-08-07 20:21:36 -0400846 // 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 +0530847 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400848 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530849 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400850 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400851 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
852 // all the modules initialized and ready to handle incoming ONUs.
853
Thomas Lee S985938d2020-05-04 11:40:41 +0530854 err = dh.initializeDeviceHandlerModules(ctx)
855 if err != nil {
856 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 -0400857 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400858
859 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800860 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530861 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400862 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800863 }
864 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700865
866 go startHeartbeatCheck(ctx, dh)
867
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400868 return nil
869 }
870
khenaidoo106c61a2021-08-11 18:05:46 -0400871 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400872 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400873 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400874 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400875 }
khenaidoo106c61a2021-08-11 18:05:46 -0400876 dh.populateActivePorts(ctx, ports.Items)
877 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400878 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400879 }
880
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400881 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530882 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 -0400883 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530884
cuilin20187b2a8c32019-03-26 19:52:28 -0700885 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800886 go func() {
887 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400888 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800889 }
890 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000891 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000892
893 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000894 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000895 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700896
897 go startHeartbeatCheck(ctx, dh)
898
cuilin20187b2a8c32019-03-26 19:52:28 -0700899 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530900}
901
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400902func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700903 var err error
904 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400905
906 if err != nil {
907 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
908 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700909 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
910 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700911
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700912 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700913 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700914 var i uint32
915 for i = 0; i < dh.totalPonPorts; i++ {
916 // Instantiate resource manager
917 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 -0700918 return olterrors.ErrResourceManagerInstantiating
919 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400920 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700921 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
922 // the KV store to manage mcast group data. Provide the first instance (0th index)
923 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
924 return olterrors.ErrGroupManagerInstantiating
925 }
926 for i = 0; i < dh.totalPonPorts; i++ {
927 // Instantiate flow manager
928 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
929 return olterrors.ErrFlowManagerInstantiating
930 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700931 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700932 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400933 /* TODO: Instantiate Alarm , stats , BW managers */
934 /* Instantiating Event Manager to handle Alarms and KPIs */
935 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
936
937 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000938 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400939
940 return nil
941
942}
943
Neha Sharma96b7bf22020-06-15 10:37:32 +0000944func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400945 var err error
946 var deviceInfo *oop.DeviceInfo
947
Neha Sharma8f4e4322020-08-06 10:51:53 +0000948 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400949
950 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000951 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400952 }
953 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000954 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400955 }
956
Neha Sharma96b7bf22020-06-15 10:37:32 +0000957 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400958 dh.device.Root = true
959 dh.device.Vendor = deviceInfo.Vendor
960 dh.device.Model = deviceInfo.Model
961 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
962 dh.device.HardwareVersion = deviceInfo.HardwareVersion
963 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
964
965 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000966 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400967 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000968 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400969 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000970 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400971 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000972 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400973 dh.device.MacAddress = genmac
974 } else {
975 dh.device.MacAddress = deviceInfo.DeviceId
976 }
977
978 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400979 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000980 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400981 }
982
983 return deviceInfo, nil
984}
985
Neha Sharma96b7bf22020-06-15 10:37:32 +0000986func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700987 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530988 for {
989 select {
990 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000991 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530992 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000993 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700994
khenaidoo106c61a2021-08-11 18:05:46 -0400995 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400996 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700997 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400998 continue
999 }
khenaidoo106c61a2021-08-11 18:05:46 -04001000 for _, port := range ports.Items {
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301001 // NNI Stats
1002 if port.Type == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001003 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301004 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001005 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001006 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001007 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301008 }
1009 // PON Stats
1010 if port.Type == voltha.Port_PON_OLT {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001011 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301012 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
1013 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001014 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001015 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301016 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001017 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001018
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001019 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001020 if len(onuGemInfoLst) > 0 {
1021 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001022 }
Chaitrashree G Sef088112020-02-03 21:39:27 -05001023 }
Naga Manjunath7615e552019-10-11 22:35:47 +05301024 }
1025 }
1026 }
1027}
1028
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001029//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +05301030func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001031 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001032 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +05301033 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +05301034
1035 // Now, set the initial PM configuration for that device
khenaidoo106c61a2021-08-11 18:05:46 -04001036 cgClient, err := dh.coreClient.GetCoreServiceClient()
1037 if err != nil {
1038 logger.Errorw(ctx, "no-core-connection", log.Fields{"device-id": dh.device.Id, "error": err})
1039 return
1040 }
1041
1042 // Now, set the initial PM configuration for that device
1043 if _, err := cgClient.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001044 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +05301045 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301046}
1047
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001048//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301049func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -07001050 return &ic.SwitchCapability{
1051 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301052 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001053 HwDesc: "open_pon",
1054 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001055 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001056 },
1057 SwitchFeatures: &of.OfpSwitchFeatures{
1058 NBuffers: 256,
1059 NTables: 2,
1060 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1061 of.OfpCapabilities_OFPC_TABLE_STATS |
1062 of.OfpCapabilities_OFPC_PORT_STATS |
1063 of.OfpCapabilities_OFPC_GROUP_STATS),
1064 },
1065 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301066}
1067
khenaidoo106c61a2021-08-11 18:05:46 -04001068// GetTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
1069func (dh *DeviceHandler) GetTechProfileDownloadMessage(ctx context.Context, request *ic.TechProfileInstanceRequestMessage) (*ic.TechProfileDownloadMessage, error) {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001070 ifID, err := plt.IntfIDFromPonPortNum(ctx, request.ParentPonPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001071 if err != nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001072 return nil, err
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001073 }
khenaidoo106c61a2021-08-11 18:05:46 -04001074 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001075}
1076
Neha Sharma96b7bf22020-06-15 10:37:32 +00001077func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001078 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 -07001079 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001080 var deviceID string
1081 var proxyDeviceID string
khenaidoo106c61a2021-08-11 18:05:46 -04001082 var childAdapterEndpoint string
cuilin20187b2a8c32019-03-26 19:52:28 -07001083
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001084 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001085 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001086 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 -07001087 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1088 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001089
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001090 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301091
1092 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1093
Neha Sharma96b7bf22020-06-15 10:37:32 +00001094 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 -07001095 ponPort := plt.IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
cuilin20187b2a8c32019-03-26 19:52:28 -07001096
khenaidoo106c61a2021-08-11 18:05:46 -04001097 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1098 ParentId: dh.device.Id,
1099 OnuId: omciInd.OnuId,
1100 ParentPortNo: ponPort,
1101 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001102 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301103 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001104 "intf-id": omciInd.IntfId,
1105 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001106 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001107 deviceType = onuDevice.Type
1108 deviceID = onuDevice.Id
1109 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
khenaidoo106c61a2021-08-11 18:05:46 -04001110 childAdapterEndpoint = onuDevice.AdapterEndpoint
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001111 //if not exist in cache, then add to cache.
khenaidoo106c61a2021-08-11 18:05:46 -04001112 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false, onuDevice.AdapterEndpoint))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001113 } else {
1114 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001115 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 +05301116 deviceType = onuInCache.(*OnuDevice).deviceType
1117 deviceID = onuInCache.(*OnuDevice).deviceID
1118 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001119 childAdapterEndpoint = onuInCache.(*OnuDevice).adapterEndpoint
cuilin20187b2a8c32019-03-26 19:52:28 -07001120 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001121
khenaidoo106c61a2021-08-11 18:05:46 -04001122 if err := dh.sendOmciIndicationToChildAdapter(ctx, childAdapterEndpoint, &ic.OmciMessage{
1123 ParentDeviceId: proxyDeviceID,
1124 ChildDeviceId: deviceID,
1125 Message: omciInd.Pkt,
1126 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301127 return olterrors.NewErrCommunication("omci-request", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001128 "source": dh.openOLT.config.AdapterEndpoint,
1129 "device-type": deviceType,
1130 "destination": childAdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001131 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001132 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001133 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001134 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301135}
1136
khenaidoo106c61a2021-08-11 18:05:46 -04001137// //ProcessInterAdapterMessage sends the proxied messages to the target device
1138// // If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1139// // is meant, and then send the unmarshalled omci message to this onu
1140// func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1141// logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
1142// if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
1143// return dh.handleInterAdapterOmciMsg(ctx, msg)
1144// }
1145// return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1146// }
cuilin20187b2a8c32019-03-26 19:52:28 -07001147
khenaidoo106c61a2021-08-11 18:05:46 -04001148// ProxyOmciMessage sends the proxied OMCI message to the target device
1149func (dh *DeviceHandler) ProxyOmciMessage(ctx context.Context, omciMsg *ic.OmciMessage) error {
1150 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 -07001151
1152 if omciMsg.GetProxyAddress() == nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001153 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsg.ChildDeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001154 if err != nil {
1155 return olterrors.NewErrNotFound("onu", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001156 "parent-device-id": dh.device.Id,
1157 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001158 }
khenaidoo106c61a2021-08-11 18:05:46 -04001159 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1160 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001161 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001162 "parent-device-id": dh.device.Id,
1163 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001164 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001165 } else {
khenaidoo106c61a2021-08-11 18:05:46 -04001166 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsg.ProxyAddress})
1167 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001168 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001169 "parent-device-id": dh.device.Id,
1170 "child-device-id": omciMsg.ChildDeviceId}, err)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001171 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001172 }
1173 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301174}
1175
khenaidoo106c61a2021-08-11 18:05:46 -04001176func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.OmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001177 var intfID uint32
1178 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001179 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001180 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001181 intfID = onuDevice.ProxyAddress.GetChannelId()
1182 onuID = onuDevice.ProxyAddress.GetOnuId()
1183 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001184 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001185 intfID = omciMsg.GetProxyAddress().GetChannelId()
1186 onuID = omciMsg.GetProxyAddress().GetOnuId()
1187 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001188 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001189 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001190 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 -08001191
Thomas Lee S94109f12020-03-03 16:39:29 +05301192 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001193 "intf-id": intfID,
1194 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001195 }
1196
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001197 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1198 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001199 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001200 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1201 hex.Encode(hexPkt, omciMsg.Message)
1202 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1203
1204 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1205 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1206 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001207 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001208 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001209
Neha Sharma8f4e4322020-08-06 10:51:53 +00001210 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001211 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301212 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001213 "intf-id": intfID,
1214 "onu-id": onuID,
1215 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001216 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001217 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001218}
1219
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301221 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 -07001222 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001223 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001224 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001225 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301226 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301227 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001228 st, _ := status.FromError(err)
1229 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001230 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1231
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001232 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301233 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001234 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001235 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001236 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001237 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001238 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001239}
1240
Mahir Gunyelb0046752021-02-26 13:51:05 -08001241func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001242 channelID := onuDiscInd.GetIntfId()
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001243 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001244
Mahir Gunyelb0046752021-02-26 13:51:05 -08001245 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001246 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301247
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301248 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001249 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001250 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301251
1252 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1253 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1254 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1255 OnuLosRaise event sent for it */
1256 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1257 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1258 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001259 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301260 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1261 "currentIntfId": onuDiscInd.GetIntfId()})
1262 // TODO:: Should we need to ignore raising OnuLosClear event
1263 // when onu connected to different PON?
1264 }
1265 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1266 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1267 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001268 go func() {
1269 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001270 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001271 }
1272 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301273 }
1274 return true
1275 })
1276
Neha Sharma96b7bf22020-06-15 10:37:32 +00001277 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001278 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001279 }
1280
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001281 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001282
1283 // check the ONU is already know to the OLT
1284 // NOTE the second time the ONU is discovered this should return a device
khenaidoo106c61a2021-08-11 18:05:46 -04001285 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1286 ParentId: dh.device.Id,
1287 SerialNumber: sn,
1288 })
Matteo Scandolo945e4012019-12-12 14:16:11 -08001289
1290 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001291 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 -08001292 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001293 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 -08001294 switch e.Code() {
1295 case codes.Internal:
1296 // this probably means NOT FOUND, so just create a new device
1297 onuDevice = nil
1298 case codes.DeadlineExceeded:
1299 // if the call times out, cleanup and exit
1300 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001301 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001302 }
1303 }
1304 }
1305
1306 if onuDevice == nil {
1307 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001308 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001309 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001310 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001311 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001312
Neha Sharma96b7bf22020-06-15 10:37:32 +00001313 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001314
1315 if err != nil {
1316 // if we can't create an ID in resource manager,
1317 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001318 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001319 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001320 "pon-intf-id": ponintfid,
1321 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001322 }
1323
khenaidoo106c61a2021-08-11 18:05:46 -04001324 if onuDevice, err = dh.sendChildDeviceDetectedToCore(ctx, &ic.DeviceDiscovery{
1325 ParentId: dh.device.Id,
1326 ParentPortNo: parentPortNo,
1327 ChannelId: channelID,
1328 VendorId: string(onuDiscInd.SerialNumber.GetVendorId()),
1329 SerialNumber: sn,
1330 OnuId: onuID,
1331 }); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001332 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001333 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 +05301334 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001335 "pon-intf-id": ponintfid,
1336 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001337 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001338 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 -07001339 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001340 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001341 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301342 log.Fields{"onuDevice": onuDevice,
1343 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001344 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301345 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001346 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001347
khenaidoo106c61a2021-08-11 18:05:46 -04001348 // Setup the gRPC connection to the adapter responsible for that onuDevice, if not setup yet
1349 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
1350 err = dh.setupChildInterAdapterClient(subCtx, onuDevice.AdapterEndpoint)
1351 cancel()
1352 if err != nil {
1353 return olterrors.NewErrCommunication("no-connection-to-child-adapter", log.Fields{"device-id": onuDevice.Id}, err)
1354 }
1355
Matteo Scandolo945e4012019-12-12 14:16:11 -08001356 // we can now use the existing ONU Id
1357 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001358 //Insert the ONU into cache to use in OnuIndication.
1359 //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 +00001360 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001361 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301362 "intfId": onuDiscInd.GetIntfId(),
1363 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001364 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001365
khenaidoo106c61a2021-08-11 18:05:46 -04001366 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301367 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001368 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301369 log.Fields{"onu": onuDev,
1370 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001371
khenaidoo106c61a2021-08-11 18:05:46 -04001372 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1373 DeviceId: onuDevice.Id,
1374 ParentDeviceId: dh.device.Id,
1375 OperStatus: common.OperStatus_DISCOVERED,
1376 ConnStatus: common.ConnectStatus_REACHABLE,
1377 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301378 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001379 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001380 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001381 }
khenaidoo106c61a2021-08-11 18:05:46 -04001382
Neha Sharma96b7bf22020-06-15 10:37:32 +00001383 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001384 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301385 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001386 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001387 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001388 }
1389 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001390}
1391
Mahir Gunyelb0046752021-02-26 13:51:05 -08001392func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001393
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001394 ponPort := plt.IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001395 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001396 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001397 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001398 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301399 log.Fields{"onuId": onuInd.OnuId,
1400 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301401 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001402 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001403 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301404
David K. Bainbridge794735f2020-02-11 21:01:37 -08001405 errFields := log.Fields{"device-id": dh.device.Id}
1406
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301407 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1408
Mahir Gunyele77977b2019-06-27 05:36:22 -07001409 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1410 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001411 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001412 onuDevice, err = dh.getDeviceFromCore(ctx, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001413 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001414 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1415 if serialNumber != "" {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001416 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001417 } else {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001418 errFields["onu-id"] = onuInd.OnuId
1419 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001420 }
khenaidoo106c61a2021-08-11 18:05:46 -04001421 onuDevice, err = dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1422 ParentId: dh.device.Id,
1423 SerialNumber: serialNumber,
1424 OnuId: onuInd.OnuId,
1425 ParentPortNo: ponPort,
1426 })
cuilin20187b2a8c32019-03-26 19:52:28 -07001427 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001428
David K. Bainbridge794735f2020-02-11 21:01:37 -08001429 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001430 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001431 }
1432
David K. Bainbridge794735f2020-02-11 21:01:37 -08001433 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001434 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001435 "previousIntfId": onuDevice.ParentPortNo,
1436 "currentIntfId": ponPort})
1437 }
1438
1439 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001440 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301441 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1442 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301443 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001444 }
1445 if !foundInCache {
1446 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1447
khenaidoo106c61a2021-08-11 18:05:46 -04001448 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 -08001449
1450 }
kesavand7cf3a052020-08-28 12:49:18 +05301451 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001452 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001453 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301454 }
1455 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001456 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001457 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001458 }
1459 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001460}
1461
Neha Sharma96b7bf22020-06-15 10:37:32 +00001462func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001463 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 -07001464 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1465 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1466 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1467 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001468 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001469 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1470 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001471 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001472 onuInd.OperState = "down"
1473 }
1474 }
1475
David K. Bainbridge794735f2020-02-11 21:01:37 -08001476 switch onuInd.OperState {
khenaidoo106c61a2021-08-11 18:05:46 -04001477 case "up", "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001478 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 -04001479
1480 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ic.OnuIndicationMessage{
1481 DeviceId: onuDevice.Id,
1482 OnuIndication: onuInd,
1483 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001484 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301485 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001486 "onu-indicator": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001487 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001488 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001489 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001490 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001491 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001492 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001493 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001494 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001495}
1496
cuilin20187b2a8c32019-03-26 19:52:28 -07001497func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1498 if serialNum != nil {
1499 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001500 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001501 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001502}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001503func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1504 decodedStr, err := hex.DecodeString(serialNum[4:])
1505 if err != nil {
1506 return nil, err
1507 }
1508 return &oop.SerialNumber{
1509 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001510 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001511 }, nil
1512}
cuilin20187b2a8c32019-03-26 19:52:28 -07001513
1514func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001515 if len(vendorSpecific) > 3 {
1516 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1517 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1518 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1519 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1520 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1521 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1522 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1523 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1524 return tmp
1525 }
1526 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001527}
1528
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001529//UpdateFlowsBulk upates the bulk flow
1530func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301531 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001532}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001533
1534//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001535func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1536 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301537 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001538 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301539 "device-id": dh.device.Id})
khenaidoo106c61a2021-08-11 18:05:46 -04001540
1541 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1542 ParentId: dh.device.Id,
1543 OnuId: onuID,
1544 ParentPortNo: parentPort,
1545 })
1546
Girish Gowdru0c588b22019-04-23 23:24:56 -04001547 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001548 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001549 "intf-id": parentPort,
1550 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001551 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001552 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 -08001553 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301554}
1555
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001556// SendPacketInToCore sends packet-in to core
1557// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1558// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001559func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001560 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001561 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001562 "port": logicalPort,
1563 "packet": hex.EncodeToString(packetPayload),
1564 "device-id": dh.device.Id,
1565 })
1566 }
khenaidoo106c61a2021-08-11 18:05:46 -04001567
1568 if err := dh.sendPacketToCore(ctx, &ic.PacketIn{
1569 DeviceId: dh.device.Id,
1570 Port: logicalPort,
1571 Packet: packetPayload,
1572 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301573 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001574 "source": "adapter",
1575 "destination": "core",
1576 "device-id": dh.device.Id,
1577 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001578 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001579 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001580 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001581 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001582 "packet": hex.EncodeToString(packetPayload),
1583 "device-id": dh.device.Id,
1584 })
1585 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001586 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001587}
1588
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001589// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001590func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001591 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001592
1593 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1594 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001596 }
1597
Kent Hagermane6ff1012020-07-14 15:07:53 -04001598 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001599 metrics := dh.metrics.GetSubscriberMetrics()
1600 for _, m := range pmConfigs.Metrics {
1601 metrics[m.Name].Enabled = m.Enabled
1602
1603 }
1604 }
1605}
1606
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001607//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301608func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001609 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
Andrea Campanellac63bba92020-03-10 17:01:04 +01001610
Girish Gowdra491a9c62021-01-06 16:43:07 -08001611 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001612 var errorsList []error
1613
Girish Gowdru0c588b22019-04-23 23:24:56 -04001614 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001615 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001616 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001617
Neha Sharma96b7bf22020-06-15 10:37:32 +00001618 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301619 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001620 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301621 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001622 if flow_utils.HasGroup(flow) {
1623 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1624 } else {
1625 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1626 }
Girish Gowdracefae192020-03-19 18:14:10 -07001627 if err != nil {
1628 errorsList = append(errorsList, err)
1629 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001630 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301631
1632 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001633 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001634 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301635 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001636 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301637 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001638 if flow_utils.HasGroup(flow) {
1639 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1640 } else {
1641 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1642 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001643 if err != nil {
1644 errorsList = append(errorsList, err)
1645 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301646 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001647 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001648
Girish Gowdracefae192020-03-19 18:14:10 -07001649 // 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 +00001650 if groups != nil {
1651 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001652 // err = dh.groupMgr.AddGroup(ctx, group)
1653 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001654 if err != nil {
1655 errorsList = append(errorsList, err)
1656 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001657 }
1658 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001659 // err = dh.groupMgr.ModifyGroup(ctx, group)
1660 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001661 if err != nil {
1662 errorsList = append(errorsList, err)
1663 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001664 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001665 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001666 // err = dh.groupMgr.DeleteGroup(ctx, group)
1667 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001668 if err != nil {
1669 errorsList = append(errorsList, err)
1670 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001671 }
1672 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001673 if len(errorsList) > 0 {
1674 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1675 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001676 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001677 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301678}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001679
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001680//DisableDevice disables the given device
1681//It marks the following for the given device:
1682//Device-Handler Admin-State : down
1683//Device Port-State: UNKNOWN
1684//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001685func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001686 /* On device disable ,admin state update has to be done prior sending request to agent since
1687 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001688 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001689 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001690 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001691 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001692 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001693 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001694 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001695 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001696 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001697 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301698
1699 dh.discOnus = sync.Map{}
1700 dh.onus = sync.Map{}
1701
Thomas Lee S85f37312020-04-03 17:06:12 +05301702 //stopping the stats collector
1703 dh.stopCollector <- true
1704
Neha Sharma96b7bf22020-06-15 10:37:32 +00001705 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001706 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301707 //Update device Admin state
1708 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -04001709
kdarapu1afeceb2020-02-12 01:38:09 -05001710 // 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 -04001711 if err := dh.updatePortsStateInCore(ctx, &ic.PortStateFilter{
1712 DeviceId: cloned.Id,
1713 PortTypeFilter: ^uint32(1 << voltha.Port_PON_OLT),
1714 OperStatus: voltha.OperStatus_UNKNOWN,
1715 }); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001716 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001717 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001718 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001719 return nil
1720}
1721
Neha Sharma96b7bf22020-06-15 10:37:32 +00001722func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001723 // Update onu state as unreachable in onu adapter
1724 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301725 onuInd.OperState = state
khenaidoo106c61a2021-08-11 18:05:46 -04001726
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001727 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -04001728 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001729 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001730 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 -04001731 }
1732 if onuDevices != nil {
1733 for _, onuDevice := range onuDevices.Items {
khenaidoo106c61a2021-08-11 18:05:46 -04001734 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ic.OnuIndicationMessage{
1735 DeviceId: onuDevice.Id,
1736 OnuIndication: &onuInd,
1737 })
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001738 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001739 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001740 "From Adapter": dh.openOLT.config.AdapterEndpoint, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001741 }
1742
1743 }
1744 }
1745
1746}
1747
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001748//ReenableDevice re-enables the olt device after disable
1749//It marks the following for the given device:
1750//Device-Handler Admin-State : up
1751//Device Port-State: ACTIVE
1752//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001753func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001754 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301755 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001756 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301757 }
1758 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001759 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001760
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001761 // Update the all ports state on that device to enable
khenaidoo106c61a2021-08-11 18:05:46 -04001762 ports, err := dh.listDevicePortsFromCore(ctx, device.Id)
Mahir Gunyele5e807a2021-10-22 11:33:25 -07001763 var retError error
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001764 if err != nil {
Mahir Gunyele5e807a2021-10-22 11:33:25 -07001765 retError = olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
1766 } else {
1767 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
1768 retError = olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
1769 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001770 }
Mahir Gunyele5e807a2021-10-22 11:33:25 -07001771 if retError == nil {
1772 //Update the device oper status as ACTIVE
1773 device.OperStatus = voltha.OperStatus_ACTIVE
1774 } else {
1775 //Update the device oper status as FAILED
1776 device.OperStatus = voltha.OperStatus_FAILED
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001777 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001778 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001779
khenaidoo106c61a2021-08-11 18:05:46 -04001780 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1781 DeviceId: device.Id,
1782 OperStatus: device.OperStatus,
1783 ConnStatus: device.ConnectStatus,
1784 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301785 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001786 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001787 "connect-status": device.ConnectStatus,
1788 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001789 }
kesavand39e0aa32020-01-28 20:58:50 -05001790
Neha Sharma96b7bf22020-06-15 10:37:32 +00001791 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001792
Mahir Gunyele5e807a2021-10-22 11:33:25 -07001793 return retError
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001794}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001795
npujarec5762e2020-01-01 14:08:48 +05301796func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001797 var uniID uint32
1798 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301799 for _, port := range onu.UniPorts {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001800 uniID = plt.UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001801 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001802 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001803 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001804 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001805 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001806 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001807 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001808 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001809 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001810 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001811 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001812 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001813 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001814 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001815 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001816 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301817 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001818 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1819 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001820 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301821 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001822 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001823 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001824 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 +00001825 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001826 }
1827 return nil
1828}
1829
Devmalya Paul495b94a2019-08-27 19:42:00 -04001830// 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 +05301831func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001832 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001833 /* Clear the KV store data associated with the all the UNI ports
1834 This clears up flow data and also resource map data for various
1835 other pon resources like alloc_id and gemport_id
1836 */
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001837 dh.cleanupDeviceResources(ctx)
1838 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 -04001839 // Stop the Stats collector
1840 dh.stopCollector <- true
1841 // stop the heartbeat check routine
1842 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301843 dh.lockDevice.RLock()
1844 // Stop the read indication only if it the routine is active
1845 if dh.isReadIndicationRoutineActive {
1846 dh.stopIndications <- true
1847 }
1848 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001849 dh.removeOnuIndicationChannels(ctx)
Girish Gowdra4736e5c2021-08-25 15:19:10 -07001850 go dh.StopAllMcastHandlerRoutines(ctx)
1851 for _, flMgr := range dh.flowMgr {
1852 go flMgr.StopAllFlowHandlerRoutines(ctx)
1853 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001854 //Reset the state
1855 if dh.Client != nil {
1856 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301857 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001858 }
1859 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001860 // There is no need to update the core about operation status and connection status of the OLT.
1861 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1862 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1863 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001864
khenaidoo7eb2d672021-10-22 19:08:50 -04001865 // Stop the adapter grpc clients for that parent device
1866 dh.deleteAdapterClients(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001867 return nil
1868}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001869func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001870
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001871 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301872 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001873 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001874 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001875 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001876 for i, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301877 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001878 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001879 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001880 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301881 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301882 // Clear flowids for gem cache.
1883 for _, gem := range onu.GemPorts {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001884 dh.resourceMgr[ponPort].DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301885 }
1886 onuID[0] = onu.OnuID
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001887 dh.resourceMgr[ponPort].FreeonuID(ctx, ponPort, onuID)
1888 err = dh.resourceMgr[ponPort].DelOnuGemInfo(ctx, ponPort, onu.OnuID)
1889 if err != nil {
1890 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
1891 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301892 }
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001893 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1894 logger.Debug(ctx, err)
1895 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001896 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001897 }
A R Karthick1f85b802019-10-11 05:06:05 +00001898
Devmalya Paul495b94a2019-08-27 19:42:00 -04001899 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301900 dh.onus.Range(func(key interface{}, value interface{}) bool {
1901 dh.onus.Delete(key)
1902 return true
1903 })
1904
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001905 /*Delete discovered ONU map for the device*/
1906 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1907 dh.discOnus.Delete(key)
1908 return true
1909 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001910}
1911
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001912//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001913func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001914 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301915 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001916 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001917 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001918 return nil
1919}
1920
David K. Bainbridge794735f2020-02-11 21:01:37 -08001921func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001922 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001923 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001924 "packet-indication": *packetIn,
1925 "device-id": dh.device.Id,
1926 "packet": hex.EncodeToString(packetIn.Pkt),
1927 })
1928 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001929 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001930 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001931 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001932 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001933 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001934 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001935 "logical-port-num": logicalPortNum,
1936 "device-id": dh.device.Id,
1937 "packet": hex.EncodeToString(packetIn.Pkt),
1938 })
1939 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001940
khenaidoo106c61a2021-08-11 18:05:46 -04001941 if err := dh.sendPacketToCore(ctx, &ic.PacketIn{
1942 DeviceId: dh.device.Id,
1943 Port: logicalPortNum,
1944 Packet: packetIn.Pkt,
1945 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301946 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001947 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301948 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001949 "device-id": dh.device.Id,
1950 "packet": hex.EncodeToString(packetIn.Pkt),
1951 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001952 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001953
Matteo Scandolo92186242020-06-12 10:54:18 -07001954 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001955 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001956 "packet": hex.EncodeToString(packetIn.Pkt),
1957 "device-id": dh.device.Id,
1958 })
1959 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001960 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001961}
1962
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001963// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
khenaidoo106c61a2021-08-11 18:05:46 -04001964func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo uint32, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001965 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001966 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001967 "device-id": dh.device.Id,
1968 "egress-port-no": egressPortNo,
1969 "pkt-length": len(packet.Data),
1970 "packet": hex.EncodeToString(packet.Data),
1971 })
1972 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001973
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001974 egressPortType := plt.IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001975 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001976 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1977 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301978 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1979 // Do not packet-out lldp packets on uni port.
1980 // ONOS has no clue about uni/nni ports, it just packets out on all
1981 // available ports on the Logical Switch. It should not be interested
1982 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001983 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001984 "device-id": dh.device.Id,
1985 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301986 return nil
1987 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001988 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1989 if innerEthType == 0x8100 {
1990 // q-in-q 802.1ad or 802.1q double tagged packet.
1991 // slice out the outer tag.
1992 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001993 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001994 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001995 "packet-data": hex.EncodeToString(packet.Data),
1996 "device-id": dh.device.Id,
1997 })
1998 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001999 }
2000 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002001 intfID := plt.IntfIDFromUniPortNum(uint32(egressPortNo))
2002 onuID := plt.OnuIDFromPortNum(uint32(egressPortNo))
2003 uniID := plt.UniIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04002004
Girish Gowdra9602eb42020-09-09 15:50:39 -07002005 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04002006 if err != nil {
2007 // In this case the openolt agent will receive the gemPortID as 0.
2008 // The agent tries to retrieve the gemPortID in this case.
2009 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002010 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002011 "intf-id": intfID,
2012 "onu-id": onuID,
2013 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002014 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05302015 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08002016 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04002017 }
2018
2019 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07002020 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002021 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002022 "egress-port-no": egressPortNo,
2023 "intf-id": intfID,
2024 "onu-id": onuID,
2025 "uni-id": uniID,
2026 "gem-port-id": gemPortID,
2027 "packet": hex.EncodeToString(packet.Data),
2028 "device-id": dh.device.Id,
2029 })
2030 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04002031
npujarec5762e2020-01-01 14:08:48 +05302032 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302033 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002034 "source": "adapter",
2035 "destination": "onu",
2036 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07002037 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08002038 "oni-id": onuID,
2039 "uni-id": uniID,
2040 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002041 "packet": hex.EncodeToString(packet.Data),
2042 "device-id": dh.device.Id,
2043 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04002044 }
2045 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002046 nniIntfID, err := plt.IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08002047 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002048 return olterrors.NewErrInvalidValue(log.Fields{
2049 "egress-nni-port": egressPortNo,
2050 "device-id": dh.device.Id,
2051 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08002052 }
2053 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04002054
Matteo Scandolo92186242020-06-12 10:54:18 -07002055 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002056 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07002057 "uplink-pkt": uplinkPkt,
2058 "packet": hex.EncodeToString(packet.Data),
2059 "device-id": dh.device.Id,
2060 })
2061 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04002062
npujarec5762e2020-01-01 14:08:48 +05302063 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07002064 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
2065 "packet": hex.EncodeToString(packet.Data),
2066 "device-id": dh.device.Id,
2067 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04002068 }
2069 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002070 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05302071 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08002072 "egressPortType": egressPortType,
2073 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05302074 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08002075 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04002076 }
2077 return nil
2078}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07002079
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07002080func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
2081 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07002082}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302083
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002084func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00002085
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302086 // start the heartbeat check towards the OLT.
2087 var timerCheck *time.Timer
2088
2089 for {
2090 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
2091 select {
2092 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00002093 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002094 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002095 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302096 if timerCheck == nil {
2097 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002098 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302099 }
2100 } else {
2101 if timerCheck != nil {
2102 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002103 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302104 }
2105 timerCheck = nil
2106 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002107 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05302108 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302109 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302110 }
2111 cancel()
2112 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002113 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302114 return
2115 }
2116 }
2117}
2118
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002119func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -04002120 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002121 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002122 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2123 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2124 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2125 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2126 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002127 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002128 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2129 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002130 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302131
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002132 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2133 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002134 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
khenaidoo106c61a2021-08-11 18:05:46 -04002135 if err = dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
2136 DeviceId: dh.device.Id,
2137 OperStatus: voltha.OperStatus_UNKNOWN,
2138 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2139 }); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002140 _ = 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 -04002141 }
khenaidoo106c61a2021-08-11 18:05:46 -04002142
2143 if err = dh.updatePortsStateInCore(ctx, &ic.PortStateFilter{
2144 DeviceId: dh.device.Id,
2145 PortTypeFilter: 0,
2146 OperStatus: voltha.OperStatus_UNKNOWN,
2147 }); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002148 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002149 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002150
2151 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002152 raisedTs := time.Now().Unix()
khenaidoo106c61a2021-08-11 18:05:46 -04002153 cloned := proto.Clone(device).(*voltha.Device)
2154 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2155 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2156 dh.device = cloned // update local copy of the device
2157 go dh.eventMgr.oltCommunicationEvent(ctx, cloned, raisedTs)
Gamze Abaka07868a52020-12-17 14:19:28 +00002158
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002159 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002160 // Stop the Stats collector
2161 dh.stopCollector <- true
2162 // stop the heartbeat check routine
2163 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002164
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002165 dh.lockDevice.RLock()
2166 // Stop the read indication only if it the routine is active
2167 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2168 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2169 // on next execution of the readIndication routine.
2170 if dh.isReadIndicationRoutineActive {
2171 dh.stopIndications <- true
2172 }
2173 dh.lockDevice.RUnlock()
2174
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002175 go dh.StopAllMcastHandlerRoutines(ctx)
2176 for _, flMgr := range dh.flowMgr {
2177 go flMgr.StopAllFlowHandlerRoutines(ctx)
2178 }
2179
Gamze Abakac2c32a62021-03-11 11:44:18 +00002180 //reset adapter reconcile flag
2181 dh.adapterPreviouslyConnected = false
2182
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002183 dh.transitionMap.Handle(ctx, DeviceInit)
2184
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302185 }
2186}
kesavand39e0aa32020-01-28 20:58:50 -05002187
2188// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002189func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2190 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2191 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002192}
2193
2194// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002195func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2196 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2197 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002198}
2199
kdarapu1afeceb2020-02-12 01:38:09 -05002200//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 +00002201func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2202 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002203 if port.GetType() == voltha.Port_ETHERNET_NNI {
2204 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002205 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302206 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302207 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002208 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002209 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002210 }
2211 // fetch interfaceid from PortNo
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002212 ponID := plt.PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
kesavand39e0aa32020-01-28 20:58:50 -05002213 ponIntf := &oop.Interface{IntfId: ponID}
2214 var operStatus voltha.OperStatus_Types
2215 if enablePort {
2216 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302217 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002218
2219 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302220 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002221 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002222 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002223 }
2224 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002225 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002226 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002227 } else {
2228 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302229 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002230 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302231 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002232 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002233 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002234 }
2235 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002236 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002237 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002238 }
khenaidoo106c61a2021-08-11 18:05:46 -04002239 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
2240 DeviceId: dh.device.Id,
2241 PortType: voltha.Port_PON_OLT,
2242 PortNo: port.PortNo,
2243 OperStatus: operStatus,
2244 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302245 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302246 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002247 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002248 }
2249 return nil
2250}
2251
kdarapu1afeceb2020-02-12 01:38:09 -05002252//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002253func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002254 // Disable the port and update the oper_port_status to core
2255 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002256 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002257 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002258 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302259 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302260 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002261 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002262 }
2263 }
2264 }
2265 return nil
2266}
2267
2268//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002269func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2270 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2271 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002272 if port.Type == voltha.Port_ETHERNET_NNI {
2273 if port.OperStatus == voltha.OperStatus_ACTIVE {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002274 dh.activePorts.Store(plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002275 } else {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002276 dh.activePorts.Store(plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002277 }
2278 }
2279 if port.Type == voltha.Port_PON_OLT {
2280 if port.OperStatus == voltha.OperStatus_ACTIVE {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002281 dh.activePorts.Store(plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002282 } else {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002283 dh.activePorts.Store(plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002284 }
2285 }
2286 }
2287}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002288
2289// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002290func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002291 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002292 intfID := plt.PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002293 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002294
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002295 var sn *oop.SerialNumber
2296 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002297 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302298 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002299 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302300 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002301 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002302 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002303
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002304 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002305 //clear PON resources associated with ONU
2306 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2307 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2308 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2309 "device-id": dh.device.Id,
2310 "intf-id": intfID,
2311 "onuID": onuID,
2312 "err": err})
2313 } else {
2314 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2315 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2316 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2317 "device-id": dh.device.Id,
2318 "onu-device": onu,
2319 "err": err})
2320 }
2321 // Clear flowids for gem cache.
2322 for _, gem := range onuGem.GemPorts {
2323 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2324 }
Girish Gowdra197acc12021-08-16 10:59:45 -07002325 if err := dh.flowMgr[intfID].RemoveOnuInfoFromFlowMgrCacheAndKvStore(ctx, intfID, onuID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002326 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2327 "intf-id": intfID,
2328 "onu-device": onu,
2329 "onu-gem": onuGem,
2330 "err": err})
2331 //Not returning error on cleanup.
2332 }
2333 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
2334 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuGem.OnuID})
2335 }
2336 dh.onus.Delete(onuKey)
2337 dh.discOnus.Delete(onuSn)
2338
2339 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002340 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302341 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302342 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002343 "onu-id": onuID}, err).Log()
2344 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002345
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002346 return nil
2347}
Girish Gowdracefae192020-03-19 18:14:10 -07002348
2349func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002350 for _, field := range flow_utils.GetOfbFields(flow) {
2351 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002352 return field.GetPort()
2353 }
2354 }
2355 return InvalidPort
2356}
2357
2358func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002359 for _, action := range flow_utils.GetActions(flow) {
2360 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002361 if out := action.GetOutput(); out != nil {
2362 return out.GetPort()
2363 }
2364 }
2365 }
2366 return InvalidPort
2367}
2368
Girish Gowdracefae192020-03-19 18:14:10 -07002369func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2370 inPort := getInPortFromFlow(flow)
2371 outPort := getOutPortFromFlow(flow)
2372
2373 if inPort == InvalidPort || outPort == InvalidPort {
2374 return inPort, outPort
2375 }
2376
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002377 if isControllerFlow := plt.IsControllerBoundFlow(outPort); isControllerFlow {
Girish Gowdracefae192020-03-19 18:14:10 -07002378 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002379 if portType := plt.IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002380 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002381 return uniPort, outPort
2382 }
2383 }
2384 } else {
2385 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002386 if portType := plt.IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002387 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002388 return inPort, uniPort
2389 }
2390 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002391 } else if portType := plt.IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002392 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002393 return uniPort, outPort
2394 }
2395 }
2396 }
2397
2398 return InvalidPort, InvalidPort
2399}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002400
2401func extractOmciTransactionID(omciPkt []byte) uint16 {
2402 if len(omciPkt) > 3 {
2403 d := omciPkt[0:2]
2404 transid := binary.BigEndian.Uint16(d)
2405 return transid
2406 }
2407 return 0
2408}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002409
2410// StoreOnuDevice stores the onu parameters to the local cache.
2411func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2412 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2413 dh.onus.Store(onuKey, onuDevice)
2414}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002415
Neha Sharma8f4e4322020-08-06 10:51:53 +00002416func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002417 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002418 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002419 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002420 resp := new(voltha.ReturnValues)
2421 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002422 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002423 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002424 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2425 return nil, err
2426 }
2427 ID = device.ProxyAddress.GetOnuId()
2428 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2429 valueparam.Onu = &Onu
2430 valueparam.Value = value
2431
2432 // This API is unsupported until agent patch is added
2433 resp.Unsupported = uint32(value)
2434 _ = ctx
2435
2436 // Uncomment this code once agent changes are complete and tests
2437 /*
2438 resp, err = dh.Client.GetValue(ctx, valueparam)
2439 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002440 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002441 return nil, err
2442 }
2443 */
2444
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002445 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 -08002446 return resp, nil
2447}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002448
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002449func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002450 // Default to PON0
2451 var intfID uint32
2452 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002453 if inPort != InvalidPort && outPort != InvalidPort {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002454 _, intfID, _, _ = plt.ExtractAccessFromFlow(inPort, outPort)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002455 }
2456 return intfID
2457}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002458
Mahir Gunyelb0046752021-02-26 13:51:05 -08002459func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2460 dh.perPonOnuIndicationChannelLock.Lock()
2461 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2462 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002463 return ch.indicationChannel
2464 }
2465 channels := onuIndicationChannels{
2466 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002467 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002468 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002469 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002470 stopChannel: make(chan struct{}),
2471 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002472 dh.perPonOnuIndicationChannel[intfID] = channels
2473 dh.perPonOnuIndicationChannelLock.Unlock()
2474 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002475 return channels.indicationChannel
2476
2477}
2478
Mahir Gunyelb0046752021-02-26 13:51:05 -08002479func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2480 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2481 dh.perPonOnuIndicationChannelLock.Lock()
2482 defer dh.perPonOnuIndicationChannelLock.Unlock()
2483 for _, v := range dh.perPonOnuIndicationChannel {
2484 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002485 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002486 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002487}
2488
Mahir Gunyelb0046752021-02-26 13:51:05 -08002489func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2490 ind := onuIndicationMsg{
2491 ctx: ctx,
2492 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002493 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002494 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002495 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002496 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002497}
2498
Mahir Gunyelb0046752021-02-26 13:51:05 -08002499func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002500 for {
2501 select {
2502 // process one indication per onu, before proceeding to the next one
2503 case onuInd := <-onuChannels.indicationChannel:
2504 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002505 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002506 switch onuInd.indication.Data.(type) {
2507 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002508 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002509 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2510 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002511 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002512 }
2513 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002514 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002515 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2516 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002517 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002518 }
2519 }
2520 case <-onuChannels.stopChannel:
2521 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2522 close(onuChannels.indicationChannel)
2523 return
2524 }
2525 }
2526}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002527
2528// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2529// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2530func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2531 // Step1 : Fill McastFlowOrGroupControlBlock
2532 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2533 // Step3 : Wait on response channel for response
2534 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002535 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002536 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2537 errChan := make(chan error)
2538 var groupID uint32
2539 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2540 ctx: ctx,
2541 flowOrGroupAction: action,
2542 flow: flow,
2543 group: group,
2544 errChan: &errChan,
2545 }
2546 if flow != nil {
2547 groupID = flow_utils.GetGroup(flow)
2548 } else if group != nil {
2549 groupID = group.Desc.GroupId
2550 } else {
2551 return errors.New("flow-and-group-both-nil")
2552 }
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002553 mcastRoutineIdx := groupID % MaxNumOfGroupHandlerChannels
2554 if dh.mcastHandlerRoutineActive[mcastRoutineIdx] {
2555 // Derive the appropriate go routine to handle the request by a simple module operation.
2556 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2557 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2558 // Wait for handler to return error value
2559 err := <-errChan
2560 logger.Debugw(ctx, "process-flow-or-group--received-resp", log.Fields{"err": err, "totalTimeInSeconds": time.Since(startTime).Milliseconds()})
2561 return err
2562 }
2563 logger.Errorw(ctx, "mcast handler routine not active for onu", log.Fields{"mcastRoutineIdx": mcastRoutineIdx})
2564 return fmt.Errorf("mcast-handler-routine-not-active-for-index-%v", mcastRoutineIdx)
Girish Gowdra491a9c62021-01-06 16:43:07 -08002565}
2566
2567// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002568func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(routineIndex int, mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock, stopHandler chan bool) {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002569 for {
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002570 select {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002571 // block on the channel to receive an incoming mcast flow/group
2572 // process the flow completely before proceeding to handle the next flow
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002573 case mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel:
2574 if mcastFlowOrGroupCb.flow != nil {
2575 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2576 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2577 log.Fields{"device-id": dh.device.Id,
2578 "flowToAdd": mcastFlowOrGroupCb.flow})
2579 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2580 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2581 // Pass the return value over the return channel
2582 *mcastFlowOrGroupCb.errChan <- err
2583 } else { // flow remove
2584 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2585 log.Fields{"device-id": dh.device.Id,
2586 "flowToRemove": mcastFlowOrGroupCb.flow})
2587 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2588 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2589 // Pass the return value over the return channel
2590 *mcastFlowOrGroupCb.errChan <- err
2591 }
2592 } else { // mcast group
2593 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2594 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2595 log.Fields{"device-id": dh.device.Id,
2596 "groupToAdd": mcastFlowOrGroupCb.group})
2597 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2598 // Pass the return value over the return channel
2599 *mcastFlowOrGroupCb.errChan <- err
2600 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2601 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2602 log.Fields{"device-id": dh.device.Id,
2603 "groupToModify": mcastFlowOrGroupCb.group})
2604 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2605 // Pass the return value over the return channel
2606 *mcastFlowOrGroupCb.errChan <- err
2607 } else { // group remove
2608 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2609 log.Fields{"device-id": dh.device.Id,
2610 "groupToRemove": mcastFlowOrGroupCb.group})
2611 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2612 // Pass the return value over the return channel
2613 *mcastFlowOrGroupCb.errChan <- err
2614 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08002615 }
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002616 case <-stopHandler:
2617 dh.mcastHandlerRoutineActive[routineIndex] = false
2618 return
Girish Gowdra491a9c62021-01-06 16:43:07 -08002619 }
2620 }
2621}
kesavand62126212021-01-12 04:56:06 -05002622
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002623// StopAllMcastHandlerRoutines stops all flow handler routines. Call this when device is being rebooted or deleted
2624func (dh *DeviceHandler) StopAllMcastHandlerRoutines(ctx context.Context) {
2625 for i, v := range dh.stopMcastHandlerRoutine {
2626 if dh.mcastHandlerRoutineActive[i] {
2627 v <- true
2628 }
2629 }
2630 logger.Debug(ctx, "stopped all mcast handler routines")
2631}
2632
kesavand62126212021-01-12 04:56:06 -05002633func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2634
2635 singleValResp := extension.SingleGetValueResponse{
2636 Response: &extension.GetValueResponse{
2637 Response: &extension.GetValueResponse_PortCoutners{
2638 PortCoutners: &extension.GetOltPortCountersResponse{},
2639 },
2640 },
2641 }
2642
2643 errResp := func(status extension.GetValueResponse_Status,
2644 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2645 return &extension.SingleGetValueResponse{
2646 Response: &extension.GetValueResponse{
2647 Status: status,
2648 ErrReason: reason,
2649 },
2650 }
2651 }
2652
2653 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2654 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2655 //send error response
2656 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2657 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2658 }
2659 statIndChn := make(chan bool, 1)
2660 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2661 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2662 //request openOlt agent to send the the port statistics indication
2663
2664 go func() {
2665 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2666 if err != nil {
2667 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2668 }
2669 }()
2670 select {
2671 case <-statIndChn:
2672 //indication received for ports stats
2673 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2674 case <-time.After(oltPortInfoTimeout * time.Second):
2675 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2676 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2677 case <-ctx.Done():
2678 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2679 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2680 }
2681 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2682 //get nni stats
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002683 intfID := plt.PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
kesavand62126212021-01-12 04:56:06 -05002684 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2685 cmnni := dh.portStats.collectNNIMetrics(intfID)
2686 if cmnni == nil {
2687 //TODO define the error reason
2688 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2689 }
2690 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2691 return &singleValResp
2692
2693 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2694 // get pon stats
Mahir Gunyel85f61c12021-10-06 11:53:45 -07002695 intfID := plt.PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
kesavand62126212021-01-12 04:56:06 -05002696 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2697 cmpon := dh.portStats.collectPONMetrics(intfID)
2698 if cmpon == nil {
2699 //TODO define the error reason
2700 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2701 }
2702 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2703 return &singleValResp
2704 }
2705 }
2706 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2707}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302708
2709func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2710
2711 singleValResp := extension.SingleGetValueResponse{
2712 Response: &extension.GetValueResponse{
2713 Response: &extension.GetValueResponse_OnuPonCounters{
2714 OnuPonCounters: &extension.GetOnuCountersResponse{},
2715 },
2716 },
2717 }
2718
2719 errResp := func(status extension.GetValueResponse_Status,
2720 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2721 return &extension.SingleGetValueResponse{
2722 Response: &extension.GetValueResponse{
2723 Status: status,
2724 ErrReason: reason,
2725 },
2726 }
2727 }
2728 intfID := onuPonInfo.IntfId
2729 onuID := onuPonInfo.OnuId
2730 onuKey := dh.formOnuKey(intfID, onuID)
2731
2732 if _, ok := dh.onus.Load(onuKey); !ok {
2733 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2734 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2735 }
2736 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2737 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2738 if cmnni == nil {
2739 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2740 }
2741 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2742 return &singleValResp
2743
2744}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002745
2746func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2747
2748 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2749 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2750 if err != nil {
2751 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2752 return generateSingleGetValueErrorResponse(err)
2753 }
2754 return &extension.SingleGetValueResponse{
2755 Response: &extension.GetValueResponse{
2756 Status: extension.GetValueResponse_OK,
2757 Response: &extension.GetValueResponse_RxPower{
2758 RxPower: &extension.GetRxPowerResponse{
2759 IntfId: rxPowerRequest.IntfId,
2760 OnuId: rxPowerRequest.OnuId,
2761 Status: rxPower.Status,
2762 FailReason: rxPower.FailReason.String(),
2763 RxPower: rxPower.RxPowerMeanDbm,
2764 },
2765 },
2766 },
2767 }
2768}
2769
2770func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2771 errResp := func(status extension.GetValueResponse_Status,
2772 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2773 return &extension.SingleGetValueResponse{
2774 Response: &extension.GetValueResponse{
2775 Status: status,
2776 ErrReason: reason,
2777 },
2778 }
2779 }
2780
2781 if err != nil {
2782 if e, ok := status.FromError(err); ok {
2783 switch e.Code() {
2784 case codes.Internal:
2785 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2786 case codes.DeadlineExceeded:
2787 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2788 case codes.Unimplemented:
2789 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2790 case codes.NotFound:
2791 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2792 }
2793 }
2794 }
2795
2796 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2797}
khenaidoo106c61a2021-08-11 18:05:46 -04002798
2799/*
2800Helper functions to communicate with Core
2801*/
2802
2803func (dh *DeviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
2804 cClient, err := dh.coreClient.GetCoreServiceClient()
2805 if err != nil || cClient == nil {
2806 return nil, err
2807 }
2808 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2809 defer cancel()
2810 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
2811}
2812
2813func (dh *DeviceHandler) getChildDeviceFromCore(ctx context.Context, childDeviceFilter *ic.ChildDeviceFilter) (*voltha.Device, error) {
2814 cClient, err := dh.coreClient.GetCoreServiceClient()
2815 if err != nil || cClient == nil {
2816 return nil, err
2817 }
2818 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2819 defer cancel()
2820 return cClient.GetChildDevice(subCtx, childDeviceFilter)
2821}
2822
2823func (dh *DeviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ic.DeviceStateFilter) error {
2824 cClient, err := dh.coreClient.GetCoreServiceClient()
2825 if err != nil || cClient == nil {
2826 return err
2827 }
2828 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2829 defer cancel()
2830 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
2831 return err
2832}
2833
2834func (dh *DeviceHandler) getChildDevicesFromCore(ctx context.Context, deviceID string) (*voltha.Devices, error) {
2835 cClient, err := dh.coreClient.GetCoreServiceClient()
2836 if err != nil || cClient == nil {
2837 return nil, err
2838 }
2839 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2840 defer cancel()
2841 return cClient.GetChildDevices(subCtx, &common.ID{Id: deviceID})
2842}
2843
2844func (dh *DeviceHandler) listDevicePortsFromCore(ctx context.Context, deviceID string) (*voltha.Ports, error) {
2845 cClient, err := dh.coreClient.GetCoreServiceClient()
2846 if err != nil || cClient == nil {
2847 return nil, err
2848 }
2849 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2850 defer cancel()
2851 return cClient.ListDevicePorts(subCtx, &common.ID{Id: deviceID})
2852}
2853
2854func (dh *DeviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
2855 cClient, err := dh.coreClient.GetCoreServiceClient()
2856 if err != nil || cClient == nil {
2857 return err
2858 }
2859 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2860 defer cancel()
2861 _, err = cClient.DeviceUpdate(subCtx, device)
2862 return err
2863}
2864
2865func (dh *DeviceHandler) sendChildDeviceDetectedToCore(ctx context.Context, deviceDiscoveryInfo *ic.DeviceDiscovery) (*voltha.Device, error) {
2866 cClient, err := dh.coreClient.GetCoreServiceClient()
2867 if err != nil || cClient == nil {
2868 return nil, err
2869 }
2870 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2871 defer cancel()
2872 return cClient.ChildDeviceDetected(subCtx, deviceDiscoveryInfo)
2873}
2874
2875func (dh *DeviceHandler) sendPacketToCore(ctx context.Context, pkt *ic.PacketIn) error {
2876 cClient, err := dh.coreClient.GetCoreServiceClient()
2877 if err != nil || cClient == nil {
2878 return err
2879 }
2880 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2881 defer cancel()
2882 _, err = cClient.SendPacketIn(subCtx, pkt)
2883 return err
2884}
2885
2886func (dh *DeviceHandler) createPortInCore(ctx context.Context, port *voltha.Port) error {
2887 cClient, err := dh.coreClient.GetCoreServiceClient()
2888 if err != nil || cClient == nil {
2889 return err
2890 }
2891 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2892 defer cancel()
2893 _, err = cClient.PortCreated(subCtx, port)
2894 return err
2895}
2896
2897func (dh *DeviceHandler) updatePortsStateInCore(ctx context.Context, portFilter *ic.PortStateFilter) error {
2898 cClient, err := dh.coreClient.GetCoreServiceClient()
2899 if err != nil || cClient == nil {
2900 return err
2901 }
2902 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2903 defer cancel()
2904 _, err = cClient.PortsStateUpdate(subCtx, portFilter)
2905 return err
2906}
2907
2908func (dh *DeviceHandler) updatePortStateInCore(ctx context.Context, portState *ic.PortState) error {
2909 cClient, err := dh.coreClient.GetCoreServiceClient()
2910 if err != nil || cClient == nil {
2911 return err
2912 }
2913 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2914 defer cancel()
2915 _, err = cClient.PortStateUpdate(subCtx, portState)
2916 return err
2917}
2918
2919func (dh *DeviceHandler) getPortFromCore(ctx context.Context, portFilter *ic.PortFilter) (*voltha.Port, error) {
2920 cClient, err := dh.coreClient.GetCoreServiceClient()
2921 if err != nil || cClient == nil {
2922 return nil, err
2923 }
2924 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2925 defer cancel()
2926 return cClient.GetDevicePort(subCtx, portFilter)
2927}
2928
2929/*
2930Helper functions to communicate with child adapter
2931*/
2932
2933func (dh *DeviceHandler) sendOmciIndicationToChildAdapter(ctx context.Context, childEndpoint string, response *ic.OmciMessage) error {
2934 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2935 if err != nil || aClient == nil {
2936 return err
2937 }
2938 logger.Debugw(ctx, "sending-omci-response", log.Fields{"response": response, "child-endpoint": childEndpoint})
2939 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2940 defer cancel()
2941 _, err = aClient.OmciIndication(subCtx, response)
2942 return err
2943}
2944
2945func (dh *DeviceHandler) sendOnuIndicationToChildAdapter(ctx context.Context, childEndpoint string, onuInd *ic.OnuIndicationMessage) error {
2946 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2947 if err != nil || aClient == nil {
2948 return err
2949 }
2950 logger.Debugw(ctx, "sending-onu-indication", log.Fields{"onu-indication": onuInd, "child-endpoint": childEndpoint})
2951 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2952 defer cancel()
2953 _, err = aClient.OnuIndication(subCtx, onuInd)
2954 return err
2955}
2956
2957func (dh *DeviceHandler) sendDeleteTContToChildAdapter(ctx context.Context, childEndpoint string, tContInfo *ic.DeleteTcontMessage) error {
2958 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2959 if err != nil || aClient == nil {
2960 return err
2961 }
2962 logger.Debugw(ctx, "sending-delete-tcont", log.Fields{"tcont": tContInfo, "child-endpoint": childEndpoint})
2963 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2964 defer cancel()
2965 _, err = aClient.DeleteTCont(subCtx, tContInfo)
2966 return err
2967}
2968
2969func (dh *DeviceHandler) sendDeleteGemPortToChildAdapter(ctx context.Context, childEndpoint string, gemPortInfo *ic.DeleteGemPortMessage) error {
2970 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2971 if err != nil || aClient == nil {
2972 return err
2973 }
2974 logger.Debugw(ctx, "sending-delete-gem-port", log.Fields{"gem-port-info": gemPortInfo, "child-endpoint": childEndpoint})
2975 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2976 defer cancel()
2977 _, err = aClient.DeleteGemPort(subCtx, gemPortInfo)
2978 return err
2979}
2980
2981func (dh *DeviceHandler) sendDownloadTechProfileToChildAdapter(ctx context.Context, childEndpoint string, tpDownloadInfo *ic.TechProfileDownloadMessage) error {
2982 aClient, err := dh.getChildAdapterServiceClient(childEndpoint)
2983 if err != nil || aClient == nil {
2984 return err
2985 }
2986 logger.Debugw(ctx, "sending-tech-profile-download", log.Fields{"tp-download-info": tpDownloadInfo, "child-endpoint": childEndpoint})
2987 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
2988 defer cancel()
2989 _, err = aClient.DownloadTechProfile(subCtx, tpDownloadInfo)
2990 return err
2991}
2992
2993/*
2994Helper functions for remote communication
2995*/
2996
2997// TODO: Use a connection tracker such that the adapter connection is stopped when the last device that adapter
2998// supports is deleted
2999func (dh *DeviceHandler) setupChildInterAdapterClient(ctx context.Context, endpoint string) error {
3000 logger.Infow(ctx, "setting-child-adapter-connection", log.Fields{"child-endpoint": endpoint})
3001
3002 dh.lockChildAdapterClients.Lock()
3003 defer dh.lockChildAdapterClients.Unlock()
3004 if _, ok := dh.childAdapterClients[endpoint]; ok {
3005 // Already set
3006 return nil
3007 }
3008
3009 // Setup child's adapter grpc connection
3010 var err error
3011 if dh.childAdapterClients[endpoint], err = vgrpc.NewClient(endpoint,
3012 dh.onuAdapterRestarted,
3013 vgrpc.ActivityCheck(true)); err != nil {
3014 logger.Errorw(ctx, "grpc-client-not-created", log.Fields{"error": err, "endpoint": endpoint})
3015 return err
3016 }
3017 go dh.childAdapterClients[endpoint].Start(log.WithSpanFromContext(context.TODO(), ctx), setAndTestAdapterServiceHandler)
3018
3019 // Wait until we have a connection to the child adapter.
3020 // Unlimited retries or until context expires
3021 subCtx := log.WithSpanFromContext(context.TODO(), ctx)
3022 backoff := vgrpc.NewBackoff(dh.cfg.MinBackoffRetryDelay, dh.cfg.MaxBackoffRetryDelay, 0)
3023 for {
3024 client, err := dh.childAdapterClients[endpoint].GetOnuInterAdapterServiceClient()
3025 if err == nil && client != nil {
3026 logger.Infow(subCtx, "connected-to-child-adapter", log.Fields{"child-endpoint": endpoint})
3027 break
3028 }
3029 logger.Warnw(subCtx, "connection-to-child-adapter-not-ready", log.Fields{"error": err, "child-endpoint": endpoint})
3030 // Backoff
3031 if err = backoff.Backoff(subCtx); err != nil {
3032 logger.Errorw(subCtx, "received-error-on-backoff", log.Fields{"error": err, "child-endpoint": endpoint})
3033 break
3034 }
3035 }
3036 return nil
3037}
3038
3039// func (dh *DeviceHandler) getChildAdapterServiceClient(endpoint string) (adapter_services.OnuInterAdapterServiceClient, error) {
3040// dh.lockChildAdapterClients.RLock()
3041// defer dh.lockChildAdapterClients.RUnlock()
3042// if cgClient, ok := dh.childAdapterClients[endpoint]; ok {
3043// return cgClient.GetOnuInterAdapterServiceClient()
3044// }
3045// return nil, fmt.Errorf("no-client-for-endpoint-%s", endpoint)
3046// }
3047
3048func (dh *DeviceHandler) getChildAdapterServiceClient(endpoint string) (adapter_services.OnuInterAdapterServiceClient, error) {
3049
3050 // First check from cache
3051 dh.lockChildAdapterClients.RLock()
3052 if cgClient, ok := dh.childAdapterClients[endpoint]; ok {
3053 dh.lockChildAdapterClients.RUnlock()
3054 return cgClient.GetOnuInterAdapterServiceClient()
3055 }
3056 dh.lockChildAdapterClients.RUnlock()
3057
3058 // Set the child connection - can occur on restarts
3059 ctx, cancel := context.WithTimeout(context.Background(), dh.cfg.RPCTimeout)
3060 err := dh.setupChildInterAdapterClient(ctx, endpoint)
3061 cancel()
3062 if err != nil {
3063 return nil, err
3064 }
3065
3066 // Get the child client now
3067 dh.lockChildAdapterClients.RLock()
3068 defer dh.lockChildAdapterClients.RUnlock()
3069 if cgClient, ok := dh.childAdapterClients[endpoint]; ok {
3070 return cgClient.GetOnuInterAdapterServiceClient()
3071 }
3072 return nil, fmt.Errorf("no-client-for-endpoint-%s", endpoint)
3073}
3074
3075func (dh *DeviceHandler) deleteAdapterClients(ctx context.Context) {
3076 dh.lockChildAdapterClients.Lock()
3077 defer dh.lockChildAdapterClients.Unlock()
3078 for key, client := range dh.childAdapterClients {
3079 client.Stop(ctx)
3080 delete(dh.childAdapterClients, key)
3081 }
3082}
3083
3084// TODO: Any action the adapter needs to do following a onu adapter restart?
3085func (dh *DeviceHandler) onuAdapterRestarted(ctx context.Context, endPoint string) error {
khenaidoo7eb2d672021-10-22 19:08:50 -04003086 logger.Warnw(ctx, "onu-adapter-reconnected", log.Fields{"endpoint": endPoint})
khenaidoo106c61a2021-08-11 18:05:46 -04003087 return nil
3088}
3089
3090// setAndTestAdapterServiceHandler is used to test whether the remote gRPC service is up
3091func setAndTestAdapterServiceHandler(ctx context.Context, conn *grpc.ClientConn) interface{} {
3092 svc := adapter_services.NewOnuInterAdapterServiceClient(conn)
3093 if h, err := svc.GetHealthStatus(ctx, &empty.Empty{}); err != nil || h.State != voltha.HealthStatus_HEALTHY {
3094 return nil
3095 }
3096 return svc
3097}