blob: 86cce43d39c5e33f2e7a08dce279a57ea5b59638 [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"
khenaidoo106c61a2021-08-11 18:05:46 -040035
Matteo Scandolo945e4012019-12-12 14:16:11 -080036 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070037 "github.com/gogo/protobuf/proto"
Girish Kumar93e91742020-07-27 16:43:19 +000038 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
39 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
khenaidoo106c61a2021-08-11 18:05:46 -040040 "github.com/opencord/voltha-lib-go/v7/pkg/config"
41 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
42 flow_utils "github.com/opencord/voltha-lib-go/v7/pkg/flows"
43 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyel85f61c12021-10-06 11:53:45 -070044 plt "github.com/opencord/voltha-lib-go/v7/pkg/platform"
khenaidoo106c61a2021-08-11 18:05:46 -040045 "github.com/opencord/voltha-lib-go/v7/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080046
khenaidoo106c61a2021-08-11 18:05:46 -040047 conf "github.com/opencord/voltha-openolt-adapter/internal/pkg/config"
Thomas Lee S94109f12020-03-03 16:39:29 +053048 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080049 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
khenaidoo106c61a2021-08-11 18:05:46 -040050 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoodc2116e2021-10-19 17:33:19 -040051 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo106c61a2021-08-11 18:05:46 -040052 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoodc2116e2021-10-19 17:33:19 -040053 "github.com/opencord/voltha-protos/v5/go/health"
54 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
55 "github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service"
khenaidoo106c61a2021-08-11 18:05:46 -040056 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
57 oop "github.com/opencord/voltha-protos/v5/go/openolt"
58 "github.com/opencord/voltha-protos/v5/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070059 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040060 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040061 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053062)
63
salmansiddiqui7ac62132019-08-22 03:58:50 +000064// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040065const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080066 InvalidPort = 0xffffffff
67 MaxNumOfGroupHandlerChannels = 256
68
69 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
70 McastFlowOrGroupModify = "McastFlowOrGroupModify"
71 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050072 oltPortInfoTimeout = 3
Manikkaraj kb1d51442019-07-23 10:41:02 -040073)
74
Phaneendra Manda4c62c802019-03-06 21:37:49 +053075//DeviceHandler will interact with the OLT device.
76type DeviceHandler struct {
khenaidoo106c61a2021-08-11 18:05:46 -040077 cm *config.ConfigManager
78 device *voltha.Device
79 cfg *conf.AdapterFlags
80 coreClient *vgrpc.Client
81 childAdapterClients map[string]*vgrpc.Client
82 lockChildAdapterClients sync.RWMutex
83 EventProxy eventif.EventProxy
84 openOLT *OpenOLT
85 exitChannel chan int
86 lockDevice sync.RWMutex
87 Client oop.OpenoltClient
88 transitionMap *TransitionMap
89 clientCon *grpc.ClientConn
90 flowMgr []*OpenOltFlowMgr
91 groupMgr *OpenOltGroupMgr
92 eventMgr *OpenOltEventMgr
93 resourceMgr []*rsrcMgr.OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070094
95 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +053096
Girish Gowdra3ab6d212020-03-24 17:33:15 -070097 discOnus sync.Map
98 onus sync.Map
99 portStats *OpenOltStatisticsMgr
100 metrics *pmmetrics.PmMetrics
101 stopCollector chan bool
102 stopHeartbeatCheck chan bool
103 activePorts sync.Map
104 stopIndications chan bool
105 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -0700106
Mahir Gunyelb0046752021-02-26 13:51:05 -0800107 totalPonPorts uint32
108 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
109 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800110
111 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
112 // 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 -0700113 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
114 stopMcastHandlerRoutine []chan bool
115 mcastHandlerRoutineActive []bool
Gamze Abakac2c32a62021-03-11 11:44:18 +0000116
117 adapterPreviouslyConnected bool
118 agentPreviouslyConnected bool
Girish Gowdra950326e2021-11-05 12:43:24 -0700119
120 isDeviceDeletionInProgress bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700121}
122
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700123//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700124type OnuDevice struct {
khenaidoo106c61a2021-08-11 18:05:46 -0400125 deviceID string
126 deviceType string
127 serialNumber string
128 onuID uint32
129 intfID uint32
130 proxyDeviceID string
131 losRaised bool
132 rdiRaised bool
133 adapterEndpoint string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700134}
135
Mahir Gunyelb0046752021-02-26 13:51:05 -0800136type onuIndicationMsg struct {
137 ctx context.Context
138 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800139}
140
141type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800142 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800143 stopChannel chan struct{}
144}
145
Girish Gowdra491a9c62021-01-06 16:43:07 -0800146//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
147//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
148//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
149//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
150type McastFlowOrGroupControlBlock struct {
khenaidoodc2116e2021-10-19 17:33:19 -0400151 ctx context.Context // Flow/group handler context
152 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
153 flow *of.OfpFlowStats // Flow message (can be nil or valid flow)
154 group *of.OfpGroupEntry // Group message (can be nil or valid group)
155 errChan *chan error // channel to report the mcast Flow/group handling error
Girish Gowdra491a9c62021-01-06 16:43:07 -0800156}
157
Naga Manjunath7615e552019-10-11 22:35:47 +0530158var pmNames = []string{
159 "rx_bytes",
160 "rx_packets",
161 "rx_mcast_packets",
162 "rx_bcast_packets",
163 "tx_bytes",
164 "tx_packets",
165 "tx_mcast_packets",
166 "tx_bcast_packets",
167}
168
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700169//NewOnuDevice creates a new Onu Device
khenaidoo106c61a2021-08-11 18:05:46 -0400170func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool, adapterEndpoint string) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700171 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700172 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700173 device.deviceType = deviceTp
174 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700175 device.onuID = onuID
176 device.intfID = intfID
177 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530178 device.losRaised = losRaised
khenaidoo106c61a2021-08-11 18:05:46 -0400179 device.adapterEndpoint = adapterEndpoint
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700180 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530181}
182
183//NewDeviceHandler creates a new device handler
khenaidoo106c61a2021-08-11 18:05:46 -0400184func 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 -0700185 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800186 dh.cm = cm
khenaidoo106c61a2021-08-11 18:05:46 -0400187 dh.coreClient = cc
Devmalya Paulfb990a52019-07-09 10:01:49 -0400188 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700189 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700190 dh.device = cloned
191 dh.openOLT = adapter
192 dh.exitChannel = make(chan int, 1)
193 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530194 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530195 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530196 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 -0500197 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400198 dh.stopIndications = make(chan bool, 1)
Mahir Gunyelb0046752021-02-26 13:51:05 -0800199 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
khenaidoo106c61a2021-08-11 18:05:46 -0400200 dh.childAdapterClients = make(map[string]*vgrpc.Client)
201 dh.cfg = cfg
Girish Gowdra491a9c62021-01-06 16:43:07 -0800202 // Create a slice of buffered channels for handling concurrent mcast flow/group.
203 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700204 dh.stopMcastHandlerRoutine = make([]chan bool, MaxNumOfGroupHandlerChannels)
205 dh.mcastHandlerRoutineActive = make([]bool, MaxNumOfGroupHandlerChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800206 for i := range dh.incomingMcastFlowOrGroup {
207 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700208 dh.stopMcastHandlerRoutine[i] = make(chan bool, 1)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800209 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
210 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
211 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
212 // for incoming mcast flow/group to be processed serially.
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700213 dh.mcastHandlerRoutineActive[i] = true
214 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
Girish Gowdra491a9c62021-01-06 16:43:07 -0800215 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700216 //TODO initialize the support classes.
217 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530218}
219
220// start save the device to the data model
221func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700222 dh.lockDevice.Lock()
223 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000224 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700225 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000226 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530227}
228
229// stop stops the device dh. Not much to do for now
230func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700231 dh.lockDevice.Lock()
232 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000233 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700234 dh.exitChannel <- 1
khenaidoo106c61a2021-08-11 18:05:46 -0400235
Neha Sharma96b7bf22020-06-15 10:37:32 +0000236 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530237}
238
ssiddiqui04386ee2021-08-23 21:58:25 +0530239func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
240 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
241 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
242 if pooledIntfID == intfID {
243 return resourceRanges.GetTechnology()
244 }
245 }
246 }
247 return ""
248}
249
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400250func macifyIP(ip net.IP) string {
251 if len(ip) > 0 {
252 oct1 := strconv.FormatInt(int64(ip[12]), 16)
253 oct2 := strconv.FormatInt(int64(ip[13]), 16)
254 oct3 := strconv.FormatInt(int64(ip[14]), 16)
255 oct4 := strconv.FormatInt(int64(ip[15]), 16)
256 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
257 }
258 return ""
259}
260
Neha Sharma96b7bf22020-06-15 10:37:32 +0000261func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400262 var genmac string
263 var addr net.IP
264 var ips []string
265 var err error
266
Neha Sharma96b7bf22020-06-15 10:37:32 +0000267 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400268
269 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000270 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400271
272 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000273 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400274 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000275 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400276 }
277 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000278 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530279 log.Fields{"host": ips[0],
280 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400281 return genmac, nil
282 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000283 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400284 }
285
286 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000287 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530288 log.Fields{"host": host,
289 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400290 return genmac, nil
291}
292
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530293func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700294 slist := strings.Split(mac, ":")
295 result := make([]uint32, len(slist))
296 var err error
297 var tmp int64
298 for index, val := range slist {
299 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
300 return []uint32{1, 2, 3, 4, 5, 6}
301 }
302 result[index] = uint32(tmp)
303 }
304 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530305}
306
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700307//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 -0800308func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530309
David K. Bainbridge794735f2020-02-11 21:01:37 -0800310 switch portType {
311 case voltha.Port_ETHERNET_NNI:
312 return fmt.Sprintf("nni-%d", portNum), nil
313 case voltha.Port_PON_OLT:
314 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700315 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800316
Girish Kumarf26e4882020-03-05 06:49:10 +0000317 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530318}
319
Neha Sharma96b7bf22020-06-15 10:37:32 +0000320func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000321 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700322 if state == "up" {
323 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500324 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500325 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700326 } else {
327 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500328 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700329 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700330 portNum := plt.IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400331 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800332 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000333 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400334 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500335
khenaidoo106c61a2021-08-11 18:05:46 -0400336 // Check if port exists
khenaidoodc2116e2021-10-19 17:33:19 -0400337 port, err := dh.getPortFromCore(ctx, &ca.PortFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400338 DeviceId: dh.device.Id,
339 Port: portNum,
340 })
341 if err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000342 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
khenaidoodc2116e2021-10-19 17:33:19 -0400343 err = dh.updatePortStateInCore(ctx, &ca.PortState{
khenaidoo106c61a2021-08-11 18:05:46 -0400344 DeviceId: dh.device.Id,
345 PortType: portType,
346 PortNo: portNum,
347 OperStatus: operStatus})
348 if err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400349 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
350 "device-id": dh.device.Id,
351 "port-type": portType,
352 "port-number": portNum,
353 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500354 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400355 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500356 }
khenaidoo106c61a2021-08-11 18:05:46 -0400357
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400358 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700359 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
khenaidoo106c61a2021-08-11 18:05:46 -0400360 port = &voltha.Port{
361 DeviceId: dh.device.Id,
cuilin20187b2a8c32019-03-26 19:52:28 -0700362 PortNo: portNum,
363 Label: label,
364 Type: portType,
365 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700366 OfpPort: &of.OfpPort{
367 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
368 Config: 0,
369 State: uint32(of.OfpPortState_OFPPS_LIVE),
370 Curr: capacity,
371 Advertised: capacity,
372 Peer: capacity,
373 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
374 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
375 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700376 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000377 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700378 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400379 err = dh.createPortInCore(ctx, port)
380 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000381 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800382 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000383 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400384 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000385 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530386 return nil
387}
388
Kent Hagermane6ff1012020-07-14 15:07:53 -0400389func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -0400390 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530391 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400392 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
393 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530394 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800395 dh.lockDevice.Lock()
396 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530397 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530398}
399
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700400// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530401// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800402func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000403 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700404 defer func() {
405 dh.lockDevice.Lock()
406 dh.isReadIndicationRoutineActive = false
407 dh.lockDevice.Unlock()
408 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700409 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700410 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700411 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700412 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400413
David Bainbridgef5879ca2019-12-13 21:17:54 +0000414 // Create an exponential backoff around re-enabling indications. The
415 // maximum elapsed time for the back off is set to 0 so that we will
416 // continue to retry. The max interval defaults to 1m, but is set
417 // here for code clarity
418 indicationBackoff := backoff.NewExponentialBackOff()
419 indicationBackoff.MaxElapsedTime = 0
420 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700421
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700422 dh.lockDevice.Lock()
423 dh.isReadIndicationRoutineActive = true
424 dh.lockDevice.Unlock()
425
Girish Gowdra3f974912020-03-23 20:35:18 -0700426Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700427 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400428 select {
429 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000430 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700431 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400432 default:
433 indication, err := indications.Recv()
434 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000435 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530436 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530437 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400438 // Use an exponential back off to prevent getting into a tight loop
439 duration := indicationBackoff.NextBackOff()
440 if duration == backoff.Stop {
441 // If we reach a maximum then warn and reset the backoff
442 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000443 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530444 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530445 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400446 indicationBackoff.Reset()
447 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700448
449 // On failure process a backoff timer while watching for stopIndications
450 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700451 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700452 select {
453 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000454 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700455 if !backoffTimer.Stop() {
456 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700457 }
458 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700459 case <-backoffTimer.C:
460 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700461 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700462 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
463 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400464 }
465 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000466 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530467 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000468 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530469 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530470 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700471 // Close the stream, and re-initialize it
472 if err = indications.CloseSend(); err != nil {
473 // Ok to ignore here, because we landed here due to a problem on the stream
474 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000475 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530476 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530477 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700478 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000479 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700480 return err
481 }
482 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400483 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530484 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400485 // Reset backoff if we have a successful receive
486 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400487 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700488 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000489 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530490 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530491 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400492 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400493 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400494 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700495 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700496 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700497 // Close the send stream
498 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700499
Girish Gowdra3f974912020-03-23 20:35:18 -0700500 return nil
501}
502
503func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700504 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700505 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
506 if err != nil {
507 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
508 }
509 if indications == nil {
510 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
511 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700512 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700513 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400514}
515
516// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
517func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
518 switch indication.Data.(type) {
519 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
520 return true
521
522 default:
523 return false
524 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700525}
526
David K. Bainbridge794735f2020-02-11 21:01:37 -0800527func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700528 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000529 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530530 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700531 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530532 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700533 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000534 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000535 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530536 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000537 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800538 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000539 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800540 }
541 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700542}
543
David K. Bainbridge794735f2020-02-11 21:01:37 -0800544// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530545func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700546 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700547 switch indication.Data.(type) {
548 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000549 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
550 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700551 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 -0800552 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400553 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800554 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700555 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000556 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
557 defer span.Finish()
558
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700559 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800560 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000561 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400562 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800563 }
564 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000565 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000567 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
568 defer span.Finish()
569
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700570 intfOperInd := indication.GetIntfOperInd()
571 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800572 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000573 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400574 _ = 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 -0800575 }
576 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577 } else if intfOperInd.GetType() == "pon" {
578 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
579 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800580 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000581 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400582 _ = 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 -0800583 }
584 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000585 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700586 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000587 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530588 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530589 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700590 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000591 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
592 defer span.Finish()
593
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700594 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000595 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800596 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800597 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700598 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000599 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
600 defer span.Finish()
601
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700602 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000603 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800604 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800605 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700606 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000607 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
608 defer span.Finish()
609
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700610 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000611 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 -0800612 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000613 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400614 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800615 }
616 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700617 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000618 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
619 defer span.Finish()
620
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700621 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000622 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700623 "intf-type": pktInd.IntfId,
624 "intf-id": pktInd.IntfId,
625 "gem-port-id": pktInd.GemportId,
626 "port-no": pktInd.PortNo,
627 "device-id": dh.device.Id,
628 })
629
630 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000631 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700632 "intf-type": pktInd.IntfId,
633 "intf-id": pktInd.IntfId,
634 "gem-port-id": pktInd.GemportId,
635 "port-no": pktInd.PortNo,
636 "packet": hex.EncodeToString(pktInd.Pkt),
637 "device-id": dh.device.Id,
638 })
639 }
640
David K. Bainbridge794735f2020-02-11 21:01:37 -0800641 go func() {
642 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400643 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800644 }
645 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700646 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000647 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
648 defer span.Finish()
649
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700650 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700651 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700652 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000653 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
654 defer span.Finish()
655
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700656 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000657 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700658 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000659 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
660 defer span.Finish()
661
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700662 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000663 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
664 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700665 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530666}
667
668// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530669func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530670 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000671 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530672
Girish Gowdra618fa572021-09-01 17:19:29 -0700673 // instantiate the mcast handler routines.
674 for i := range dh.incomingMcastFlowOrGroup {
675 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
676 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
677 if !dh.mcastHandlerRoutineActive[i] {
678 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
679 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
680 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
681 // for incoming mcast flow/group to be processed serially.
682 dh.mcastHandlerRoutineActive[i] = true
683 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
684 }
685 }
686
Girish Gowdru0c588b22019-04-23 23:24:56 -0400687 // Synchronous call to update device state - this method is run in its own go routine
khenaidoodc2116e2021-10-19 17:33:19 -0400688 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400689 DeviceId: dh.device.Id,
690 OperStatus: voltha.OperStatus_ACTIVE,
691 ConnStatus: voltha.ConnectStatus_REACHABLE,
692 }); err != nil {
693 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400694 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000695
696 //Clear olt communication failure event
697 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
698 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700699 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000700 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
701
Gamze Abakac2c32a62021-03-11 11:44:18 +0000702 //check adapter and agent reconcile status
703 //reboot olt if needed (olt disconnection case)
704 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
705 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
706 log.Fields{
707 "device-id": dh.device.Id,
708 "adapter-status": dh.adapterPreviouslyConnected,
709 "agent-status": dh.agentPreviouslyConnected,
710 })
711 _ = dh.RebootDevice(ctx, dh.device)
712 }
713
Girish Gowdru0c588b22019-04-23 23:24:56 -0400714 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530715}
716
717// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530718func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000719 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400720
khenaidoo106c61a2021-08-11 18:05:46 -0400721 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400722 if err != nil || device == nil {
723 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000724 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400725 }
726
727 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400728
729 //Update the device oper state and connection status
730 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800731 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400732 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800733 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400734
khenaidoodc2116e2021-10-19 17:33:19 -0400735 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400736 DeviceId: cloned.Id,
737 OperStatus: cloned.OperStatus,
738 ConnStatus: cloned.ConnectStatus,
739 }); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000740 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400741 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400742
743 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -0400744 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400745 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000746 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400747 }
748 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400749 // Update onu state as down in onu adapter
750 onuInd := oop.OnuIndication{}
751 onuInd.OperState = "down"
khenaidoo106c61a2021-08-11 18:05:46 -0400752
753 ogClient, err := dh.getChildAdapterServiceClient(onuDevice.AdapterEndpoint)
754 if err != nil {
755 return err
756 }
757 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
khenaidoodc2116e2021-10-19 17:33:19 -0400758 _, err = ogClient.OnuIndication(subCtx, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -0400759 DeviceId: onuDevice.Id,
760 OnuIndication: &onuInd,
761 })
762 cancel()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800763 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400764 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -0400765 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800766 "onu-indicator": onuInd,
767 "device-type": onuDevice.Type,
768 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700769 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800770 } else {
771 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 -0700772 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400773 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800774 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700775 /* Discovered ONUs entries need to be cleared , since after OLT
776 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530777 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800778 dh.lockDevice.Unlock()
779
Neha Sharma96b7bf22020-06-15 10:37:32 +0000780 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700781 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530782}
783
784// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530785func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400786 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000787
788 // if the connection is already available, close the previous connection (olt reboot case)
789 if dh.clientCon != nil {
790 if err = dh.clientCon.Close(); err != nil {
791 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
792 } else {
793 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
794 }
795 }
796
797 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000798 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
799 grpc.WithInsecure(),
800 grpc.WithBlock(),
801 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000802 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000803 )),
804 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000805 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000806 )))
807
808 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530809 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530810 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000811 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400812 }
813 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530814}
815
816// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530817func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400818 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530819 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400820 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530821}
822
823// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530824func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530825 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000826 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400827
828 // Case where OLT is disabled and then rebooted.
khenaidoo106c61a2021-08-11 18:05:46 -0400829 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Thomas Lee S985938d2020-05-04 11:40:41 +0530830 if err != nil || device == nil {
831 /*TODO: needs to handle error scenarios */
832 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
833 }
834 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000835 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400836
837 cloned := proto.Clone(device).(*voltha.Device)
838 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
839 cloned.OperStatus = voltha.OperStatus_UNKNOWN
840 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -0400841
khenaidoodc2116e2021-10-19 17:33:19 -0400842 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400843 DeviceId: cloned.Id,
844 OperStatus: cloned.OperStatus,
845 ConnStatus: cloned.ConnectStatus,
846 }); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530847 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 -0400848 }
849
Chaitrashree G S44124192019-08-07 20:21:36 -0400850 // 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 +0530851 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400852 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530853 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400854 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400855 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
856 // all the modules initialized and ready to handle incoming ONUs.
857
Thomas Lee S985938d2020-05-04 11:40:41 +0530858 err = dh.initializeDeviceHandlerModules(ctx)
859 if err != nil {
860 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 -0400861 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400862
863 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800864 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530865 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400866 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800867 }
868 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700869
870 go startHeartbeatCheck(ctx, dh)
871
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400872 return nil
873 }
874
khenaidoo106c61a2021-08-11 18:05:46 -0400875 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400876 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400877 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400878 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400879 }
khenaidoo106c61a2021-08-11 18:05:46 -0400880 dh.populateActivePorts(ctx, ports.Items)
881 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400882 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400883 }
884
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400885 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530886 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 -0400887 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530888
cuilin20187b2a8c32019-03-26 19:52:28 -0700889 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800890 go func() {
891 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400892 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800893 }
894 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000895 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000896
897 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000898 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000899 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700900
901 go startHeartbeatCheck(ctx, dh)
902
cuilin20187b2a8c32019-03-26 19:52:28 -0700903 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530904}
905
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400906func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700907 var err error
908 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400909
910 if err != nil {
911 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
912 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700913 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
914 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700915
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700916 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700917 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700918 var i uint32
919 for i = 0; i < dh.totalPonPorts; i++ {
920 // Instantiate resource manager
921 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 -0700922 return olterrors.ErrResourceManagerInstantiating
923 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400924 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700925 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
926 // the KV store to manage mcast group data. Provide the first instance (0th index)
927 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
928 return olterrors.ErrGroupManagerInstantiating
929 }
930 for i = 0; i < dh.totalPonPorts; i++ {
931 // Instantiate flow manager
932 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
933 return olterrors.ErrFlowManagerInstantiating
934 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700935 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700936 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400937 /* TODO: Instantiate Alarm , stats , BW managers */
938 /* Instantiating Event Manager to handle Alarms and KPIs */
939 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
940
941 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000942 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400943
944 return nil
945
946}
947
Neha Sharma96b7bf22020-06-15 10:37:32 +0000948func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400949 var err error
950 var deviceInfo *oop.DeviceInfo
951
Neha Sharma8f4e4322020-08-06 10:51:53 +0000952 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400953
954 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000955 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400956 }
957 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000958 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400959 }
960
Neha Sharma96b7bf22020-06-15 10:37:32 +0000961 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400962 dh.device.Root = true
963 dh.device.Vendor = deviceInfo.Vendor
964 dh.device.Model = deviceInfo.Model
965 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
966 dh.device.HardwareVersion = deviceInfo.HardwareVersion
967 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
968
969 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000970 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400971 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000972 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400973 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000974 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400975 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000976 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400977 dh.device.MacAddress = genmac
978 } else {
979 dh.device.MacAddress = deviceInfo.DeviceId
980 }
981
982 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400983 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000984 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400985 }
986
987 return deviceInfo, nil
988}
989
Neha Sharma96b7bf22020-06-15 10:37:32 +0000990func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700991 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530992 for {
993 select {
994 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000995 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530996 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000997 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700998
khenaidoo106c61a2021-08-11 18:05:46 -0400999 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001000 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001001 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001002 continue
1003 }
khenaidoo106c61a2021-08-11 18:05:46 -04001004 for _, port := range ports.Items {
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301005 // NNI Stats
1006 if port.Type == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001007 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301008 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001009 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001010 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001011 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301012 }
1013 // PON Stats
1014 if port.Type == voltha.Port_PON_OLT {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001015 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301016 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
1017 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001018 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001019 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301020 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001021 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001022
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001023 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001024 if len(onuGemInfoLst) > 0 {
1025 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001026 }
Chaitrashree G Sef088112020-02-03 21:39:27 -05001027 }
Naga Manjunath7615e552019-10-11 22:35:47 +05301028 }
1029 }
1030 }
1031}
1032
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001033//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +05301034func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001035 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001036 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +05301037 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +05301038
1039 // Now, set the initial PM configuration for that device
khenaidoo106c61a2021-08-11 18:05:46 -04001040 cgClient, err := dh.coreClient.GetCoreServiceClient()
1041 if err != nil {
1042 logger.Errorw(ctx, "no-core-connection", log.Fields{"device-id": dh.device.Id, "error": err})
1043 return
1044 }
1045
1046 // Now, set the initial PM configuration for that device
1047 if _, err := cgClient.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001048 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +05301049 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301050}
1051
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001052//GetOfpDeviceInfo Gets the Ofp information of the given device
khenaidoodc2116e2021-10-19 17:33:19 -04001053func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ca.SwitchCapability, error) {
1054 return &ca.SwitchCapability{
cuilin20187b2a8c32019-03-26 19:52:28 -07001055 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301056 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001057 HwDesc: "open_pon",
1058 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001059 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001060 },
1061 SwitchFeatures: &of.OfpSwitchFeatures{
1062 NBuffers: 256,
1063 NTables: 2,
1064 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1065 of.OfpCapabilities_OFPC_TABLE_STATS |
1066 of.OfpCapabilities_OFPC_PORT_STATS |
1067 of.OfpCapabilities_OFPC_GROUP_STATS),
1068 },
1069 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301070}
1071
khenaidoo106c61a2021-08-11 18:05:46 -04001072// GetTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
khenaidoodc2116e2021-10-19 17:33:19 -04001073func (dh *DeviceHandler) GetTechProfileDownloadMessage(ctx context.Context, request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001074 ifID, err := plt.IntfIDFromPonPortNum(ctx, request.ParentPonPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001075 if err != nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001076 return nil, err
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001077 }
khenaidoo106c61a2021-08-11 18:05:46 -04001078 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001079}
1080
Neha Sharma96b7bf22020-06-15 10:37:32 +00001081func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001082 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 -07001083 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001084 var deviceID string
1085 var proxyDeviceID string
khenaidoo106c61a2021-08-11 18:05:46 -04001086 var childAdapterEndpoint string
cuilin20187b2a8c32019-03-26 19:52:28 -07001087
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001088 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001089 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001090 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 -07001091 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1092 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001093
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001094 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301095
1096 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1097
Neha Sharma96b7bf22020-06-15 10:37:32 +00001098 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 -07001099 ponPort := plt.IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
cuilin20187b2a8c32019-03-26 19:52:28 -07001100
khenaidoodc2116e2021-10-19 17:33:19 -04001101 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001102 ParentId: dh.device.Id,
1103 OnuId: omciInd.OnuId,
1104 ParentPortNo: ponPort,
1105 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001106 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301107 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001108 "intf-id": omciInd.IntfId,
1109 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001110 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001111 deviceType = onuDevice.Type
1112 deviceID = onuDevice.Id
1113 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
khenaidoo106c61a2021-08-11 18:05:46 -04001114 childAdapterEndpoint = onuDevice.AdapterEndpoint
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001115 //if not exist in cache, then add to cache.
khenaidoo106c61a2021-08-11 18:05:46 -04001116 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false, onuDevice.AdapterEndpoint))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001117 } else {
1118 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001119 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 +05301120 deviceType = onuInCache.(*OnuDevice).deviceType
1121 deviceID = onuInCache.(*OnuDevice).deviceID
1122 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001123 childAdapterEndpoint = onuInCache.(*OnuDevice).adapterEndpoint
cuilin20187b2a8c32019-03-26 19:52:28 -07001124 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001125
khenaidoodc2116e2021-10-19 17:33:19 -04001126 if err := dh.sendOmciIndicationToChildAdapter(ctx, childAdapterEndpoint, &ia.OmciMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001127 ParentDeviceId: proxyDeviceID,
1128 ChildDeviceId: deviceID,
1129 Message: omciInd.Pkt,
1130 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301131 return olterrors.NewErrCommunication("omci-request", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001132 "source": dh.openOLT.config.AdapterEndpoint,
1133 "device-type": deviceType,
1134 "destination": childAdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001135 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001136 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001137 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001138 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301139}
1140
khenaidoo106c61a2021-08-11 18:05:46 -04001141// //ProcessInterAdapterMessage sends the proxied messages to the target device
1142// // If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1143// // is meant, and then send the unmarshalled omci message to this onu
khenaidoodc2116e2021-10-19 17:33:19 -04001144// func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ca.InterAdapterMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001145// logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
khenaidoodc2116e2021-10-19 17:33:19 -04001146// if msg.Header.Type == ca.InterAdapterMessageType_OMCI_REQUEST {
khenaidoo106c61a2021-08-11 18:05:46 -04001147// return dh.handleInterAdapterOmciMsg(ctx, msg)
1148// }
1149// return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1150// }
cuilin20187b2a8c32019-03-26 19:52:28 -07001151
khenaidoo106c61a2021-08-11 18:05:46 -04001152// ProxyOmciMessage sends the proxied OMCI message to the target device
khenaidoodc2116e2021-10-19 17:33:19 -04001153func (dh *DeviceHandler) ProxyOmciMessage(ctx context.Context, omciMsg *ia.OmciMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001154 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 -07001155
1156 if omciMsg.GetProxyAddress() == nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001157 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsg.ChildDeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001158 if err != nil {
1159 return olterrors.NewErrNotFound("onu", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001160 "parent-device-id": dh.device.Id,
1161 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001162 }
khenaidoo106c61a2021-08-11 18:05:46 -04001163 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1164 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001165 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001166 "parent-device-id": dh.device.Id,
1167 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001168 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001169 } else {
khenaidoo106c61a2021-08-11 18:05:46 -04001170 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsg.ProxyAddress})
1171 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001172 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001173 "parent-device-id": dh.device.Id,
1174 "child-device-id": omciMsg.ChildDeviceId}, err)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001175 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001176 }
1177 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301178}
1179
khenaidoodc2116e2021-10-19 17:33:19 -04001180func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ia.OmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001181 var intfID uint32
1182 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001183 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001184 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001185 intfID = onuDevice.ProxyAddress.GetChannelId()
1186 onuID = onuDevice.ProxyAddress.GetOnuId()
1187 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001188 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001189 intfID = omciMsg.GetProxyAddress().GetChannelId()
1190 onuID = omciMsg.GetProxyAddress().GetOnuId()
1191 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001192 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001193 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001194 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 -08001195
Thomas Lee S94109f12020-03-03 16:39:29 +05301196 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001197 "intf-id": intfID,
1198 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001199 }
1200
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001201 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1202 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001203 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001204 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1205 hex.Encode(hexPkt, omciMsg.Message)
1206 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1207
1208 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1209 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1210 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001211 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001212 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001213
Neha Sharma8f4e4322020-08-06 10:51:53 +00001214 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001215 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301216 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001217 "intf-id": intfID,
1218 "onu-id": onuID,
1219 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001220 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001221 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001222}
1223
David K. Bainbridge794735f2020-02-11 21:01:37 -08001224func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301225 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 -07001226 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001227 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001228 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001229 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301230 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301231 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001232 st, _ := status.FromError(err)
1233 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001234 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1235
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001236 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301237 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001238 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001239 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001240 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001241 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001242 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001243}
1244
Mahir Gunyelb0046752021-02-26 13:51:05 -08001245func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001246 channelID := onuDiscInd.GetIntfId()
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001247 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001248
Mahir Gunyelb0046752021-02-26 13:51:05 -08001249 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001250 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301251
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301252 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001253 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001254 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301255
1256 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1257 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1258 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1259 OnuLosRaise event sent for it */
1260 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1261 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1262 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001263 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301264 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1265 "currentIntfId": onuDiscInd.GetIntfId()})
1266 // TODO:: Should we need to ignore raising OnuLosClear event
1267 // when onu connected to different PON?
1268 }
1269 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1270 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1271 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001272 go func() {
1273 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001274 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001275 }
1276 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301277 }
1278 return true
1279 })
1280
Neha Sharma96b7bf22020-06-15 10:37:32 +00001281 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001282 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001283 }
1284
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001285 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001286
1287 // check the ONU is already know to the OLT
1288 // NOTE the second time the ONU is discovered this should return a device
khenaidoodc2116e2021-10-19 17:33:19 -04001289 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001290 ParentId: dh.device.Id,
1291 SerialNumber: sn,
1292 })
Matteo Scandolo945e4012019-12-12 14:16:11 -08001293
1294 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001295 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 -08001296 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001297 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 -08001298 switch e.Code() {
1299 case codes.Internal:
1300 // this probably means NOT FOUND, so just create a new device
1301 onuDevice = nil
1302 case codes.DeadlineExceeded:
1303 // if the call times out, cleanup and exit
1304 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001305 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001306 }
1307 }
1308 }
1309
1310 if onuDevice == nil {
1311 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001312 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001313 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001314 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001315 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001316
Neha Sharma96b7bf22020-06-15 10:37:32 +00001317 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001318
1319 if err != nil {
1320 // if we can't create an ID in resource manager,
1321 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001322 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001323 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001324 "pon-intf-id": ponintfid,
1325 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001326 }
1327
khenaidoodc2116e2021-10-19 17:33:19 -04001328 if onuDevice, err = dh.sendChildDeviceDetectedToCore(ctx, &ca.DeviceDiscovery{
khenaidoo106c61a2021-08-11 18:05:46 -04001329 ParentId: dh.device.Id,
1330 ParentPortNo: parentPortNo,
1331 ChannelId: channelID,
1332 VendorId: string(onuDiscInd.SerialNumber.GetVendorId()),
1333 SerialNumber: sn,
1334 OnuId: onuID,
1335 }); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001336 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001337 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 +05301338 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001339 "pon-intf-id": ponintfid,
1340 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001341 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001342 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 -07001343 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001344 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001345 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301346 log.Fields{"onuDevice": onuDevice,
1347 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001348 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301349 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001350 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001351
khenaidoo106c61a2021-08-11 18:05:46 -04001352 // Setup the gRPC connection to the adapter responsible for that onuDevice, if not setup yet
1353 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
1354 err = dh.setupChildInterAdapterClient(subCtx, onuDevice.AdapterEndpoint)
1355 cancel()
1356 if err != nil {
1357 return olterrors.NewErrCommunication("no-connection-to-child-adapter", log.Fields{"device-id": onuDevice.Id}, err)
1358 }
1359
Matteo Scandolo945e4012019-12-12 14:16:11 -08001360 // we can now use the existing ONU Id
1361 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001362 //Insert the ONU into cache to use in OnuIndication.
1363 //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 +00001364 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001365 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301366 "intfId": onuDiscInd.GetIntfId(),
1367 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001368 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001369
khenaidoo106c61a2021-08-11 18:05:46 -04001370 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301371 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001372 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301373 log.Fields{"onu": onuDev,
1374 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001375
khenaidoodc2116e2021-10-19 17:33:19 -04001376 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001377 DeviceId: onuDevice.Id,
1378 ParentDeviceId: dh.device.Id,
1379 OperStatus: common.OperStatus_DISCOVERED,
1380 ConnStatus: common.ConnectStatus_REACHABLE,
1381 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301382 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001383 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001384 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001385 }
khenaidoo106c61a2021-08-11 18:05:46 -04001386
Neha Sharma96b7bf22020-06-15 10:37:32 +00001387 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001388 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301389 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001390 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001391 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001392 }
1393 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001394}
1395
Mahir Gunyelb0046752021-02-26 13:51:05 -08001396func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001397
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001398 ponPort := plt.IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001399 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001400 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001401 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001402 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301403 log.Fields{"onuId": onuInd.OnuId,
1404 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301405 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001406 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001407 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301408
David K. Bainbridge794735f2020-02-11 21:01:37 -08001409 errFields := log.Fields{"device-id": dh.device.Id}
1410
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301411 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1412
Mahir Gunyele77977b2019-06-27 05:36:22 -07001413 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1414 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001415 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001416 onuDevice, err = dh.getDeviceFromCore(ctx, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001417 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001418 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1419 if serialNumber != "" {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001420 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001421 } else {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001422 errFields["onu-id"] = onuInd.OnuId
1423 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001424 }
khenaidoodc2116e2021-10-19 17:33:19 -04001425 onuDevice, err = dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001426 ParentId: dh.device.Id,
1427 SerialNumber: serialNumber,
1428 OnuId: onuInd.OnuId,
1429 ParentPortNo: ponPort,
1430 })
cuilin20187b2a8c32019-03-26 19:52:28 -07001431 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001432
David K. Bainbridge794735f2020-02-11 21:01:37 -08001433 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001434 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001435 }
1436
David K. Bainbridge794735f2020-02-11 21:01:37 -08001437 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001438 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001439 "previousIntfId": onuDevice.ParentPortNo,
1440 "currentIntfId": ponPort})
1441 }
1442
1443 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001444 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301445 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1446 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301447 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001448 }
1449 if !foundInCache {
1450 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1451
khenaidoo106c61a2021-08-11 18:05:46 -04001452 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 -08001453
1454 }
kesavand7cf3a052020-08-28 12:49:18 +05301455 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001456 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001457 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301458 }
1459 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001460 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001461 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001462 }
1463 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001464}
1465
Neha Sharma96b7bf22020-06-15 10:37:32 +00001466func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001467 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 -07001468 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1469 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1470 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1471 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001472 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001473 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1474 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001475 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001476 onuInd.OperState = "down"
1477 }
1478 }
1479
David K. Bainbridge794735f2020-02-11 21:01:37 -08001480 switch onuInd.OperState {
khenaidoo106c61a2021-08-11 18:05:46 -04001481 case "up", "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001482 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 -04001483
khenaidoodc2116e2021-10-19 17:33:19 -04001484 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001485 DeviceId: onuDevice.Id,
1486 OnuIndication: onuInd,
1487 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001488 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301489 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001490 "onu-indicator": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001491 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001492 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001493 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001494 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001495 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001496 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001497 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001498 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001499}
1500
cuilin20187b2a8c32019-03-26 19:52:28 -07001501func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1502 if serialNum != nil {
1503 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001504 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001505 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001506}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001507func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1508 decodedStr, err := hex.DecodeString(serialNum[4:])
1509 if err != nil {
1510 return nil, err
1511 }
1512 return &oop.SerialNumber{
1513 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001514 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001515 }, nil
1516}
cuilin20187b2a8c32019-03-26 19:52:28 -07001517
1518func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001519 if len(vendorSpecific) > 3 {
1520 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1521 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1522 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1523 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1524 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1525 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1526 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1527 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1528 return tmp
1529 }
1530 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001531}
1532
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001533//UpdateFlowsBulk upates the bulk flow
1534func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301535 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001536}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001537
1538//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001539func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1540 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301541 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001542 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301543 "device-id": dh.device.Id})
khenaidoo106c61a2021-08-11 18:05:46 -04001544
khenaidoodc2116e2021-10-19 17:33:19 -04001545 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001546 ParentId: dh.device.Id,
1547 OnuId: onuID,
1548 ParentPortNo: parentPort,
1549 })
1550
Girish Gowdru0c588b22019-04-23 23:24:56 -04001551 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001552 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001553 "intf-id": parentPort,
1554 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001555 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001556 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 -08001557 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301558}
1559
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001560// SendPacketInToCore sends packet-in to core
1561// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1562// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001563func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001564 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001565 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001566 "port": logicalPort,
1567 "packet": hex.EncodeToString(packetPayload),
1568 "device-id": dh.device.Id,
1569 })
1570 }
khenaidoo106c61a2021-08-11 18:05:46 -04001571
khenaidoodc2116e2021-10-19 17:33:19 -04001572 if err := dh.sendPacketToCore(ctx, &ca.PacketIn{
khenaidoo106c61a2021-08-11 18:05:46 -04001573 DeviceId: dh.device.Id,
1574 Port: logicalPort,
1575 Packet: packetPayload,
1576 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301577 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001578 "source": "adapter",
1579 "destination": "core",
1580 "device-id": dh.device.Id,
1581 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001582 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001583 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001584 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001586 "packet": hex.EncodeToString(packetPayload),
1587 "device-id": dh.device.Id,
1588 })
1589 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001590 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001591}
1592
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001593// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001596
1597 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1598 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001599 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001600 }
1601
Kent Hagermane6ff1012020-07-14 15:07:53 -04001602 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001603 metrics := dh.metrics.GetSubscriberMetrics()
1604 for _, m := range pmConfigs.Metrics {
1605 metrics[m.Name].Enabled = m.Enabled
1606
1607 }
1608 }
1609}
1610
khenaidoodc2116e2021-10-19 17:33:19 -04001611func (dh *DeviceHandler) handleFlows(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, flowMetadata *of.FlowMetadata) []error {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001612 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001613 var errorsList []error
1614
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001615 if dh.getDeviceDeletionInProgressFlag() {
1616 // The device itself is going to be reset as part of deletion. So nothing to be done.
1617 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1618 return nil
1619 }
1620
Girish Gowdru0c588b22019-04-23 23:24:56 -04001621 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001622 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001623 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001624
Neha Sharma96b7bf22020-06-15 10:37:32 +00001625 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301626 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001627 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301628 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001629 if flow_utils.HasGroup(flow) {
1630 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1631 } else {
1632 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1633 }
Girish Gowdracefae192020-03-19 18:14:10 -07001634 if err != nil {
1635 errorsList = append(errorsList, err)
1636 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001637 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301638
1639 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001640 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001641 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301642 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001643 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301644 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001645 if flow_utils.HasGroup(flow) {
1646 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1647 } else {
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001648 if dh.flowMgr == nil || dh.flowMgr[ponIf] == nil {
1649 // The flow manager module could be uninitialized if the flow arrives too soon before the device has reconciled fully
1650 logger.Errorw(ctx, "flow-manager-uninitialized", log.Fields{"device-id": device.Id})
1651 err = fmt.Errorf("flow-manager-uninitialized-%v", device.Id)
1652 } else {
1653 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1654 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08001655 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001656 if err != nil {
1657 errorsList = append(errorsList, err)
1658 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301659 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001660 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001661
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001662 return errorsList
1663}
1664
1665func (dh *DeviceHandler) handleGroups(ctx context.Context, groups *of.FlowGroupChanges) []error {
1666 var err error
1667 var errorsList []error
1668
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001669 if dh.getDeviceDeletionInProgressFlag() {
1670 // The device itself is going to be reset as part of deletion. So nothing to be done.
1671 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": dh.device.Id})
1672 return nil
1673 }
1674
Girish Gowdracefae192020-03-19 18:14:10 -07001675 // 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 +00001676 if groups != nil {
1677 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001678 // err = dh.groupMgr.AddGroup(ctx, group)
1679 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001680 if err != nil {
1681 errorsList = append(errorsList, err)
1682 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001683 }
1684 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001685 // err = dh.groupMgr.ModifyGroup(ctx, group)
1686 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001687 if err != nil {
1688 errorsList = append(errorsList, err)
1689 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001690 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001691 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001692 // err = dh.groupMgr.DeleteGroup(ctx, group)
1693 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001694 if err != nil {
1695 errorsList = append(errorsList, err)
1696 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001697 }
1698 }
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001699
1700 return errorsList
1701}
1702
1703//UpdateFlowsIncrementally updates the device flow
khenaidoodc2116e2021-10-19 17:33:19 -04001704func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *of.FlowMetadata) error {
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001705
1706 var errorsList []error
Girish Gowdra950326e2021-11-05 12:43:24 -07001707
1708 if dh.getDeviceDeletionInProgressFlag() {
1709 // The device itself is going to be reset as part of deletion. So nothing to be done.
1710 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1711 return nil
1712 }
1713
Girish Gowdra0fb24a32021-10-27 15:15:27 -07001714 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
1715 errorsList = append(errorsList, dh.handleFlows(ctx, device, flows, flowMetadata)...)
1716 errorsList = append(errorsList, dh.handleGroups(ctx, groups)...)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001717 if len(errorsList) > 0 {
1718 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1719 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001720 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001721 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301722}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001723
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001724//DisableDevice disables the given device
1725//It marks the following for the given device:
1726//Device-Handler Admin-State : down
1727//Device Port-State: UNKNOWN
1728//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001729func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001730 /* On device disable ,admin state update has to be done prior sending request to agent since
1731 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001732 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001733 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001734 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001735 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001736 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001737 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001738 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001739 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001740 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001741 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301742
1743 dh.discOnus = sync.Map{}
1744 dh.onus = sync.Map{}
1745
Thomas Lee S85f37312020-04-03 17:06:12 +05301746 //stopping the stats collector
1747 dh.stopCollector <- true
1748
Neha Sharma96b7bf22020-06-15 10:37:32 +00001749 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001750 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301751 //Update device Admin state
1752 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -04001753
kdarapu1afeceb2020-02-12 01:38:09 -05001754 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
khenaidoodc2116e2021-10-19 17:33:19 -04001755 if err := dh.updatePortsStateInCore(ctx, &ca.PortStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001756 DeviceId: cloned.Id,
1757 PortTypeFilter: ^uint32(1 << voltha.Port_PON_OLT),
1758 OperStatus: voltha.OperStatus_UNKNOWN,
1759 }); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001760 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001761 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001762 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001763 return nil
1764}
1765
Neha Sharma96b7bf22020-06-15 10:37:32 +00001766func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001767 // Update onu state as unreachable in onu adapter
1768 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301769 onuInd.OperState = state
khenaidoo106c61a2021-08-11 18:05:46 -04001770
Chaitrashree G S