blob: 9ccb21d494b3810fdc6c3632604cbd64853449b7 [file] [log] [blame]
Naveen Sampath04696f72022-06-13 15:19:14 +05301/*
2* Copyright 2022-present Open Networking Foundation
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14 */
15
16package controller
17
18import (
19 "context"
20 "errors"
21 "sync"
22 "time"
23
24 "encoding/hex"
25
26 "voltha-go-controller/database"
27 errorCodes "voltha-go-controller/internal/pkg/errorcodes"
28 "voltha-go-controller/internal/pkg/intf"
29 "voltha-go-controller/internal/pkg/of"
30 "voltha-go-controller/internal/pkg/tasks"
31 "voltha-go-controller/internal/pkg/util"
32 "voltha-go-controller/internal/pkg/vpagent"
33
Tinoj Joseph1d108322022-07-13 10:07:39 +053034 "voltha-go-controller/log"
Naveen Sampath04696f72022-06-13 15:19:14 +053035)
36
37var logger log.CLogger
38var ctx = context.TODO()
39
40func init() {
41 // Setup this package so that it's log level can be modified at run time
42 var err error
Tinoj Joseph1d108322022-07-13 10:07:39 +053043 logger, err = log.AddPackageWithDefaultParam()
Naveen Sampath04696f72022-06-13 15:19:14 +053044 if err != nil {
45 panic(err)
46 }
47}
48
49var db database.DBIntf
50
Naveen Sampath04696f72022-06-13 15:19:14 +053051// VoltController structure
52type VoltController struct {
Naveen Sampath04696f72022-06-13 15:19:14 +053053 ctx context.Context
54 app intf.App
Naveen Sampath04696f72022-06-13 15:19:14 +053055 BlockedDeviceList *util.ConcurrentMap
56 deviceTaskQueue *util.ConcurrentMap
vinokuma926cb3e2023-03-29 11:41:06 +053057 vagent map[string]*vpagent.VPAgent
58 devices map[string]*Device
59 rebootInProgressDevices map[string]string
60 deviceLock sync.RWMutex
61 rebootLock sync.Mutex
Tinoj Josephaf37ce82022-12-28 11:59:43 +053062 deviceTableSyncDuration time.Duration
vinokuma926cb3e2023-03-29 11:41:06 +053063 RebootFlow bool
Naveen Sampath04696f72022-06-13 15:19:14 +053064}
65
66var vcontroller *VoltController
67
68// NewController is the constructor for VoltController
69func NewController(ctx context.Context, app intf.App) intf.IVPClientAgent {
70 var controller VoltController
71
72 controller.rebootInProgressDevices = make(map[string]string)
73 controller.devices = make(map[string]*Device)
74 controller.deviceLock = sync.RWMutex{}
75 controller.ctx = ctx
76 controller.app = app
77 controller.BlockedDeviceList = util.NewConcurrentMap()
78 controller.deviceTaskQueue = util.NewConcurrentMap()
79 db = database.GetDatabase()
80 vcontroller = &controller
81 return &controller
82}
83
vinokuma926cb3e2023-03-29 11:41:06 +053084// SetDeviceTableSyncDuration - sets interval between device table sync up activity
85// duration - in minutes
Tinoj Josephaf37ce82022-12-28 11:59:43 +053086func (v *VoltController) SetDeviceTableSyncDuration(duration int) {
87 v.deviceTableSyncDuration = time.Duration(duration) * time.Second
88}
89
vinokuma926cb3e2023-03-29 11:41:06 +053090// GetDeviceTableSyncDuration - returns configured device table sync duration
Tinoj Josephaf37ce82022-12-28 11:59:43 +053091func (v *VoltController) GetDeviceTableSyncDuration() time.Duration {
92 return v.deviceTableSyncDuration
93}
94
Naveen Sampath04696f72022-06-13 15:19:14 +053095// AddDevice to add device
Tinoj Joseph07cc5372022-07-18 22:53:51 +053096func (v *VoltController) AddDevice(cntx context.Context, config *intf.VPClientCfg) intf.IVPClient {
Tinoj Joseph429b9d92022-11-16 18:51:05 +053097 d := NewDevice(cntx, config.DeviceID, config.SerialNum, config.VolthaClient, config.SouthBoundID, config.MfrDesc, config.HwDesc, config.SwDesc)
Naveen Sampath04696f72022-06-13 15:19:14 +053098 v.devices[config.DeviceID] = d
Tinoj Joseph07cc5372022-07-18 22:53:51 +053099 v.app.AddDevice(cntx, d.ID, d.SerialNum, config.SouthBoundID)
Naveen Sampath04696f72022-06-13 15:19:14 +0530100
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530101 d.RestoreMetersFromDb(cntx)
102 d.RestoreGroupsFromDb(cntx)
103 d.RestoreFlowsFromDb(cntx)
104 d.RestorePortsFromDb(cntx)
Naveen Sampath04696f72022-06-13 15:19:14 +0530105 d.ConnectInd(context.TODO(), intf.DeviceDisc)
106 d.packetOutChannel = config.PacketOutChannel
107
Akash Soni6168f312023-05-18 20:57:33 +0530108 logger.Debugw(ctx, "Added device", log.Fields{"Device": config.DeviceID, "SerialNo": d.SerialNum, "State": d.State})
Naveen Sampath04696f72022-06-13 15:19:14 +0530109
110 return d
111}
112
113// DelDevice to delete device
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530114func (v *VoltController) DelDevice(cntx context.Context, id string) {
Naveen Sampath04696f72022-06-13 15:19:14 +0530115 d, ok := v.devices[id]
116 if ok {
117 delete(v.devices, id)
118 d.Delete()
119 }
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530120 v.app.DelDevice(cntx, id)
Naveen Sampath04696f72022-06-13 15:19:14 +0530121 d.cancel() // To stop the device tables sync routine
Akash Soni6168f312023-05-18 20:57:33 +0530122 logger.Debugw(ctx, "Deleted device", log.Fields{"Device": id})
Naveen Sampath04696f72022-06-13 15:19:14 +0530123}
124
vinokuma926cb3e2023-03-29 11:41:06 +0530125// AddControllerTask - add task to controller queue
Naveen Sampath04696f72022-06-13 15:19:14 +0530126func (v *VoltController) AddControllerTask(device string, task tasks.Task) {
127 var taskQueueIntf interface{}
128 var taskQueue *tasks.Tasks
129 var found bool
130 if taskQueueIntf, found = v.deviceTaskQueue.Get(device); !found {
131 taskQueue = tasks.NewTasks(context.TODO())
132 v.deviceTaskQueue.Set(device, taskQueue)
133 } else {
134 taskQueue = taskQueueIntf.(*tasks.Tasks)
135 }
136 taskQueue.AddTask(task)
137 logger.Warnw(ctx, "Task Added to Controller Task List", log.Fields{"Len": taskQueue.NumPendingTasks(), "Total": taskQueue.TotalTasks()})
138}
139
vinokuma926cb3e2023-03-29 11:41:06 +0530140// AddNewDevice - called when new device is discovered. This will be
141// processed as part of controller queue
Naveen Sampath04696f72022-06-13 15:19:14 +0530142func (v *VoltController) AddNewDevice(config *intf.VPClientCfg) {
143 adt := NewAddDeviceTask(config)
144 v.AddControllerTask(config.DeviceID, adt)
145}
146
147// GetDevice to get device info
148func (v *VoltController) GetDevice(id string) (*Device, error) {
149 d, ok := v.devices[id]
150 if ok {
151 return d, nil
152 }
153 return nil, errorCodes.ErrDeviceNotFound
154}
155
156// IsRebootInProgressForDevice to check if reboot is in progress for the device
157func (v *VoltController) IsRebootInProgressForDevice(device string) bool {
158 v.rebootLock.Lock()
159 defer v.rebootLock.Unlock()
160 _, ok := v.rebootInProgressDevices[device]
161 return ok
162}
163
164// SetRebootInProgressForDevice to set reboot in progress for the device
165func (v *VoltController) SetRebootInProgressForDevice(device string) bool {
166 v.rebootLock.Lock()
167 defer v.rebootLock.Unlock()
168 _, ok := v.rebootInProgressDevices[device]
169 if ok {
170 return true
171 }
172 v.rebootInProgressDevices[device] = device
173 logger.Warnw(ctx, "Setted Reboot-In-Progress flag", log.Fields{"Device": device})
174
175 d, err := v.GetDevice(device)
176 if err == nil {
177 d.ResetCache()
178 } else {
179 logger.Errorw(ctx, "Failed to get device", log.Fields{"Device": device, "Error": err})
180 }
181
182 return true
183}
184
185// ReSetRebootInProgressForDevice to reset reboot in progress for the device
186func (v *VoltController) ReSetRebootInProgressForDevice(device string) bool {
187 v.rebootLock.Lock()
188 defer v.rebootLock.Unlock()
189 _, ok := v.rebootInProgressDevices[device]
190 if !ok {
191 return true
192 }
193 delete(v.rebootInProgressDevices, device)
194 logger.Warnw(ctx, "Resetted Reboot-In-Progress flag", log.Fields{"Device": device})
195 return true
196}
197
198// DeviceRebootInd is device reboot indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530199func (v *VoltController) DeviceRebootInd(cntx context.Context, dID string, srNo string, sbID string) {
200 v.app.DeviceRebootInd(cntx, dID, srNo, sbID)
201 _ = db.DelAllRoutesForDevice(cntx, dID)
202 _ = db.DelAllGroup(cntx, dID)
203 _ = db.DelAllMeter(cntx, dID)
204 _ = db.DelAllPONCounters(cntx, dID)
Naveen Sampath04696f72022-06-13 15:19:14 +0530205}
206
207// DeviceDisableInd is device deactivation indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530208func (v *VoltController) DeviceDisableInd(cntx context.Context, dID string) {
209 v.app.DeviceDisableInd(cntx, dID)
Naveen Sampath04696f72022-06-13 15:19:14 +0530210}
211
vinokuma926cb3e2023-03-29 11:41:06 +0530212// TriggerPendingProfileDeleteReq - trigger pending profile delete requests
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530213func (v *VoltController) TriggerPendingProfileDeleteReq(cntx context.Context, device string) {
214 v.app.TriggerPendingProfileDeleteReq(cntx, device)
Naveen Sampath04696f72022-06-13 15:19:14 +0530215}
216
vinokuma926cb3e2023-03-29 11:41:06 +0530217// TriggerPendingMigrateServicesReq - trigger pending services migration requests
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530218func (v *VoltController) TriggerPendingMigrateServicesReq(cntx context.Context, device string) {
219 v.app.TriggerPendingMigrateServicesReq(cntx, device)
Naveen Sampath04696f72022-06-13 15:19:14 +0530220}
221
222// SetAuditFlags to set the audit flags
223func (v *VoltController) SetAuditFlags(device *Device) {
224 v.app.SetRebootFlag(true)
225 device.auditInProgress = true
226}
227
228// ResetAuditFlags to reset the audit flags
229func (v *VoltController) ResetAuditFlags(device *Device) {
230 v.app.SetRebootFlag(false)
231 device.auditInProgress = false
232}
233
vinokuma926cb3e2023-03-29 11:41:06 +0530234// ProcessFlowModResultIndication - send flow mod result notification
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530235func (v *VoltController) ProcessFlowModResultIndication(cntx context.Context, flowStatus intf.FlowStatus) {
236 v.app.ProcessFlowModResultIndication(cntx, flowStatus)
Naveen Sampath04696f72022-06-13 15:19:14 +0530237}
238
239// AddVPAgent to add the vpagent
240func (v *VoltController) AddVPAgent(vep string, vpa *vpagent.VPAgent) {
241 v.vagent[vep] = vpa
242}
243
244// VPAgent to get vpagent info
245func (v *VoltController) VPAgent(vep string) (*vpagent.VPAgent, error) {
246 vpa, ok := v.vagent[vep]
247 if ok {
248 return vpa, nil
249 }
250 return nil, errors.New("VPA Not Registered")
251}
252
253// PacketOutReq for packet out request
254func (v *VoltController) PacketOutReq(device string, inport string, outport string, pkt []byte, isCustomPkt bool) error {
255 logger.Debugw(ctx, "Packet Out Req", log.Fields{"Device": device, "OutPort": outport})
256 d, err := v.GetDevice(device)
257 if err != nil {
258 return err
259 }
260 logger.Debugw(ctx, "Packet Out Pkt", log.Fields{"Pkt": hex.EncodeToString(pkt)})
261 return d.PacketOutReq(inport, outport, pkt, isCustomPkt)
262}
263
264// AddFlows to add flows
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530265func (v *VoltController) AddFlows(cntx context.Context, port string, device string, flow *of.VoltFlow) error {
Naveen Sampath04696f72022-06-13 15:19:14 +0530266 d, err := v.GetDevice(device)
267 if err != nil {
268 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
269 return err
270 }
271 devPort := d.GetPortByName(port)
272 if devPort == nil {
273 logger.Errorw(ctx, "Port Not Found", log.Fields{"Device": device})
274 return errorCodes.ErrPortNotFound
275 }
276 if d.ctx == nil {
vinokuma926cb3e2023-03-29 11:41:06 +0530277 // FIXME: Application should know the context before it could submit task. Handle at application level
Naveen Sampath04696f72022-06-13 15:19:14 +0530278 logger.Errorw(ctx, "Context is missing. AddFlow Operation Not added to Task", log.Fields{"Device": device})
279 return errorCodes.ErrInvalidParamInRequest
280 }
281
282 var isMigrationRequired bool
283 if flow.MigrateCookie {
284 // flow migration to new cookie must be done only during the audit. Migration for all subflows must be done if
285 // atlease one subflow with old cookie found in the device.
286 for _, subFlow := range flow.SubFlows {
287 if isMigrationRequired = d.IsFlowPresentWithOldCookie(subFlow); isMigrationRequired {
288 break
289 }
290 }
291 }
292
293 if isMigrationRequired {
294 // In this case, the flow is updated in local cache and db here.
295 // Actual flow deletion and addition at voltha will happen during flow tables audit.
296 for _, subFlow := range flow.SubFlows {
297 logger.Debugw(ctx, "Cookie Migration Required", log.Fields{"OldCookie": subFlow.OldCookie, "NewCookie": subFlow.Cookie})
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530298 if err := d.DelFlowWithOldCookie(cntx, subFlow); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530299 logger.Errorw(ctx, "Delete flow with old cookie failed", log.Fields{"Error": err, "OldCookie": subFlow.OldCookie})
300 }
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530301 if err := d.AddFlow(cntx, subFlow); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530302 logger.Errorw(ctx, "Flow Add Failed", log.Fields{"Error": err, "Cookie": subFlow.Cookie})
303 }
304 }
305 } else {
306 flow.Command = of.CommandAdd
307 d.UpdateFlows(flow, devPort)
308 for cookie := range flow.SubFlows {
309 logger.Debugw(ctx, "Flow Add added to queue", log.Fields{"Cookie": cookie, "Device": device, "Port": port})
310 }
311 }
312 return nil
313}
314
315// DelFlows to delete flows
Sridhar Ravindra03aa0bf2023-09-12 17:46:40 +0530316// delFlowsOnlyInDevice flag indicates that flows should be deleted only in DB/device and should not be forwarded to core
317func (v *VoltController) DelFlows(cntx context.Context, port string, device string, flow *of.VoltFlow, delFlowsOnlyInDevice bool) error {
Naveen Sampath04696f72022-06-13 15:19:14 +0530318 d, err := v.GetDevice(device)
319 if err != nil {
320 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
321 return err
322 }
323 devPort := d.GetPortByName(port)
324 if devPort == nil {
325 logger.Errorw(ctx, "Port Not Found", log.Fields{"Device": device})
326 return errorCodes.ErrPortNotFound
327 }
328 if d.ctx == nil {
vinokuma926cb3e2023-03-29 11:41:06 +0530329 // FIXME: Application should know the context before it could submit task. Handle at application level
Naveen Sampath04696f72022-06-13 15:19:14 +0530330 logger.Errorw(ctx, "Context is missing. DelFlow Operation Not added to Task", log.Fields{"Device": device})
331 return errorCodes.ErrInvalidParamInRequest
332 }
333
334 var isMigrationRequired bool
335 if flow.MigrateCookie {
336 // flow migration to new cookie must be done only during the audit. Migration for all subflows must be done if
337 // atlease one subflow with old cookie found in the device.
338 for _, subFlow := range flow.SubFlows {
339 if isMigrationRequired = d.IsFlowPresentWithOldCookie(subFlow); isMigrationRequired {
340 break
341 }
342 }
343 }
344
345 if isMigrationRequired {
346 // In this case, the flow is deleted from local cache and db here.
347 // Actual flow deletion at voltha will happen during flow tables audit.
348 for _, subFlow := range flow.SubFlows {
349 logger.Debugw(ctx, "Old Cookie delete Required", log.Fields{"OldCookie": subFlow.OldCookie})
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530350 if err := d.DelFlowWithOldCookie(cntx, subFlow); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530351 logger.Errorw(ctx, "DelFlowWithOldCookie failed", log.Fields{"OldCookie": subFlow.OldCookie, "Error": err})
352 }
353 }
354 } else {
Sridhar Ravindra03aa0bf2023-09-12 17:46:40 +0530355 // Delete flows only in DB/device when Port Delete has come. Do not send flows to core during Port Delete
356 if delFlowsOnlyInDevice {
357 for cookie, subFlow := range flow.SubFlows {
358 err := d.DelFlow(ctx, subFlow)
359 logger.Infow(ctx, "Flow Deleted from device/DB", log.Fields{"Cookie": cookie, "Device": device, "Port": port, "Error": err})
360 }
361 } else {
362 flow.Command = of.CommandDel
363 d.UpdateFlows(flow, devPort)
364 for cookie := range flow.SubFlows {
365 logger.Debugw(ctx, "Flow Del added to queue", log.Fields{"Cookie": cookie, "Device": device, "Port": port})
366 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530367 }
368 }
369 return nil
370}
371
372// GroupUpdate for group update
373func (v *VoltController) GroupUpdate(port string, device string, group *of.Group) error {
374 d, err := v.GetDevice(device)
375 if err != nil {
376 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
377 return err
378 }
379
380 devPort := d.GetPortByName(port)
381 if devPort == nil {
382 logger.Errorw(ctx, "Port Not Found", log.Fields{"Device": device})
383 return errorCodes.ErrPortNotFound
384 }
385
386 if d.ctx == nil {
vinokuma926cb3e2023-03-29 11:41:06 +0530387 // FIXME: Application should know the context before it could submit task. Handle at application level
Naveen Sampath04696f72022-06-13 15:19:14 +0530388 logger.Errorw(ctx, "Context is missing. GroupMod Operation Not added to task", log.Fields{"Device": device})
389 return errorCodes.ErrInvalidParamInRequest
390 }
391
392 d.UpdateGroup(group, devPort)
393 return nil
394}
395
396// ModMeter to get mod meter info
397func (v *VoltController) ModMeter(port string, device string, command of.MeterCommand, meter *of.Meter) error {
398 d, err := v.GetDevice(device)
399 if err != nil {
400 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
401 return err
402 }
403
404 devPort := d.GetPortByName(port)
405 if devPort == nil {
406 logger.Errorw(ctx, "Port Not Found", log.Fields{"Device": device})
407 return errorCodes.ErrPortNotFound
408 }
409
410 d.ModMeter(command, meter, devPort)
411 return nil
412}
413
414// PortAddInd for port add indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530415func (v *VoltController) PortAddInd(cntx context.Context, device string, id uint32, name string) {
416 v.app.PortAddInd(cntx, device, id, name)
Naveen Sampath04696f72022-06-13 15:19:14 +0530417}
418
419// PortDelInd for port delete indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530420func (v *VoltController) PortDelInd(cntx context.Context, device string, port string) {
421 v.app.PortDelInd(cntx, device, port)
Naveen Sampath04696f72022-06-13 15:19:14 +0530422}
423
424// PortUpdateInd for port update indication
425func (v *VoltController) PortUpdateInd(device string, name string, id uint32) {
426 v.app.PortUpdateInd(device, name, id)
427}
428
429// PortUpInd for port up indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530430func (v *VoltController) PortUpInd(cntx context.Context, device string, port string) {
431 v.app.PortUpInd(cntx, device, port)
Naveen Sampath04696f72022-06-13 15:19:14 +0530432}
433
434// PortDownInd for port down indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530435func (v *VoltController) PortDownInd(cntx context.Context, device string, port string) {
436 v.app.PortDownInd(cntx, device, port)
Naveen Sampath04696f72022-06-13 15:19:14 +0530437}
438
439// DeviceUpInd for device up indication
440func (v *VoltController) DeviceUpInd(device string) {
441 v.app.DeviceUpInd(device)
442}
443
444// DeviceDownInd for device down indication
445func (v *VoltController) DeviceDownInd(device string) {
446 v.app.DeviceDownInd(device)
447}
448
449// PacketInInd for packet in indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530450func (v *VoltController) PacketInInd(cntx context.Context, device string, port string, data []byte) {
451 v.app.PacketInInd(cntx, device, port, data)
Naveen Sampath04696f72022-06-13 15:19:14 +0530452}
453
454// GetPortState to get port status
455func (v *VoltController) GetPortState(device string, name string) (PortState, error) {
456 d, err := v.GetDevice(device)
457 if err != nil {
458 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
459 return PortStateDown, err
460 }
461 return d.GetPortState(name)
462}
463
464// UpdateMvlanProfiles for update mvlan profiles
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530465func (v *VoltController) UpdateMvlanProfiles(cntx context.Context, device string) {
466 v.app.UpdateMvlanProfilesForDevice(cntx, device)
Naveen Sampath04696f72022-06-13 15:19:14 +0530467}
468
469// GetController to get controller
470func GetController() *VoltController {
471 return vcontroller
472}
473
474/*
475// PostIndication to post indication
476func (v *VoltController) PostIndication(device string, task interface{}) error {
477 var srvTask AddServiceIndTask
478 var portTask AddPortIndTask
479 var taskCommon tasks.Task
480 var isSvcTask bool
481
482 switch data := task.(type) {
483 case *AddServiceIndTask:
484 srvTask = *data
485 taskCommon = data
486 isSvcTask = true
487 case *AddPortIndTask:
488 portTask = *data
489 taskCommon = data
490 }
491
492 d, err := v.GetDevice(device)
493 if err != nil {
494 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
495 //It means device itself it not present so just post the indication directly
496 if isSvcTask {
497 msgbus.PostAccessConfigInd(srvTask.result, d.SerialNum, srvTask.indicationType, srvTask.serviceName, 0, srvTask.reason, srvTask.trigger, srvTask.portState)
498 } else {
499 msgbus.ProcessPortInd(portTask.indicationType, d.SerialNum, portTask.portName, portTask.accessConfig, portTask.serviceList)
500 }
501 return err
502 }
503 if taskCommon != nil {
504 d.AddTask(taskCommon)
505 }
506 return nil
507}
508*/
509
510// GetTaskList to get the task list
511func (v *VoltController) GetTaskList(device string) []tasks.Task {
512 d, err := v.GetDevice(device)
513 if err != nil || d.ctx == nil {
514 logger.Errorw(ctx, "Device Not Connected/Found", log.Fields{"Device": device, "Dev Obj": d})
515 return []tasks.Task{}
516 }
517 return d.GetTaskList()
Naveen Sampath04696f72022-06-13 15:19:14 +0530518}
519
520// AddBlockedDevices to add devices to blocked devices list
521func (v *VoltController) AddBlockedDevices(deviceSerialNumber string) {
522 v.BlockedDeviceList.Set(deviceSerialNumber, deviceSerialNumber)
523}
524
525// DelBlockedDevices to remove device from blocked device list
526func (v *VoltController) DelBlockedDevices(deviceSerialNumber string) {
527 v.BlockedDeviceList.Remove(deviceSerialNumber)
528}
529
530// IsBlockedDevice to check if device is blocked
531func (v *VoltController) IsBlockedDevice(deviceSerialNumber string) bool {
532 _, ifPresent := v.BlockedDeviceList.Get(deviceSerialNumber)
533 return ifPresent
534}
Tinoj Josephec742f62022-09-29 19:11:10 +0530535
536// GetFlows returns flow specific to device and flowID
537func (v *VoltController) GetFlow(deviceID string, cookie uint64) (*of.VoltSubFlow, error) {
538 d, err := v.GetDevice(deviceID)
539 if err != nil {
540 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": deviceID, "Error": err})
541 return nil, err
542 }
543 if flow, ok := d.GetFlow(cookie); ok {
544 return flow, nil
545 }
546 return nil, nil
547}
548
549// GetFlows returns list of flows for a particular device
550func (v *VoltController) GetFlows(deviceID string) ([]*of.VoltSubFlow, error) {
551 d, err := v.GetDevice(deviceID)
552 if err != nil {
553 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": deviceID, "Error": err})
Akash Sonia8246972023-01-03 10:37:08 +0530554 return nil, nil
Tinoj Josephec742f62022-09-29 19:11:10 +0530555 }
556 return d.GetAllFlows(), nil
557}
558
559// GetAllFlows returns list of all flows
560func (v *VoltController) GetAllFlows() ([]*of.VoltSubFlow, error) {
561 var flows []*of.VoltSubFlow
562 for _, d := range v.devices {
563 flows = append(flows, d.GetAllFlows()...)
564 }
565 return flows, nil
566}
567
568// GetAllPendingFlows returns list of all flows
569func (v *VoltController) GetAllPendingFlows() ([]*of.VoltSubFlow, error) {
570 var flows []*of.VoltSubFlow
571 for _, d := range v.devices {
572 flows = append(flows, d.GetAllPendingFlows()...)
573 }
574 return flows, nil
575}
Akash Sonib3abf522022-12-19 13:20:02 +0530576func (v *VoltController) GetAllMeterInfo() (map[string][]*of.Meter, error) {
577 logger.Info(ctx, "Entering into GetAllMeterInfo method")
578 meters := map[string][]*of.Meter{}
579 for _, device := range v.devices {
Akash Soni6168f312023-05-18 20:57:33 +0530580 logger.Debugw(ctx, "Inside GetAllMeterInfo method", log.Fields{"deviceId": device.ID, "southbound": device.SouthBoundID, "serial no": device.SerialNum})
Akash Sonib3abf522022-12-19 13:20:02 +0530581 for _, meter := range device.meters {
582 meters[device.ID] = append(meters[device.ID], meter)
583 }
Akash Soni6168f312023-05-18 20:57:33 +0530584 logger.Debugw(ctx, "Inside GetAllMeterInfo method", log.Fields{"meters": meters})
Akash Sonib3abf522022-12-19 13:20:02 +0530585 }
586 return meters, nil
587}
588
589func (v *VoltController) GetMeterInfo(cntx context.Context, id uint32) (map[string]*of.Meter, error) {
590 logger.Info(ctx, "Entering into GetMeterInfo method")
591 meters := map[string]*of.Meter{}
592 for _, device := range v.devices {
Akash Soni6168f312023-05-18 20:57:33 +0530593 logger.Debugw(ctx, "Inside GetMeterInfo method", log.Fields{"deviceId": device.ID})
Akash Sonib3abf522022-12-19 13:20:02 +0530594 meter, err := device.GetMeter(id)
595 if err != nil {
596 logger.Errorw(ctx, "Failed to fetch the meter", log.Fields{"Reason": err.Error()})
597 return nil, err
598 }
599 meters[device.ID] = meter
Akash Soni6168f312023-05-18 20:57:33 +0530600 logger.Debugw(ctx, "meters", log.Fields{"Meter": meters})
Akash Sonib3abf522022-12-19 13:20:02 +0530601 }
602 return meters, nil
603}
604
605func (v *VoltController) GetGroupList() ([]*of.Group, error) {
606 logger.Info(ctx, "Entering into GetGroupList method")
607 groups := []*of.Group{}
608 for _, device := range v.devices {
609 device.groups.Range(func(key, value interface{}) bool {
610 groupID := key.(uint32)
Akash Soni6168f312023-05-18 20:57:33 +0530611 logger.Debugw(ctx, "Inside GetGroupList method", log.Fields{"groupID": groupID})
Akash Sonib3abf522022-12-19 13:20:02 +0530612 //Obtain all groups associated with the device
613 grps, ok := device.groups.Load(groupID)
614 if !ok {
615 return true
616 }
617 grp := grps.(*of.Group)
618 groups = append(groups, grp)
619 return true
620 })
621 }
622 logger.Debugw(ctx, "Groups", log.Fields{"groups": groups})
623 return groups, nil
624}
625
626func (v *VoltController) GetGroups(cntx context.Context, id uint32) (*of.Group, error) {
Akash Sonib3abf522022-12-19 13:20:02 +0530627 logger.Info(ctx, "Entering into GetGroupList method")
628 var groups *of.Group
629 for _, device := range v.devices {
Akash Soni6168f312023-05-18 20:57:33 +0530630 logger.Debugw(ctx, "Inside GetGroupList method", log.Fields{"groupID": id})
Akash Sonib3abf522022-12-19 13:20:02 +0530631 grps, ok := device.groups.Load(id)
632 if !ok {
Akash Sonid36d23b2023-08-18 12:51:40 +0530633 return nil, errors.New("group not found")
Akash Sonib3abf522022-12-19 13:20:02 +0530634 }
635 groups = grps.(*of.Group)
636 logger.Debugw(ctx, "Groups", log.Fields{"groups": groups})
637 }
638 return groups, nil
639}