blob: 50e05399b3cecc3e04815c0f7988fb8c3d8b8d33 [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
232 // Stop the adapter grpc clients for that parent device
233 dh.deleteAdapterClients(ctx)
234
Neha Sharma96b7bf22020-06-15 10:37:32 +0000235 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530236}
237
ssiddiqui04386ee2021-08-23 21:58:25 +0530238func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
239 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
240 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
241 if pooledIntfID == intfID {
242 return resourceRanges.GetTechnology()
243 }
244 }
245 }
246 return ""
247}
248
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400249func macifyIP(ip net.IP) string {
250 if len(ip) > 0 {
251 oct1 := strconv.FormatInt(int64(ip[12]), 16)
252 oct2 := strconv.FormatInt(int64(ip[13]), 16)
253 oct3 := strconv.FormatInt(int64(ip[14]), 16)
254 oct4 := strconv.FormatInt(int64(ip[15]), 16)
255 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
256 }
257 return ""
258}
259
Neha Sharma96b7bf22020-06-15 10:37:32 +0000260func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400261 var genmac string
262 var addr net.IP
263 var ips []string
264 var err error
265
Neha Sharma96b7bf22020-06-15 10:37:32 +0000266 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400267
268 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000269 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400270
271 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000272 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400273 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000274 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400275 }
276 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000277 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530278 log.Fields{"host": ips[0],
279 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400280 return genmac, nil
281 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000282 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400283 }
284
285 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000286 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530287 log.Fields{"host": host,
288 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400289 return genmac, nil
290}
291
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530292func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700293 slist := strings.Split(mac, ":")
294 result := make([]uint32, len(slist))
295 var err error
296 var tmp int64
297 for index, val := range slist {
298 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
299 return []uint32{1, 2, 3, 4, 5, 6}
300 }
301 result[index] = uint32(tmp)
302 }
303 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530304}
305
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700306//GetportLabel returns the label for the NNI and the PON port based on port number and port type
David K. Bainbridge794735f2020-02-11 21:01:37 -0800307func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530308
David K. Bainbridge794735f2020-02-11 21:01:37 -0800309 switch portType {
310 case voltha.Port_ETHERNET_NNI:
311 return fmt.Sprintf("nni-%d", portNum), nil
312 case voltha.Port_PON_OLT:
313 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700314 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800315
Girish Kumarf26e4882020-03-05 06:49:10 +0000316 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530317}
318
Neha Sharma96b7bf22020-06-15 10:37:32 +0000319func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000320 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700321 if state == "up" {
322 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500323 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500324 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700325 } else {
326 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500327 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700328 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700329 portNum := plt.IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400330 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800331 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000332 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400333 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500334
khenaidoo106c61a2021-08-11 18:05:46 -0400335 // Check if port exists
336 port, err := dh.getPortFromCore(ctx, &ic.PortFilter{
337 DeviceId: dh.device.Id,
338 Port: portNum,
339 })
340 if err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000341 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
khenaidoo106c61a2021-08-11 18:05:46 -0400342 err = dh.updatePortStateInCore(ctx, &ic.PortState{
343 DeviceId: dh.device.Id,
344 PortType: portType,
345 PortNo: portNum,
346 OperStatus: operStatus})
347 if err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400348 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
349 "device-id": dh.device.Id,
350 "port-type": portType,
351 "port-number": portNum,
352 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500353 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400354 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500355 }
khenaidoo106c61a2021-08-11 18:05:46 -0400356
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400357 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700358 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
khenaidoo106c61a2021-08-11 18:05:46 -0400359 port = &voltha.Port{
360 DeviceId: dh.device.Id,
cuilin20187b2a8c32019-03-26 19:52:28 -0700361 PortNo: portNum,
362 Label: label,
363 Type: portType,
364 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700365 OfpPort: &of.OfpPort{
366 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
367 Config: 0,
368 State: uint32(of.OfpPortState_OFPPS_LIVE),
369 Curr: capacity,
370 Advertised: capacity,
371 Peer: capacity,
372 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
373 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
374 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700375 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000376 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700377 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400378 err = dh.createPortInCore(ctx, port)
379 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000380 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800381 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000382 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400383 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000384 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530385 return nil
386}
387
Kent Hagermane6ff1012020-07-14 15:07:53 -0400388func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -0400389 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530390 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400391 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
392 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530393 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800394 dh.lockDevice.Lock()
395 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530396 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530397}
398
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700399// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530400// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800401func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000402 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700403 defer func() {
404 dh.lockDevice.Lock()
405 dh.isReadIndicationRoutineActive = false
406 dh.lockDevice.Unlock()
407 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700408 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700409 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700410 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700411 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400412
David Bainbridgef5879ca2019-12-13 21:17:54 +0000413 // Create an exponential backoff around re-enabling indications. The
414 // maximum elapsed time for the back off is set to 0 so that we will
415 // continue to retry. The max interval defaults to 1m, but is set
416 // here for code clarity
417 indicationBackoff := backoff.NewExponentialBackOff()
418 indicationBackoff.MaxElapsedTime = 0
419 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700420
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700421 dh.lockDevice.Lock()
422 dh.isReadIndicationRoutineActive = true
423 dh.lockDevice.Unlock()
424
Girish Gowdra3f974912020-03-23 20:35:18 -0700425Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700426 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400427 select {
428 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000429 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700430 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400431 default:
432 indication, err := indications.Recv()
433 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000434 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530435 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530436 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400437 // Use an exponential back off to prevent getting into a tight loop
438 duration := indicationBackoff.NextBackOff()
439 if duration == backoff.Stop {
440 // If we reach a maximum then warn and reset the backoff
441 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000442 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530443 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530444 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400445 indicationBackoff.Reset()
446 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700447
448 // On failure process a backoff timer while watching for stopIndications
449 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700450 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700451 select {
452 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000453 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700454 if !backoffTimer.Stop() {
455 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700456 }
457 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700458 case <-backoffTimer.C:
459 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700460 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700461 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
462 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400463 }
464 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000465 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530466 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000467 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530468 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530469 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700470 // Close the stream, and re-initialize it
471 if err = indications.CloseSend(); err != nil {
472 // Ok to ignore here, because we landed here due to a problem on the stream
473 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000474 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530475 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530476 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700477 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000478 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700479 return err
480 }
481 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400482 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530483 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400484 // Reset backoff if we have a successful receive
485 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400486 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700487 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000488 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530489 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530490 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400491 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400492 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400493 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700494 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700495 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700496 // Close the send stream
497 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700498
Girish Gowdra3f974912020-03-23 20:35:18 -0700499 return nil
500}
501
502func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700503 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700504 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
505 if err != nil {
506 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
507 }
508 if indications == nil {
509 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
510 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700511 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700512 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400513}
514
515// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
516func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
517 switch indication.Data.(type) {
518 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
519 return true
520
521 default:
522 return false
523 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700524}
525
David K. Bainbridge794735f2020-02-11 21:01:37 -0800526func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700527 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000528 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530529 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700530 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530531 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700532 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000533 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000534 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530535 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000536 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800537 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000538 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800539 }
540 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700541}
542
David K. Bainbridge794735f2020-02-11 21:01:37 -0800543// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530544func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700545 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700546 switch indication.Data.(type) {
547 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000548 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
549 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700550 logger.Infow(ctx, "received olt indication", log.Fields{"device-id": dh.device.Id, "olt-ind": indication.GetOltInd()})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800551 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400552 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800553 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700554 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000555 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
556 defer span.Finish()
557
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700558 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800559 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000560 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400561 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800562 }
563 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000564 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700565 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000566 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
567 defer span.Finish()
568
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700569 intfOperInd := indication.GetIntfOperInd()
570 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800571 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000572 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400573 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-nni", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800574 }
575 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700576 } else if intfOperInd.GetType() == "pon" {
577 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
578 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800579 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000580 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400581 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-pon", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800582 }
583 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000584 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700585 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000586 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530587 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530588 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700589 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000590 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
591 defer span.Finish()
592
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700593 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000594 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800595 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800596 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700597 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000598 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
599 defer span.Finish()
600
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700601 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000602 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800603 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800604 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700605 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000606 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
607 defer span.Finish()
608
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700609 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000610 logger.Debugw(ctx, "received-omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800611 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000612 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400613 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800614 }
615 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700616 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000617 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
618 defer span.Finish()
619
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700620 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000621 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700622 "intf-type": pktInd.IntfId,
623 "intf-id": pktInd.IntfId,
624 "gem-port-id": pktInd.GemportId,
625 "port-no": pktInd.PortNo,
626 "device-id": dh.device.Id,
627 })
628
629 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700631 "intf-type": pktInd.IntfId,
632 "intf-id": pktInd.IntfId,
633 "gem-port-id": pktInd.GemportId,
634 "port-no": pktInd.PortNo,
635 "packet": hex.EncodeToString(pktInd.Pkt),
636 "device-id": dh.device.Id,
637 })
638 }
639
David K. Bainbridge794735f2020-02-11 21:01:37 -0800640 go func() {
641 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400642 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800643 }
644 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700645 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000646 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
647 defer span.Finish()
648
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700649 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700650 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700651 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000652 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
653 defer span.Finish()
654
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700655 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000656 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700657 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000658 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
659 defer span.Finish()
660
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700661 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000662 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
663 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700664 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530665}
666
667// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530668func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530669 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000670 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530671
Girish Gowdra618fa572021-09-01 17:19:29 -0700672 // instantiate the mcast handler routines.
673 for i := range dh.incomingMcastFlowOrGroup {
674 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
675 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
676 if !dh.mcastHandlerRoutineActive[i] {
677 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
678 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
679 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
680 // for incoming mcast flow/group to be processed serially.
681 dh.mcastHandlerRoutineActive[i] = true
682 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
683 }
684 }
685
Girish Gowdru0c588b22019-04-23 23:24:56 -0400686 // Synchronous call to update device state - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400687 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
688 DeviceId: dh.device.Id,
689 OperStatus: voltha.OperStatus_ACTIVE,
690 ConnStatus: voltha.ConnectStatus_REACHABLE,
691 }); err != nil {
692 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400693 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000694
695 //Clear olt communication failure event
696 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
697 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700698 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000699 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
700
Gamze Abakac2c32a62021-03-11 11:44:18 +0000701 //check adapter and agent reconcile status
702 //reboot olt if needed (olt disconnection case)
703 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
704 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
705 log.Fields{
706 "device-id": dh.device.Id,
707 "adapter-status": dh.adapterPreviouslyConnected,
708 "agent-status": dh.agentPreviouslyConnected,
709 })
710 _ = dh.RebootDevice(ctx, dh.device)
711 }
712
Girish Gowdru0c588b22019-04-23 23:24:56 -0400713 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530714}
715
716// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530717func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000718 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400719
khenaidoo106c61a2021-08-11 18:05:46 -0400720 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400721 if err != nil || device == nil {
722 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000723 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400724 }
725
726 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400727
728 //Update the device oper state and connection status
729 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800730 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400731 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800732 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400733
khenaidoo106c61a2021-08-11 18:05:46 -0400734 if err = dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
735 DeviceId: cloned.Id,
736 OperStatus: cloned.OperStatus,
737 ConnStatus: cloned.ConnectStatus,
738 }); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000739 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400740 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400741
742 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -0400743 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400744 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000745 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400746 }
747 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400748 // Update onu state as down in onu adapter
749 onuInd := oop.OnuIndication{}
750 onuInd.OperState = "down"
khenaidoo106c61a2021-08-11 18:05:46 -0400751
752 ogClient, err := dh.getChildAdapterServiceClient(onuDevice.AdapterEndpoint)
753 if err != nil {
754 return err
755 }
756 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
757 _, err = ogClient.OnuIndication(subCtx, &ic.OnuIndicationMessage{
758 DeviceId: onuDevice.Id,
759 OnuIndication: &onuInd,
760 })
761 cancel()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800762 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400763 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -0400764 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800765 "onu-indicator": onuInd,
766 "device-type": onuDevice.Type,
767 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700768 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800769 } else {
770 logger.Debugw(ctx, "sending inter adapter down ind to onu success", log.Fields{"olt-device-id": device.Id, "onu-device-id": onuDevice.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700771 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400772 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800773 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700774 /* Discovered ONUs entries need to be cleared , since after OLT
775 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530776 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800777 dh.lockDevice.Unlock()
778
Neha Sharma96b7bf22020-06-15 10:37:32 +0000779 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700780 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530781}
782
783// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530784func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400785 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000786
787 // if the connection is already available, close the previous connection (olt reboot case)
788 if dh.clientCon != nil {
789 if err = dh.clientCon.Close(); err != nil {
790 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
791 } else {
792 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
793 }
794 }
795
796 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000797 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
798 grpc.WithInsecure(),
799 grpc.WithBlock(),
800 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000801 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000802 )),
803 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000804 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000805 )))
806
807 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530808 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530809 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000810 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400811 }
812 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530813}
814
815// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530816func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400817 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530818 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400819 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530820}
821
822// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530823func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530824 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000825 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400826
827 // Case where OLT is disabled and then rebooted.
khenaidoo106c61a2021-08-11 18:05:46 -0400828 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Thomas Lee S985938d2020-05-04 11:40:41 +0530829 if err != nil || device == nil {
830 /*TODO: needs to handle error scenarios */
831 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
832 }
833 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000834 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400835
836 cloned := proto.Clone(device).(*voltha.Device)
837 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
838 cloned.OperStatus = voltha.OperStatus_UNKNOWN
839 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -0400840
841 if err = dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
842 DeviceId: cloned.Id,
843 OperStatus: cloned.OperStatus,
844 ConnStatus: cloned.ConnectStatus,
845 }); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530846 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400847 }
848
Chaitrashree G S44124192019-08-07 20:21:36 -0400849 // Since the device was disabled before the OLT was rebooted, enforce the OLT to be Disabled after re-connection.
npujarec5762e2020-01-01 14:08:48 +0530850 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400851 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530852 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400853 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400854 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
855 // all the modules initialized and ready to handle incoming ONUs.
856
Thomas Lee S985938d2020-05-04 11:40:41 +0530857 err = dh.initializeDeviceHandlerModules(ctx)
858 if err != nil {
859 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400860 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400861
862 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800863 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530864 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400865 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800866 }
867 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700868
869 go startHeartbeatCheck(ctx, dh)
870
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400871 return nil
872 }
873
khenaidoo106c61a2021-08-11 18:05:46 -0400874 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400875 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400876 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400877 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400878 }
khenaidoo106c61a2021-08-11 18:05:46 -0400879 dh.populateActivePorts(ctx, ports.Items)
880 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400881 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400882 }
883
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400884 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530885 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400886 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530887
cuilin20187b2a8c32019-03-26 19:52:28 -0700888 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800889 go func() {
890 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400891 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800892 }
893 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000894 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000895
896 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000897 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000898 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700899
900 go startHeartbeatCheck(ctx, dh)
901
cuilin20187b2a8c32019-03-26 19:52:28 -0700902 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530903}
904
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400905func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700906 var err error
907 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400908
909 if err != nil {
910 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
911 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700912 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
913 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700914
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700915 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700916 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700917 var i uint32
918 for i = 0; i < dh.totalPonPorts; i++ {
919 // Instantiate resource manager
920 if dh.resourceMgr[i] = rsrcMgr.NewResourceMgr(ctx, i, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, dh.deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700921 return olterrors.ErrResourceManagerInstantiating
922 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400923 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700924 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
925 // the KV store to manage mcast group data. Provide the first instance (0th index)
926 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
927 return olterrors.ErrGroupManagerInstantiating
928 }
929 for i = 0; i < dh.totalPonPorts; i++ {
930 // Instantiate flow manager
931 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
932 return olterrors.ErrFlowManagerInstantiating
933 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700934 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700935 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400936 /* TODO: Instantiate Alarm , stats , BW managers */
937 /* Instantiating Event Manager to handle Alarms and KPIs */
938 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
939
940 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000941 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400942
943 return nil
944
945}
946
Neha Sharma96b7bf22020-06-15 10:37:32 +0000947func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400948 var err error
949 var deviceInfo *oop.DeviceInfo
950
Neha Sharma8f4e4322020-08-06 10:51:53 +0000951 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400952
953 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000954 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400955 }
956 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000957 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400958 }
959
Neha Sharma96b7bf22020-06-15 10:37:32 +0000960 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400961 dh.device.Root = true
962 dh.device.Vendor = deviceInfo.Vendor
963 dh.device.Model = deviceInfo.Model
964 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
965 dh.device.HardwareVersion = deviceInfo.HardwareVersion
966 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
967
968 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000969 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400970 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000971 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400972 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000973 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400974 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000975 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400976 dh.device.MacAddress = genmac
977 } else {
978 dh.device.MacAddress = deviceInfo.DeviceId
979 }
980
981 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400982 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000983 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400984 }
985
986 return deviceInfo, nil
987}
988
Neha Sharma96b7bf22020-06-15 10:37:32 +0000989func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700990 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530991 for {
992 select {
993 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000994 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530995 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000996 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700997
khenaidoo106c61a2021-08-11 18:05:46 -0400998 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400999 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001000 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001001 continue
1002 }
khenaidoo106c61a2021-08-11 18:05:46 -04001003 for _, port := range ports.Items {
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301004 // NNI Stats
1005 if port.Type == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001006 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301007 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001008 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001009 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001010 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301011 }
1012 // PON Stats
1013 if port.Type == voltha.Port_PON_OLT {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001014 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301015 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
1016 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001017 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001018 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301019 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001020 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001021
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001022 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001023 if len(onuGemInfoLst) > 0 {
1024 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001025 }
Chaitrashree G Sef088112020-02-03 21:39:27 -05001026 }
Naga Manjunath7615e552019-10-11 22:35:47 +05301027 }
1028 }
1029 }
1030}
1031
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001032//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +05301033func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001034 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001035 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +05301036 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +05301037
1038 // Now, set the initial PM configuration for that device
khenaidoo106c61a2021-08-11 18:05:46 -04001039 cgClient, err := dh.coreClient.GetCoreServiceClient()
1040 if err != nil {
1041 logger.Errorw(ctx, "no-core-connection", log.Fields{"device-id": dh.device.Id, "error": err})
1042 return
1043 }
1044
1045 // Now, set the initial PM configuration for that device
1046 if _, err := cgClient.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001047 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +05301048 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301049}
1050
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001051//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301052func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -07001053 return &ic.SwitchCapability{
1054 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301055 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001056 HwDesc: "open_pon",
1057 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001058 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001059 },
1060 SwitchFeatures: &of.OfpSwitchFeatures{
1061 NBuffers: 256,
1062 NTables: 2,
1063 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1064 of.OfpCapabilities_OFPC_TABLE_STATS |
1065 of.OfpCapabilities_OFPC_PORT_STATS |
1066 of.OfpCapabilities_OFPC_GROUP_STATS),
1067 },
1068 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301069}
1070
khenaidoo106c61a2021-08-11 18:05:46 -04001071// GetTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
1072func (dh *DeviceHandler) GetTechProfileDownloadMessage(ctx context.Context, request *ic.TechProfileInstanceRequestMessage) (*ic.TechProfileDownloadMessage, error) {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001073 ifID, err := plt.IntfIDFromPonPortNum(ctx, request.ParentPonPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001074 if err != nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001075 return nil, err
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001076 }
khenaidoo106c61a2021-08-11 18:05:46 -04001077 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001078}
1079
Neha Sharma96b7bf22020-06-15 10:37:32 +00001080func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001081 logger.Debugw(ctx, "omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "parent-device-id": dh.device.Id})
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001082 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001083 var deviceID string
1084 var proxyDeviceID string
khenaidoo106c61a2021-08-11 18:05:46 -04001085 var childAdapterEndpoint string
cuilin20187b2a8c32019-03-26 19:52:28 -07001086
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001087 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001088 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001089 logger.Debugw(ctx, "recv-omci-msg", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id,
Matteo Scandolo92186242020-06-12 10:54:18 -07001090 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1091 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001092
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001093 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301094
1095 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1096
Neha Sharma96b7bf22020-06-15 10:37:32 +00001097 logger.Debugw(ctx, "omci-indication-for-a-device-not-in-cache.", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001098 ponPort := plt.IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
cuilin20187b2a8c32019-03-26 19:52:28 -07001099
khenaidoo106c61a2021-08-11 18:05:46 -04001100 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1101 ParentId: dh.device.Id,
1102 OnuId: omciInd.OnuId,
1103 ParentPortNo: ponPort,
1104 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001105 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301106 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001107 "intf-id": omciInd.IntfId,
1108 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001109 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001110 deviceType = onuDevice.Type
1111 deviceID = onuDevice.Id
1112 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
khenaidoo106c61a2021-08-11 18:05:46 -04001113 childAdapterEndpoint = onuDevice.AdapterEndpoint
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001114 //if not exist in cache, then add to cache.
khenaidoo106c61a2021-08-11 18:05:46 -04001115 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false, onuDevice.AdapterEndpoint))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001116 } else {
1117 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001118 logger.Debugw(ctx, "omci-indication-for-a-device-in-cache.", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301119 deviceType = onuInCache.(*OnuDevice).deviceType
1120 deviceID = onuInCache.(*OnuDevice).deviceID
1121 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001122 childAdapterEndpoint = onuInCache.(*OnuDevice).adapterEndpoint
cuilin20187b2a8c32019-03-26 19:52:28 -07001123 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001124
khenaidoo106c61a2021-08-11 18:05:46 -04001125 if err := dh.sendOmciIndicationToChildAdapter(ctx, childAdapterEndpoint, &ic.OmciMessage{
1126 ParentDeviceId: proxyDeviceID,
1127 ChildDeviceId: deviceID,
1128 Message: omciInd.Pkt,
1129 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301130 return olterrors.NewErrCommunication("omci-request", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001131 "source": dh.openOLT.config.AdapterEndpoint,
1132 "device-type": deviceType,
1133 "destination": childAdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001134 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001135 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001136 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001137 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301138}
1139
khenaidoo106c61a2021-08-11 18:05:46 -04001140// //ProcessInterAdapterMessage sends the proxied messages to the target device
1141// // If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1142// // is meant, and then send the unmarshalled omci message to this onu
1143// func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1144// logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
1145// if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
1146// return dh.handleInterAdapterOmciMsg(ctx, msg)
1147// }
1148// return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1149// }
cuilin20187b2a8c32019-03-26 19:52:28 -07001150
khenaidoo106c61a2021-08-11 18:05:46 -04001151// ProxyOmciMessage sends the proxied OMCI message to the target device
1152func (dh *DeviceHandler) ProxyOmciMessage(ctx context.Context, omciMsg *ic.OmciMessage) error {
1153 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 -07001154
1155 if omciMsg.GetProxyAddress() == nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001156 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsg.ChildDeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001157 if err != nil {
1158 return olterrors.NewErrNotFound("onu", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001159 "parent-device-id": dh.device.Id,
1160 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001161 }
khenaidoo106c61a2021-08-11 18:05:46 -04001162 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1163 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001164 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001165 "parent-device-id": dh.device.Id,
1166 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001167 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001168 } else {
khenaidoo106c61a2021-08-11 18:05:46 -04001169 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsg.ProxyAddress})
1170 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001171 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001172 "parent-device-id": dh.device.Id,
1173 "child-device-id": omciMsg.ChildDeviceId}, err)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001174 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001175 }
1176 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301177}
1178
khenaidoo106c61a2021-08-11 18:05:46 -04001179func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.OmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001180 var intfID uint32
1181 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001182 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001183 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001184 intfID = onuDevice.ProxyAddress.GetChannelId()
1185 onuID = onuDevice.ProxyAddress.GetOnuId()
1186 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001187 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001188 intfID = omciMsg.GetProxyAddress().GetChannelId()
1189 onuID = omciMsg.GetProxyAddress().GetOnuId()
1190 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001191 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001192 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001193 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 -08001194
Thomas Lee S94109f12020-03-03 16:39:29 +05301195 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001196 "intf-id": intfID,
1197 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001198 }
1199
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001200 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1201 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001202 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001203 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1204 hex.Encode(hexPkt, omciMsg.Message)
1205 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1206
1207 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1208 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1209 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001210 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001211 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001212
Neha Sharma8f4e4322020-08-06 10:51:53 +00001213 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001214 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301215 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001216 "intf-id": intfID,
1217 "onu-id": onuID,
1218 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001219 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001220 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001221}
1222
David K. Bainbridge794735f2020-02-11 21:01:37 -08001223func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301224 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 -07001225 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001226 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001227 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001228 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301229 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301230 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001231 st, _ := status.FromError(err)
1232 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001233 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1234
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001235 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301236 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001237 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001238 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001239 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001240 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001241 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001242}
1243
Mahir Gunyelb0046752021-02-26 13:51:05 -08001244func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001245 channelID := onuDiscInd.GetIntfId()
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001246 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001247
Mahir Gunyelb0046752021-02-26 13:51:05 -08001248 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001249 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301250
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301251 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001252 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001253 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301254
1255 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1256 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1257 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1258 OnuLosRaise event sent for it */
1259 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1260 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1261 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001262 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301263 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1264 "currentIntfId": onuDiscInd.GetIntfId()})
1265 // TODO:: Should we need to ignore raising OnuLosClear event
1266 // when onu connected to different PON?
1267 }
1268 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1269 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1270 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001271 go func() {
1272 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001273 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001274 }
1275 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301276 }
1277 return true
1278 })
1279
Neha Sharma96b7bf22020-06-15 10:37:32 +00001280 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001281 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001282 }
1283
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001284 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001285
1286 // check the ONU is already know to the OLT
1287 // NOTE the second time the ONU is discovered this should return a device
khenaidoo106c61a2021-08-11 18:05:46 -04001288 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1289 ParentId: dh.device.Id,
1290 SerialNumber: sn,
1291 })
Matteo Scandolo945e4012019-12-12 14:16:11 -08001292
1293 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001294 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 -08001295 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001296 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 -08001297 switch e.Code() {
1298 case codes.Internal:
1299 // this probably means NOT FOUND, so just create a new device
1300 onuDevice = nil
1301 case codes.DeadlineExceeded:
1302 // if the call times out, cleanup and exit
1303 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001304 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001305 }
1306 }
1307 }
1308
1309 if onuDevice == nil {
1310 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001311 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001312 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001313 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001314 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001315
Neha Sharma96b7bf22020-06-15 10:37:32 +00001316 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001317
1318 if err != nil {
1319 // if we can't create an ID in resource manager,
1320 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001321 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001322 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001323 "pon-intf-id": ponintfid,
1324 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001325 }
1326
khenaidoo106c61a2021-08-11 18:05:46 -04001327 if onuDevice, err = dh.sendChildDeviceDetectedToCore(ctx, &ic.DeviceDiscovery{
1328 ParentId: dh.device.Id,
1329 ParentPortNo: parentPortNo,
1330 ChannelId: channelID,
1331 VendorId: string(onuDiscInd.SerialNumber.GetVendorId()),
1332 SerialNumber: sn,
1333 OnuId: onuID,
1334 }); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001335 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001336 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 +05301337 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001338 "pon-intf-id": ponintfid,
1339 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001340 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001341 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 -07001342 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001343 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001344 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301345 log.Fields{"onuDevice": onuDevice,
1346 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001347 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301348 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001349 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001350
khenaidoo106c61a2021-08-11 18:05:46 -04001351 // Setup the gRPC connection to the adapter responsible for that onuDevice, if not setup yet
1352 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
1353 err = dh.setupChildInterAdapterClient(subCtx, onuDevice.AdapterEndpoint)
1354 cancel()
1355 if err != nil {
1356 return olterrors.NewErrCommunication("no-connection-to-child-adapter", log.Fields{"device-id": onuDevice.Id}, err)
1357 }
1358
Matteo Scandolo945e4012019-12-12 14:16:11 -08001359 // we can now use the existing ONU Id
1360 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001361 //Insert the ONU into cache to use in OnuIndication.
1362 //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 +00001363 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001364 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301365 "intfId": onuDiscInd.GetIntfId(),
1366 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001367 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001368
khenaidoo106c61a2021-08-11 18:05:46 -04001369 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301370 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001371 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301372 log.Fields{"onu": onuDev,
1373 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001374
khenaidoo106c61a2021-08-11 18:05:46 -04001375 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1376 DeviceId: onuDevice.Id,
1377 ParentDeviceId: dh.device.Id,
1378 OperStatus: common.OperStatus_DISCOVERED,
1379 ConnStatus: common.ConnectStatus_REACHABLE,
1380 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301381 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001382 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001383 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001384 }
khenaidoo106c61a2021-08-11 18:05:46 -04001385
Neha Sharma96b7bf22020-06-15 10:37:32 +00001386 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001387 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301388 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001389 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001390 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001391 }
1392 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001393}
1394
Mahir Gunyelb0046752021-02-26 13:51:05 -08001395func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001396
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001397 ponPort := plt.IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001398 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001399 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001400 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001401 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301402 log.Fields{"onuId": onuInd.OnuId,
1403 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301404 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001405 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001406 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301407
David K. Bainbridge794735f2020-02-11 21:01:37 -08001408 errFields := log.Fields{"device-id": dh.device.Id}
1409
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301410 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1411
Mahir Gunyele77977b2019-06-27 05:36:22 -07001412 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1413 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001414 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001415 onuDevice, err = dh.getDeviceFromCore(ctx, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001416 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001417 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1418 if serialNumber != "" {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001419 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001420 } else {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001421 errFields["onu-id"] = onuInd.OnuId
1422 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001423 }
khenaidoo106c61a2021-08-11 18:05:46 -04001424 onuDevice, err = dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1425 ParentId: dh.device.Id,
1426 SerialNumber: serialNumber,
1427 OnuId: onuInd.OnuId,
1428 ParentPortNo: ponPort,
1429 })
cuilin20187b2a8c32019-03-26 19:52:28 -07001430 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001431
David K. Bainbridge794735f2020-02-11 21:01:37 -08001432 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001433 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001434 }
1435
David K. Bainbridge794735f2020-02-11 21:01:37 -08001436 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001437 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001438 "previousIntfId": onuDevice.ParentPortNo,
1439 "currentIntfId": ponPort})
1440 }
1441
1442 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001443 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301444 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1445 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301446 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001447 }
1448 if !foundInCache {
1449 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1450
khenaidoo106c61a2021-08-11 18:05:46 -04001451 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 -08001452
1453 }
kesavand7cf3a052020-08-28 12:49:18 +05301454 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001455 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001456 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301457 }
1458 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001459 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001460 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001461 }
1462 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001463}
1464
Neha Sharma96b7bf22020-06-15 10:37:32 +00001465func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001466 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 -07001467 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1468 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1469 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1470 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001471 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001472 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1473 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001474 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001475 onuInd.OperState = "down"
1476 }
1477 }
1478
David K. Bainbridge794735f2020-02-11 21:01:37 -08001479 switch onuInd.OperState {
khenaidoo106c61a2021-08-11 18:05:46 -04001480 case "up", "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001481 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 -04001482
1483 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ic.OnuIndicationMessage{
1484 DeviceId: onuDevice.Id,
1485 OnuIndication: onuInd,
1486 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001487 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301488 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001489 "onu-indicator": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001490 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001491 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001492 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001493 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001494 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001495 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001496 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001497 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001498}
1499
cuilin20187b2a8c32019-03-26 19:52:28 -07001500func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1501 if serialNum != nil {
1502 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001503 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001504 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001505}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001506func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1507 decodedStr, err := hex.DecodeString(serialNum[4:])
1508 if err != nil {
1509 return nil, err
1510 }
1511 return &oop.SerialNumber{
1512 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001513 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001514 }, nil
1515}
cuilin20187b2a8c32019-03-26 19:52:28 -07001516
1517func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001518 if len(vendorSpecific) > 3 {
1519 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1520 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1521 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1522 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1523 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1524 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1525 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1526 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1527 return tmp
1528 }
1529 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001530}
1531
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001532//UpdateFlowsBulk upates the bulk flow
1533func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301534 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001535}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001536
1537//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001538func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1539 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301540 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001541 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301542 "device-id": dh.device.Id})
khenaidoo106c61a2021-08-11 18:05:46 -04001543
1544 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ic.ChildDeviceFilter{
1545 ParentId: dh.device.Id,
1546 OnuId: onuID,
1547 ParentPortNo: parentPort,
1548 })
1549
Girish Gowdru0c588b22019-04-23 23:24:56 -04001550 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001551 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001552 "intf-id": parentPort,
1553 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001554 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001555 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 -08001556 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301557}
1558
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001559// SendPacketInToCore sends packet-in to core
1560// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1561// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001562func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001563 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001564 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001565 "port": logicalPort,
1566 "packet": hex.EncodeToString(packetPayload),
1567 "device-id": dh.device.Id,
1568 })
1569 }
khenaidoo106c61a2021-08-11 18:05:46 -04001570
1571 if err := dh.sendPacketToCore(ctx, &ic.PacketIn{
1572 DeviceId: dh.device.Id,
1573 Port: logicalPort,
1574 Packet: packetPayload,
1575 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301576 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001577 "source": "adapter",
1578 "destination": "core",
1579 "device-id": dh.device.Id,
1580 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001581 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001582 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001583 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001584 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001585 "packet": hex.EncodeToString(packetPayload),
1586 "device-id": dh.device.Id,
1587 })
1588 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001589 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001590}
1591
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001592// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001595
1596 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1597 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001598 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001599 }
1600
Kent Hagermane6ff1012020-07-14 15:07:53 -04001601 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001602 metrics := dh.metrics.GetSubscriberMetrics()
1603 for _, m := range pmConfigs.Metrics {
1604 metrics[m.Name].Enabled = m.Enabled
1605
1606 }
1607 }
1608}
1609
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001610//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301611func (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 +00001612 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 +01001613
Girish Gowdra491a9c62021-01-06 16:43:07 -08001614 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001615 var errorsList []error
1616
Girish Gowdru0c588b22019-04-23 23:24:56 -04001617 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001618 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001619 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001620
Neha Sharma96b7bf22020-06-15 10:37:32 +00001621 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301622 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001623 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301624 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001625 if flow_utils.HasGroup(flow) {
1626 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1627 } else {
1628 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1629 }
Girish Gowdracefae192020-03-19 18:14:10 -07001630 if err != nil {
1631 errorsList = append(errorsList, err)
1632 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001633 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301634
1635 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001636 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001637 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301638 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001639 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301640 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001641 if flow_utils.HasGroup(flow) {
1642 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1643 } else {
1644 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1645 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001646 if err != nil {
1647 errorsList = append(errorsList, err)
1648 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301649 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001650 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001651
Girish Gowdracefae192020-03-19 18:14:10 -07001652 // 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 +00001653 if groups != nil {
1654 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001655 // err = dh.groupMgr.AddGroup(ctx, group)
1656 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001657 if err != nil {
1658 errorsList = append(errorsList, err)
1659 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001660 }
1661 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001662 // err = dh.groupMgr.ModifyGroup(ctx, group)
1663 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001664 if err != nil {
1665 errorsList = append(errorsList, err)
1666 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001667 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001668 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001669 // err = dh.groupMgr.DeleteGroup(ctx, group)
1670 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001671 if err != nil {
1672 errorsList = append(errorsList, err)
1673 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001674 }
1675 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001676 if len(errorsList) > 0 {
1677 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1678 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001679 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001680 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301681}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001682
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001683//DisableDevice disables the given device
1684//It marks the following for the given device:
1685//Device-Handler Admin-State : down
1686//Device Port-State: UNKNOWN
1687//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001688func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001689 /* On device disable ,admin state update has to be done prior sending request to agent since
1690 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001691 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001692 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001693 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001694 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001695 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001696 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001697 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001698 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001699 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001700 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301701
1702 dh.discOnus = sync.Map{}
1703 dh.onus = sync.Map{}
1704
Thomas Lee S85f37312020-04-03 17:06:12 +05301705 //stopping the stats collector
1706 dh.stopCollector <- true
1707
Neha Sharma96b7bf22020-06-15 10:37:32 +00001708 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001709 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301710 //Update device Admin state
1711 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -04001712
kdarapu1afeceb2020-02-12 01:38:09 -05001713 // 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 -04001714 if err := dh.updatePortsStateInCore(ctx, &ic.PortStateFilter{
1715 DeviceId: cloned.Id,
1716 PortTypeFilter: ^uint32(1 << voltha.Port_PON_OLT),
1717 OperStatus: voltha.OperStatus_UNKNOWN,
1718 }); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001719 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001720 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001721 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001722 return nil
1723}
1724
Neha Sharma96b7bf22020-06-15 10:37:32 +00001725func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001726 // Update onu state as unreachable in onu adapter
1727 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301728 onuInd.OperState = state
khenaidoo106c61a2021-08-11 18:05:46 -04001729
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001730 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -04001731 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001732 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001733 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 -04001734 }
1735 if onuDevices != nil {
1736 for _, onuDevice := range onuDevices.Items {
khenaidoo106c61a2021-08-11 18:05:46 -04001737 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ic.OnuIndicationMessage{
1738 DeviceId: onuDevice.Id,
1739 OnuIndication: &onuInd,
1740 })
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001741 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001742 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001743 "From Adapter": dh.openOLT.config.AdapterEndpoint, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001744 }
1745
1746 }
1747 }
1748
1749}
1750
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001751//ReenableDevice re-enables the olt device after disable
1752//It marks the following for the given device:
1753//Device-Handler Admin-State : up
1754//Device Port-State: ACTIVE
1755//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001756func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001757 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301758 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001759 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301760 }
1761 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001762 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001763
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001764 // Update the all ports state on that device to enable
khenaidoo106c61a2021-08-11 18:05:46 -04001765 ports, err := dh.listDevicePortsFromCore(ctx, device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001766 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001767 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001768 }
khenaidoo106c61a2021-08-11 18:05:46 -04001769 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001770 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001771 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001772 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001773 device.OperStatus = voltha.OperStatus_ACTIVE
1774 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001775
khenaidoo106c61a2021-08-11 18:05:46 -04001776 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1777 DeviceId: device.Id,
1778 OperStatus: device.OperStatus,
1779 ConnStatus: device.ConnectStatus,
1780 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301781 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001782 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001783 "connect-status": device.ConnectStatus,
1784 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001785 }
kesavand39e0aa32020-01-28 20:58:50 -05001786
Neha Sharma96b7bf22020-06-15 10:37:32 +00001787