blob: 109d0602cea77caf77893ce4e4cfda4fdf24ec5f [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 */
npujar03b018e2019-11-13 15:29:36 +053016
Stephane Barbariea75791c2019-01-24 10:58:06 -050017package core
18
19import (
20 "context"
npujar03b018e2019-11-13 15:29:36 +053021 "sync"
22
Stephane Barbariea75791c2019-01-24 10:58:06 -050023 "github.com/gogo/protobuf/proto"
sbarbari17d7e222019-11-05 10:02:29 -050024 "github.com/opencord/voltha-go/db/model"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080025 "github.com/opencord/voltha-lib-go/v3/pkg/log"
26 "github.com/opencord/voltha-protos/v3/go/voltha"
Stephane Barbariea75791c2019-01-24 10:58:06 -050027 "google.golang.org/grpc/codes"
28 "google.golang.org/grpc/status"
Stephane Barbariea75791c2019-01-24 10:58:06 -050029)
30
npujar03b018e2019-11-13 15:29:36 +053031// DeviceAgent holds device specific information
Stephane Barbariea75791c2019-01-24 10:58:06 -050032type DeviceAgent struct {
npujar03b018e2019-11-13 15:29:36 +053033 deviceID string
Stephane Barbariea75791c2019-01-24 10:58:06 -050034 deviceType string
35 lastData *voltha.Device
36 deviceMgr *DeviceManager
37 clusterDataProxy *model.Proxy
38 exitChannel chan int
39 lockDevice sync.RWMutex
40}
41
42//newDeviceAgent creates a new device agent along as creating a unique ID for the device and set the device state to
43//preprovisioning
44func newDeviceAgent(device *voltha.Device, deviceMgr *DeviceManager, cdProxy *model.Proxy) *DeviceAgent {
45 var agent DeviceAgent
npujar03b018e2019-11-13 15:29:36 +053046 agent.deviceID = device.Id
Stephane Barbariea75791c2019-01-24 10:58:06 -050047 agent.deviceType = device.Type
48 agent.lastData = device
49 agent.deviceMgr = deviceMgr
50 agent.exitChannel = make(chan int, 1)
51 agent.clusterDataProxy = cdProxy
52 agent.lockDevice = sync.RWMutex{}
53 return &agent
54}
55
56// start save the device to the data model and registers for callbacks on that device
Stephane Barbarie1e28f3e2019-02-08 15:45:20 -050057func (agent *DeviceAgent) start(ctx context.Context, loadFromDb bool) error {
Stephane Barbariea75791c2019-01-24 10:58:06 -050058 agent.lockDevice.Lock()
59 defer agent.lockDevice.Unlock()
Stephane Barbarie1e28f3e2019-02-08 15:45:20 -050060 log.Debugw("starting-device-agent", log.Fields{"device": agent.lastData})
61 if loadFromDb {
Thomas Lee Se5a44012019-11-07 20:32:24 +053062 if device, err := agent.clusterDataProxy.Get(ctx, "/devices/"+agent.deviceID, 0, false, ""); err != nil {
63 log.Errorw("failed-to-get-device", log.Fields{"error": err})
64 return err
65 } else if device != nil {
Stephane Barbarie1e28f3e2019-02-08 15:45:20 -050066 if d, ok := device.(*voltha.Device); ok {
67 agent.lastData = proto.Clone(d).(*voltha.Device)
68 }
69 } else {
npujar03b018e2019-11-13 15:29:36 +053070 log.Errorw("failed-to-load-device", log.Fields{"deviceID": agent.deviceID})
71 return status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbarie1e28f3e2019-02-08 15:45:20 -050072 }
73 log.Debugw("device-loaded-from-dB", log.Fields{"device": agent.lastData})
74 }
Stephane Barbariea75791c2019-01-24 10:58:06 -050075 log.Debug("device-agent-started")
Stephane Barbarie1e28f3e2019-02-08 15:45:20 -050076 return nil
Stephane Barbariea75791c2019-01-24 10:58:06 -050077}
78
79// stop stops the device agent. Not much to do for now
80func (agent *DeviceAgent) stop(ctx context.Context) {
81 agent.lockDevice.Lock()
82 defer agent.lockDevice.Unlock()
83 log.Debug("stopping-device-agent")
84 agent.exitChannel <- 1
85 log.Debug("device-agent-stopped")
86}
87
88// GetDevice retrieves the latest device information from the data model
89func (agent *DeviceAgent) getDevice() (*voltha.Device, error) {
90 agent.lockDevice.Lock()
91 defer agent.lockDevice.Unlock()
Thomas Lee Se5a44012019-11-07 20:32:24 +053092 if device, err := agent.clusterDataProxy.Get(context.Background(), "/devices/"+agent.deviceID, 0, false, ""); err != nil {
93 log.Errorw("failed-to-get-device", log.Fields{"error": err})
94 return nil, err
95 } else if device != nil {
Stephane Barbariea75791c2019-01-24 10:58:06 -050096 if d, ok := device.(*voltha.Device); ok {
97 cloned := proto.Clone(d).(*voltha.Device)
98 return cloned, nil
99 }
100 }
npujar03b018e2019-11-13 15:29:36 +0530101 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500102}
103
104// ListDevicePorts retrieves the ports information for a particular device.
105func (agent *DeviceAgent) ListDevicePorts(ctx context.Context) (*voltha.Ports, error) {
npujar03b018e2019-11-13 15:29:36 +0530106 log.Debugw("ListDevicePorts", log.Fields{"id": agent.deviceID})
Stephane Barbariea75791c2019-01-24 10:58:06 -0500107 ports := &voltha.Ports{}
npujar03b018e2019-11-13 15:29:36 +0530108 if device, _ := agent.deviceMgr.GetDevice(agent.deviceID); device != nil {
109 ports.Items = append(ports.Items, device.GetPorts()...)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500110 return ports, nil
111 }
npujar03b018e2019-11-13 15:29:36 +0530112 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500113}
114
115// ListDevicePmConfigs retrieves the ports information for a particular device.
116func (agent *DeviceAgent) ListDevicePmConfigs(ctx context.Context) (*voltha.PmConfigs, error) {
npujar03b018e2019-11-13 15:29:36 +0530117 log.Debugw("ListDevicePmConfigs", log.Fields{"id": agent.deviceID})
118 if device, _ := agent.deviceMgr.GetDevice(agent.deviceID); device != nil {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500119 return device.GetPmConfigs(), nil
120 }
npujar03b018e2019-11-13 15:29:36 +0530121 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500122}
123
124// ListDeviceFlows retrieves the ports information for a particular device.
125func (agent *DeviceAgent) ListDeviceFlows(ctx context.Context) (*voltha.Flows, error) {
npujar03b018e2019-11-13 15:29:36 +0530126 log.Debugw("ListDeviceFlows", log.Fields{"id": agent.deviceID})
127 if device, _ := agent.deviceMgr.GetDevice(agent.deviceID); device != nil {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500128 return device.GetFlows(), nil
129 }
npujar03b018e2019-11-13 15:29:36 +0530130 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500131}
132
npujar03b018e2019-11-13 15:29:36 +0530133// ListDeviceFlowGroups retrieves the ports information for a particular device.
Stephane Barbariea75791c2019-01-24 10:58:06 -0500134func (agent *DeviceAgent) ListDeviceFlowGroups(ctx context.Context) (*voltha.FlowGroups, error) {
npujar03b018e2019-11-13 15:29:36 +0530135 log.Debugw("ListDeviceFlowGroups", log.Fields{"id": agent.deviceID})
136 if device, _ := agent.deviceMgr.GetDevice(agent.deviceID); device != nil {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500137 return device.GetFlowGroups(), nil
138 }
npujar03b018e2019-11-13 15:29:36 +0530139 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500140}
141
142// GetImageDownloadStatus retrieves the download status of an image of a particular device.
143func (agent *DeviceAgent) GetImageDownloadStatus(ctx context.Context, imageName string) (*voltha.ImageDownload, error) {
npujar03b018e2019-11-13 15:29:36 +0530144 log.Debugw("GetImageDownloadStatus", log.Fields{"id": agent.deviceID})
145 if device, _ := agent.deviceMgr.GetDevice(agent.deviceID); device != nil {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500146 for _, img := range device.GetImageDownloads() {
147 if img.GetName() == imageName {
148 return img, nil
149 }
150 }
npujar03b018e2019-11-13 15:29:36 +0530151 return nil, status.Errorf(codes.NotFound, "device-%s, image-%s", agent.deviceID, imageName)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500152 }
npujar03b018e2019-11-13 15:29:36 +0530153 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500154}
155
156// GetImageDownload retrieves the image download for a particular device.
157func (agent *DeviceAgent) GetImageDownload(ctx context.Context, imageName string) (*voltha.ImageDownload, error) {
npujar03b018e2019-11-13 15:29:36 +0530158 log.Debugw("GetImageDownload", log.Fields{"id": agent.deviceID})
159 if device, _ := agent.deviceMgr.GetDevice(agent.deviceID); device != nil {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500160 for _, img := range device.GetImageDownloads() {
161 if img.GetName() == imageName {
162 return img, nil
163 }
164 }
npujar03b018e2019-11-13 15:29:36 +0530165 return nil, status.Errorf(codes.NotFound, "device-%s, image-%s", agent.deviceID, imageName)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500166 }
npujar03b018e2019-11-13 15:29:36 +0530167 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500168}
169
170// ListImageDownloads retrieves the image downloads for a particular device.
171func (agent *DeviceAgent) ListImageDownloads(ctx context.Context) (*voltha.ImageDownloads, error) {
npujar03b018e2019-11-13 15:29:36 +0530172 log.Debugw("ListImageDownloads", log.Fields{"id": agent.deviceID})
173 if device, _ := agent.deviceMgr.GetDevice(agent.deviceID); device != nil {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500174 return &voltha.ImageDownloads{Items: device.GetImageDownloads()}, nil
175 }
npujar03b018e2019-11-13 15:29:36 +0530176 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Stephane Barbariea75791c2019-01-24 10:58:06 -0500177}
178
179// GetImages retrieves the list of images for a particular device.
180func (agent *DeviceAgent) GetImages(ctx context.Context) (*voltha.Images, error) {
npujar03b018e2019-11-13 15:29:36 +0530181 log.Debugw("GetImages", log.Fields{"id": agent.deviceID})
182 if device, _ := agent.deviceMgr.GetDevice(agent.deviceID); device != nil {
Stephane Barbariea75791c2019-01-24 10:58:06 -0500183 return device.GetImages(), nil
184 }
npujar03b018e2019-11-13 15:29:36 +0530185 return nil, status.Errorf(codes.NotFound, "device-%s", agent.deviceID)
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400186}