blob: 500dbf194e82be40992822d5a0ee9a988aaaced6 [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"
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +053024 "encoding/json"
Girish Gowdra491a9c62021-01-06 16:43:07 -080025 "errors"
cuilin20187b2a8c32019-03-26 19:52:28 -070026 "fmt"
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
Elia Battiston599d25f2022-02-16 14:49:08 +010033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
35
khenaidoo106c61a2021-08-11 18:05:46 -040036 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
khenaidoo106c61a2021-08-11 18:05:46 -040037
Matteo Scandolo945e4012019-12-12 14:16:11 -080038 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070039 "github.com/gogo/protobuf/proto"
Girish Kumar93e91742020-07-27 16:43:19 +000040 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
41 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
khenaidoo106c61a2021-08-11 18:05:46 -040042 "github.com/opencord/voltha-lib-go/v7/pkg/config"
43 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
44 flow_utils "github.com/opencord/voltha-lib-go/v7/pkg/flows"
45 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyel85f61c12021-10-06 11:53:45 -070046 plt "github.com/opencord/voltha-lib-go/v7/pkg/platform"
khenaidoo106c61a2021-08-11 18:05:46 -040047 "github.com/opencord/voltha-lib-go/v7/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080048
khenaidoo106c61a2021-08-11 18:05:46 -040049 conf "github.com/opencord/voltha-openolt-adapter/internal/pkg/config"
Thomas Lee S94109f12020-03-03 16:39:29 +053050 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080051 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
khenaidoo106c61a2021-08-11 18:05:46 -040052 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoodc2116e2021-10-19 17:33:19 -040053 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo106c61a2021-08-11 18:05:46 -040054 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoodc2116e2021-10-19 17:33:19 -040055 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
56 "github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service"
khenaidoo106c61a2021-08-11 18:05:46 -040057 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
58 oop "github.com/opencord/voltha-protos/v5/go/openolt"
59 "github.com/opencord/voltha-protos/v5/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070060 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040061 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040062 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053063)
64
salmansiddiqui7ac62132019-08-22 03:58:50 +000065// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040066const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080067 InvalidPort = 0xffffffff
68 MaxNumOfGroupHandlerChannels = 256
69
70 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
71 McastFlowOrGroupModify = "McastFlowOrGroupModify"
72 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050073 oltPortInfoTimeout = 3
Elia Battiston596406d2022-02-02 12:19:00 +010074
75 defaultPortSpeedMbps = 1000
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +053076 heartbeatPath = "heartbeat"
Manikkaraj kb1d51442019-07-23 10:41:02 -040077)
78
Phaneendra Manda4c62c802019-03-06 21:37:49 +053079//DeviceHandler will interact with the OLT device.
80type DeviceHandler struct {
khenaidoo106c61a2021-08-11 18:05:46 -040081 cm *config.ConfigManager
82 device *voltha.Device
83 cfg *conf.AdapterFlags
84 coreClient *vgrpc.Client
85 childAdapterClients map[string]*vgrpc.Client
86 lockChildAdapterClients sync.RWMutex
87 EventProxy eventif.EventProxy
88 openOLT *OpenOLT
khenaidooefff76e2021-12-15 16:51:30 -050089 exitChannel chan struct{}
khenaidoo106c61a2021-08-11 18:05:46 -040090 lockDevice sync.RWMutex
91 Client oop.OpenoltClient
92 transitionMap *TransitionMap
93 clientCon *grpc.ClientConn
94 flowMgr []*OpenOltFlowMgr
95 groupMgr *OpenOltGroupMgr
96 eventMgr *OpenOltEventMgr
97 resourceMgr []*rsrcMgr.OpenOltResourceMgr
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +053098 kvStore *db.Backend // backend kv store connection handle
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070099
100 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530101
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700102 discOnus sync.Map
103 onus sync.Map
104 portStats *OpenOltStatisticsMgr
105 metrics *pmmetrics.PmMetrics
106 stopCollector chan bool
107 stopHeartbeatCheck chan bool
108 activePorts sync.Map
109 stopIndications chan bool
110 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -0700111
Mahir Gunyelb0046752021-02-26 13:51:05 -0800112 totalPonPorts uint32
113 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
114 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800115
116 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
117 // 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 -0700118 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
119 stopMcastHandlerRoutine []chan bool
120 mcastHandlerRoutineActive []bool
Gamze Abakac2c32a62021-03-11 11:44:18 +0000121
122 adapterPreviouslyConnected bool
123 agentPreviouslyConnected bool
Girish Gowdra950326e2021-11-05 12:43:24 -0700124
125 isDeviceDeletionInProgress bool
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +0530126 heartbeatSignature uint32
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700127}
128
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700129//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700130type OnuDevice struct {
khenaidoo106c61a2021-08-11 18:05:46 -0400131 deviceID string
132 deviceType string
133 serialNumber string
134 onuID uint32
135 intfID uint32
136 proxyDeviceID string
137 losRaised bool
138 rdiRaised bool
139 adapterEndpoint string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700140}
141
Mahir Gunyelb0046752021-02-26 13:51:05 -0800142type onuIndicationMsg struct {
143 ctx context.Context
144 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800145}
146
147type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800148 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800149 stopChannel chan struct{}
150}
151
Girish Gowdra491a9c62021-01-06 16:43:07 -0800152//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
153//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
154//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
155//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
156type McastFlowOrGroupControlBlock struct {
khenaidoodc2116e2021-10-19 17:33:19 -0400157 ctx context.Context // Flow/group handler context
158 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
159 flow *of.OfpFlowStats // Flow message (can be nil or valid flow)
160 group *of.OfpGroupEntry // Group message (can be nil or valid group)
161 errChan *chan error // channel to report the mcast Flow/group handling error
Girish Gowdra491a9c62021-01-06 16:43:07 -0800162}
163
Naga Manjunath7615e552019-10-11 22:35:47 +0530164var pmNames = []string{
165 "rx_bytes",
166 "rx_packets",
167 "rx_mcast_packets",
168 "rx_bcast_packets",
169 "tx_bytes",
170 "tx_packets",
171 "tx_mcast_packets",
172 "tx_bcast_packets",
173}
174
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700175//NewOnuDevice creates a new Onu Device
khenaidoo106c61a2021-08-11 18:05:46 -0400176func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool, adapterEndpoint string) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700177 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700178 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700179 device.deviceType = deviceTp
180 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700181 device.onuID = onuID
182 device.intfID = intfID
183 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530184 device.losRaised = losRaised
khenaidoo106c61a2021-08-11 18:05:46 -0400185 device.adapterEndpoint = adapterEndpoint
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700186 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530187}
188
189//NewDeviceHandler creates a new device handler
khenaidoo106c61a2021-08-11 18:05:46 -0400190func 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 -0700191 var dh DeviceHandler
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +0530192 ctx := context.Background()
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800193 dh.cm = cm
khenaidoo106c61a2021-08-11 18:05:46 -0400194 dh.coreClient = cc
Devmalya Paulfb990a52019-07-09 10:01:49 -0400195 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700196 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700197 dh.device = cloned
198 dh.openOLT = adapter
khenaidooefff76e2021-12-15 16:51:30 -0500199 dh.exitChannel = make(chan struct{})
cuilin20187b2a8c32019-03-26 19:52:28 -0700200 dh.lockDevice = sync.RWMutex{}
Girish Gowdraae56c722021-11-22 14:31:11 -0800201 dh.stopCollector = make(chan bool, 2) // TODO: Why buffered?
202 dh.stopHeartbeatCheck = make(chan bool, 2) // TODO: Why buffered?
Naga Manjunath7615e552019-10-11 22:35:47 +0530203 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 -0500204 dh.activePorts = sync.Map{}
Girish Gowdraae56c722021-11-22 14:31:11 -0800205 dh.stopIndications = make(chan bool, 1) // TODO: Why buffered?
Mahir Gunyelb0046752021-02-26 13:51:05 -0800206 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
khenaidoo106c61a2021-08-11 18:05:46 -0400207 dh.childAdapterClients = make(map[string]*vgrpc.Client)
208 dh.cfg = cfg
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +0530209 kvStoreDevicePath := fmt.Sprintf(dh.cm.Backend.PathPrefix, "/%s/", dh.device.Id)
210 dh.kvStore = SetKVClient(ctx, dh.openOLT.KVStoreType, dh.openOLT.KVStoreAddress, dh.device.Id, kvStoreDevicePath)
211 if dh.kvStore == nil {
212 logger.Error(ctx, "Failed to setup KV store")
213 return nil
214 }
215
Girish Gowdra491a9c62021-01-06 16:43:07 -0800216 // Create a slice of buffered channels for handling concurrent mcast flow/group.
217 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700218 dh.stopMcastHandlerRoutine = make([]chan bool, MaxNumOfGroupHandlerChannels)
219 dh.mcastHandlerRoutineActive = make([]bool, MaxNumOfGroupHandlerChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800220 for i := range dh.incomingMcastFlowOrGroup {
221 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdraae56c722021-11-22 14:31:11 -0800222 dh.stopMcastHandlerRoutine[i] = make(chan bool)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800223 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
224 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
225 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
226 // for incoming mcast flow/group to be processed serially.
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700227 dh.mcastHandlerRoutineActive[i] = true
228 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
Girish Gowdra491a9c62021-01-06 16:43:07 -0800229 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700230 //TODO initialize the support classes.
231 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530232}
233
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +0530234func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
235 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
236 switch storeType {
237 case "etcd":
238 return kvstore.NewEtcdClient(ctx, address, timeout, log.FatalLevel)
239 }
240 return nil, errors.New("unsupported-kv-store")
241}
242
243// SetKVClient sets the KV client and return a kv backend
244func SetKVClient(ctx context.Context, backend string, addr string, DeviceID string, basePathKvStore string) *db.Backend {
245 kvClient, err := newKVClient(ctx, backend, addr, rsrcMgr.KvstoreTimeout)
246 if err != nil {
247 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
248 return nil
249 }
250
251 kvbackend := &db.Backend{
252 Client: kvClient,
253 StoreType: backend,
254 Address: addr,
255 Timeout: rsrcMgr.KvstoreTimeout,
256 PathPrefix: fmt.Sprintf(rsrcMgr.BasePathKvStore, basePathKvStore, DeviceID)}
257
258 return kvbackend
259}
260
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530261// start save the device to the data model
262func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700263 dh.lockDevice.Lock()
264 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000265 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700266 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000267 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530268}
269
khenaidooefff76e2021-12-15 16:51:30 -0500270// Stop stops the device handler
271func (dh *DeviceHandler) Stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700272 dh.lockDevice.Lock()
273 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000274 logger.Debug(ctx, "stopping-device-agent")
khenaidooefff76e2021-12-15 16:51:30 -0500275 close(dh.exitChannel)
khenaidoo106c61a2021-08-11 18:05:46 -0400276
khenaidooefff76e2021-12-15 16:51:30 -0500277 // Delete (which will stop also) all grpc connections to the child adapters
278 dh.deleteAdapterClients(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000279 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530280}
281
ssiddiqui04386ee2021-08-23 21:58:25 +0530282func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
283 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
284 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
285 if pooledIntfID == intfID {
286 return resourceRanges.GetTechnology()
287 }
288 }
289 }
290 return ""
291}
292
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400293func macifyIP(ip net.IP) string {
294 if len(ip) > 0 {
295 oct1 := strconv.FormatInt(int64(ip[12]), 16)
296 oct2 := strconv.FormatInt(int64(ip[13]), 16)
297 oct3 := strconv.FormatInt(int64(ip[14]), 16)
298 oct4 := strconv.FormatInt(int64(ip[15]), 16)
299 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
300 }
301 return ""
302}
303
Neha Sharma96b7bf22020-06-15 10:37:32 +0000304func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400305 var genmac string
306 var addr net.IP
307 var ips []string
308 var err error
309
Neha Sharma96b7bf22020-06-15 10:37:32 +0000310 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400311
312 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000313 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400314
315 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000316 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400317 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000318 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400319 }
320 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000321 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530322 log.Fields{"host": ips[0],
323 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400324 return genmac, nil
325 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000326 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400327 }
328
329 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000330 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530331 log.Fields{"host": host,
332 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400333 return genmac, nil
334}
335
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530336func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700337 slist := strings.Split(mac, ":")
338 result := make([]uint32, len(slist))
339 var err error
340 var tmp int64
341 for index, val := range slist {
342 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
343 return []uint32{1, 2, 3, 4, 5, 6}
344 }
345 result[index] = uint32(tmp)
346 }
347 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530348}
349
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700350//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 -0800351func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530352
David K. Bainbridge794735f2020-02-11 21:01:37 -0800353 switch portType {
354 case voltha.Port_ETHERNET_NNI:
355 return fmt.Sprintf("nni-%d", portNum), nil
356 case voltha.Port_PON_OLT:
357 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700358 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800359
Girish Kumarf26e4882020-03-05 06:49:10 +0000360 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530361}
362
Elia Battiston596406d2022-02-02 12:19:00 +0100363func makeOfpPort(macAddress string, speedMbps uint32) *of.OfpPort {
364 if speedMbps == 0 {
365 //In case it was not set in the indication
366 //and no other value was provided
367 speedMbps = defaultPortSpeedMbps
368 }
369
370 ofpPortSpeed := of.OfpPortFeatures_OFPPF_OTHER
371 switch speedMbps {
372 case 1000000:
373 ofpPortSpeed = of.OfpPortFeatures_OFPPF_1TB_FD
374 case 100000:
375 ofpPortSpeed = of.OfpPortFeatures_OFPPF_100GB_FD
376 case 40000:
377 ofpPortSpeed = of.OfpPortFeatures_OFPPF_40GB_FD
378 case 10000:
379 ofpPortSpeed = of.OfpPortFeatures_OFPPF_10GB_FD
380 case 1000:
381 ofpPortSpeed = of.OfpPortFeatures_OFPPF_1GB_FD
382 case 100:
383 ofpPortSpeed = of.OfpPortFeatures_OFPPF_100MB_FD
384 case 10:
385 ofpPortSpeed = of.OfpPortFeatures_OFPPF_10MB_FD
386 }
387
388 capacity := uint32(ofpPortSpeed | of.OfpPortFeatures_OFPPF_FIBER)
389
390 port := &of.OfpPort{
391 HwAddr: macAddressToUint32Array(macAddress),
392 Config: 0,
393 State: uint32(of.OfpPortState_OFPPS_LIVE),
394 Curr: capacity,
395 Advertised: capacity,
396 Peer: capacity,
397 CurrSpeed: speedMbps * 1000, //kbps
398 MaxSpeed: speedMbps * 1000, //kbps
399 }
400
401 return port
402}
403
404func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string, speedMbps uint32) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000405 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700406 if state == "up" {
407 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500408 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500409 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700410 } else {
411 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500412 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700413 }
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700414 portNum := plt.IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400415 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800416 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000417 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400418 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500419
khenaidoo106c61a2021-08-11 18:05:46 -0400420 // Check if port exists
khenaidoodc2116e2021-10-19 17:33:19 -0400421 port, err := dh.getPortFromCore(ctx, &ca.PortFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400422 DeviceId: dh.device.Id,
423 Port: portNum,
424 })
425 if err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000426 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
khenaidoodc2116e2021-10-19 17:33:19 -0400427 err = dh.updatePortStateInCore(ctx, &ca.PortState{
khenaidoo106c61a2021-08-11 18:05:46 -0400428 DeviceId: dh.device.Id,
429 PortType: portType,
430 PortNo: portNum,
431 OperStatus: operStatus})
432 if err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400433 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
434 "device-id": dh.device.Id,
435 "port-type": portType,
436 "port-number": portNum,
437 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500438 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400439 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500440 }
khenaidoo106c61a2021-08-11 18:05:46 -0400441
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400442 // Now create Port
khenaidoo106c61a2021-08-11 18:05:46 -0400443 port = &voltha.Port{
444 DeviceId: dh.device.Id,
cuilin20187b2a8c32019-03-26 19:52:28 -0700445 PortNo: portNum,
446 Label: label,
447 Type: portType,
448 OperStatus: operStatus,
Elia Battiston596406d2022-02-02 12:19:00 +0100449 OfpPort: makeOfpPort(dh.device.MacAddress, speedMbps),
cuilin20187b2a8c32019-03-26 19:52:28 -0700450 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000451 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700452 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -0400453 err = dh.createPortInCore(ctx, port)
454 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000455 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800456 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000457 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400458 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000459 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530460 return nil
461}
462
Kent Hagermane6ff1012020-07-14 15:07:53 -0400463func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
khenaidoo106c61a2021-08-11 18:05:46 -0400464 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530465 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400466 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
467 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530468 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800469 dh.lockDevice.Lock()
470 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530471 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530472}
473
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700474// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530475// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800476func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000477 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700478 defer func() {
479 dh.lockDevice.Lock()
480 dh.isReadIndicationRoutineActive = false
481 dh.lockDevice.Unlock()
482 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700483 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700484 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700485 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700486 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400487
David Bainbridgef5879ca2019-12-13 21:17:54 +0000488 // Create an exponential backoff around re-enabling indications. The
489 // maximum elapsed time for the back off is set to 0 so that we will
490 // continue to retry. The max interval defaults to 1m, but is set
491 // here for code clarity
492 indicationBackoff := backoff.NewExponentialBackOff()
493 indicationBackoff.MaxElapsedTime = 0
494 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700495
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700496 dh.lockDevice.Lock()
497 dh.isReadIndicationRoutineActive = true
498 dh.lockDevice.Unlock()
499
Girish Gowdra3f974912020-03-23 20:35:18 -0700500Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700501 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400502 select {
503 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000504 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700505 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400506 default:
507 indication, err := indications.Recv()
Elia Battiston599d25f2022-02-16 14:49:08 +0100508
509 select {
510 case <-indications.Context().Done():
511 if err != nil {
512 logger.Warnw(ctx, "error-during-enable-indications",
513 log.Fields{"err": err,
514 "device-id": dh.device.Id})
515 }
516
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400517 // Use an exponential back off to prevent getting into a tight loop
518 duration := indicationBackoff.NextBackOff()
Elia Battiston599d25f2022-02-16 14:49:08 +0100519 logger.Infow(ctx, "backing-off-enable-indication", log.Fields{
520 "device-id": dh.device.Id,
521 "duration": duration,
522 })
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400523 if duration == backoff.Stop {
524 // If we reach a maximum then warn and reset the backoff
525 // timer and keep attempting.
Elia Battiston599d25f2022-02-16 14:49:08 +0100526 logger.Warnw(ctx, "maximum-indication-backoff-reached-resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530527 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530528 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400529 indicationBackoff.Reset()
530 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700531
532 // On failure process a backoff timer while watching for stopIndications
533 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700534 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700535 select {
536 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000537 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700538 if !backoffTimer.Stop() {
539 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700540 }
541 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700542 case <-backoffTimer.C:
543 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700544 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700545 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
546 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400547 }
548 continue
Elia Battiston599d25f2022-02-16 14:49:08 +0100549 default:
550 if err != nil {
551 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530552 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530553 "device-id": dh.device.Id})
Elia Battiston599d25f2022-02-16 14:49:08 +0100554 // Close the stream, and re-initialize it
555 if err = indications.CloseSend(); err != nil {
556 // Ok to ignore here, because we landed here due to a problem on the stream
557 // In all probability, the closeSend call may fail
558 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
559 log.Fields{"err": err,
560 "device-id": dh.device.Id})
561 }
562 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
563 return err
564 }
565 // once we re-initialized the indication stream, continue to read indications
566 continue
Girish Gowdra3f974912020-03-23 20:35:18 -0700567 }
Elia Battiston599d25f2022-02-16 14:49:08 +0100568 // Reset backoff if we have a successful receive
569 indicationBackoff.Reset()
570 // When OLT is admin down, ignore all indications.
571 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
572 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
573 log.Fields{"indication": indication,
574 "device-id": dh.device.Id})
575 continue
Girish Gowdra3f974912020-03-23 20:35:18 -0700576 }
Elia Battiston599d25f2022-02-16 14:49:08 +0100577 dh.handleIndication(ctx, indication)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530578 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700579 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700580 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700581 // Close the send stream
582 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700583
Girish Gowdra3f974912020-03-23 20:35:18 -0700584 return nil
585}
586
587func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700588 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700589 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
590 if err != nil {
591 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
592 }
593 if indications == nil {
594 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
595 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700596 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700597 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400598}
599
600// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
601func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
602 switch indication.Data.(type) {
603 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
604 return true
605
606 default:
607 return false
608 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700609}
610
David K. Bainbridge794735f2020-02-11 21:01:37 -0800611func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700612 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000613 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530614 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700615 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530616 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700617 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000618 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000619 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530620 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000621 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800622 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000623 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800624 }
625 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700626}
627
David K. Bainbridge794735f2020-02-11 21:01:37 -0800628// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530629func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700630 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700631 switch indication.Data.(type) {
632 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000633 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
634 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700635 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 -0800636 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400637 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800638 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700639 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000640 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
641 defer span.Finish()
642
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700643 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800644 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100645 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState(), defaultPortSpeedMbps); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400646 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800647 }
648 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000649 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700650 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000651 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
652 defer span.Finish()
653
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700654 intfOperInd := indication.GetIntfOperInd()
655 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800656 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100657 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState(), intfOperInd.GetSpeed()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400658 _ = 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 -0800659 }
660 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700661 } else if intfOperInd.GetType() == "pon" {
662 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
663 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800664 go func() {
Elia Battiston596406d2022-02-02 12:19:00 +0100665 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState(), defaultPortSpeedMbps); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400666 _ = 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 -0800667 }
668 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000669 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700670 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000671 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530672 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530673 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700674 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000675 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
676 defer span.Finish()
677
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700678 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000679 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800680 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800681 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700682 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000683 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
684 defer span.Finish()
685
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700686 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000687 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800688 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800689 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700690 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000691 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
692 defer span.Finish()
693
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700694 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000695 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 -0800696 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000697 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400698 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800699 }
700 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700701 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000702 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
703 defer span.Finish()
704
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700705 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000706 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700707 "intf-type": pktInd.IntfId,
708 "intf-id": pktInd.IntfId,
709 "gem-port-id": pktInd.GemportId,
710 "port-no": pktInd.PortNo,
711 "device-id": dh.device.Id,
712 })
713
714 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000715 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700716 "intf-type": pktInd.IntfId,
717 "intf-id": pktInd.IntfId,
718 "gem-port-id": pktInd.GemportId,
719 "port-no": pktInd.PortNo,
720 "packet": hex.EncodeToString(pktInd.Pkt),
721 "device-id": dh.device.Id,
722 })
723 }
724
David K. Bainbridge794735f2020-02-11 21:01:37 -0800725 go func() {
726 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400727 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800728 }
729 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700730 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000731 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
732 defer span.Finish()
733
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700734 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700735 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700736 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000737 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
738 defer span.Finish()
739
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700740 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000741 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700742 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000743 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
744 defer span.Finish()
745
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700746 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000747 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
748 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700749 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530750}
751
752// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530753func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530754 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000755 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530756
Girish Gowdra618fa572021-09-01 17:19:29 -0700757 // instantiate the mcast handler routines.
758 for i := range dh.incomingMcastFlowOrGroup {
759 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
760 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
761 if !dh.mcastHandlerRoutineActive[i] {
762 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
763 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
764 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
765 // for incoming mcast flow/group to be processed serially.
766 dh.mcastHandlerRoutineActive[i] = true
767 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
768 }
769 }
770
Girish Gowdru0c588b22019-04-23 23:24:56 -0400771 // Synchronous call to update device state - this method is run in its own go routine
khenaidoodc2116e2021-10-19 17:33:19 -0400772 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400773 DeviceId: dh.device.Id,
774 OperStatus: voltha.OperStatus_ACTIVE,
775 ConnStatus: voltha.ConnectStatus_REACHABLE,
776 }); err != nil {
777 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400778 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000779
780 //Clear olt communication failure event
781 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
782 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700783 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000784 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
785
Girish Gowdru0c588b22019-04-23 23:24:56 -0400786 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530787}
788
789// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530790func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000791 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400792
khenaidoo106c61a2021-08-11 18:05:46 -0400793 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400794 if err != nil || device == nil {
795 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000796 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400797 }
798
799 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400800
801 //Update the device oper state and connection status
802 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800803 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400804 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800805 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400806
khenaidoodc2116e2021-10-19 17:33:19 -0400807 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400808 DeviceId: cloned.Id,
809 OperStatus: cloned.OperStatus,
810 ConnStatus: cloned.ConnectStatus,
811 }); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000812 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400813 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400814
815 //get the child device for the parent device
khenaidoo106c61a2021-08-11 18:05:46 -0400816 onuDevices, err := dh.getChildDevicesFromCore(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400817 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000818 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400819 }
820 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400821 // Update onu state as down in onu adapter
822 onuInd := oop.OnuIndication{}
823 onuInd.OperState = "down"
khenaidoo106c61a2021-08-11 18:05:46 -0400824
825 ogClient, err := dh.getChildAdapterServiceClient(onuDevice.AdapterEndpoint)
826 if err != nil {
827 return err
828 }
829 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
khenaidoodc2116e2021-10-19 17:33:19 -0400830 _, err = ogClient.OnuIndication(subCtx, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -0400831 DeviceId: onuDevice.Id,
832 OnuIndication: &onuInd,
833 })
834 cancel()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800835 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400836 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -0400837 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800838 "onu-indicator": onuInd,
839 "device-type": onuDevice.Type,
840 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700841 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800842 } else {
843 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 -0700844 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400845 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800846 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700847 /* Discovered ONUs entries need to be cleared , since after OLT
848 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530849 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800850 dh.lockDevice.Unlock()
851
Neha Sharma96b7bf22020-06-15 10:37:32 +0000852 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700853 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530854}
855
856// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530857func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400858 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000859
860 // if the connection is already available, close the previous connection (olt reboot case)
861 if dh.clientCon != nil {
862 if err = dh.clientCon.Close(); err != nil {
863 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
864 } else {
865 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
866 }
867 }
868
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +0530869 logger.Debugw(ctx, "Dailing grpc", log.Fields{"device-id": dh.device.Id})
Gamze Abaka49c40b32021-05-06 09:30:41 +0000870 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000871 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
872 grpc.WithInsecure(),
873 grpc.WithBlock(),
874 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000875 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000876 )),
877 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000878 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000879 )))
880
881 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530882 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530883 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000884 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400885 }
886 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530887}
888
889// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530890func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400891 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530892 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400893 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530894}
895
896// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530897func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530898 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000899 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400900
901 // Case where OLT is disabled and then rebooted.
khenaidoo106c61a2021-08-11 18:05:46 -0400902 device, err := dh.getDeviceFromCore(ctx, dh.device.Id)
Thomas Lee S985938d2020-05-04 11:40:41 +0530903 if err != nil || device == nil {
904 /*TODO: needs to handle error scenarios */
905 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
906 }
907 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000908 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400909
910 cloned := proto.Clone(device).(*voltha.Device)
911 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
912 cloned.OperStatus = voltha.OperStatus_UNKNOWN
913 dh.device = cloned
khenaidoo106c61a2021-08-11 18:05:46 -0400914
khenaidoodc2116e2021-10-19 17:33:19 -0400915 if err = dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -0400916 DeviceId: cloned.Id,
917 OperStatus: cloned.OperStatus,
918 ConnStatus: cloned.ConnectStatus,
919 }); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530920 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 -0400921 }
922
Chaitrashree G S44124192019-08-07 20:21:36 -0400923 // 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 +0530924 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400925 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530926 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400927 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400928 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
929 // all the modules initialized and ready to handle incoming ONUs.
930
Thomas Lee S985938d2020-05-04 11:40:41 +0530931 err = dh.initializeDeviceHandlerModules(ctx)
932 if err != nil {
933 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 -0400934 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400935
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700936 go startHeartbeatCheck(ctx, dh)
937
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400938 return nil
939 }
940
khenaidoo106c61a2021-08-11 18:05:46 -0400941 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400942 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400943 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400944 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400945 }
khenaidoo106c61a2021-08-11 18:05:46 -0400946 dh.populateActivePorts(ctx, ports.Items)
947 if err := dh.disableAdminDownPorts(ctx, ports.Items); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400948 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400949 }
950
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400951 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530952 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 -0400953 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530954
Neha Sharma96b7bf22020-06-15 10:37:32 +0000955 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000956
957 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000958 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000959 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700960
961 go startHeartbeatCheck(ctx, dh)
962
cuilin20187b2a8c32019-03-26 19:52:28 -0700963 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530964}
965
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400966func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700967 var err error
968 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400969
970 if err != nil {
971 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
972 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700973 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
974 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
yasin saplid0566272021-12-21 09:10:30 +0000975 // +1 is for NNI
976 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts+1)
977 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts+1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700978 var i uint32
yasin saplid0566272021-12-21 09:10:30 +0000979 // Index from 0 to until totalPonPorts ( Ex: 0 .. 15 ) -> PonPort Managers
980 // Index totalPonPorts ( Ex: 16 ) -> NniPort Manager
981 // There is only one NNI manager since multiple NNI is not supported for now
982 for i = 0; i < dh.totalPonPorts+1; i++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700983 // Instantiate resource manager
984 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 -0700985 return olterrors.ErrResourceManagerInstantiating
986 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400987 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700988 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
989 // the KV store to manage mcast group data. Provide the first instance (0th index)
990 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
991 return olterrors.ErrGroupManagerInstantiating
992 }
yasin saplid0566272021-12-21 09:10:30 +0000993 for i = 0; i < dh.totalPonPorts+1; i++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700994 // Instantiate flow manager
995 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
996 return olterrors.ErrFlowManagerInstantiating
997 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700998 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700999 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001000 /* TODO: Instantiate Alarm , stats , BW managers */
1001 /* Instantiating Event Manager to handle Alarms and KPIs */
1002 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
1003
1004 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001005 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001006
1007 return nil
1008
1009}
1010
Neha Sharma96b7bf22020-06-15 10:37:32 +00001011func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001012 var err error
1013 var deviceInfo *oop.DeviceInfo
1014
Neha Sharma8f4e4322020-08-06 10:51:53 +00001015 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001016
1017 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001018 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001019 }
1020 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001021 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001022 }
1023
Neha Sharma96b7bf22020-06-15 10:37:32 +00001024 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001025 dh.device.Root = true
1026 dh.device.Vendor = deviceInfo.Vendor
1027 dh.device.Model = deviceInfo.Model
1028 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
1029 dh.device.HardwareVersion = deviceInfo.HardwareVersion
1030 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
1031
1032 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001033 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001034 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +00001035 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001036 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001037 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001038 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001039 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001040 dh.device.MacAddress = genmac
1041 } else {
1042 dh.device.MacAddress = deviceInfo.DeviceId
1043 }
1044
1045 // Synchronous call to update device - this method is run in its own go routine
khenaidoo106c61a2021-08-11 18:05:46 -04001046 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001047 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -04001048 }
1049
1050 return deviceInfo, nil
1051}
1052
Neha Sharma96b7bf22020-06-15 10:37:32 +00001053func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001054 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +05301055 for {
1056 select {
1057 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +00001058 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +05301059 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001060 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -07001061
khenaidoo106c61a2021-08-11 18:05:46 -04001062 ports, err := dh.listDevicePortsFromCore(ctx, dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001063 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001064 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001065 continue
1066 }
khenaidoo106c61a2021-08-11 18:05:46 -04001067 for _, port := range ports.Items {
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301068 // NNI Stats
1069 if port.Type == voltha.Port_ETHERNET_NNI {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001070 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301071 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001072 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001073 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001074 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301075 }
1076 // PON Stats
1077 if port.Type == voltha.Port_PON_OLT {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001078 intfID := plt.PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301079 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
1080 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001081 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001082 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +05301083 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001084 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001085
yasin sapli9e4c5092022-02-01 13:52:33 +00001086 onuGemInfoLst := dh.resourceMgr[intfID].GetOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001087 if len(onuGemInfoLst) > 0 {
1088 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +00001089 }
Chaitrashree G Sef088112020-02-03 21:39:27 -05001090 }
Naga Manjunath7615e552019-10-11 22:35:47 +05301091 }
1092 }
1093 }
1094}
1095
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001096//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +05301097func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -04001098 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001099 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +05301100 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +05301101
1102 // Now, set the initial PM configuration for that device
khenaidoo106c61a2021-08-11 18:05:46 -04001103 cgClient, err := dh.coreClient.GetCoreServiceClient()
1104 if err != nil {
1105 logger.Errorw(ctx, "no-core-connection", log.Fields{"device-id": dh.device.Id, "error": err})
1106 return
1107 }
1108
1109 // Now, set the initial PM configuration for that device
1110 if _, err := cgClient.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001111 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +05301112 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301113}
1114
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001115//GetOfpDeviceInfo Gets the Ofp information of the given device
khenaidoodc2116e2021-10-19 17:33:19 -04001116func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ca.SwitchCapability, error) {
1117 return &ca.SwitchCapability{
cuilin20187b2a8c32019-03-26 19:52:28 -07001118 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301119 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001120 HwDesc: "open_pon",
1121 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001122 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001123 },
1124 SwitchFeatures: &of.OfpSwitchFeatures{
1125 NBuffers: 256,
1126 NTables: 2,
1127 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1128 of.OfpCapabilities_OFPC_TABLE_STATS |
1129 of.OfpCapabilities_OFPC_PORT_STATS |
1130 of.OfpCapabilities_OFPC_GROUP_STATS),
1131 },
1132 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301133}
1134
khenaidoo106c61a2021-08-11 18:05:46 -04001135// GetTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
khenaidoodc2116e2021-10-19 17:33:19 -04001136func (dh *DeviceHandler) GetTechProfileDownloadMessage(ctx context.Context, request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001137 ifID, err := plt.IntfIDFromPonPortNum(ctx, request.ParentPonPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001138 if err != nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001139 return nil, err
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001140 }
khenaidoo106c61a2021-08-11 18:05:46 -04001141 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001142}
1143
Neha Sharma96b7bf22020-06-15 10:37:32 +00001144func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001145 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 -07001146 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001147 var deviceID string
1148 var proxyDeviceID string
khenaidoo106c61a2021-08-11 18:05:46 -04001149 var childAdapterEndpoint string
cuilin20187b2a8c32019-03-26 19:52:28 -07001150
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001151 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001152 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001153 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 -07001154 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1155 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001156
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001157 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301158
1159 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1160
Neha Sharma96b7bf22020-06-15 10:37:32 +00001161 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 -07001162 ponPort := plt.IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
cuilin20187b2a8c32019-03-26 19:52:28 -07001163
khenaidoodc2116e2021-10-19 17:33:19 -04001164 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001165 ParentId: dh.device.Id,
1166 OnuId: omciInd.OnuId,
1167 ParentPortNo: ponPort,
1168 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001169 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301170 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001171 "intf-id": omciInd.IntfId,
1172 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001173 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001174 deviceType = onuDevice.Type
1175 deviceID = onuDevice.Id
1176 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
khenaidoo106c61a2021-08-11 18:05:46 -04001177 childAdapterEndpoint = onuDevice.AdapterEndpoint
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001178 //if not exist in cache, then add to cache.
khenaidoo106c61a2021-08-11 18:05:46 -04001179 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false, onuDevice.AdapterEndpoint))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001180 } else {
1181 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001182 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 +05301183 deviceType = onuInCache.(*OnuDevice).deviceType
1184 deviceID = onuInCache.(*OnuDevice).deviceID
1185 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001186 childAdapterEndpoint = onuInCache.(*OnuDevice).adapterEndpoint
cuilin20187b2a8c32019-03-26 19:52:28 -07001187 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001188
khenaidoodc2116e2021-10-19 17:33:19 -04001189 if err := dh.sendOmciIndicationToChildAdapter(ctx, childAdapterEndpoint, &ia.OmciMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001190 ParentDeviceId: proxyDeviceID,
1191 ChildDeviceId: deviceID,
1192 Message: omciInd.Pkt,
1193 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301194 return olterrors.NewErrCommunication("omci-request", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001195 "source": dh.openOLT.config.AdapterEndpoint,
1196 "device-type": deviceType,
1197 "destination": childAdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001198 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001199 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001200 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001201 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301202}
1203
khenaidoo106c61a2021-08-11 18:05:46 -04001204// //ProcessInterAdapterMessage sends the proxied messages to the target device
1205// // If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1206// // is meant, and then send the unmarshalled omci message to this onu
khenaidoodc2116e2021-10-19 17:33:19 -04001207// func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ca.InterAdapterMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001208// logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
khenaidoodc2116e2021-10-19 17:33:19 -04001209// if msg.Header.Type == ca.InterAdapterMessageType_OMCI_REQUEST {
khenaidoo106c61a2021-08-11 18:05:46 -04001210// return dh.handleInterAdapterOmciMsg(ctx, msg)
1211// }
1212// return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1213// }
cuilin20187b2a8c32019-03-26 19:52:28 -07001214
kesavandb9f54fd2021-11-25 20:08:04 +05301215// ProxyOmciRequests sends the proxied OMCI message to the target device
1216func (dh *DeviceHandler) ProxyOmciRequests(ctx context.Context, omciMsgs *ia.OmciMessages) error {
1217 if omciMsgs.GetProxyAddress() == nil {
1218 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsgs.ChildDeviceId)
1219 if err != nil {
1220 return olterrors.NewErrNotFound("onu", log.Fields{
1221 "parent-device-id": dh.device.Id,
1222 "child-device-id": omciMsgs.ChildDeviceId}, err)
1223 }
1224 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1225 if err := dh.sendProxyOmciRequests(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsgs); err != nil {
1226 return olterrors.NewErrCommunication("send-failed", log.Fields{
1227 "parent-device-id": dh.device.Id,
1228 "child-device-id": omciMsgs.ChildDeviceId}, err)
1229 }
1230 } else {
1231 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsgs.ProxyAddress})
1232 if err := dh.sendProxyOmciRequests(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsgs); err != nil {
1233 return olterrors.NewErrCommunication("send-failed", log.Fields{
1234 "parent-device-id": dh.device.Id,
1235 "child-device-id": omciMsgs.ChildDeviceId}, err)
1236 }
1237 }
1238 return nil
1239}
1240
1241func (dh *DeviceHandler) sendProxyOmciRequests(ctx context.Context, onuDevice *voltha.Device, omciMsgs *ia.OmciMessages) error {
1242 var intfID uint32
1243 var onuID uint32
1244 var connectStatus common.ConnectStatus_Types
1245 if onuDevice != nil {
1246 intfID = onuDevice.ProxyAddress.GetChannelId()
1247 onuID = onuDevice.ProxyAddress.GetOnuId()
1248 connectStatus = onuDevice.ConnectStatus
1249 } else {
1250 intfID = omciMsgs.GetProxyAddress().GetChannelId()
1251 onuID = omciMsgs.GetProxyAddress().GetOnuId()
1252 connectStatus = omciMsgs.GetConnectStatus()
1253 }
1254 if connectStatus != voltha.ConnectStatus_REACHABLE {
1255 logger.Debugw(ctx, "onu-not-reachable--cannot-send-omci", log.Fields{"intf-id": intfID, "onu-id": onuID})
1256
1257 return olterrors.NewErrCommunication("unreachable", log.Fields{
1258 "intf-id": intfID,
1259 "onu-id": onuID}, nil)
1260 }
1261
1262 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1263 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
1264
1265 onuSecOmciMsgList := omciMsgs.GetMessages()
1266
1267 for _, onuSecOmciMsg := range onuSecOmciMsgList {
1268
1269 var omciMessage *oop.OmciMsg
1270 hexPkt := make([]byte, hex.EncodedLen(len(onuSecOmciMsg)))
1271 hex.Encode(hexPkt, onuSecOmciMsg)
1272 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1273
1274 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1275 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1276 //https://jira.opencord.org/browse/VOL-4604
1277 transid := extractOmciTransactionID(onuSecOmciMsg)
1278 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
1279 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
1280
1281 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
1282 if err != nil {
1283 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
1284 "intf-id": intfID,
1285 "onu-id": onuID,
1286 "message": omciMessage}, err)
1287 }
1288 }
1289 return nil
1290}
1291
khenaidoo106c61a2021-08-11 18:05:46 -04001292// ProxyOmciMessage sends the proxied OMCI message to the target device
khenaidoodc2116e2021-10-19 17:33:19 -04001293func (dh *DeviceHandler) ProxyOmciMessage(ctx context.Context, omciMsg *ia.OmciMessage) error {
khenaidoo106c61a2021-08-11 18:05:46 -04001294 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 -07001295
1296 if omciMsg.GetProxyAddress() == nil {
khenaidoo106c61a2021-08-11 18:05:46 -04001297 onuDevice, err := dh.getDeviceFromCore(ctx, omciMsg.ChildDeviceId)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001298 if err != nil {
1299 return olterrors.NewErrNotFound("onu", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001300 "parent-device-id": dh.device.Id,
1301 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001302 }
khenaidoo106c61a2021-08-11 18:05:46 -04001303 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"onu-device-proxy-address": onuDevice.ProxyAddress})
1304 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001305 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001306 "parent-device-id": dh.device.Id,
1307 "child-device-id": omciMsg.ChildDeviceId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001308 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001309 } else {
khenaidoo106c61a2021-08-11 18:05:46 -04001310 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"onu-device-proxy-address": omciMsg.ProxyAddress})
1311 if err := dh.sendProxiedMessage(log.WithSpanFromContext(context.Background(), ctx), nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001312 return olterrors.NewErrCommunication("send-failed", log.Fields{
khenaidoo106c61a2021-08-11 18:05:46 -04001313 "parent-device-id": dh.device.Id,
1314 "child-device-id": omciMsg.ChildDeviceId}, err)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001315 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001316 }
1317 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301318}
1319
khenaidoodc2116e2021-10-19 17:33:19 -04001320func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ia.OmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001321 var intfID uint32
1322 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001323 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001324 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001325 intfID = onuDevice.ProxyAddress.GetChannelId()
1326 onuID = onuDevice.ProxyAddress.GetOnuId()
1327 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001328 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001329 intfID = omciMsg.GetProxyAddress().GetChannelId()
1330 onuID = omciMsg.GetProxyAddress().GetOnuId()
1331 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001332 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001333 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001334 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 -08001335
Thomas Lee S94109f12020-03-03 16:39:29 +05301336 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001337 "intf-id": intfID,
1338 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001339 }
1340
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001341 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1342 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
kesavandb9f54fd2021-11-25 20:08:04 +05301343 // https://jira.opencord.org/browse/VOL-4604
lcuie24ef182019-04-29 22:58:36 -07001344 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001345 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1346 hex.Encode(hexPkt, omciMsg.Message)
1347 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1348
1349 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1350 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1351 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001352 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001353 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001354
Neha Sharma8f4e4322020-08-06 10:51:53 +00001355 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001356 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301357 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001358 "intf-id": intfID,
1359 "onu-id": onuID,
1360 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001361 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001362 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001363}
1364
David K. Bainbridge794735f2020-02-11 21:01:37 -08001365func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301366 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
yasin saplibddc2d72022-02-08 13:10:17 +00001367 if err := dh.resourceMgr[intfID].AddNewOnuGemInfoToCacheAndKvStore(ctx, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001368 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001369 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001370 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301371 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301372 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001373 st, _ := status.FromError(err)
1374 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001375 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1376
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001377 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301378 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001379 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001380 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001381 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001382 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001383 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001384}
1385
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +05301386//getChildDevice function can be used in general to get child device, if not found in cache the function will
1387//get from core and update the cache and return the child device.
1388func (dh *DeviceHandler) getChildDevice(ctx context.Context, sn string, parentPortNo uint32) *OnuDevice {
1389 var InCacheOnuDev *OnuDevice
1390 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1391 if onuInCache.(*OnuDevice).serialNumber == sn {
1392 InCacheOnuDev = onuInCache.(*OnuDevice)
1393 return false
1394 }
1395 return true
1396 })
1397 //Got the onu device from cache return
1398 if InCacheOnuDev != nil {
1399 logger.Debugw(ctx, "Got child device from cache", log.Fields{"onudev": InCacheOnuDev.serialNumber})
1400 return InCacheOnuDev
1401 }
1402 onuDevice, _ := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
1403 ParentId: dh.device.Id,
1404 SerialNumber: sn,
1405 ParentPortNo: parentPortNo,
1406 })
1407 //No device found in core return nil
1408 if onuDevice == nil {
1409 return nil
1410 }
1411 onuID := onuDevice.ProxyAddress.OnuId
1412 intfID := plt.PortNoToIntfID(parentPortNo, voltha.Port_PON_OLT)
1413 onuKey := dh.formOnuKey(intfID, onuID)
1414
1415 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, intfID, onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
1416 dh.onus.Store(onuKey, onuDev)
1417 logger.Debugw(ctx, "got child device from core", log.Fields{"onudev": onuDevice})
1418 return onuDev
1419}
1420
1421func (dh *DeviceHandler) checkForResourceExistance(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) (bool, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001422 channelID := onuDiscInd.GetIntfId()
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001423 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +05301424 tpInstExists := false
Matt Jeanneret53539512019-07-20 14:47:02 -04001425
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +05301426 //CheckOnuDevExistenceAtOnuDiscovery if true , a check will be made for the existence of the onu device. If the onu device
1427 // still exists , the onu discovery will be ignored, else a check for active techprofiles for ONU is checked.
1428 if !dh.openOLT.CheckOnuDevExistenceAtOnuDiscovery {
1429 onuDev := dh.getChildDevice(ctx, sn, parentPortNo)
1430 if onuDev != nil {
1431 var onuGemInfo *rsrcMgr.OnuGemInfo
1432 var err error
1433 if onuGemInfo, err = dh.resourceMgr[channelID].GetOnuGemInfo(ctx, onuDev.onuID); err != nil {
1434 logger.Warnw(ctx, "Unable to find onuGemInfo", log.Fields{"onuID": onuDev.onuID})
1435 return false, err
1436 }
1437 if onuGemInfo != nil {
1438 for _, uni := range onuGemInfo.UniPorts {
1439 uniID := plt.UniIDFromPortNum(uni)
1440 tpIDs := dh.resourceMgr[channelID].GetTechProfileIDForOnu(ctx, onuDev.onuID, uniID)
1441 if len(tpIDs) != 0 {
1442 logger.Warnw(ctx, "Techprofile present for ONU, ignoring onu discovery", log.Fields{"onuID": onuDev.onuID})
1443 tpInstExists = true
1444 break
1445 }
1446 }
1447 }
1448 }
1449 return tpInstExists, nil
1450 }
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301451
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +05301452 onuDevice, _ := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
1453 ParentId: dh.device.Id,
1454 SerialNumber: sn,
1455 ParentPortNo: parentPortNo,
1456 })
1457 if onuDevice != nil {
1458 logger.Infow(ctx, "Child device still present ignoring discovery indication", log.Fields{"sn": sn})
1459 return true, nil
1460 }
1461 logger.Infow(ctx, "No device present in core , continuing with discovery", log.Fields{"sn": sn})
1462
1463 return false, nil
1464
1465}
1466
1467func (dh *DeviceHandler) processDiscONULOSClear(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) bool {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301468 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001469 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001470 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301471
1472 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1473 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1474 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1475 OnuLosRaise event sent for it */
1476 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1477 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1478 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001479 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301480 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1481 "currentIntfId": onuDiscInd.GetIntfId()})
1482 // TODO:: Should we need to ignore raising OnuLosClear event
1483 // when onu connected to different PON?
1484 }
1485 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1486 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1487 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001488 go func() {
1489 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001490 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001491 }
1492 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301493 }
1494 return true
1495 })
1496
Neha Sharma96b7bf22020-06-15 10:37:32 +00001497 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +05301498 return true
1499 }
1500 return false
1501}
1502
1503func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
1504 channelID := onuDiscInd.GetIntfId()
1505 parentPortNo := plt.IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
1506
1507 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
1508 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
1509
1510 tpInstExists, errtp := dh.checkForResourceExistance(ctx, onuDiscInd, sn)
1511 if errtp != nil {
1512 return errtp
1513 }
1514 if tpInstExists {
1515 //ignore the discovery if tpinstance is present.
David K. Bainbridge794735f2020-02-11 21:01:37 -08001516 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001517 }
Abhilash Laxmeshward0f58cf2022-06-01 12:15:19 +05301518 if onuBeingProcessed := dh.processDiscONULOSClear(ctx, onuDiscInd, sn); onuBeingProcessed {
1519 return nil
1520 }
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001521 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001522
1523 // check the ONU is already know to the OLT
1524 // NOTE the second time the ONU is discovered this should return a device
khenaidoodc2116e2021-10-19 17:33:19 -04001525 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001526 ParentId: dh.device.Id,
1527 SerialNumber: sn,
1528 })
Matteo Scandolo945e4012019-12-12 14:16:11 -08001529
1530 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001531 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 -08001532 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001533 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 -08001534 switch e.Code() {
1535 case codes.Internal:
1536 // this probably means NOT FOUND, so just create a new device
1537 onuDevice = nil
1538 case codes.DeadlineExceeded:
1539 // if the call times out, cleanup and exit
1540 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001541 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001542 }
1543 }
1544 }
1545
1546 if onuDevice == nil {
1547 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001548 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001549 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001550 ponintfid := onuDiscInd.GetIntfId()
yasin saplibddc2d72022-02-08 13:10:17 +00001551 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001552
Neha Sharma96b7bf22020-06-15 10:37:32 +00001553 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001554
1555 if err != nil {
1556 // if we can't create an ID in resource manager,
1557 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001558 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001559 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001560 "pon-intf-id": ponintfid,
1561 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001562 }
1563
khenaidoodc2116e2021-10-19 17:33:19 -04001564 if onuDevice, err = dh.sendChildDeviceDetectedToCore(ctx, &ca.DeviceDiscovery{
khenaidoo106c61a2021-08-11 18:05:46 -04001565 ParentId: dh.device.Id,
1566 ParentPortNo: parentPortNo,
1567 ChannelId: channelID,
1568 VendorId: string(onuDiscInd.SerialNumber.GetVendorId()),
1569 SerialNumber: sn,
1570 OnuId: onuID,
1571 }); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001572 dh.discOnus.Delete(sn)
yasin saplibddc2d72022-02-08 13:10:17 +00001573 dh.resourceMgr[ponintfid].FreeonuID(ctx, []uint32{onuID}) // NOTE I'm not sure this method is actually cleaning up the right thing
Thomas Lee S94109f12020-03-03 16:39:29 +05301574 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001575 "pon-intf-id": ponintfid,
1576 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001577 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001578 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 -07001579 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001580 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001581 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301582 log.Fields{"onuDevice": onuDevice,
1583 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001584 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301585 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001586 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001587
khenaidoo106c61a2021-08-11 18:05:46 -04001588 // Setup the gRPC connection to the adapter responsible for that onuDevice, if not setup yet
1589 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.cfg.RPCTimeout)
1590 err = dh.setupChildInterAdapterClient(subCtx, onuDevice.AdapterEndpoint)
1591 cancel()
1592 if err != nil {
1593 return olterrors.NewErrCommunication("no-connection-to-child-adapter", log.Fields{"device-id": onuDevice.Id}, err)
1594 }
1595
Matteo Scandolo945e4012019-12-12 14:16:11 -08001596 // we can now use the existing ONU Id
1597 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001598 //Insert the ONU into cache to use in OnuIndication.
1599 //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 +00001600 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001601 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301602 "intfId": onuDiscInd.GetIntfId(),
1603 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001604 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001605
khenaidoo106c61a2021-08-11 18:05:46 -04001606 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false, onuDevice.AdapterEndpoint)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301607 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001608 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301609 log.Fields{"onu": onuDev,
1610 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001611
khenaidoodc2116e2021-10-19 17:33:19 -04001612 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001613 DeviceId: onuDevice.Id,
1614 ParentDeviceId: dh.device.Id,
1615 OperStatus: common.OperStatus_DISCOVERED,
1616 ConnStatus: common.ConnectStatus_REACHABLE,
1617 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301618 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001619 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001620 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001621 }
khenaidoo106c61a2021-08-11 18:05:46 -04001622
Neha Sharma96b7bf22020-06-15 10:37:32 +00001623 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001624 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301625 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001626 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001627 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001628 }
1629 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001630}
1631
Mahir Gunyelb0046752021-02-26 13:51:05 -08001632func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001633
Mahir Gunyel85f61c12021-10-06 11:53:45 -07001634 ponPort := plt.IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001635 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001636 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001637 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001638 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301639 log.Fields{"onuId": onuInd.OnuId,
1640 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301641 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001642 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001643 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301644
David K. Bainbridge794735f2020-02-11 21:01:37 -08001645 errFields := log.Fields{"device-id": dh.device.Id}
1646
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301647 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1648
Mahir Gunyele77977b2019-06-27 05:36:22 -07001649 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1650 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001651 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
khenaidoo106c61a2021-08-11 18:05:46 -04001652 onuDevice, err = dh.getDeviceFromCore(ctx, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001653 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001654 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1655 if serialNumber != "" {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001656 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001657 } else {
David K. Bainbridge794735f2020-02-11 21:01:37 -08001658 errFields["onu-id"] = onuInd.OnuId
1659 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001660 }
khenaidoodc2116e2021-10-19 17:33:19 -04001661 onuDevice, err = dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001662 ParentId: dh.device.Id,
1663 SerialNumber: serialNumber,
1664 OnuId: onuInd.OnuId,
1665 ParentPortNo: ponPort,
1666 })
cuilin20187b2a8c32019-03-26 19:52:28 -07001667 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001668
David K. Bainbridge794735f2020-02-11 21:01:37 -08001669 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001670 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001671 }
1672
David K. Bainbridge794735f2020-02-11 21:01:37 -08001673 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001674 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001675 "previousIntfId": onuDevice.ParentPortNo,
1676 "currentIntfId": ponPort})
1677 }
1678
1679 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001680 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301681 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1682 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301683 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001684 }
1685 if !foundInCache {
1686 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1687
khenaidoo106c61a2021-08-11 18:05:46 -04001688 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 -08001689
1690 }
kesavand7cf3a052020-08-28 12:49:18 +05301691 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001692 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001693 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301694 }
1695 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001696 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001697 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001698 }
1699 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001700}
1701
Neha Sharma96b7bf22020-06-15 10:37:32 +00001702func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001703 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 -07001704 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1705 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1706 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1707 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001708 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001709 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1710 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001711 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001712 onuInd.OperState = "down"
1713 }
1714 }
1715
David K. Bainbridge794735f2020-02-11 21:01:37 -08001716 switch onuInd.OperState {
khenaidoo106c61a2021-08-11 18:05:46 -04001717 case "up", "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001718 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 -04001719
khenaidoodc2116e2021-10-19 17:33:19 -04001720 err := dh.sendOnuIndicationToChildAdapter(ctx, onuDevice.AdapterEndpoint, &ia.OnuIndicationMessage{
khenaidoo106c61a2021-08-11 18:05:46 -04001721 DeviceId: onuDevice.Id,
1722 OnuIndication: onuInd,
1723 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001724 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301725 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001726 "onu-indicator": onuInd,
khenaidoo106c61a2021-08-11 18:05:46 -04001727 "source": dh.openOLT.config.AdapterEndpoint,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001728 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001729 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001730 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001731 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001732 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001733 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001734 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001735}
1736
cuilin20187b2a8c32019-03-26 19:52:28 -07001737func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1738 if serialNum != nil {
1739 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001740 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001741 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001742}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001743func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1744 decodedStr, err := hex.DecodeString(serialNum[4:])
1745 if err != nil {
1746 return nil, err
1747 }
1748 return &oop.SerialNumber{
1749 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001750 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001751 }, nil
1752}
cuilin20187b2a8c32019-03-26 19:52:28 -07001753
1754func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001755 if len(vendorSpecific) > 3 {
1756 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1757 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1758 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1759 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1760 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1761 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1762 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1763 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1764 return tmp
1765 }
1766 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001767}
1768
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001769//UpdateFlowsBulk upates the bulk flow
1770func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301771 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001772}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001773
1774//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001775func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1776 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301777 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001778 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301779 "device-id": dh.device.Id})
khenaidoo106c61a2021-08-11 18:05:46 -04001780
khenaidoodc2116e2021-10-19 17:33:19 -04001781 onuDevice, err := dh.getChildDeviceFromCore(ctx, &ca.ChildDeviceFilter{
khenaidoo106c61a2021-08-11 18:05:46 -04001782 ParentId: dh.device.Id,
1783 OnuId: onuID,
1784 ParentPortNo: parentPort,
1785 })
1786
Girish Gowdru0c588b22019-04-23 23:24:56 -04001787 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001788 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001789 "intf-id": parentPort,
1790 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001791 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001792 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 -08001793 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301794}
1795
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001796// SendPacketInToCore sends packet-in to core
1797// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1798// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001799func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001800 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001801 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001802 "port": logicalPort,
1803 "packet": hex.EncodeToString(packetPayload),
1804 "device-id": dh.device.Id,
1805 })
1806 }
khenaidoo106c61a2021-08-11 18:05:46 -04001807
khenaidoodc2116e2021-10-19 17:33:19 -04001808 if err := dh.sendPacketToCore(ctx, &ca.PacketIn{
khenaidoo106c61a2021-08-11 18:05:46 -04001809 DeviceId: dh.device.Id,
1810 Port: logicalPort,
1811 Packet: packetPayload,
1812 }); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301813 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001814 "source": "adapter",
1815 "destination": "core",
1816 "device-id": dh.device.Id,
1817 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001818 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001819 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001820 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001821 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001822 "packet": hex.EncodeToString(packetPayload),
1823 "device-id": dh.device.Id,
1824 })
1825 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001826 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001827}
1828
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001829// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001830func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001831 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001832
1833 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1834 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001835 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001836 }
1837
Kent Hagermane6ff1012020-07-14 15:07:53 -04001838 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001839 metrics := dh.metrics.GetSubscriberMetrics()
1840 for _, m := range pmConfigs.Metrics {
1841 metrics[m.Name].Enabled = m.Enabled
1842
1843 }
1844 }
1845}
1846
khenaidoodc2116e2021-10-19 17:33:19 -04001847func (dh *DeviceHandler) handleFlows(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, flowMetadata *of.FlowMetadata) []error {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001848 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001849 var errorsList []error
1850
Girish Gowdra20e3dcd2021-11-18 22:56:49 -08001851 if dh.getDeviceDeletionInProgressFlag() {
1852 // The device itself is going to be reset as part of deletion. So nothing to be done.
1853 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1854 return nil
1855 }
1856
Girish Gowdru0c588b22019-04-23 23:24:56 -04001857 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001858 for _, flow := range flows.ToRemove.Items {
yasin saplid0566272021-12-21 09:10:30 +00001859 intfID := dh.getIntfIDFromFlow(ctx, flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001860
Neha Sharma96b7bf22020-06-15 10:37:32 +00001861 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301862 log.Fields{"device-id": device.Id,
yasin saplid0566272021-12-21 09:10:30 +00001863 "intfId": intfID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301864 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001865 if flow_utils.HasGroup(flow) {
1866 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1867 } else {
yasin saplid0566272021-12-21 09:10:30 +00001868 err = dh.flowMgr[intfID].RouteFlowToOnuChannel(ctx, flow, false, nil)
Girish Gowdra491a9c62021-01-06 16:43:07 -08001869 }
Girish Gowdracefae192020-03-19 18:14:10 -07001870 if err != nil {
Elia Battiston2aaf4342022-02-07 15:16:38 +01001871 if werr, ok := err.(olterrors.WrappedError); ok && status.Code(werr.Unwrap()) == codes.NotFound {
1872 //The flow we want to remove is not there, there is no need to throw an error
1873 logger.Warnw(ctx, "flow-to-remove-not-found",
1874 log.Fields{
1875 "ponIf": intfID,
1876 "flowToRemove": flow,
1877 "error": err,
1878 })
1879 } else {
1880 errorsList = append(errorsList, err)
1881 }
Girish Gowdracefae192020-03-19 18:14:10 -07001882 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001883 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301884
1885 for _, flow := range flows.ToAdd.Items {
yasin saplid0566272021-12-21 09:10:30 +00001886 intfID := dh.getIntfIDFromFlow(ctx, flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001887 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301888 log.Fields{"device-id": device.Id,
yasin saplid0566272021-12-