blob: bef078c2fbf9bd83de13c1cb007d580f68feb1f0 [file] [log] [blame]
khenaidoob9203542018-09-17 22:56:37 -04001/*
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 */
16package core
17
18import (
19 "context"
20 "errors"
21 "github.com/opencord/voltha-go/common/log"
22 "github.com/opencord/voltha-go/db/model"
23 "github.com/opencord/voltha-go/kafka"
24 "github.com/opencord/voltha-go/protos/voltha"
25 "google.golang.org/grpc/codes"
26 "google.golang.org/grpc/status"
khenaidoob9203542018-09-17 22:56:37 -040027 "strings"
28 "sync"
29)
30
31type LogicalDeviceManager struct {
32 logicalDeviceAgents map[string]*LogicalDeviceAgent
33 deviceMgr *DeviceManager
34 adapterProxy *AdapterProxy
35 kafkaProxy *kafka.KafkaMessagingProxy
khenaidoo9a468962018-09-19 15:33:13 -040036 clusterDataProxy *model.Proxy
khenaidoob9203542018-09-17 22:56:37 -040037 exitChannel chan int
38 lockLogicalDeviceAgentsMap sync.RWMutex
39}
40
khenaidoo9a468962018-09-19 15:33:13 -040041func NewLogicalDeviceManager(deviceMgr *DeviceManager, kafkaProxy *kafka.KafkaMessagingProxy, cdProxy *model.Proxy) *LogicalDeviceManager {
khenaidoob9203542018-09-17 22:56:37 -040042 var logicalDeviceMgr LogicalDeviceManager
43 logicalDeviceMgr.exitChannel = make(chan int, 1)
44 logicalDeviceMgr.logicalDeviceAgents = make(map[string]*LogicalDeviceAgent)
45 logicalDeviceMgr.deviceMgr = deviceMgr
46 logicalDeviceMgr.kafkaProxy = kafkaProxy
khenaidoo9a468962018-09-19 15:33:13 -040047 logicalDeviceMgr.clusterDataProxy = cdProxy
khenaidoob9203542018-09-17 22:56:37 -040048 logicalDeviceMgr.lockLogicalDeviceAgentsMap = sync.RWMutex{}
49 return &logicalDeviceMgr
50}
51
52func (ldMgr *LogicalDeviceManager) Start(ctx context.Context) {
53 log.Info("starting-logical-device-manager")
54 log.Info("logical-device-manager-started")
55}
56
57func (ldMgr *LogicalDeviceManager) Stop(ctx context.Context) {
58 log.Info("stopping-logical-device-manager")
59 ldMgr.exitChannel <- 1
60 log.Info("logical-device-manager-stopped")
61}
62
63func (ldMgr *LogicalDeviceManager) addLogicalDeviceAgentToMap(agent *LogicalDeviceAgent) {
64 ldMgr.lockLogicalDeviceAgentsMap.Lock()
65 defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
66 if _, exist := ldMgr.logicalDeviceAgents[agent.logicalDeviceId]; !exist {
67 ldMgr.logicalDeviceAgents[agent.logicalDeviceId] = agent
68 }
69}
70
71func (ldMgr *LogicalDeviceManager) getLogicalDeviceAgent(logicalDeviceId string) *LogicalDeviceAgent {
72 ldMgr.lockLogicalDeviceAgentsMap.Lock()
73 defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
74 if agent, ok := ldMgr.logicalDeviceAgents[logicalDeviceId]; ok {
75 return agent
76 }
77 return nil
78}
79
khenaidoo92e62c52018-10-03 14:02:54 -040080func (ldMgr *LogicalDeviceManager) deleteLogicalDeviceAgent(logicalDeviceId string) {
81 ldMgr.lockLogicalDeviceAgentsMap.Lock()
82 defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
83 delete(ldMgr.logicalDeviceAgents, logicalDeviceId)
84}
85
86// getLogicalDevice provides a cloned most up to date logical device
khenaidoob9203542018-09-17 22:56:37 -040087func (ldMgr *LogicalDeviceManager) getLogicalDevice(id string) (*voltha.LogicalDevice, error) {
khenaidoo92e62c52018-10-03 14:02:54 -040088 log.Debugw("getlogicalDevice", log.Fields{"logicaldeviceid": id})
89 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
90 return agent.getLogicalDevice()
khenaidoob9203542018-09-17 22:56:37 -040091 }
92 return nil, status.Errorf(codes.NotFound, "%s", id)
93}
94
95func (ldMgr *LogicalDeviceManager) listLogicalDevices() (*voltha.LogicalDevices, error) {
khenaidoo92e62c52018-10-03 14:02:54 -040096 log.Debug("listLogicalDevices")
khenaidoob9203542018-09-17 22:56:37 -040097 result := &voltha.LogicalDevices{}
98 ldMgr.lockLogicalDeviceAgentsMap.Lock()
99 defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
100 for _, agent := range ldMgr.logicalDeviceAgents {
khenaidoo92e62c52018-10-03 14:02:54 -0400101 if lDevice, err := agent.getLogicalDevice(); err == nil {
102 result.Items = append(result.Items, lDevice)
khenaidoob9203542018-09-17 22:56:37 -0400103 }
104 }
105 return result, nil
106}
107
108func (ldMgr *LogicalDeviceManager) CreateLogicalDevice(ctx context.Context, device *voltha.Device) (*string, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400109 log.Debugw("creating-logical-device", log.Fields{"deviceId": device.Id})
khenaidoob9203542018-09-17 22:56:37 -0400110 // Sanity check
111 if !device.Root {
112 return nil, errors.New("Device-not-root")
113 }
114
115 // Create a logical device agent - the logical device Id is based on the mac address of the device
116 // For now use the serial number - it may contain any combination of alphabetic characters and numbers,
117 // with length varying from eight characters to a maximum of 14 characters. Mac Address is part of oneof
118 // in the Device model. May need to be moved out.
119 macAddress := device.MacAddress
120 id := strings.Replace(macAddress, ":", "", -1)
khenaidoo92e62c52018-10-03 14:02:54 -0400121 if id == "" {
122 log.Errorw("mac-address-not-set", log.Fields{"deviceId": device.Id})
123 return nil, errors.New("mac-address-not-set")
124 }
125 log.Debugw("logical-device-id", log.Fields{"logicaldeviceId": id})
khenaidoob9203542018-09-17 22:56:37 -0400126
khenaidoo9a468962018-09-19 15:33:13 -0400127 agent := NewLogicalDeviceAgent(id, device, ldMgr, ldMgr.deviceMgr, ldMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400128 ldMgr.addLogicalDeviceAgentToMap(agent)
129 go agent.Start(ctx)
130
khenaidoo92e62c52018-10-03 14:02:54 -0400131 log.Debug("creating-logical-device-ends")
khenaidoob9203542018-09-17 22:56:37 -0400132 return &id, nil
133}
134
khenaidoo92e62c52018-10-03 14:02:54 -0400135func (ldMgr *LogicalDeviceManager) DeleteLogicalDevice(ctx context.Context, device *voltha.Device) error {
136 log.Debugw("deleting-logical-device", log.Fields{"deviceId": device.Id})
137 // Sanity check
138 if !device.Root {
139 return errors.New("Device-not-root")
140 }
141 logDeviceId := device.ParentId
142 if agent := ldMgr.getLogicalDeviceAgent(logDeviceId); agent != nil {
143 // Stop the logical device agent
144 agent.Stop(ctx)
145 //Remove the logical device agent from the Map
146 ldMgr.deleteLogicalDeviceAgent(logDeviceId)
147 }
148
149 log.Debug("deleting-logical-device-ends")
150 return nil
151}
152
153func (ldMgr *LogicalDeviceManager) getLogicalDeviceId(device *voltha.Device) (*string, error) {
154 // Device can either be a parent or a child device
155 if device.Root {
156 // Parent device. The ID of a parent device is the logical device ID
157 return &device.ParentId, nil
158 }
159 // Device is child device
160 // retrieve parent device using child device ID
161 if parentDevice := ldMgr.deviceMgr.getParentDevice(device); parentDevice != nil {
162 return &parentDevice.ParentId, nil
163 }
164 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
165}
166
167// DeleteLogicalDevice removes the logical port associated with a child device
168func (ldMgr *LogicalDeviceManager) DeleteLogicalPort(ctx context.Context, device *voltha.Device) error {
169 log.Debugw("deleting-logical-port", log.Fields{"deviceId": device.Id})
170 // Sanity check
171 if device.Root {
172 return errors.New("Device-root")
173 }
174 logDeviceId, _ := ldMgr.getLogicalDeviceId(device)
175 if logDeviceId == nil {
176 log.Debugw("no-logical-device-present", log.Fields{"deviceId": device.Id})
177 return nil
178 }
179 if agent := ldMgr.getLogicalDeviceAgent(*logDeviceId); agent != nil {
180 agent.deleteLogicalPort(device)
181 }
182
183 log.Debug("deleting-logical-port-ends")
184 return nil
185}
186
khenaidoob9203542018-09-17 22:56:37 -0400187func (ldMgr *LogicalDeviceManager) AddUNILogicalPort(ctx context.Context, childDevice *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400188 log.Debugw("AddUNILogicalPort", log.Fields{"deviceId": childDevice.Id})
khenaidoob9203542018-09-17 22:56:37 -0400189 // Sanity check
190 if childDevice.Root {
191 return errors.New("Device-root")
192 }
193
194 // Get the logical device id parent device
195 parentId := childDevice.ParentId
196 logDeviceId := ldMgr.deviceMgr.GetParentDeviceId(parentId)
197
khenaidoo92e62c52018-10-03 14:02:54 -0400198 log.Debugw("AddUNILogicalPort", log.Fields{"logDeviceId": logDeviceId, "parentId": parentId})
khenaidoob9203542018-09-17 22:56:37 -0400199
200 if agent := ldMgr.getLogicalDeviceAgent(*logDeviceId); agent != nil {
201 return agent.addUNILogicalPort(ctx, childDevice, childDevice.ProxyAddress.ChannelId)
202 }
203 return status.Errorf(codes.NotFound, "%s", childDevice.Id)
204}