blob: 5a9562af45c76a2ac1d380a977e58e40f4b835b3 [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 "github.com/gogo/protobuf/proto"
21 "github.com/opencord/voltha-go/common/log"
22 "github.com/opencord/voltha-go/db/model"
23 ca "github.com/opencord/voltha-go/protos/core_adapter"
24 "github.com/opencord/voltha-go/protos/openflow_13"
25 "github.com/opencord/voltha-go/protos/voltha"
26 "google.golang.org/grpc/codes"
27 "google.golang.org/grpc/status"
28 "reflect"
29)
30
31type LogicalDeviceAgent struct {
32 logicalDeviceId string
33 lastData *voltha.LogicalDevice
34 rootDeviceId string
35 deviceMgr *DeviceManager
36 ldeviceMgr *LogicalDeviceManager
37 localDataProxy *model.Proxy
38 exitChannel chan int
39}
40
41func NewLogicalDeviceAgent(id string, device *voltha.Device, ldeviceMgr *LogicalDeviceManager, deviceMgr *DeviceManager,
42 ldProxy *model.Proxy) *LogicalDeviceAgent {
43 var agent LogicalDeviceAgent
44 agent.exitChannel = make(chan int, 1)
45 agent.logicalDeviceId = id
46 agent.rootDeviceId = device.Id
47 agent.deviceMgr = deviceMgr
48 agent.localDataProxy = ldProxy
49 agent.ldeviceMgr = ldeviceMgr
50 return &agent
51}
52
53func (agent *LogicalDeviceAgent) Start(ctx context.Context) error {
54 log.Info("starting-logical_device-agent")
55 //Build the logical device based on information retrieved from the device adapter
56 var switchCap *ca.SwitchCapability
57 var err error
58 if switchCap, err = agent.deviceMgr.getSwitchCapability(ctx, agent.rootDeviceId); err != nil {
59 log.Errorw("error-creating-logical-device", log.Fields{"error": err})
60 return err
61 }
62 ld := &voltha.LogicalDevice{Id: agent.logicalDeviceId, RootDeviceId: agent.rootDeviceId}
63 ld.Desc = (proto.Clone(switchCap.Desc)).(*openflow_13.OfpDesc)
64 ld.SwitchFeatures = (proto.Clone(switchCap.SwitchFeatures)).(*openflow_13.OfpSwitchFeatures)
65
66 //Add logical ports to the logical device based on the number of NNI ports discovered
67 //First get the default port capability - TODO: each NNI port may have different capabilities,
68 //hence. may need to extract the port by the NNI port id defined by the adapter during device
69 //creation
70 var nniPorts *voltha.Ports
71 if nniPorts, err = agent.deviceMgr.getNNIPorts(ctx, agent.rootDeviceId); err != nil {
72 log.Errorw("error-creating-logical-port", log.Fields{"error": err})
73 }
74 var portCap *ca.PortCapability
75 for _, port := range nniPorts.Items {
76 log.Infow("NNI PORTS", log.Fields{"NNI": port})
77 if portCap, err = agent.deviceMgr.getPortCapability(ctx, agent.rootDeviceId, port.PortNo); err != nil {
78 log.Errorw("error-creating-logical-device", log.Fields{"error": err})
79 return err
80 }
81
82 lp := (proto.Clone(portCap.Port)).(*voltha.LogicalPort)
83 ld.Ports = append(ld.Ports, lp)
84 }
85 // Save the logical device
86 if added := agent.localDataProxy.Add("/logical_devices", ld, ""); added == nil {
87 log.Errorw("failed-to-add-logical-device", log.Fields{"logicaldeviceId": agent.logicalDeviceId})
88 } else {
89 log.Debugw("logicaldevice-created", log.Fields{"logicaldeviceId": agent.logicalDeviceId})
90 }
91
92 return nil
93}
94
95func (agent *LogicalDeviceAgent) addUNILogicalPort(ctx context.Context, childDevice *voltha.Device, portNo uint32) error {
96 log.Info("addUNILogicalPort-start")
97 // Build the logical device based on information retrieved from the device adapter
98 var portCap *ca.PortCapability
99 var err error
100 if portCap, err = agent.deviceMgr.getPortCapability(ctx, childDevice.Id, portNo); err != nil {
101 log.Errorw("error-creating-logical-port", log.Fields{"error": err})
102 return err
103 }
104 // Get stored logical device
105 if ldevice, err := agent.ldeviceMgr.getLogicalDevice(agent.logicalDeviceId); err != nil {
106 return status.Error(codes.NotFound, agent.logicalDeviceId)
107 } else {
108 cloned := reflect.ValueOf(ldevice).Elem().Interface().(voltha.LogicalDevice)
109 lp := (proto.Clone(portCap.Port)).(*voltha.LogicalPort)
110 cloned.Ports = append(cloned.Ports, lp)
111 afterUpdate := agent.localDataProxy.Update("/logical_devices/"+agent.logicalDeviceId, &cloned, false, "")
112 if afterUpdate == nil {
113 return status.Errorf(codes.Internal, "failed-add-UNI-port:%s", agent.logicalDeviceId)
114 }
115 return nil
116 }
117}
118
119func (agent *LogicalDeviceAgent) Stop(ctx context.Context) {
120 log.Info("stopping-logical_device-agent")
121 agent.exitChannel <- 1
122 log.Info("logical_device-agent-stopped")
123}
124
125func (agent *LogicalDeviceAgent) getLogicalDevice(ctx context.Context) *voltha.LogicalDevice {
126 log.Debug("getLogicalDevice")
127 cp := proto.Clone(agent.lastData)
128 return cp.(*voltha.LogicalDevice)
129}