blob: b2ab478c5c0f087599d8e1d03ba07b948dfeceac [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"
khenaidoo92e62c52018-10-03 14:02:54 -040021 "github.com/gogo/protobuf/proto"
khenaidoob9203542018-09-17 22:56:37 -040022 "github.com/opencord/voltha-go/common/log"
23 "github.com/opencord/voltha-go/db/model"
24 "github.com/opencord/voltha-go/kafka"
25 "github.com/opencord/voltha-go/protos/core_adapter"
khenaidoo19d7b632018-10-30 10:49:50 -040026 ofp "github.com/opencord/voltha-go/protos/openflow_13"
khenaidoob9203542018-09-17 22:56:37 -040027 "github.com/opencord/voltha-go/protos/voltha"
28 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/status"
30 "reflect"
31 "runtime"
32 "sync"
33)
34
35type DeviceManager struct {
36 deviceAgents map[string]*DeviceAgent
37 adapterProxy *AdapterProxy
38 logicalDeviceMgr *LogicalDeviceManager
39 kafkaProxy *kafka.KafkaMessagingProxy
40 stateTransitions *TransitionMap
khenaidoo9a468962018-09-19 15:33:13 -040041 clusterDataProxy *model.Proxy
khenaidoob9203542018-09-17 22:56:37 -040042 exitChannel chan int
43 lockDeviceAgentsMap sync.RWMutex
44}
45
khenaidoo4d4802d2018-10-04 21:59:49 -040046func newDeviceManager(kafkaProxy *kafka.KafkaMessagingProxy, cdProxy *model.Proxy) *DeviceManager {
khenaidoob9203542018-09-17 22:56:37 -040047 var deviceMgr DeviceManager
48 deviceMgr.exitChannel = make(chan int, 1)
49 deviceMgr.deviceAgents = make(map[string]*DeviceAgent)
50 deviceMgr.adapterProxy = NewAdapterProxy(kafkaProxy)
51 deviceMgr.kafkaProxy = kafkaProxy
khenaidoo9a468962018-09-19 15:33:13 -040052 deviceMgr.clusterDataProxy = cdProxy
khenaidoob9203542018-09-17 22:56:37 -040053 deviceMgr.lockDeviceAgentsMap = sync.RWMutex{}
54 return &deviceMgr
55}
56
khenaidoo4d4802d2018-10-04 21:59:49 -040057func (dMgr *DeviceManager) start(ctx context.Context, logicalDeviceMgr *LogicalDeviceManager) {
khenaidoob9203542018-09-17 22:56:37 -040058 log.Info("starting-device-manager")
59 dMgr.logicalDeviceMgr = logicalDeviceMgr
60 dMgr.stateTransitions = NewTransitionMap(dMgr)
61 log.Info("device-manager-started")
62}
63
khenaidoo4d4802d2018-10-04 21:59:49 -040064func (dMgr *DeviceManager) stop(ctx context.Context) {
khenaidoob9203542018-09-17 22:56:37 -040065 log.Info("stopping-device-manager")
66 dMgr.exitChannel <- 1
67 log.Info("device-manager-stopped")
68}
69
70func sendResponse(ctx context.Context, ch chan interface{}, result interface{}) {
71 if ctx.Err() == nil {
72 // Returned response only of the ctx has not been cancelled/timeout/etc
73 // Channel is automatically closed when a context is Done
74 ch <- result
75 log.Debugw("sendResponse", log.Fields{"result": result})
76 } else {
77 // Should the transaction be reverted back?
78 log.Debugw("sendResponse-context-error", log.Fields{"context-error": ctx.Err()})
79 }
80}
81
82func (dMgr *DeviceManager) addDeviceAgentToMap(agent *DeviceAgent) {
83 dMgr.lockDeviceAgentsMap.Lock()
84 defer dMgr.lockDeviceAgentsMap.Unlock()
85 if _, exist := dMgr.deviceAgents[agent.deviceId]; !exist {
86 dMgr.deviceAgents[agent.deviceId] = agent
87 }
88}
89
khenaidoo4d4802d2018-10-04 21:59:49 -040090func (dMgr *DeviceManager) deleteDeviceAgentToMap(agent *DeviceAgent) {
91 dMgr.lockDeviceAgentsMap.Lock()
92 defer dMgr.lockDeviceAgentsMap.Unlock()
93 delete(dMgr.deviceAgents, agent.deviceId)
94}
95
khenaidoob9203542018-09-17 22:56:37 -040096func (dMgr *DeviceManager) getDeviceAgent(deviceId string) *DeviceAgent {
khenaidoo4d4802d2018-10-04 21:59:49 -040097 // TODO If the device is not in memory it needs to be loaded first
khenaidoob9203542018-09-17 22:56:37 -040098 dMgr.lockDeviceAgentsMap.Lock()
99 defer dMgr.lockDeviceAgentsMap.Unlock()
100 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
101 return agent
102 }
103 return nil
104}
105
106func (dMgr *DeviceManager) createDevice(ctx context.Context, device *voltha.Device, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400107 log.Debugw("createDevice", log.Fields{"device": device, "aproxy": dMgr.adapterProxy})
khenaidoob9203542018-09-17 22:56:37 -0400108
109 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400110 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400111 dMgr.addDeviceAgentToMap(agent)
112 agent.start(ctx)
113
khenaidoo92e62c52018-10-03 14:02:54 -0400114 sendResponse(ctx, ch, agent.lastData)
khenaidoob9203542018-09-17 22:56:37 -0400115}
116
117func (dMgr *DeviceManager) enableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400118 log.Debugw("enableDevice", log.Fields{"deviceid": id})
khenaidoob9203542018-09-17 22:56:37 -0400119 var res interface{}
120 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
121 res = agent.enableDevice(ctx)
122 log.Debugw("EnableDevice-result", log.Fields{"result": res})
123 } else {
124 res = status.Errorf(codes.NotFound, "%s", id.Id)
125 }
126
127 sendResponse(ctx, ch, res)
128}
129
khenaidoo92e62c52018-10-03 14:02:54 -0400130func (dMgr *DeviceManager) disableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
131 log.Debugw("disableDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400132 var res interface{}
133 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
134 res = agent.disableDevice(ctx)
135 log.Debugw("disableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400136 } else {
khenaidoo92e62c52018-10-03 14:02:54 -0400137 res = status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoob9203542018-09-17 22:56:37 -0400138 }
khenaidoo92e62c52018-10-03 14:02:54 -0400139
140 sendResponse(ctx, ch, res)
141}
142
khenaidoo4d4802d2018-10-04 21:59:49 -0400143func (dMgr *DeviceManager) rebootDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
144 log.Debugw("rebootDevice", log.Fields{"deviceid": id})
145 var res interface{}
146 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
147 res = agent.rebootDevice(ctx)
148 log.Debugw("rebootDevice-result", log.Fields{"result": res})
149 } else {
150 res = status.Errorf(codes.NotFound, "%s", id.Id)
151 }
152 sendResponse(ctx, ch, res)
153}
154
155func (dMgr *DeviceManager) deleteDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
156 log.Debugw("deleteDevice", log.Fields{"deviceid": id})
157 var res interface{}
158 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
159 res = agent.deleteDevice(ctx)
160 if res == nil { //Success
161 agent.stop(ctx)
162 dMgr.deleteDeviceAgentToMap(agent)
163 }
164 log.Debugw("deleteDevice-result", log.Fields{"result": res})
165 } else {
166 res = status.Errorf(codes.NotFound, "%s", id.Id)
167 }
168 sendResponse(ctx, ch, res)
169}
170
khenaidoo19d7b632018-10-30 10:49:50 -0400171func (dMgr *DeviceManager) GetDevice(id string) (*voltha.Device, error) {
172 log.Debugw("GetDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400173 if agent := dMgr.getDeviceAgent(id); agent != nil {
174 return agent.getDevice()
175 }
176 return nil, status.Errorf(codes.NotFound, "%s", id)
khenaidoob9203542018-09-17 22:56:37 -0400177}
178
khenaidoo19d7b632018-10-30 10:49:50 -0400179func (dMgr *DeviceManager) IsRootDevice(id string) (bool, error) {
180 device, err := dMgr.GetDevice(id)
181 if err != nil {
182 return false, err
183 }
184 return device.Root, nil
185}
186
khenaidoob9203542018-09-17 22:56:37 -0400187func (dMgr *DeviceManager) ListDevices() (*voltha.Devices, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400188 log.Debug("ListDevices")
khenaidoob9203542018-09-17 22:56:37 -0400189 result := &voltha.Devices{}
190 dMgr.lockDeviceAgentsMap.Lock()
191 defer dMgr.lockDeviceAgentsMap.Unlock()
192 for _, agent := range dMgr.deviceAgents {
khenaidoo92e62c52018-10-03 14:02:54 -0400193 if device, err := agent.getDevice(); err == nil {
194 cloned := proto.Clone(device).(*voltha.Device)
195 result.Items = append(result.Items, cloned)
khenaidoob9203542018-09-17 22:56:37 -0400196 }
197 }
198 return result, nil
199}
200
201func (dMgr *DeviceManager) updateDevice(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400202 log.Debugw("updateDevice", log.Fields{"deviceid": device.Id, "device": device})
khenaidoob9203542018-09-17 22:56:37 -0400203 if agent := dMgr.getDeviceAgent(device.Id); agent != nil {
204 return agent.updateDevice(device)
205 }
206 return status.Errorf(codes.NotFound, "%s", device.Id)
207}
208
209func (dMgr *DeviceManager) addPort(deviceId string, port *voltha.Port) error {
210 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400211 if err := agent.addPort(port); err != nil {
212 return err
213 }
214 // Setup peer ports
215 meAsPeer := &voltha.Port_PeerPort{DeviceId: deviceId, PortNo: port.PortNo}
216 for _, peerPort := range port.Peers {
217 if agent := dMgr.getDeviceAgent(peerPort.DeviceId); agent != nil {
218 if err := agent.addPeerPort(meAsPeer); err != nil {
219 log.Errorw("failed-to-add-peer", log.Fields{"peer-device-id": peerPort.DeviceId})
220 return err
221 }
222 }
223 }
224 return nil
225 } else {
226 return status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoob9203542018-09-17 22:56:37 -0400227 }
khenaidoob9203542018-09-17 22:56:37 -0400228}
229
khenaidoo19d7b632018-10-30 10:49:50 -0400230func (dMgr *DeviceManager) updateFlows(deviceId string, flows []*ofp.OfpFlowStats) error {
231 log.Debugw("updateFlows", log.Fields{"deviceid": deviceId})
232 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
233 return agent.updateFlows(flows)
234 }
235 return status.Errorf(codes.NotFound, "%s", deviceId)
236}
237
238func (dMgr *DeviceManager) updateGroups(deviceId string, groups []*ofp.OfpGroupEntry) error {
239 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
240 return agent.updateGroups(groups)
241 }
242 return status.Errorf(codes.NotFound, "%s", deviceId)
243}
244
khenaidoob9203542018-09-17 22:56:37 -0400245func (dMgr *DeviceManager) updatePmConfigs(deviceId string, pmConfigs *voltha.PmConfigs) error {
246 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
247 return agent.updatePmConfigs(pmConfigs)
248 }
249 return status.Errorf(codes.NotFound, "%s", deviceId)
250}
251
252func (dMgr *DeviceManager) getSwitchCapability(ctx context.Context, deviceId string) (*core_adapter.SwitchCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400253 log.Debugw("getSwitchCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400254 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
255 return agent.getSwitchCapability(ctx)
256 }
257 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
258}
259
khenaidoo92e62c52018-10-03 14:02:54 -0400260func (dMgr *DeviceManager) getPorts(ctx context.Context, deviceId string, portType voltha.Port_PortType) (*voltha.Ports, error) {
261 log.Debugw("getPorts", log.Fields{"deviceid": deviceId, "portType": portType})
khenaidoob9203542018-09-17 22:56:37 -0400262 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400263 return agent.getPorts(ctx, portType), nil
khenaidoob9203542018-09-17 22:56:37 -0400264 }
265 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoo92e62c52018-10-03 14:02:54 -0400266
khenaidoob9203542018-09-17 22:56:37 -0400267}
268
269func (dMgr *DeviceManager) getPortCapability(ctx context.Context, deviceId string, portNo uint32) (*core_adapter.PortCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400270 log.Debugw("getPortCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400271 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
272 return agent.getPortCapability(ctx, portNo)
273 }
274 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
275}
276
khenaidoo92e62c52018-10-03 14:02:54 -0400277func (dMgr *DeviceManager) updateDeviceStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
278 log.Debugw("updateDeviceStatus", log.Fields{"deviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400279 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400280 return agent.updateDeviceStatus(operStatus, connStatus)
281 }
282 return status.Errorf(codes.NotFound, "%s", deviceId)
283}
284
khenaidoo4d4802d2018-10-04 21:59:49 -0400285func (dMgr *DeviceManager) updateChildrenStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
286 log.Debugw("updateChildrenStatus", log.Fields{"parentDeviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
287 var parentDevice *voltha.Device
288 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400289 if parentDevice, err = dMgr.GetDevice(deviceId); err != nil {
khenaidoo4d4802d2018-10-04 21:59:49 -0400290 return status.Errorf(codes.Aborted, "%s", err.Error())
291 }
292 var childDeviceIds []string
293 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
294 return status.Errorf(codes.Aborted, "%s", err.Error())
295 }
296 if len(childDeviceIds) == 0 {
297 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
298 }
299 for _, childDeviceId := range childDeviceIds {
300 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
301 if err = agent.updateDeviceStatus(operStatus, connStatus); err != nil {
302 return status.Errorf(codes.Aborted, "childDevice:%s, error:%s", childDeviceId, err.Error())
303 }
304 }
305 }
306 return nil
307}
308
khenaidoo92e62c52018-10-03 14:02:54 -0400309func (dMgr *DeviceManager) updatePortState(deviceId string, portType voltha.Port_PortType, portNo uint32, operStatus voltha.OperStatus_OperStatus) error {
310 log.Debugw("updatePortState", log.Fields{"deviceid": deviceId, "portType": portType, "portNo": portNo, "operStatus": operStatus})
311 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
312 return agent.updatePortState(portType, portNo, operStatus)
khenaidoob9203542018-09-17 22:56:37 -0400313 }
314 return status.Errorf(codes.NotFound, "%s", deviceId)
315}
316
317func (dMgr *DeviceManager) childDeviceDetected(parentDeviceId string, parentPortNo int64, deviceType string, channelId int64) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400318 log.Debugw("childDeviceDetected", log.Fields{"parentDeviceId": parentDeviceId})
khenaidoob9203542018-09-17 22:56:37 -0400319
320 // Create the ONU device
321 childDevice := &voltha.Device{}
khenaidoob9203542018-09-17 22:56:37 -0400322 childDevice.Type = deviceType
323 childDevice.ParentId = parentDeviceId
324 childDevice.ParentPortNo = uint32(parentPortNo)
325 childDevice.Root = false
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400326
327 //Get parent device type
328 parent, err := dMgr.GetDevice(parentDeviceId)
329 if err != nil {
330 log.Error("no-parent-found", log.Fields{"parentId":parentDeviceId})
331 return status.Errorf(codes.NotFound, "%s", parentDeviceId)
332 }
333
334 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{DeviceId: parentDeviceId, DeviceType: parent.Type, ChannelId: uint32(channelId)}
khenaidoob9203542018-09-17 22:56:37 -0400335
336 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400337 agent := newDeviceAgent(dMgr.adapterProxy, childDevice, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400338 dMgr.addDeviceAgentToMap(agent)
339 agent.start(nil)
340
341 // Activate the child device
khenaidoo92e62c52018-10-03 14:02:54 -0400342 if agent := dMgr.getDeviceAgent(agent.deviceId); agent != nil {
khenaidoob9203542018-09-17 22:56:37 -0400343 return agent.enableDevice(nil)
344 }
345
346 return nil
347}
348
349func (dMgr *DeviceManager) processTransition(previous *voltha.Device, current *voltha.Device) error {
350 // This will be triggered on every update to the device.
khenaidoo92e62c52018-10-03 14:02:54 -0400351 handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
352 if handlers == nil {
353 log.Debugw("handlers-not-found", log.Fields{"deviceId": current.Id})
354 return nil
khenaidoob9203542018-09-17 22:56:37 -0400355 }
khenaidoo92e62c52018-10-03 14:02:54 -0400356 for _, handler := range handlers {
357 log.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
358 if err := handler(current); err != nil {
359 return err
360 }
361 }
khenaidoob9203542018-09-17 22:56:37 -0400362 return nil
363}
364
khenaidoo92e62c52018-10-03 14:02:54 -0400365func (dMgr *DeviceManager) createLogicalDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400366 log.Info("createLogicalDevice")
367 var logicalId *string
368 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400369 if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400370 log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
371 return err
372 }
373 // Update the parent device with the logical id
374 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
375 return nil
376}
377
khenaidoo92e62c52018-10-03 14:02:54 -0400378func (dMgr *DeviceManager) deleteLogicalDevice(cDevice *voltha.Device) error {
379 log.Info("deleteLogicalDevice")
380 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400381 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400382 log.Warnw("deleteLogical-device-error", log.Fields{"deviceId": cDevice.Id})
383 return err
384 }
385 // Remove the logical device Id from the parent device
386 logicalId := ""
387 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", logicalId)
388 return nil
389}
390
khenaidoo19d7b632018-10-30 10:49:50 -0400391func (dMgr *DeviceManager) deleteLogicalPort(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400392 log.Info("deleteLogicalPort")
393 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400394 // Get the logical port associated with this device
395 var lPortId *voltha.LogicalPortId
396 if lPortId, err = dMgr.logicalDeviceMgr.getLogicalPortId(device); err != nil {
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400397 log.Warnw("getLogical-port-error", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo19d7b632018-10-30 10:49:50 -0400398 return err
399 }
400 if err = dMgr.logicalDeviceMgr.deleteLogicalPort(nil, lPortId); err != nil {
401 log.Warnw("deleteLogical-port-error", log.Fields{"deviceId": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400402 return err
403 }
khenaidoo92e62c52018-10-03 14:02:54 -0400404 return nil
405}
406
407func (dMgr *DeviceManager) getParentDevice(childDevice *voltha.Device) *voltha.Device {
408 // Sanity check
409 if childDevice.Root {
410 // childDevice is the parent device
411 return childDevice
412 }
khenaidoo19d7b632018-10-30 10:49:50 -0400413 parentDevice, _ := dMgr.GetDevice(childDevice.ParentId)
khenaidoo92e62c52018-10-03 14:02:54 -0400414 return parentDevice
415}
416
khenaidoo4d4802d2018-10-04 21:59:49 -0400417/*
418All the functions below are callback functions where they are invoked with the latest and previous data. We can
419therefore use the data as is without trying to get the latest from the model.
420*/
421
422//disableAllChildDevices is invoked as a callback when the parent device is disabled
423func (dMgr *DeviceManager) disableAllChildDevices(parentDevice *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400424 log.Debug("disableAllChildDevices")
425 var childDeviceIds []string
426 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400427 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
428 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400429 }
430 if len(childDeviceIds) == 0 {
khenaidoo4d4802d2018-10-04 21:59:49 -0400431 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400432 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400433 allChildDisable := true
khenaidoo92e62c52018-10-03 14:02:54 -0400434 for _, childDeviceId := range childDeviceIds {
435 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
436 if err = agent.disableDevice(nil); err != nil {
437 log.Errorw("failure-disable-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
khenaidoo4d4802d2018-10-04 21:59:49 -0400438 allChildDisable = false
khenaidoo92e62c52018-10-03 14:02:54 -0400439 }
440 }
441 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400442 if !allChildDisable {
443 return err
444 }
khenaidoo92e62c52018-10-03 14:02:54 -0400445 return nil
446}
447
khenaidoo4d4802d2018-10-04 21:59:49 -0400448//deleteAllChildDevices is invoked as a callback when the parent device is deleted
449func (dMgr *DeviceManager) deleteAllChildDevices(parentDevice *voltha.Device) error {
450 log.Debug("deleteAllChildDevices")
451 var childDeviceIds []string
khenaidoo92e62c52018-10-03 14:02:54 -0400452 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400453 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
454 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400455 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400456 if len(childDeviceIds) == 0 {
457 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
458 }
459 allChildDeleted := true
460 for _, childDeviceId := range childDeviceIds {
461 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
462 if err = agent.deleteDevice(nil); err != nil {
463 log.Errorw("failure-delete-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
464 allChildDeleted = false
465 } else {
466 agent.stop(nil)
467 dMgr.deleteDeviceAgentToMap(agent)
468 }
469 }
470 }
471 if !allChildDeleted {
472 return err
473 }
474 return nil
475}
476
477//getAllChildDeviceIds is a helper method to get all the child device IDs from the device passed as parameter
478func (dMgr *DeviceManager) getAllChildDeviceIds(parentDevice *voltha.Device) ([]string, error) {
479 log.Debugw("getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400480 childDeviceIds := make([]string, 0)
khenaidoo4d4802d2018-10-04 21:59:49 -0400481 if parentDevice != nil {
482 for _, port := range parentDevice.Ports {
483 for _, peer := range port.Peers {
484 childDeviceIds = append(childDeviceIds, peer.DeviceId)
485 }
khenaidoo92e62c52018-10-03 14:02:54 -0400486 }
487 }
488 return childDeviceIds, nil
489}
490
491func (dMgr *DeviceManager) addUNILogicalPort(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400492 log.Info("addUNILogicalPort")
khenaidoo4d4802d2018-10-04 21:59:49 -0400493 if err := dMgr.logicalDeviceMgr.addUNILogicalPort(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400494 log.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
495 return err
496 }
497 return nil
498}
499
khenaidoo92e62c52018-10-03 14:02:54 -0400500func (dMgr *DeviceManager) activateDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400501 log.Info("activateDevice")
502 return nil
503}
504
khenaidoo92e62c52018-10-03 14:02:54 -0400505func (dMgr *DeviceManager) disableDeviceHandler(cDevice *voltha.Device) error {
506 log.Info("disableDevice-donothing")
khenaidoob9203542018-09-17 22:56:37 -0400507 return nil
508}
509
khenaidoo92e62c52018-10-03 14:02:54 -0400510func (dMgr *DeviceManager) abandonDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400511 log.Info("abandonDevice")
512 return nil
513}
514
khenaidoo92e62c52018-10-03 14:02:54 -0400515func (dMgr *DeviceManager) reEnableDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400516 log.Info("reEnableDevice")
517 return nil
518}
519
khenaidoo92e62c52018-10-03 14:02:54 -0400520func (dMgr *DeviceManager) noOp(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400521 log.Info("noOp")
522 return nil
523}
524
khenaidoo92e62c52018-10-03 14:02:54 -0400525func (dMgr *DeviceManager) notAllowed(pcDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400526 log.Info("notAllowed")
527 return errors.New("Transition-not-allowed")
528}
529
530func funcName(f interface{}) string {
531 p := reflect.ValueOf(f).Pointer()
532 rf := runtime.FuncForPC(p)
533 return rf.Name()
534}
535
536func (dMgr *DeviceManager) UpdateDeviceAttribute(deviceId string, attribute string, value interface{}) {
537 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
538 agent.updateDeviceAttribute(attribute, value)
539 }
540}
541
542func (dMgr *DeviceManager) GetParentDeviceId(deviceId string) *string {
khenaidoo19d7b632018-10-30 10:49:50 -0400543 if device, _ := dMgr.GetDevice(deviceId); device != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400544 log.Infow("GetParentDeviceId", log.Fields{"deviceId": device.Id, "parentId": device.ParentId})
khenaidoob9203542018-09-17 22:56:37 -0400545 return &device.ParentId
546 }
547 return nil
548}