blob: 1ae12753e5918259c763364fa7245793cf1de999 [file] [log] [blame]
Stephane Barbariea75791c2019-01-24 10:58:06 -05001/*
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 "github.com/opencord/voltha-go/protos/voltha"
24 "google.golang.org/grpc/codes"
25 "google.golang.org/grpc/status"
26 "sync"
27)
28
29type DeviceAgent struct {
30 deviceId string
31 deviceType string
32 lastData *voltha.Device
33 deviceMgr *DeviceManager
34 clusterDataProxy *model.Proxy
35 exitChannel chan int
36 lockDevice sync.RWMutex
37}
38
39//newDeviceAgent creates a new device agent along as creating a unique ID for the device and set the device state to
40//preprovisioning
41func newDeviceAgent(device *voltha.Device, deviceMgr *DeviceManager, cdProxy *model.Proxy) *DeviceAgent {
42 var agent DeviceAgent
43 agent.deviceId = device.Id
44 agent.deviceType = device.Type
45 agent.lastData = device
46 agent.deviceMgr = deviceMgr
47 agent.exitChannel = make(chan int, 1)
48 agent.clusterDataProxy = cdProxy
49 agent.lockDevice = sync.RWMutex{}
50 return &agent
51}
52
53// start save the device to the data model and registers for callbacks on that device
54func (agent *DeviceAgent) start(ctx context.Context) {
55 log.Debugw("starting-device-agent", log.Fields{"device": agent.lastData})
56 agent.lockDevice.Lock()
57 defer agent.lockDevice.Unlock()
58 log.Debug("device-agent-started")
59}
60
61// stop stops the device agent. Not much to do for now
62func (agent *DeviceAgent) stop(ctx context.Context) {
63 agent.lockDevice.Lock()
64 defer agent.lockDevice.Unlock()
65 log.Debug("stopping-device-agent")
66 agent.exitChannel <- 1
67 log.Debug("device-agent-stopped")
68}
69
70// GetDevice retrieves the latest device information from the data model
71func (agent *DeviceAgent) getDevice() (*voltha.Device, error) {
72 agent.lockDevice.Lock()
73 defer agent.lockDevice.Unlock()
74 if device := agent.clusterDataProxy.Get("/devices/"+agent.deviceId, 1, false, ""); device != nil {
75 if d, ok := device.(*voltha.Device); ok {
76 cloned := proto.Clone(d).(*voltha.Device)
77 return cloned, nil
78 }
79 }
80 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
81}
82
83// getDeviceWithoutLock is a helper function to be used ONLY by any device agent function AFTER it has acquired the device lock.
84// This function is meant so that we do not have duplicate code all over the device agent functions
85func (agent *DeviceAgent) getDeviceWithoutLock() (*voltha.Device, error) {
86 if device := agent.clusterDataProxy.Get("/devices/"+agent.deviceId, 1, false, ""); device != nil {
87 if d, ok := device.(*voltha.Device); ok {
88 cloned := proto.Clone(d).(*voltha.Device)
89 return cloned, nil
90 }
91 }
92 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
93}
94
95// getPorts retrieves the ports information of the device based on the port type.
96func (agent *DeviceAgent) getPorts(ctx context.Context, portType voltha.Port_PortType) *voltha.Ports {
97 log.Debugw("getPorts", log.Fields{"id": agent.deviceId, "portType": portType})
98 ports := &voltha.Ports{}
99 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
100 for _, port := range device.Ports {
101 if port.Type == portType {
102 ports.Items = append(ports.Items, port)
103 }
104 }
105 }
106 return ports
107}
108
109// ListDevicePorts retrieves the ports information for a particular device.
110func (agent *DeviceAgent) ListDevicePorts(ctx context.Context) (*voltha.Ports, error) {
111 log.Debugw("ListDevicePorts", log.Fields{"id": agent.deviceId})
112 ports := &voltha.Ports{}
113 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
114 for _, entry := range device.GetPorts() {
115 ports.Items = append(ports.Items, entry)
116 }
117 return ports, nil
118 }
119 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
120}
121
122// ListDevicePmConfigs retrieves the ports information for a particular device.
123func (agent *DeviceAgent) ListDevicePmConfigs(ctx context.Context) (*voltha.PmConfigs, error) {
124 log.Debugw("ListDevicePmConfigs", log.Fields{"id": agent.deviceId})
125 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
126 return device.GetPmConfigs(), nil
127 }
128 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
129}
130
131// ListDeviceFlows retrieves the ports information for a particular device.
132func (agent *DeviceAgent) ListDeviceFlows(ctx context.Context) (*voltha.Flows, error) {
133 log.Debugw("ListDeviceFlows", log.Fields{"id": agent.deviceId})
134 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
135 return device.GetFlows(), nil
136 }
137 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
138}
139
140// ListDeviceFlows retrieves the ports information for a particular device.
141func (agent *DeviceAgent) ListDeviceFlowGroups(ctx context.Context) (*voltha.FlowGroups, error) {
142 log.Debugw("ListDeviceFlowGroups", log.Fields{"id": agent.deviceId})
143 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
144 return device.GetFlowGroups(), nil
145 }
146 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
147}
148
149// GetImageDownloadStatus retrieves the download status of an image of a particular device.
150func (agent *DeviceAgent) GetImageDownloadStatus(ctx context.Context, imageName string) (*voltha.ImageDownload, error) {
151 log.Debugw("GetImageDownloadStatus", log.Fields{"id": agent.deviceId})
152 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
153 for _, img := range device.GetImageDownloads() {
154 if img.GetName() == imageName {
155 return img, nil
156 }
157 }
158 return nil, status.Errorf(codes.NotFound, "device-%s, image-%s", agent.deviceId, imageName)
159 }
160 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
161}
162
163// GetImageDownload retrieves the image download for a particular device.
164func (agent *DeviceAgent) GetImageDownload(ctx context.Context, imageName string) (*voltha.ImageDownload, error) {
165 log.Debugw("GetImageDownload", log.Fields{"id": agent.deviceId})
166 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
167 for _, img := range device.GetImageDownloads() {
168 if img.GetName() == imageName {
169 return img, nil
170 }
171 }
172 return nil, status.Errorf(codes.NotFound, "device-%s, image-%s", agent.deviceId, imageName)
173 }
174 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
175}
176
177// ListImageDownloads retrieves the image downloads for a particular device.
178func (agent *DeviceAgent) ListImageDownloads(ctx context.Context) (*voltha.ImageDownloads, error) {
179 log.Debugw("ListImageDownloads", log.Fields{"id": agent.deviceId})
180 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
181 return &voltha.ImageDownloads{Items: device.GetImageDownloads()}, nil
182 }
183 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
184}
185
186// GetImages retrieves the list of images for a particular device.
187func (agent *DeviceAgent) GetImages(ctx context.Context) (*voltha.Images, error) {
188 log.Debugw("GetImages", log.Fields{"id": agent.deviceId})
189 if device, _ := agent.deviceMgr.GetDevice(agent.deviceId); device != nil {
190 return device.GetImages(), nil
191 }
192 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceId)
193}