blob: 1063e29aec0f95414261397d13bc69ec9e9c2d6a [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"
26 "github.com/opencord/voltha-go/protos/voltha"
27 "google.golang.org/grpc/codes"
28 "google.golang.org/grpc/status"
29 "reflect"
30 "runtime"
31 "sync"
32)
33
34type DeviceManager struct {
35 deviceAgents map[string]*DeviceAgent
36 adapterProxy *AdapterProxy
37 logicalDeviceMgr *LogicalDeviceManager
38 kafkaProxy *kafka.KafkaMessagingProxy
39 stateTransitions *TransitionMap
khenaidoo9a468962018-09-19 15:33:13 -040040 clusterDataProxy *model.Proxy
khenaidoob9203542018-09-17 22:56:37 -040041 exitChannel chan int
42 lockDeviceAgentsMap sync.RWMutex
43}
44
khenaidoo4d4802d2018-10-04 21:59:49 -040045func newDeviceManager(kafkaProxy *kafka.KafkaMessagingProxy, cdProxy *model.Proxy) *DeviceManager {
khenaidoob9203542018-09-17 22:56:37 -040046 var deviceMgr DeviceManager
47 deviceMgr.exitChannel = make(chan int, 1)
48 deviceMgr.deviceAgents = make(map[string]*DeviceAgent)
49 deviceMgr.adapterProxy = NewAdapterProxy(kafkaProxy)
50 deviceMgr.kafkaProxy = kafkaProxy
khenaidoo9a468962018-09-19 15:33:13 -040051 deviceMgr.clusterDataProxy = cdProxy
khenaidoob9203542018-09-17 22:56:37 -040052 deviceMgr.lockDeviceAgentsMap = sync.RWMutex{}
53 return &deviceMgr
54}
55
khenaidoo4d4802d2018-10-04 21:59:49 -040056func (dMgr *DeviceManager) start(ctx context.Context, logicalDeviceMgr *LogicalDeviceManager) {
khenaidoob9203542018-09-17 22:56:37 -040057 log.Info("starting-device-manager")
58 dMgr.logicalDeviceMgr = logicalDeviceMgr
59 dMgr.stateTransitions = NewTransitionMap(dMgr)
60 log.Info("device-manager-started")
61}
62
khenaidoo4d4802d2018-10-04 21:59:49 -040063func (dMgr *DeviceManager) stop(ctx context.Context) {
khenaidoob9203542018-09-17 22:56:37 -040064 log.Info("stopping-device-manager")
65 dMgr.exitChannel <- 1
66 log.Info("device-manager-stopped")
67}
68
69func sendResponse(ctx context.Context, ch chan interface{}, result interface{}) {
70 if ctx.Err() == nil {
71 // Returned response only of the ctx has not been cancelled/timeout/etc
72 // Channel is automatically closed when a context is Done
73 ch <- result
74 log.Debugw("sendResponse", log.Fields{"result": result})
75 } else {
76 // Should the transaction be reverted back?
77 log.Debugw("sendResponse-context-error", log.Fields{"context-error": ctx.Err()})
78 }
79}
80
81func (dMgr *DeviceManager) addDeviceAgentToMap(agent *DeviceAgent) {
82 dMgr.lockDeviceAgentsMap.Lock()
83 defer dMgr.lockDeviceAgentsMap.Unlock()
84 if _, exist := dMgr.deviceAgents[agent.deviceId]; !exist {
85 dMgr.deviceAgents[agent.deviceId] = agent
86 }
87}
88
khenaidoo4d4802d2018-10-04 21:59:49 -040089func (dMgr *DeviceManager) deleteDeviceAgentToMap(agent *DeviceAgent) {
90 dMgr.lockDeviceAgentsMap.Lock()
91 defer dMgr.lockDeviceAgentsMap.Unlock()
92 delete(dMgr.deviceAgents, agent.deviceId)
93}
94
khenaidoob9203542018-09-17 22:56:37 -040095func (dMgr *DeviceManager) getDeviceAgent(deviceId string) *DeviceAgent {
khenaidoo4d4802d2018-10-04 21:59:49 -040096 // TODO If the device is not in memory it needs to be loaded first
khenaidoob9203542018-09-17 22:56:37 -040097 dMgr.lockDeviceAgentsMap.Lock()
98 defer dMgr.lockDeviceAgentsMap.Unlock()
99 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
100 return agent
101 }
102 return nil
103}
104
105func (dMgr *DeviceManager) createDevice(ctx context.Context, device *voltha.Device, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400106 log.Debugw("createDevice", log.Fields{"device": device, "aproxy": dMgr.adapterProxy})
khenaidoob9203542018-09-17 22:56:37 -0400107
108 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400109 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400110 dMgr.addDeviceAgentToMap(agent)
111 agent.start(ctx)
112
khenaidoo92e62c52018-10-03 14:02:54 -0400113 sendResponse(ctx, ch, agent.lastData)
khenaidoob9203542018-09-17 22:56:37 -0400114}
115
116func (dMgr *DeviceManager) enableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400117 log.Debugw("enableDevice", log.Fields{"deviceid": id})
khenaidoob9203542018-09-17 22:56:37 -0400118 var res interface{}
119 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
120 res = agent.enableDevice(ctx)
121 log.Debugw("EnableDevice-result", log.Fields{"result": res})
122 } else {
123 res = status.Errorf(codes.NotFound, "%s", id.Id)
124 }
125
126 sendResponse(ctx, ch, res)
127}
128
khenaidoo92e62c52018-10-03 14:02:54 -0400129func (dMgr *DeviceManager) disableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
130 log.Debugw("disableDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400131 var res interface{}
132 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
133 res = agent.disableDevice(ctx)
134 log.Debugw("disableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400135 } else {
khenaidoo92e62c52018-10-03 14:02:54 -0400136 res = status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoob9203542018-09-17 22:56:37 -0400137 }
khenaidoo92e62c52018-10-03 14:02:54 -0400138
139 sendResponse(ctx, ch, res)
140}
141
khenaidoo4d4802d2018-10-04 21:59:49 -0400142func (dMgr *DeviceManager) rebootDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
143 log.Debugw("rebootDevice", log.Fields{"deviceid": id})
144 var res interface{}
145 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
146 res = agent.rebootDevice(ctx)
147 log.Debugw("rebootDevice-result", log.Fields{"result": res})
148 } else {
149 res = status.Errorf(codes.NotFound, "%s", id.Id)
150 }
151 sendResponse(ctx, ch, res)
152}
153
154func (dMgr *DeviceManager) deleteDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
155 log.Debugw("deleteDevice", log.Fields{"deviceid": id})
156 var res interface{}
157 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
158 res = agent.deleteDevice(ctx)
159 if res == nil { //Success
160 agent.stop(ctx)
161 dMgr.deleteDeviceAgentToMap(agent)
162 }
163 log.Debugw("deleteDevice-result", log.Fields{"result": res})
164 } else {
165 res = status.Errorf(codes.NotFound, "%s", id.Id)
166 }
167 sendResponse(ctx, ch, res)
168}
169
khenaidoo92e62c52018-10-03 14:02:54 -0400170func (dMgr *DeviceManager) getDevice(id string) (*voltha.Device, error) {
171 log.Debugw("getDevice", log.Fields{"deviceid": id})
172 if agent := dMgr.getDeviceAgent(id); agent != nil {
173 return agent.getDevice()
174 }
175 return nil, status.Errorf(codes.NotFound, "%s", id)
khenaidoob9203542018-09-17 22:56:37 -0400176}
177
178func (dMgr *DeviceManager) ListDevices() (*voltha.Devices, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400179 log.Debug("ListDevices")
khenaidoob9203542018-09-17 22:56:37 -0400180 result := &voltha.Devices{}
181 dMgr.lockDeviceAgentsMap.Lock()
182 defer dMgr.lockDeviceAgentsMap.Unlock()
183 for _, agent := range dMgr.deviceAgents {
khenaidoo92e62c52018-10-03 14:02:54 -0400184 if device, err := agent.getDevice(); err == nil {
185 cloned := proto.Clone(device).(*voltha.Device)
186 result.Items = append(result.Items, cloned)
khenaidoob9203542018-09-17 22:56:37 -0400187 }
188 }
189 return result, nil
190}
191
192func (dMgr *DeviceManager) updateDevice(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400193 log.Debugw("updateDevice", log.Fields{"deviceid": device.Id, "device": device})
khenaidoob9203542018-09-17 22:56:37 -0400194 if agent := dMgr.getDeviceAgent(device.Id); agent != nil {
195 return agent.updateDevice(device)
196 }
197 return status.Errorf(codes.NotFound, "%s", device.Id)
198}
199
200func (dMgr *DeviceManager) addPort(deviceId string, port *voltha.Port) error {
201 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400202 if err := agent.addPort(port); err != nil {
203 return err
204 }
205 // Setup peer ports
206 meAsPeer := &voltha.Port_PeerPort{DeviceId: deviceId, PortNo: port.PortNo}
207 for _, peerPort := range port.Peers {
208 if agent := dMgr.getDeviceAgent(peerPort.DeviceId); agent != nil {
209 if err := agent.addPeerPort(meAsPeer); err != nil {
210 log.Errorw("failed-to-add-peer", log.Fields{"peer-device-id": peerPort.DeviceId})
211 return err
212 }
213 }
214 }
215 return nil
216 } else {
217 return status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoob9203542018-09-17 22:56:37 -0400218 }
khenaidoob9203542018-09-17 22:56:37 -0400219}
220
221func (dMgr *DeviceManager) updatePmConfigs(deviceId string, pmConfigs *voltha.PmConfigs) error {
222 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
223 return agent.updatePmConfigs(pmConfigs)
224 }
225 return status.Errorf(codes.NotFound, "%s", deviceId)
226}
227
228func (dMgr *DeviceManager) getSwitchCapability(ctx context.Context, deviceId string) (*core_adapter.SwitchCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400229 log.Debugw("getSwitchCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400230 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
231 return agent.getSwitchCapability(ctx)
232 }
233 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
234}
235
khenaidoo92e62c52018-10-03 14:02:54 -0400236func (dMgr *DeviceManager) getPorts(ctx context.Context, deviceId string, portType voltha.Port_PortType) (*voltha.Ports, error) {
237 log.Debugw("getPorts", log.Fields{"deviceid": deviceId, "portType": portType})
khenaidoob9203542018-09-17 22:56:37 -0400238 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400239 return agent.getPorts(ctx, portType), nil
khenaidoob9203542018-09-17 22:56:37 -0400240 }
241 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoo92e62c52018-10-03 14:02:54 -0400242
khenaidoob9203542018-09-17 22:56:37 -0400243}
244
245func (dMgr *DeviceManager) getPortCapability(ctx context.Context, deviceId string, portNo uint32) (*core_adapter.PortCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400246 log.Debugw("getPortCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400247 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
248 return agent.getPortCapability(ctx, portNo)
249 }
250 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
251}
252
khenaidoo92e62c52018-10-03 14:02:54 -0400253func (dMgr *DeviceManager) updateDeviceStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
254 log.Debugw("updateDeviceStatus", log.Fields{"deviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400255 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400256 return agent.updateDeviceStatus(operStatus, connStatus)
257 }
258 return status.Errorf(codes.NotFound, "%s", deviceId)
259}
260
khenaidoo4d4802d2018-10-04 21:59:49 -0400261func (dMgr *DeviceManager) updateChildrenStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
262 log.Debugw("updateChildrenStatus", log.Fields{"parentDeviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
263 var parentDevice *voltha.Device
264 var err error
265 if parentDevice, err = dMgr.getDevice(deviceId); err != nil {
266 return status.Errorf(codes.Aborted, "%s", err.Error())
267 }
268 var childDeviceIds []string
269 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
270 return status.Errorf(codes.Aborted, "%s", err.Error())
271 }
272 if len(childDeviceIds) == 0 {
273 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
274 }
275 for _, childDeviceId := range childDeviceIds {
276 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
277 if err = agent.updateDeviceStatus(operStatus, connStatus); err != nil {
278 return status.Errorf(codes.Aborted, "childDevice:%s, error:%s", childDeviceId, err.Error())
279 }
280 }
281 }
282 return nil
283}
284
khenaidoo92e62c52018-10-03 14:02:54 -0400285func (dMgr *DeviceManager) updatePortState(deviceId string, portType voltha.Port_PortType, portNo uint32, operStatus voltha.OperStatus_OperStatus) error {
286 log.Debugw("updatePortState", log.Fields{"deviceid": deviceId, "portType": portType, "portNo": portNo, "operStatus": operStatus})
287 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
288 return agent.updatePortState(portType, portNo, operStatus)
khenaidoob9203542018-09-17 22:56:37 -0400289 }
290 return status.Errorf(codes.NotFound, "%s", deviceId)
291}
292
293func (dMgr *DeviceManager) childDeviceDetected(parentDeviceId string, parentPortNo int64, deviceType string, channelId int64) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400294 log.Debugw("childDeviceDetected", log.Fields{"parentDeviceId": parentDeviceId})
khenaidoob9203542018-09-17 22:56:37 -0400295
296 // Create the ONU device
297 childDevice := &voltha.Device{}
khenaidoob9203542018-09-17 22:56:37 -0400298 childDevice.Type = deviceType
299 childDevice.ParentId = parentDeviceId
300 childDevice.ParentPortNo = uint32(parentPortNo)
301 childDevice.Root = false
302 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{ChannelId: uint32(channelId)}
303
304 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400305 agent := newDeviceAgent(dMgr.adapterProxy, childDevice, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400306 dMgr.addDeviceAgentToMap(agent)
307 agent.start(nil)
308
309 // Activate the child device
khenaidoo92e62c52018-10-03 14:02:54 -0400310 if agent := dMgr.getDeviceAgent(agent.deviceId); agent != nil {
khenaidoob9203542018-09-17 22:56:37 -0400311 return agent.enableDevice(nil)
312 }
313
314 return nil
315}
316
317func (dMgr *DeviceManager) processTransition(previous *voltha.Device, current *voltha.Device) error {
318 // This will be triggered on every update to the device.
khenaidoo92e62c52018-10-03 14:02:54 -0400319 handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
320 if handlers == nil {
321 log.Debugw("handlers-not-found", log.Fields{"deviceId": current.Id})
322 return nil
khenaidoob9203542018-09-17 22:56:37 -0400323 }
khenaidoo92e62c52018-10-03 14:02:54 -0400324 for _, handler := range handlers {
325 log.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
326 if err := handler(current); err != nil {
327 return err
328 }
329 }
khenaidoob9203542018-09-17 22:56:37 -0400330 return nil
331}
332
khenaidoo92e62c52018-10-03 14:02:54 -0400333func (dMgr *DeviceManager) createLogicalDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400334 log.Info("createLogicalDevice")
335 var logicalId *string
336 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400337 if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400338 log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
339 return err
340 }
341 // Update the parent device with the logical id
342 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
343 return nil
344}
345
khenaidoo92e62c52018-10-03 14:02:54 -0400346func (dMgr *DeviceManager) deleteLogicalDevice(cDevice *voltha.Device) error {
347 log.Info("deleteLogicalDevice")
348 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400349 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400350 log.Warnw("deleteLogical-device-error", log.Fields{"deviceId": cDevice.Id})
351 return err
352 }
353 // Remove the logical device Id from the parent device
354 logicalId := ""
355 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", logicalId)
356 return nil
357}
358
359func (dMgr *DeviceManager) deleteLogicalPort(cDevice *voltha.Device) error {
360 log.Info("deleteLogicalPort")
361 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400362 if err = dMgr.logicalDeviceMgr.deleteLogicalPort(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400363 log.Warnw("deleteLogical-port-error", log.Fields{"deviceId": cDevice.Id})
364 return err
365 }
khenaidoo92e62c52018-10-03 14:02:54 -0400366 return nil
367}
368
369func (dMgr *DeviceManager) getParentDevice(childDevice *voltha.Device) *voltha.Device {
370 // Sanity check
371 if childDevice.Root {
372 // childDevice is the parent device
373 return childDevice
374 }
375 parentDevice, _ := dMgr.getDevice(childDevice.ParentId)
376 return parentDevice
377}
378
khenaidoo4d4802d2018-10-04 21:59:49 -0400379/*
380All the functions below are callback functions where they are invoked with the latest and previous data. We can
381therefore use the data as is without trying to get the latest from the model.
382*/
383
384//disableAllChildDevices is invoked as a callback when the parent device is disabled
385func (dMgr *DeviceManager) disableAllChildDevices(parentDevice *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400386 log.Debug("disableAllChildDevices")
387 var childDeviceIds []string
388 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400389 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
390 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400391 }
392 if len(childDeviceIds) == 0 {
khenaidoo4d4802d2018-10-04 21:59:49 -0400393 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400394 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400395 allChildDisable := true
khenaidoo92e62c52018-10-03 14:02:54 -0400396 for _, childDeviceId := range childDeviceIds {
397 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
398 if err = agent.disableDevice(nil); err != nil {
399 log.Errorw("failure-disable-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
khenaidoo4d4802d2018-10-04 21:59:49 -0400400 allChildDisable = false
khenaidoo92e62c52018-10-03 14:02:54 -0400401 }
402 }
403 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400404 if !allChildDisable {
405 return err
406 }
khenaidoo92e62c52018-10-03 14:02:54 -0400407 return nil
408}
409
khenaidoo4d4802d2018-10-04 21:59:49 -0400410//deleteAllChildDevices is invoked as a callback when the parent device is deleted
411func (dMgr *DeviceManager) deleteAllChildDevices(parentDevice *voltha.Device) error {
412 log.Debug("deleteAllChildDevices")
413 var childDeviceIds []string
khenaidoo92e62c52018-10-03 14:02:54 -0400414 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400415 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
416 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400417 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400418 if len(childDeviceIds) == 0 {
419 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
420 }
421 allChildDeleted := true
422 for _, childDeviceId := range childDeviceIds {
423 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
424 if err = agent.deleteDevice(nil); err != nil {
425 log.Errorw("failure-delete-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
426 allChildDeleted = false
427 } else {
428 agent.stop(nil)
429 dMgr.deleteDeviceAgentToMap(agent)
430 }
431 }
432 }
433 if !allChildDeleted {
434 return err
435 }
436 return nil
437}
438
439//getAllChildDeviceIds is a helper method to get all the child device IDs from the device passed as parameter
440func (dMgr *DeviceManager) getAllChildDeviceIds(parentDevice *voltha.Device) ([]string, error) {
441 log.Debugw("getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400442 childDeviceIds := make([]string, 0)
khenaidoo4d4802d2018-10-04 21:59:49 -0400443 if parentDevice != nil {
444 for _, port := range parentDevice.Ports {
445 for _, peer := range port.Peers {
446 childDeviceIds = append(childDeviceIds, peer.DeviceId)
447 }
khenaidoo92e62c52018-10-03 14:02:54 -0400448 }
449 }
450 return childDeviceIds, nil
451}
452
453func (dMgr *DeviceManager) addUNILogicalPort(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400454 log.Info("addUNILogicalPort")
khenaidoo4d4802d2018-10-04 21:59:49 -0400455 if err := dMgr.logicalDeviceMgr.addUNILogicalPort(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400456 log.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
457 return err
458 }
459 return nil
460}
461
khenaidoo92e62c52018-10-03 14:02:54 -0400462func (dMgr *DeviceManager) activateDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400463 log.Info("activateDevice")
464 return nil
465}
466
khenaidoo92e62c52018-10-03 14:02:54 -0400467func (dMgr *DeviceManager) disableDeviceHandler(cDevice *voltha.Device) error {
468 log.Info("disableDevice-donothing")
khenaidoob9203542018-09-17 22:56:37 -0400469 return nil
470}
471
khenaidoo92e62c52018-10-03 14:02:54 -0400472func (dMgr *DeviceManager) abandonDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400473 log.Info("abandonDevice")
474 return nil
475}
476
khenaidoo92e62c52018-10-03 14:02:54 -0400477func (dMgr *DeviceManager) reEnableDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400478 log.Info("reEnableDevice")
479 return nil
480}
481
khenaidoo92e62c52018-10-03 14:02:54 -0400482func (dMgr *DeviceManager) noOp(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400483 log.Info("noOp")
484 return nil
485}
486
khenaidoo92e62c52018-10-03 14:02:54 -0400487func (dMgr *DeviceManager) notAllowed(pcDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400488 log.Info("notAllowed")
489 return errors.New("Transition-not-allowed")
490}
491
492func funcName(f interface{}) string {
493 p := reflect.ValueOf(f).Pointer()
494 rf := runtime.FuncForPC(p)
495 return rf.Name()
496}
497
498func (dMgr *DeviceManager) UpdateDeviceAttribute(deviceId string, attribute string, value interface{}) {
499 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
500 agent.updateDeviceAttribute(attribute, value)
501 }
502}
503
504func (dMgr *DeviceManager) GetParentDeviceId(deviceId string) *string {
505 if device, _ := dMgr.getDevice(deviceId); device != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400506 log.Infow("GetParentDeviceId", log.Fields{"deviceId": device.Id, "parentId": device.ParentId})
khenaidoob9203542018-09-17 22:56:37 -0400507 return &device.ParentId
508 }
509 return nil
510}