blob: 6bd42eb2dfc59f68db643bcbcaf45714105187ef [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001/*
2 * Copyright 2021-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 */
16package device
17
18import (
19 "context"
20
21 "github.com/opencord/voltha-lib-go/v7/pkg/log"
22 "github.com/opencord/voltha-protos/v5/go/core"
23 "github.com/opencord/voltha-protos/v5/go/voltha"
24 "google.golang.org/grpc/codes"
25 "google.golang.org/grpc/status"
26)
27
28//
29//CreateLogicalDevice creates logical device in core
30func (dMgr *Manager) CreateLogicalDevice(ctx context.Context, cDevice *voltha.Device) error {
31 logger.Info(ctx, "create-logical-device")
32 // Verify whether the logical device has already been created
33 if cDevice.ParentId != "" {
34 logger.Debugw(ctx, "parent-device-already-exist", log.Fields{"device-id": cDevice.Id, "logical-device-id": cDevice.Id})
35 return nil
36 }
37 var err error
38 if _, err = dMgr.logicalDeviceMgr.createLogicalDevice(ctx, cDevice); err != nil {
39 logger.Warnw(ctx, "create-logical-device-error", log.Fields{"device": cDevice})
40 return err
41 }
42 return nil
43}
44
45// DeleteLogicalDevice deletes logical device from core
46func (dMgr *Manager) DeleteLogicalDevice(ctx context.Context, cDevice *voltha.Device) error {
47 logger.Info(ctx, "delete-logical-device")
48 var err error
49 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(ctx, cDevice); err != nil {
50 logger.Warnw(ctx, "delete-logical-device-error", log.Fields{"device-id": cDevice.Id})
51 return err
52 }
53 // Remove the logical device Id from the parent device
54 logicalID := ""
55 dMgr.UpdateDeviceAttribute(ctx, cDevice.Id, "ParentId", logicalID)
56 return nil
57}
58
59// DeleteLogicalPorts removes the logical ports associated with that deviceId
60func (dMgr *Manager) DeleteLogicalPorts(ctx context.Context, cDevice *voltha.Device) error {
61 logger.Debugw(ctx, "delete-all-logical-ports", log.Fields{"device-id": cDevice.Id})
62 if err := dMgr.logicalDeviceMgr.deleteLogicalPorts(ctx, cDevice.Id); err != nil {
63 // Just log the error. The logical device or port may already have been deleted before this callback is invoked.
64 logger.Warnw(ctx, "delete-logical-ports-error", log.Fields{"device-id": cDevice.Id, "error": err})
65 }
66 return nil
67}
68
69// SetupUNILogicalPorts creates UNI ports on the logical device that represents a child UNI interface
70func (dMgr *Manager) SetupUNILogicalPorts(ctx context.Context, cDevice *voltha.Device) error {
71 logger.Info(ctx, "setup-uni-logical-ports")
72 cDevicePorts, err := dMgr.listDevicePorts(ctx, cDevice.Id)
73 if err != nil {
74 return err
75 }
76 if err := dMgr.logicalDeviceMgr.setupUNILogicalPorts(ctx, cDevice, cDevicePorts); err != nil {
77 logger.Warnw(ctx, "setup-uni-logical-ports-error", log.Fields{"device": cDevice, "err": err})
78 return err
79 }
80 return nil
81}
82
83// RunPostDeviceDelete removes any reference of this device
84func (dMgr *Manager) RunPostDeviceDelete(ctx context.Context, cDevice *voltha.Device) error {
85 logger.Infow(ctx, "run-post-device-delete", log.Fields{"device-id": cDevice.Id})
86 dMgr.stopManagingDevice(ctx, cDevice.Id)
87 return nil
88}
89
90//DeleteAllLogicalPorts is invoked as a callback when the parent device's connection status moves to UNREACHABLE
91func (dMgr *Manager) DeleteAllLogicalPorts(ctx context.Context, parentDevice *voltha.Device) error {
92 logger.Debugw(ctx, "delete-all-logical-ports", log.Fields{"parent-device-id": parentDevice.Id})
93 if err := dMgr.logicalDeviceMgr.deleteAllLogicalPorts(ctx, parentDevice); err != nil {
94 // Just log error as logical device may already have been deleted
95 logger.Warnw(ctx, "delete-all-logical-ports-fail", log.Fields{"parent-device-id": parentDevice.Id, "error": err})
96 }
97 return nil
98}
99
100//DeleteAllChildDevices is invoked as a callback when the parent device is deleted
101func (dMgr *Manager) DeleteAllChildDevices(ctx context.Context, parentCurrDevice *voltha.Device) error {
102 logger.Debugw(ctx, "delete-all-child-devices", log.Fields{"parent-device-id": parentCurrDevice.Id})
103 force := false
104 // Get the parent device Transient state, if its FORCE_DELETED(go for force delete for child devices)
105 // So in cases when this handler is getting called other than DELETE operation, no force option would be used.
106 agent := dMgr.getDeviceAgent(ctx, parentCurrDevice.Id)
107 if agent == nil {
108 return status.Errorf(codes.NotFound, "%s", parentCurrDevice.Id)
109 }
110
111 force = agent.getTransientState() == core.DeviceTransientState_FORCE_DELETING
112
113 ports, _ := dMgr.listDevicePorts(ctx, parentCurrDevice.Id)
114 for childDeviceID := range dMgr.getAllChildDeviceIds(ctx, ports) {
115 if agent := dMgr.getDeviceAgent(ctx, childDeviceID); agent != nil {
116 logger.Debugw(ctx, "invoking-delete-device", log.Fields{"device-id": childDeviceID, "force-delete": force})
117 if force {
118 if err := agent.deleteDeviceForce(ctx); err != nil {
119 logger.Warnw(ctx, "failure-delete-device-force", log.Fields{"device-id": childDeviceID,
120 "error": err.Error()})
121 }
122 } else {
123 if err := agent.deleteDevice(ctx); err != nil {
124 logger.Warnw(ctx, "failure-delete-device", log.Fields{"device-id": childDeviceID,
125 "error": err.Error()})
126 }
127 }
128 // No further action is required here. The deleteDevice will change the device state where the resulting
129 // callback will take care of cleaning the child device agent.
130 }
131 }
132 return nil
133}
134
135//DeleteAllDeviceFlows is invoked as a callback when the parent device's connection status moves to UNREACHABLE
136func (dMgr *Manager) DeleteAllDeviceFlows(ctx context.Context, parentDevice *voltha.Device) error {
137 logger.Debugw(ctx, "delete-all-device-flows", log.Fields{"parent-device-id": parentDevice.Id})
138 if agent := dMgr.getDeviceAgent(ctx, parentDevice.Id); agent != nil {
139 if err := agent.deleteAllFlows(ctx); err != nil {
140 logger.Errorw(ctx, "error-deleting-all-device-flows", log.Fields{"parent-device-id": parentDevice.Id})
141 return err
142 }
143 return nil
144 }
145 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
146}
147
148// ChildDeviceLost calls parent adapter to delete child device and all its references
149func (dMgr *Manager) ChildDeviceLost(ctx context.Context, curr *voltha.Device) error {
150 logger.Debugw(ctx, "child-device-lost", log.Fields{"child-device-id": curr.Id, "parent-device-id": curr.ParentId})
151 if parentAgent := dMgr.getDeviceAgent(ctx, curr.ParentId); parentAgent != nil {
152 if err := parentAgent.ChildDeviceLost(ctx, curr); err != nil {
153 // Just log the message and let the remaining pipeline proceed.
154 logger.Warnw(ctx, "childDeviceLost", log.Fields{"child-device-id": curr.Id, "parent-device-id": curr.ParentId, "error": err})
155 }
156 }
157 // Do not return an error as parent device may also have been deleted. Let the remaining pipeline proceed.
158 return nil
159}