blob: 257b707a273534a447c8cf4676a25cc1f952183b [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"
21 "github.com/opencord/voltha-go/common/log"
22 "github.com/opencord/voltha-go/db/model"
23 "github.com/opencord/voltha-go/kafka"
khenaidoo3d3b8c22019-05-22 18:10:39 -040024 "github.com/opencord/voltha-go/rw_core/utils"
William Kurkiandaa6bb22019-03-07 12:26:28 -050025 ic "github.com/opencord/voltha-protos/go/inter_container"
26 ofp "github.com/opencord/voltha-protos/go/openflow_13"
27 "github.com/opencord/voltha-protos/go/voltha"
khenaidoob9203542018-09-17 22:56:37 -040028 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/status"
30 "reflect"
31 "runtime"
32 "sync"
33)
34
35type DeviceManager struct {
Stephane Barbarieef6650d2019-07-18 12:15:09 -040036 deviceAgents sync.Map
37 rootDevices map[string]bool
38 lockRootDeviceMap sync.RWMutex
39 core *Core
40 adapterProxy *AdapterProxy
41 adapterMgr *AdapterManager
42 logicalDeviceMgr *LogicalDeviceManager
43 kafkaICProxy *kafka.InterContainerProxy
44 stateTransitions *TransitionMap
45 clusterDataProxy *model.Proxy
46 coreInstanceId string
47 exitChannel chan int
48 defaultTimeout int64
khenaidoob9203542018-09-17 22:56:37 -040049}
50
Richard Jankowski199fd862019-03-18 14:49:51 -040051func newDeviceManager(core *Core) *DeviceManager {
khenaidoob9203542018-09-17 22:56:37 -040052 var deviceMgr DeviceManager
Richard Jankowski199fd862019-03-18 14:49:51 -040053 deviceMgr.core = core
khenaidoob9203542018-09-17 22:56:37 -040054 deviceMgr.exitChannel = make(chan int, 1)
khenaidoo2c6a0992019-04-29 13:46:56 -040055 deviceMgr.rootDevices = make(map[string]bool)
Richard Jankowski199fd862019-03-18 14:49:51 -040056 deviceMgr.kafkaICProxy = core.kmp
57 deviceMgr.adapterProxy = NewAdapterProxy(core.kmp)
58 deviceMgr.coreInstanceId = core.instanceId
59 deviceMgr.clusterDataProxy = core.clusterDataProxy
60 deviceMgr.adapterMgr = core.adapterMgr
khenaidoo2c6a0992019-04-29 13:46:56 -040061 deviceMgr.lockRootDeviceMap = sync.RWMutex{}
62 deviceMgr.defaultTimeout = core.config.DefaultCoreTimeout
khenaidoob9203542018-09-17 22:56:37 -040063 return &deviceMgr
64}
65
khenaidoo4d4802d2018-10-04 21:59:49 -040066func (dMgr *DeviceManager) start(ctx context.Context, logicalDeviceMgr *LogicalDeviceManager) {
khenaidoob9203542018-09-17 22:56:37 -040067 log.Info("starting-device-manager")
68 dMgr.logicalDeviceMgr = logicalDeviceMgr
69 dMgr.stateTransitions = NewTransitionMap(dMgr)
70 log.Info("device-manager-started")
71}
72
khenaidoo4d4802d2018-10-04 21:59:49 -040073func (dMgr *DeviceManager) stop(ctx context.Context) {
khenaidoob9203542018-09-17 22:56:37 -040074 log.Info("stopping-device-manager")
75 dMgr.exitChannel <- 1
76 log.Info("device-manager-stopped")
77}
78
79func sendResponse(ctx context.Context, ch chan interface{}, result interface{}) {
80 if ctx.Err() == nil {
81 // Returned response only of the ctx has not been cancelled/timeout/etc
82 // Channel is automatically closed when a context is Done
83 ch <- result
84 log.Debugw("sendResponse", log.Fields{"result": result})
85 } else {
86 // Should the transaction be reverted back?
87 log.Debugw("sendResponse-context-error", log.Fields{"context-error": ctx.Err()})
88 }
89}
90
91func (dMgr *DeviceManager) addDeviceAgentToMap(agent *DeviceAgent) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -040092 if _, exist := dMgr.deviceAgents.Load(agent.deviceId); !exist {
93 dMgr.deviceAgents.Store(agent.deviceId, agent)
khenaidoob9203542018-09-17 22:56:37 -040094 }
khenaidoo2c6a0992019-04-29 13:46:56 -040095 dMgr.lockRootDeviceMap.Lock()
96 defer dMgr.lockRootDeviceMap.Unlock()
97 dMgr.rootDevices[agent.deviceId] = agent.isRootdevice
98
khenaidoob9203542018-09-17 22:56:37 -040099}
100
khenaidoo4d4802d2018-10-04 21:59:49 -0400101func (dMgr *DeviceManager) deleteDeviceAgentToMap(agent *DeviceAgent) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400102 dMgr.deviceAgents.Delete(agent.deviceId)
khenaidoo2c6a0992019-04-29 13:46:56 -0400103 dMgr.lockRootDeviceMap.Lock()
104 defer dMgr.lockRootDeviceMap.Unlock()
105 delete(dMgr.rootDevices, agent.deviceId)
khenaidoo4d4802d2018-10-04 21:59:49 -0400106}
107
khenaidoo297cd252019-02-07 22:10:23 -0500108// getDeviceAgent returns the agent managing the device. If the device is not in memory, it will loads it, if it exists
khenaidoob9203542018-09-17 22:56:37 -0400109func (dMgr *DeviceManager) getDeviceAgent(deviceId string) *DeviceAgent {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400110 if agent, ok := dMgr.deviceAgents.Load(deviceId); ok {
111 return agent.(*DeviceAgent)
khenaidoo297cd252019-02-07 22:10:23 -0500112 } else {
khenaidoo3d3b8c22019-05-22 18:10:39 -0400113 // Try to load into memory - loading will also create the device agent and set the device ownership
khenaidoo297cd252019-02-07 22:10:23 -0500114 if err := dMgr.load(deviceId); err == nil {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400115 if agent, ok = dMgr.deviceAgents.Load(deviceId); !ok {
khenaidoo3d3b8c22019-05-22 18:10:39 -0400116 return nil
117 } else {
118 // Register this device for ownership tracking
119 go dMgr.core.deviceOwnership.OwnedByMe(&utils.DeviceID{Id: deviceId})
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400120 return agent.(*DeviceAgent)
khenaidoo297cd252019-02-07 22:10:23 -0500121 }
khenaidoo3d3b8c22019-05-22 18:10:39 -0400122 } else {
123 //TODO: Change the return params to return an error as well
124 log.Errorw("loading-device-failed", log.Fields{"deviceId": deviceId, "error": err})
khenaidoo297cd252019-02-07 22:10:23 -0500125 }
khenaidoob9203542018-09-17 22:56:37 -0400126 }
127 return nil
128}
129
khenaidoo297cd252019-02-07 22:10:23 -0500130// listDeviceIdsFromMap returns the list of device IDs that are in memory
khenaidoo7ccedd52018-12-14 16:48:54 -0500131func (dMgr *DeviceManager) listDeviceIdsFromMap() *voltha.IDs {
khenaidoo7ccedd52018-12-14 16:48:54 -0500132 result := &voltha.IDs{Items: make([]*voltha.ID, 0)}
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400133
134 dMgr.deviceAgents.Range(func(key, value interface{}) bool {
135 result.Items = append(result.Items, &voltha.ID{Id: key.(string)})
136 return true
137 })
138
khenaidoo7ccedd52018-12-14 16:48:54 -0500139 return result
140}
141
khenaidoob9203542018-09-17 22:56:37 -0400142func (dMgr *DeviceManager) createDevice(ctx context.Context, device *voltha.Device, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400143 log.Debugw("createDevice", log.Fields{"device": device, "aproxy": dMgr.adapterProxy})
khenaidoob9203542018-09-17 22:56:37 -0400144
khenaidoo5e677ae2019-02-28 17:26:29 -0500145 // Ensure this device is set as root
146 device.Root = true
khenaidoob9203542018-09-17 22:56:37 -0400147 // Create and start a device agent for that device
khenaidoo2c6a0992019-04-29 13:46:56 -0400148 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
khenaidoob9203542018-09-17 22:56:37 -0400149 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500150 agent.start(ctx, false)
khenaidoob9203542018-09-17 22:56:37 -0400151
khenaidoo92e62c52018-10-03 14:02:54 -0400152 sendResponse(ctx, ch, agent.lastData)
khenaidoob9203542018-09-17 22:56:37 -0400153}
154
155func (dMgr *DeviceManager) enableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400156 log.Debugw("enableDevice", log.Fields{"deviceid": id})
khenaidoob9203542018-09-17 22:56:37 -0400157 var res interface{}
158 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
159 res = agent.enableDevice(ctx)
160 log.Debugw("EnableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400161 }
162
163 sendResponse(ctx, ch, res)
164}
165
khenaidoo92e62c52018-10-03 14:02:54 -0400166func (dMgr *DeviceManager) disableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
167 log.Debugw("disableDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400168 var res interface{}
169 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
170 res = agent.disableDevice(ctx)
171 log.Debugw("disableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400172 } else {
khenaidoo92e62c52018-10-03 14:02:54 -0400173 res = status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoob9203542018-09-17 22:56:37 -0400174 }
khenaidoo92e62c52018-10-03 14:02:54 -0400175
176 sendResponse(ctx, ch, res)
177}
178
khenaidoo4d4802d2018-10-04 21:59:49 -0400179func (dMgr *DeviceManager) rebootDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
180 log.Debugw("rebootDevice", log.Fields{"deviceid": id})
181 var res interface{}
182 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
183 res = agent.rebootDevice(ctx)
184 log.Debugw("rebootDevice-result", log.Fields{"result": res})
185 } else {
186 res = status.Errorf(codes.NotFound, "%s", id.Id)
187 }
188 sendResponse(ctx, ch, res)
189}
190
191func (dMgr *DeviceManager) deleteDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
192 log.Debugw("deleteDevice", log.Fields{"deviceid": id})
193 var res interface{}
194 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
195 res = agent.deleteDevice(ctx)
khenaidoo4d4802d2018-10-04 21:59:49 -0400196 log.Debugw("deleteDevice-result", log.Fields{"result": res})
197 } else {
198 res = status.Errorf(codes.NotFound, "%s", id.Id)
199 }
200 sendResponse(ctx, ch, res)
201}
202
khenaidoo6d62c002019-05-15 21:57:03 -0400203// stopManagingDevice stops the management of the device as well as any of its reference device and logical device.
204// This function is called only in the Core that does not own this device. In the Core that owns this device then a
205// deletion deletion also includes removal of any reference of this device.
206func (dMgr *DeviceManager) stopManagingDevice(id string) {
207 log.Infow("stopManagingDevice", log.Fields{"deviceId": id})
208 if dMgr.IsDeviceInCache(id) { // Proceed only if an agent is present for this device
209 if root, _ := dMgr.IsRootDevice(id); root == true {
210 // stop managing the logical device
211 ldeviceId := dMgr.logicalDeviceMgr.stopManagingLogicalDeviceWithDeviceId(id)
212 if ldeviceId != "" { // Can happen if logical device agent was already stopped
213 dMgr.core.deviceOwnership.AbandonDevice(ldeviceId)
214 }
215 // stop managing the child devices
216 childDeviceIds := dMgr.getAllDeviceIdsWithDeviceParentId(id)
217 for _, cId := range childDeviceIds {
218 dMgr.stopManagingDevice(cId)
219 }
220 }
221 if agent := dMgr.getDeviceAgent(id); agent != nil {
222 agent.stop(nil)
223 dMgr.deleteDeviceAgentToMap(agent)
224 // Abandon the device ownership
225 dMgr.core.deviceOwnership.AbandonDevice(id)
226 }
227 }
228}
229
khenaidoo0a822f92019-05-08 15:15:57 -0400230func (dMgr *DeviceManager) RunPostDeviceDelete(cDevice *voltha.Device) error {
231 log.Infow("RunPostDeviceDelete", log.Fields{"deviceId": cDevice.Id})
khenaidoo6d62c002019-05-15 21:57:03 -0400232 dMgr.stopManagingDevice(cDevice.Id)
233 return nil
khenaidoo0a822f92019-05-08 15:15:57 -0400234}
235
khenaidoo297cd252019-02-07 22:10:23 -0500236// GetDevice will returns a device, either from memory or from the dB, if present
khenaidoo19d7b632018-10-30 10:49:50 -0400237func (dMgr *DeviceManager) GetDevice(id string) (*voltha.Device, error) {
238 log.Debugw("GetDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400239 if agent := dMgr.getDeviceAgent(id); agent != nil {
240 return agent.getDevice()
241 }
242 return nil, status.Errorf(codes.NotFound, "%s", id)
khenaidoob9203542018-09-17 22:56:37 -0400243}
244
Matt Jeanneret4e241952019-02-28 11:16:04 -0500245func (dMgr *DeviceManager) GetChildDevice(parentDeviceId string, serialNumber string, onuId int64, parentPortNo int64) (*voltha.Device, error) {
Matt Jeanneret0c5088c2019-04-22 16:16:19 -0400246 log.Debugw("GetChildDevice", log.Fields{"parentDeviceid": parentDeviceId, "serialNumber": serialNumber,
247 "parentPortNo": parentPortNo, "onuId": onuId})
Matt Jeanneret4e241952019-02-28 11:16:04 -0500248
249 var parentDevice *voltha.Device
250 var err error
251 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
252 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
253 }
254 var childDeviceIds []string
255 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
256 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
257 }
258 if len(childDeviceIds) == 0 {
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700259 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id, "serialNumber": serialNumber, "onuId": onuId})
Matt Jeanneret4e241952019-02-28 11:16:04 -0500260 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
261 }
262
263 var foundChildDevice *voltha.Device
264 for _, childDeviceId := range childDeviceIds {
265 found := false
266 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
267
268 foundOnuId := false
269 if searchDevice.ProxyAddress.OnuId == uint32(onuId) {
270 if searchDevice.ParentPortNo == uint32(parentPortNo) {
271 log.Debugw("found-child-by-onuid", log.Fields{"parentDeviceId": parentDevice.Id, "onuId": onuId})
272 foundOnuId = true
273 }
274 }
275
276 foundSerialNumber := false
277 if searchDevice.SerialNumber == serialNumber {
278 log.Debugw("found-child-by-serialnumber", log.Fields{"parentDeviceId": parentDevice.Id, "serialNumber": serialNumber})
279 foundSerialNumber = true
280 }
281
282 // if both onuId and serialNumber are provided both must be true for the device to be found
283 // otherwise whichever one found a match is good enough
284 if onuId > 0 && serialNumber != "" {
285 found = foundOnuId && foundSerialNumber
286 } else {
287 found = foundOnuId || foundSerialNumber
288 }
289
290 if found == true {
291 foundChildDevice = searchDevice
292 break
293 }
294 }
295 }
296
297 if foundChildDevice != nil {
298 log.Debugw("child-device-found", log.Fields{"parentDeviceId": parentDevice.Id, "foundChildDevice": foundChildDevice})
299 return foundChildDevice, nil
300 }
301
302 log.Warnw("child-device-not-found", log.Fields{"parentDeviceId": parentDevice.Id,
303 "serialNumber": serialNumber, "onuId": onuId, "parentPortNo": parentPortNo})
304 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
305}
306
Matt Jeanneret2a20aaa2019-03-05 21:04:02 -0500307func (dMgr *DeviceManager) GetChildDeviceWithProxyAddress(proxyAddress *voltha.Device_ProxyAddress) (*voltha.Device, error) {
308 log.Debugw("GetChildDeviceWithProxyAddress", log.Fields{"proxyAddress": proxyAddress})
309
310 var parentDevice *voltha.Device
311 var err error
312 if parentDevice, err = dMgr.GetDevice(proxyAddress.DeviceId); err != nil {
313 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
314 }
315 var childDeviceIds []string
316 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
317 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
318 }
319 if len(childDeviceIds) == 0 {
320 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id})
321 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
322 }
323
324 var foundChildDevice *voltha.Device
325 for _, childDeviceId := range childDeviceIds {
326 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
327 if searchDevice.ProxyAddress == proxyAddress {
328 foundChildDevice = searchDevice
329 break
330 }
331 }
332 }
333
334 if foundChildDevice != nil {
335 log.Debugw("child-device-found", log.Fields{"proxyAddress": proxyAddress})
336 return foundChildDevice, nil
337 }
338
339 log.Warnw("child-device-not-found", log.Fields{"proxyAddress": proxyAddress})
340 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
341}
342
khenaidoo297cd252019-02-07 22:10:23 -0500343func (dMgr *DeviceManager) IsDeviceInCache(id string) bool {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400344 _, exist := dMgr.deviceAgents.Load(id)
khenaidoo297cd252019-02-07 22:10:23 -0500345 return exist
346}
347
khenaidoo19d7b632018-10-30 10:49:50 -0400348func (dMgr *DeviceManager) IsRootDevice(id string) (bool, error) {
khenaidoo2c6a0992019-04-29 13:46:56 -0400349 dMgr.lockRootDeviceMap.RLock()
350 defer dMgr.lockRootDeviceMap.RUnlock()
351 if exist := dMgr.rootDevices[id]; exist {
352 return dMgr.rootDevices[id], nil
khenaidoo19d7b632018-10-30 10:49:50 -0400353 }
khenaidoo2c6a0992019-04-29 13:46:56 -0400354 return false, nil
khenaidoo19d7b632018-10-30 10:49:50 -0400355}
356
Stephane Barbarieaa467942019-02-06 14:09:44 -0500357// ListDevices retrieves the latest devices from the data model
khenaidoob9203542018-09-17 22:56:37 -0400358func (dMgr *DeviceManager) ListDevices() (*voltha.Devices, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400359 log.Debug("ListDevices")
khenaidoob9203542018-09-17 22:56:37 -0400360 result := &voltha.Devices{}
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400361 if devices := dMgr.clusterDataProxy.List(context.Background(), "/devices", 0, false, ""); devices != nil {
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500362 for _, device := range devices.([]interface{}) {
khenaidoo297cd252019-02-07 22:10:23 -0500363 // If device is not in memory then set it up
364 if !dMgr.IsDeviceInCache(device.(*voltha.Device).Id) {
khenaidoo6d62c002019-05-15 21:57:03 -0400365 log.Debugw("loading-device-from-Model", log.Fields{"id": device.(*voltha.Device).Id})
khenaidoo2c6a0992019-04-29 13:46:56 -0400366 agent := newDeviceAgent(dMgr.adapterProxy, device.(*voltha.Device), dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
khenaidoo297cd252019-02-07 22:10:23 -0500367 if err := agent.start(nil, true); err != nil {
368 log.Warnw("failure-starting-agent", log.Fields{"deviceId": device.(*voltha.Device).Id})
369 agent.stop(nil)
370 } else {
371 dMgr.addDeviceAgentToMap(agent)
372 }
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500373 }
374 result.Items = append(result.Items, device.(*voltha.Device))
khenaidoob9203542018-09-17 22:56:37 -0400375 }
376 }
khenaidoo6d62c002019-05-15 21:57:03 -0400377 log.Debugw("ListDevices-end", log.Fields{"len": len(result.Items)})
khenaidoob9203542018-09-17 22:56:37 -0400378 return result, nil
379}
380
khenaidoo6d62c002019-05-15 21:57:03 -0400381//getDeviceFromModelretrieves the device data from the model.
382func (dMgr *DeviceManager) getDeviceFromModel(deviceId string) (*voltha.Device, error) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400383 if device := dMgr.clusterDataProxy.Get(context.Background(), "/devices/"+deviceId, 0, false, ""); device != nil {
khenaidoo6d62c002019-05-15 21:57:03 -0400384 if d, ok := device.(*voltha.Device); ok {
385 return d, nil
386 }
387 }
388 return nil, status.Error(codes.NotFound, deviceId)
389}
390
khenaidoo297cd252019-02-07 22:10:23 -0500391// loadDevice loads the deviceId in memory, if not present
392func (dMgr *DeviceManager) loadDevice(deviceId string) (*DeviceAgent, error) {
393 log.Debugw("loading-device", log.Fields{"deviceId": deviceId})
394 // Sanity check
395 if deviceId == "" {
396 return nil, status.Error(codes.InvalidArgument, "deviceId empty")
397 }
398 if !dMgr.IsDeviceInCache(deviceId) {
khenaidoo6d62c002019-05-15 21:57:03 -0400399 // Proceed with the loading only if the device exist in the Model (could have been deleted)
400 if device, err := dMgr.getDeviceFromModel(deviceId); err == nil {
401 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
402 if err := agent.start(nil, true); err != nil {
403 agent.stop(nil)
404 return nil, err
405 }
406 dMgr.addDeviceAgentToMap(agent)
407 } else {
408 return nil, status.Error(codes.NotFound, deviceId)
khenaidoo297cd252019-02-07 22:10:23 -0500409 }
khenaidoo297cd252019-02-07 22:10:23 -0500410 }
411 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
412 return agent, nil
413 }
Matt Jeanneret4e241952019-02-28 11:16:04 -0500414 return nil, status.Error(codes.NotFound, deviceId) // This should not happen
khenaidoo297cd252019-02-07 22:10:23 -0500415}
416
417// loadRootDeviceParentAndChildren loads the children and parents of a root device in memory
418func (dMgr *DeviceManager) loadRootDeviceParentAndChildren(device *voltha.Device) error {
419 log.Debugw("loading-parent-and-children", log.Fields{"deviceId": device.Id})
420 if device.Root {
421 // Scenario A
422 if device.ParentId != "" {
423 // Load logical device if needed.
424 if err := dMgr.logicalDeviceMgr.load(device.ParentId); err != nil {
425 log.Warnw("failure-loading-logical-device", log.Fields{"lDeviceId": device.ParentId})
426 }
427 } else {
428 log.Debugw("no-parent-to-load", log.Fields{"deviceId": device.Id})
429 }
430 // Load all child devices, if needed
431 if childDeviceIds, err := dMgr.getAllChildDeviceIds(device); err == nil {
432 for _, childDeviceId := range childDeviceIds {
433 if _, err := dMgr.loadDevice(childDeviceId); err != nil {
434 log.Warnw("failure-loading-device", log.Fields{"deviceId": childDeviceId})
435 return err
436 }
437 }
438 log.Debugw("loaded-children", log.Fields{"deviceId": device.Id, "numChildren": len(childDeviceIds)})
439 } else {
440 log.Debugw("no-child-to-load", log.Fields{"deviceId": device.Id})
441 }
442 }
443 return nil
444}
445
446// load loads the deviceId in memory, if not present, and also loads its accompanying parents and children. Loading
447// in memory is for improved performance. It is not imperative that a device needs to be in memory when a request
448// acting on the device is received by the core. In such a scenario, the Core will load the device in memory first
449// and the proceed with the request.
450func (dMgr *DeviceManager) load(deviceId string) error {
451 log.Debug("load...")
452 // First load the device - this may fail in case the device was deleted intentionally by the other core
453 var dAgent *DeviceAgent
454 var err error
455 if dAgent, err = dMgr.loadDevice(deviceId); err != nil {
khenaidoo297cd252019-02-07 22:10:23 -0500456 return err
457 }
458 // Get the loaded device details
459 var device *voltha.Device
460 if device, err = dAgent.getDevice(); err != nil {
461 return err
462 }
463
464 // If the device is in Pre-provisioning or deleted state stop here
465 if device.AdminState == voltha.AdminState_PREPROVISIONED || device.AdminState == voltha.AdminState_DELETED {
466 return nil
467 }
468
469 // Now we face two scenarios
470 if device.Root {
471 // Load all children as well as the parent of this device (logical_device)
472 if err := dMgr.loadRootDeviceParentAndChildren(device); err != nil {
473 log.Warnw("failure-loading-device-parent-and-children", log.Fields{"deviceId": deviceId})
474 return err
475 }
476 log.Debugw("successfully-loaded-parent-and-children", log.Fields{"deviceId": deviceId})
477 } else {
478 // Scenario B - use the parentId of that device (root device) to trigger the loading
479 if device.ParentId != "" {
480 return dMgr.load(device.ParentId)
481 }
482 }
483 return nil
484}
485
khenaidoo7ccedd52018-12-14 16:48:54 -0500486// ListDeviceIds retrieves the latest device IDs information from the data model (memory data only)
487func (dMgr *DeviceManager) ListDeviceIds() (*voltha.IDs, error) {
488 log.Debug("ListDeviceIDs")
489 // Report only device IDs that are in the device agent map
490 return dMgr.listDeviceIdsFromMap(), nil
491}
492
493//ReconcileDevices is a request to a voltha core to managed a list of devices based on their IDs
494func (dMgr *DeviceManager) ReconcileDevices(ctx context.Context, ids *voltha.IDs, ch chan interface{}) {
495 log.Debug("ReconcileDevices")
496 var res interface{}
497 if ids != nil {
498 toReconcile := len(ids.Items)
499 reconciled := 0
500 for _, id := range ids.Items {
501 // Act on the device only if its not present in the agent map
khenaidoo297cd252019-02-07 22:10:23 -0500502 if !dMgr.IsDeviceInCache(id.Id) {
khenaidoo7ccedd52018-12-14 16:48:54 -0500503 // Device Id not in memory
504 log.Debugw("reconciling-device", log.Fields{"id": id.Id})
khenaidoo6d62c002019-05-15 21:57:03 -0400505 // Proceed with the loading only if the device exist in the Model (could have been deleted)
506 if device, err := dMgr.getDeviceFromModel(id.Id); err == nil {
507 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
508 if err := agent.start(nil, true); err != nil {
509 log.Warnw("failure-loading-device", log.Fields{"deviceId": id.Id})
510 agent.stop(nil)
511 } else {
512 dMgr.addDeviceAgentToMap(agent)
513 reconciled += 1
514 }
khenaidoo7ccedd52018-12-14 16:48:54 -0500515 } else {
khenaidoo297cd252019-02-07 22:10:23 -0500516 reconciled += 1
khenaidoo7ccedd52018-12-14 16:48:54 -0500517 }
khenaidoo7ccedd52018-12-14 16:48:54 -0500518 }
519 }
520 if toReconcile != reconciled {
521 res = status.Errorf(codes.DataLoss, "less-device-reconciled:%d/%d", reconciled, toReconcile)
522 }
523 } else {
524 res = status.Errorf(codes.InvalidArgument, "empty-list-of-ids")
525 }
526 sendResponse(ctx, ch, res)
527}
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500528
khenaidoob9203542018-09-17 22:56:37 -0400529func (dMgr *DeviceManager) updateDevice(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400530 log.Debugw("updateDevice", log.Fields{"deviceid": device.Id, "device": device})
khenaidoob9203542018-09-17 22:56:37 -0400531 if agent := dMgr.getDeviceAgent(device.Id); agent != nil {
532 return agent.updateDevice(device)
533 }
534 return status.Errorf(codes.NotFound, "%s", device.Id)
535}
536
537func (dMgr *DeviceManager) addPort(deviceId string, port *voltha.Port) error {
538 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400539 if err := agent.addPort(port); err != nil {
540 return err
541 }
542 // Setup peer ports
543 meAsPeer := &voltha.Port_PeerPort{DeviceId: deviceId, PortNo: port.PortNo}
544 for _, peerPort := range port.Peers {
545 if agent := dMgr.getDeviceAgent(peerPort.DeviceId); agent != nil {
546 if err := agent.addPeerPort(meAsPeer); err != nil {
547 log.Errorw("failed-to-add-peer", log.Fields{"peer-device-id": peerPort.DeviceId})
548 return err
549 }
550 }
551 }
khenaidoo2c6a0992019-04-29 13:46:56 -0400552 // Notify the logical device manager to setup a logical port, if needed. If the added port is an NNI or UNI
553 // then a logical port will be added to the logical device and the device graph generated. If the port is a
554 // PON port then only the device graph will be generated.
555 if device, err := dMgr.GetDevice(deviceId); err == nil {
556 go dMgr.logicalDeviceMgr.updateLogicalPort(device, port)
557 } else {
558 log.Errorw("failed-to-retrieve-device", log.Fields{"deviceId": deviceId})
559 return err
khenaidoofc1314d2019-03-14 09:34:21 -0400560 }
khenaidoo92e62c52018-10-03 14:02:54 -0400561 return nil
562 } else {
563 return status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoob9203542018-09-17 22:56:37 -0400564 }
khenaidoob9203542018-09-17 22:56:37 -0400565}
566
khenaidoo0a822f92019-05-08 15:15:57 -0400567func (dMgr *DeviceManager) deletePeerPorts(fromDeviceId string, deviceId string) error {
568 log.Debugw("deletePeerPorts", log.Fields{"fromDeviceId": fromDeviceId, "deviceid": deviceId})
569 if agent := dMgr.getDeviceAgent(fromDeviceId); agent != nil {
570 return agent.deletePeerPorts(deviceId)
571 }
572 return status.Errorf(codes.NotFound, "%s", deviceId)
573}
574
khenaidoo2c6a0992019-04-29 13:46:56 -0400575func (dMgr *DeviceManager) addFlowsAndGroups(deviceId string, flows []*ofp.OfpFlowStats, groups []*ofp.OfpGroupEntry) error {
576 log.Debugw("addFlowsAndGroups", log.Fields{"deviceid": deviceId})
khenaidoo19d7b632018-10-30 10:49:50 -0400577 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo2c6a0992019-04-29 13:46:56 -0400578 return agent.addFlowsAndGroups(flows, groups)
khenaidoo0458db62019-06-20 08:50:36 -0400579 }
580 return status.Errorf(codes.NotFound, "%s", deviceId)
581}
582
583func (dMgr *DeviceManager) deleteFlowsAndGroups(deviceId string, flows []*ofp.OfpFlowStats, groups []*ofp.OfpGroupEntry) error {
584 log.Debugw("deleteFlowsAndGroups", log.Fields{"deviceid": deviceId})
585 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
586 return agent.deleteFlowsAndGroups(flows, groups)
587 }
588 return status.Errorf(codes.NotFound, "%s", deviceId)
589}
590
591func (dMgr *DeviceManager) updateFlowsAndGroups(deviceId string, flows []*ofp.OfpFlowStats, groups []*ofp.OfpGroupEntry) error {
592 log.Debugw("updateFlowsAndGroups", log.Fields{"deviceid": deviceId})
593 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
594 return agent.updateFlowsAndGroups(flows, groups)
khenaidoo19d7b632018-10-30 10:49:50 -0400595 }
596 return status.Errorf(codes.NotFound, "%s", deviceId)
597}
598
khenaidoob9203542018-09-17 22:56:37 -0400599func (dMgr *DeviceManager) updatePmConfigs(deviceId string, pmConfigs *voltha.PmConfigs) error {
600 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
601 return agent.updatePmConfigs(pmConfigs)
602 }
603 return status.Errorf(codes.NotFound, "%s", deviceId)
604}
605
khenaidoo79232702018-12-04 11:00:41 -0500606func (dMgr *DeviceManager) getSwitchCapability(ctx context.Context, deviceId string) (*ic.SwitchCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400607 log.Debugw("getSwitchCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400608 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
609 return agent.getSwitchCapability(ctx)
610 }
611 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
612}
613
khenaidoo92e62c52018-10-03 14:02:54 -0400614func (dMgr *DeviceManager) getPorts(ctx context.Context, deviceId string, portType voltha.Port_PortType) (*voltha.Ports, error) {
615 log.Debugw("getPorts", log.Fields{"deviceid": deviceId, "portType": portType})
khenaidoob9203542018-09-17 22:56:37 -0400616 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400617 return agent.getPorts(ctx, portType), nil
khenaidoob9203542018-09-17 22:56:37 -0400618 }
619 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoo92e62c52018-10-03 14:02:54 -0400620
khenaidoob9203542018-09-17 22:56:37 -0400621}
622
khenaidoo79232702018-12-04 11:00:41 -0500623func (dMgr *DeviceManager) getPortCapability(ctx context.Context, deviceId string, portNo uint32) (*ic.PortCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400624 log.Debugw("getPortCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400625 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
626 return agent.getPortCapability(ctx, portNo)
627 }
628 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
629}
630
khenaidoo92e62c52018-10-03 14:02:54 -0400631func (dMgr *DeviceManager) updateDeviceStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
632 log.Debugw("updateDeviceStatus", log.Fields{"deviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400633 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400634 return agent.updateDeviceStatus(operStatus, connStatus)
635 }
636 return status.Errorf(codes.NotFound, "%s", deviceId)
637}
638
khenaidoo4d4802d2018-10-04 21:59:49 -0400639func (dMgr *DeviceManager) updateChildrenStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
640 log.Debugw("updateChildrenStatus", log.Fields{"parentDeviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
641 var parentDevice *voltha.Device
642 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400643 if parentDevice, err = dMgr.GetDevice(deviceId); err != nil {
khenaidoo4d4802d2018-10-04 21:59:49 -0400644 return status.Errorf(codes.Aborted, "%s", err.Error())
645 }
646 var childDeviceIds []string
647 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
648 return status.Errorf(codes.Aborted, "%s", err.Error())
649 }
650 if len(childDeviceIds) == 0 {
651 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
652 }
653 for _, childDeviceId := range childDeviceIds {
654 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
655 if err = agent.updateDeviceStatus(operStatus, connStatus); err != nil {
656 return status.Errorf(codes.Aborted, "childDevice:%s, error:%s", childDeviceId, err.Error())
657 }
658 }
659 }
660 return nil
661}
662
khenaidoo92e62c52018-10-03 14:02:54 -0400663func (dMgr *DeviceManager) updatePortState(deviceId string, portType voltha.Port_PortType, portNo uint32, operStatus voltha.OperStatus_OperStatus) error {
664 log.Debugw("updatePortState", log.Fields{"deviceid": deviceId, "portType": portType, "portNo": portNo, "operStatus": operStatus})
665 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
666 return agent.updatePortState(portType, portNo, operStatus)
khenaidoob9203542018-09-17 22:56:37 -0400667 }
668 return status.Errorf(codes.NotFound, "%s", deviceId)
669}
670
khenaidoo0a822f92019-05-08 15:15:57 -0400671func (dMgr *DeviceManager) deleteAllPorts(deviceId string) error {
672 log.Debugw("DeleteAllPorts", log.Fields{"deviceid": deviceId})
673 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
674 if err := agent.deleteAllPorts(); err != nil {
675 return err
676 }
677 // Notify the logical device manager to remove all logical ports, if needed.
678 // At this stage the device itself may gave been deleted already at a deleteAllPorts
679 // typically is part of a device deletion phase.
680 if device, err := dMgr.GetDevice(deviceId); err == nil {
681 go dMgr.logicalDeviceMgr.deleteAllLogicalPorts(device)
682 } else {
683 log.Warnw("failed-to-retrieve-device", log.Fields{"deviceId": deviceId})
684 return err
685 }
686 return nil
687 }
688 return status.Errorf(codes.NotFound, "%s", deviceId)
689}
690
khenaidoo3ab34882019-05-02 21:33:30 -0400691//updatePortsState updates all ports on the device
692func (dMgr *DeviceManager) updatePortsState(deviceId string, state voltha.OperStatus_OperStatus) error {
693 log.Debugw("updatePortsState", log.Fields{"deviceid": deviceId})
694
695 var adminState voltha.AdminState_AdminState
696 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
697 switch state {
698 case voltha.OperStatus_ACTIVE:
699 adminState = voltha.AdminState_ENABLED
700 if err := agent.enablePorts(); err != nil {
701 log.Warnw("enable-all-ports-failed", log.Fields{"deviceId": deviceId, "error": err})
702 return err
703 }
704 case voltha.OperStatus_UNKNOWN:
705 adminState = voltha.AdminState_DISABLED
706 if err := agent.disablePorts(); err != nil {
707 log.Warnw("disable-all-ports-failed", log.Fields{"deviceId": deviceId, "error": err})
708 return err
709 }
710 default:
711 return status.Error(codes.Unimplemented, "state-change-not-implemented")
712 }
713 // Notify the logical device about the state change
714 if device, err := dMgr.GetDevice(deviceId); err != nil {
715 log.Warnw("non-existent-device", log.Fields{"deviceId": deviceId, "error": err})
716 return err
717 } else {
718 if err := dMgr.logicalDeviceMgr.updatePortsState(device, adminState); err != nil {
719 log.Warnw("failed-updating-ports-state", log.Fields{"deviceId": deviceId, "error": err})
720 return err
721 }
722 return nil
723 }
724 }
725 return status.Errorf(codes.NotFound, "%s", deviceId)
726}
727
Matt Jeanneret4e241952019-02-28 11:16:04 -0500728func (dMgr *DeviceManager) childDeviceDetected(parentDeviceId string, parentPortNo int64, deviceType string,
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700729 channelId int64, vendorId string, serialNumber string, onuId int64) (*voltha.Device, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400730 log.Debugw("childDeviceDetected", log.Fields{"parentDeviceId": parentDeviceId})
khenaidoob9203542018-09-17 22:56:37 -0400731
732 // Create the ONU device
733 childDevice := &voltha.Device{}
khenaidoob9203542018-09-17 22:56:37 -0400734 childDevice.Type = deviceType
735 childDevice.ParentId = parentDeviceId
736 childDevice.ParentPortNo = uint32(parentPortNo)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500737 childDevice.VendorId = vendorId
738 childDevice.SerialNumber = serialNumber
khenaidoob9203542018-09-17 22:56:37 -0400739 childDevice.Root = false
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400740
741 //Get parent device type
742 parent, err := dMgr.GetDevice(parentDeviceId)
743 if err != nil {
khenaidoo43c82122018-11-22 18:38:28 -0500744 log.Error("no-parent-found", log.Fields{"parentId": parentDeviceId})
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700745 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400746 }
747
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700748 if device, err := dMgr.GetChildDevice(parentDeviceId, serialNumber, onuId, parentPortNo); err == nil {
Matt Jeanneret4e241952019-02-28 11:16:04 -0500749 log.Warnw("child-device-exists", log.Fields{"parentId": parentDeviceId, "serialNumber": serialNumber})
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700750 return device, status.Errorf(codes.AlreadyExists, "%s", serialNumber)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500751 }
752
753 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{DeviceId: parentDeviceId, DeviceType: parent.Type, ChannelId: uint32(channelId), OnuId: uint32(onuId)}
khenaidoob9203542018-09-17 22:56:37 -0400754
755 // Create and start a device agent for that device
khenaidoo2c6a0992019-04-29 13:46:56 -0400756 agent := newDeviceAgent(dMgr.adapterProxy, childDevice, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
khenaidoob9203542018-09-17 22:56:37 -0400757 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500758 agent.start(nil, false)
khenaidoob9203542018-09-17 22:56:37 -0400759
760 // Activate the child device
khenaidoo92e62c52018-10-03 14:02:54 -0400761 if agent := dMgr.getDeviceAgent(agent.deviceId); agent != nil {
khenaidoo79232702018-12-04 11:00:41 -0500762 go agent.enableDevice(nil)
khenaidoob9203542018-09-17 22:56:37 -0400763 }
764
khenaidoo79232702018-12-04 11:00:41 -0500765 // Publish on the messaging bus that we have discovered new devices
khenaidoo19374072018-12-11 11:05:15 -0500766 go dMgr.kafkaICProxy.DeviceDiscovered(agent.deviceId, deviceType, parentDeviceId, dMgr.coreInstanceId)
khenaidoo79232702018-12-04 11:00:41 -0500767
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700768 return agent.lastData, nil
khenaidoob9203542018-09-17 22:56:37 -0400769}
770
771func (dMgr *DeviceManager) processTransition(previous *voltha.Device, current *voltha.Device) error {
772 // This will be triggered on every update to the device.
khenaidoo92e62c52018-10-03 14:02:54 -0400773 handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
774 if handlers == nil {
khenaidoo43c82122018-11-22 18:38:28 -0500775 log.Debugw("no-op-transition", log.Fields{"deviceId": current.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400776 return nil
khenaidoob9203542018-09-17 22:56:37 -0400777 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400778 log.Debugw("handler-found", log.Fields{"num-handlers": len(handlers), "isParent": current.Root, "current-data": current})
khenaidoo92e62c52018-10-03 14:02:54 -0400779 for _, handler := range handlers {
780 log.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
781 if err := handler(current); err != nil {
khenaidoo6d62c002019-05-15 21:57:03 -0400782 log.Warnw("handler-failed", log.Fields{"handler": funcName(handler), "error": err})
khenaidoo92e62c52018-10-03 14:02:54 -0400783 return err
784 }
785 }
khenaidoob9203542018-09-17 22:56:37 -0400786 return nil
787}
788
khenaidoofdbad6e2018-11-06 22:26:38 -0500789func (dMgr *DeviceManager) packetOut(deviceId string, outPort uint32, packet *ofp.OfpPacketOut) error {
790 log.Debugw("packetOut", log.Fields{"deviceId": deviceId, "outPort": outPort})
791 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
792 return agent.packetOut(outPort, packet)
793 }
794 return status.Errorf(codes.NotFound, "%s", deviceId)
795}
796
khenaidoo297cd252019-02-07 22:10:23 -0500797func (dMgr *DeviceManager) PacketIn(deviceId string, port uint32, transactionId string, packet []byte) error {
khenaidoofdbad6e2018-11-06 22:26:38 -0500798 log.Debugw("PacketIn", log.Fields{"deviceId": deviceId, "port": port})
799 // Get the logical device Id based on the deviceId
800 var device *voltha.Device
801 var err error
802 if device, err = dMgr.GetDevice(deviceId); err != nil {
803 log.Errorw("device-not-found", log.Fields{"deviceId": deviceId})
804 return err
805 }
khenaidoo43c82122018-11-22 18:38:28 -0500806 if !device.Root {
khenaidoofdbad6e2018-11-06 22:26:38 -0500807 log.Errorw("device-not-root", log.Fields{"deviceId": deviceId})
808 return status.Errorf(codes.FailedPrecondition, "%s", deviceId)
809 }
810
khenaidoo297cd252019-02-07 22:10:23 -0500811 if err := dMgr.logicalDeviceMgr.packetIn(device.ParentId, port, transactionId, packet); err != nil {
khenaidoofdbad6e2018-11-06 22:26:38 -0500812 return err
813 }
814 return nil
815}
816
khenaidoo0a822f92019-05-08 15:15:57 -0400817func (dMgr *DeviceManager) CreateLogicalDevice(cDevice *voltha.Device) error {
818 log.Info("CreateLogicalDevice")
khenaidoo59ef7be2019-06-21 12:40:28 -0400819 // Verify whether the logical device has already been created
820 if cDevice.ParentId != "" {
821 log.Debugw("Parent device already exist.", log.Fields{"deviceId": cDevice.Id, "logicalDeviceId": cDevice.Id})
822 return nil
823 }
khenaidoob9203542018-09-17 22:56:37 -0400824 var logicalId *string
825 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400826 if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400827 log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
828 return err
829 }
830 // Update the parent device with the logical id
831 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
832 return nil
833}
834
khenaidoo0a822f92019-05-08 15:15:57 -0400835func (dMgr *DeviceManager) DeleteLogicalDevice(cDevice *voltha.Device) error {
836 log.Info("DeleteLogicalDevice")
khenaidoo92e62c52018-10-03 14:02:54 -0400837 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400838 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400839 log.Warnw("deleteLogical-device-error", log.Fields{"deviceId": cDevice.Id})
840 return err
841 }
842 // Remove the logical device Id from the parent device
843 logicalId := ""
844 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", logicalId)
845 return nil
846}
847
khenaidoo0a822f92019-05-08 15:15:57 -0400848func (dMgr *DeviceManager) DeleteLogicalPort(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400849 log.Info("deleteLogicalPort")
850 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400851 // Get the logical port associated with this device
852 var lPortId *voltha.LogicalPortId
853 if lPortId, err = dMgr.logicalDeviceMgr.getLogicalPortId(device); err != nil {
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400854 log.Warnw("getLogical-port-error", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo19d7b632018-10-30 10:49:50 -0400855 return err
856 }
857 if err = dMgr.logicalDeviceMgr.deleteLogicalPort(nil, lPortId); err != nil {
858 log.Warnw("deleteLogical-port-error", log.Fields{"deviceId": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400859 return err
860 }
khenaidoo92e62c52018-10-03 14:02:54 -0400861 return nil
862}
863
khenaidoo0a822f92019-05-08 15:15:57 -0400864func (dMgr *DeviceManager) DeleteLogicalPorts(device *voltha.Device) error {
865 log.Info("deleteLogicalPorts")
866 if err := dMgr.logicalDeviceMgr.deleteLogicalPorts(device.Id); err != nil {
867 log.Warnw("deleteLogical-ports-error", log.Fields{"deviceId": device.Id})
868 return err
869 }
870 return nil
871}
872
khenaidoo59ef7be2019-06-21 12:40:28 -0400873func (dMgr *DeviceManager) MarkChildDevicesAsUnReachable(device *voltha.Device) error {
874 log.Info("MarkChildDevicesAsUnReachable")
875 // Set the connection status to unreachable
876 connStatus := voltha.ConnectStatus_UNREACHABLE
877 // Do not set the operational status. Setting it to -1 will do the trick
878 operStatus := voltha.OperStatus_OperStatus(-1)
879 if err := dMgr.updateChildrenStatus(device.Id, operStatus, connStatus); err != nil {
880 log.Warnw("deleteLogical-ports-error", log.Fields{"deviceId": device.Id})
881 return err
882 }
883 return nil
884}
885
khenaidoo92e62c52018-10-03 14:02:54 -0400886func (dMgr *DeviceManager) getParentDevice(childDevice *voltha.Device) *voltha.Device {
887 // Sanity check
888 if childDevice.Root {
889 // childDevice is the parent device
890 return childDevice
891 }
khenaidoo19d7b632018-10-30 10:49:50 -0400892 parentDevice, _ := dMgr.GetDevice(childDevice.ParentId)
khenaidoo92e62c52018-10-03 14:02:54 -0400893 return parentDevice
894}
895
khenaidoo0a822f92019-05-08 15:15:57 -0400896//childDevicesLost is invoked by an adapter to indicate that a parent device is in a state (Disabled) where it
897//cannot manage the child devices. This will trigger the Core to disable all the child devices.
898func (dMgr *DeviceManager) childDevicesLost(parentDeviceId string) error {
899 log.Debug("childDevicesLost")
900 var err error
901 var parentDevice *voltha.Device
902 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
903 log.Warnw("failed-getting-device", log.Fields{"deviceId": parentDeviceId, "error": err})
904 return err
905 }
906 return dMgr.DisableAllChildDevices(parentDevice)
907}
908
909//childDevicesDetected is invoked by an adapter when child devices are found, typically after after a
910// disable/enable sequence. This will trigger the Core to Enable all the child devices of that parent.
911func (dMgr *DeviceManager) childDevicesDetected(parentDeviceId string) error {
912 log.Debug("childDevicesDetected")
913 var err error
914 var parentDevice *voltha.Device
915 var childDeviceIds []string
916
917 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
918 log.Warnw("failed-getting-device", log.Fields{"deviceId": parentDeviceId, "error": err})
919 return err
920 }
921
922 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
923 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
924 }
925 if len(childDeviceIds) == 0 {
926 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
927 }
khenaidoo59ef7be2019-06-21 12:40:28 -0400928 allChildEnableRequestSent := true
khenaidoo0a822f92019-05-08 15:15:57 -0400929 for _, childDeviceId := range childDeviceIds {
930 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
khenaidoo59ef7be2019-06-21 12:40:28 -0400931 // Run the children re-registration in its own routine
932 go agent.enableDevice(nil)
933 } else {
934 err = status.Errorf(codes.Unavailable, "no agent for child device %s", childDeviceId)
935 log.Errorw("no-child-device-agent", log.Fields{"parentDeviceId": parentDevice.Id, "childId": childDeviceId})
936 allChildEnableRequestSent = false
khenaidoo0a822f92019-05-08 15:15:57 -0400937 }
938 }
khenaidoo59ef7be2019-06-21 12:40:28 -0400939 if !allChildEnableRequestSent {
khenaidoo0a822f92019-05-08 15:15:57 -0400940 return err
941 }
942 return nil
943}
944
khenaidoo4d4802d2018-10-04 21:59:49 -0400945/*
946All the functions below are callback functions where they are invoked with the latest and previous data. We can
947therefore use the data as is without trying to get the latest from the model.
948*/
949
khenaidoo0a822f92019-05-08 15:15:57 -0400950//DisableAllChildDevices is invoked as a callback when the parent device is disabled
951func (dMgr *DeviceManager) DisableAllChildDevices(parentDevice *voltha.Device) error {
952 log.Debug("DisableAllChildDevices")
khenaidoo92e62c52018-10-03 14:02:54 -0400953 var childDeviceIds []string
954 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400955 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
956 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400957 }
958 if len(childDeviceIds) == 0 {
khenaidoo4d4802d2018-10-04 21:59:49 -0400959 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400960 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400961 allChildDisable := true
khenaidoo92e62c52018-10-03 14:02:54 -0400962 for _, childDeviceId := range childDeviceIds {
963 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
964 if err = agent.disableDevice(nil); err != nil {
965 log.Errorw("failure-disable-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
khenaidoo4d4802d2018-10-04 21:59:49 -0400966 allChildDisable = false
khenaidoo92e62c52018-10-03 14:02:54 -0400967 }
968 }
969 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400970 if !allChildDisable {
971 return err
972 }
khenaidoo92e62c52018-10-03 14:02:54 -0400973 return nil
974}
975
khenaidoo0a822f92019-05-08 15:15:57 -0400976//DeleteAllChildDevices is invoked as a callback when the parent device is deleted
977func (dMgr *DeviceManager) DeleteAllChildDevices(parentDevice *voltha.Device) error {
978 log.Debug("DeleteAllChildDevices")
khenaidoo4d4802d2018-10-04 21:59:49 -0400979 var childDeviceIds []string
khenaidoo92e62c52018-10-03 14:02:54 -0400980 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400981 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
982 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400983 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400984 if len(childDeviceIds) == 0 {
985 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
986 }
987 allChildDeleted := true
988 for _, childDeviceId := range childDeviceIds {
989 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
990 if err = agent.deleteDevice(nil); err != nil {
991 log.Errorw("failure-delete-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
992 allChildDeleted = false
993 } else {
994 agent.stop(nil)
995 dMgr.deleteDeviceAgentToMap(agent)
996 }
997 }
998 }
999 if !allChildDeleted {
1000 return err
1001 }
1002 return nil
1003}
1004
khenaidoo6d62c002019-05-15 21:57:03 -04001005//getAllDeviceIdsWithDeviceParentId returns the list of device Ids which has id as parent Id. This function uses the
1006// data from the agent instead of using the data from the parent device as that data would disappear from a parent
1007// device during a delete device operation.
1008func (dMgr *DeviceManager) getAllDeviceIdsWithDeviceParentId(id string) []string {
1009 log.Debugw("getAllAgentsWithDeviceParentId", log.Fields{"parentDeviceId": id})
1010 deviceIds := make([]string, 0)
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001011 dMgr.deviceAgents.Range(func(key, value interface{}) bool {
1012 agent := value.(*DeviceAgent)
khenaidoo6d62c002019-05-15 21:57:03 -04001013 if agent.parentId == id {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001014 deviceIds = append(deviceIds, key.(string))
khenaidoo6d62c002019-05-15 21:57:03 -04001015 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001016 return true
1017 })
khenaidoo6d62c002019-05-15 21:57:03 -04001018 return deviceIds
1019}
1020
khenaidoo4d4802d2018-10-04 21:59:49 -04001021//getAllChildDeviceIds is a helper method to get all the child device IDs from the device passed as parameter
1022func (dMgr *DeviceManager) getAllChildDeviceIds(parentDevice *voltha.Device) ([]string, error) {
1023 log.Debugw("getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -04001024 childDeviceIds := make([]string, 0)
khenaidoo4d4802d2018-10-04 21:59:49 -04001025 if parentDevice != nil {
1026 for _, port := range parentDevice.Ports {
1027 for _, peer := range port.Peers {
1028 childDeviceIds = append(childDeviceIds, peer.DeviceId)
1029 }
khenaidoo92e62c52018-10-03 14:02:54 -04001030 }
khenaidoo2c6a0992019-04-29 13:46:56 -04001031 log.Debugw("returning-getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id, "childDeviceIds": childDeviceIds})
khenaidoo92e62c52018-10-03 14:02:54 -04001032 }
1033 return childDeviceIds, nil
1034}
1035
khenaidoo297cd252019-02-07 22:10:23 -05001036//getAllChildDevices is a helper method to get all the child device IDs from the device passed as parameter
1037func (dMgr *DeviceManager) getAllChildDevices(parentDeviceId string) (*voltha.Devices, error) {
1038 log.Debugw("getAllChildDevices", log.Fields{"parentDeviceId": parentDeviceId})
1039 if parentDevice, err := dMgr.GetDevice(parentDeviceId); err == nil {
1040 childDevices := make([]*voltha.Device, 0)
1041 if childDeviceIds, er := dMgr.getAllChildDeviceIds(parentDevice); er == nil {
1042 for _, deviceId := range childDeviceIds {
1043 if d, e := dMgr.GetDevice(deviceId); e == nil && d != nil {
1044 childDevices = append(childDevices, d)
1045 }
1046 }
1047 }
1048 return &voltha.Devices{Items: childDevices}, nil
1049 }
1050 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
1051}
1052
khenaidoo0a822f92019-05-08 15:15:57 -04001053func (dMgr *DeviceManager) SetupUNILogicalPorts(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001054 log.Info("addUNILogicalPort")
khenaidoofc1314d2019-03-14 09:34:21 -04001055 if err := dMgr.logicalDeviceMgr.setupUNILogicalPorts(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -04001056 log.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
1057 return err
1058 }
1059 return nil
1060}
1061
khenaidoof5a5bfa2019-01-23 22:20:29 -05001062func (dMgr *DeviceManager) downloadImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1063 log.Debugw("downloadImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1064 var res interface{}
1065 var err error
1066 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1067 if res, err = agent.downloadImage(ctx, img); err != nil {
1068 log.Debugw("downloadImage-failed", log.Fields{"err": err, "imageName": img.Name})
1069 res = err
1070 }
1071 } else {
1072 res = status.Errorf(codes.NotFound, "%s", img.Id)
1073 }
1074 sendResponse(ctx, ch, res)
1075}
1076
1077func (dMgr *DeviceManager) cancelImageDownload(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1078 log.Debugw("cancelImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1079 var res interface{}
1080 var err error
1081 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1082 if res, err = agent.cancelImageDownload(ctx, img); err != nil {
1083 log.Debugw("cancelImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
1084 res = err
1085 }
1086 } else {
1087 res = status.Errorf(codes.NotFound, "%s", img.Id)
1088 }
1089 sendResponse(ctx, ch, res)
1090}
1091
1092func (dMgr *DeviceManager) activateImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1093 log.Debugw("activateImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1094 var res interface{}
1095 var err error
1096 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1097 if res, err = agent.activateImage(ctx, img); err != nil {
1098 log.Debugw("activateImage-failed", log.Fields{"err": err, "imageName": img.Name})
1099 res = err
1100 }
1101 } else {
1102 res = status.Errorf(codes.NotFound, "%s", img.Id)
1103 }
1104 sendResponse(ctx, ch, res)
1105}
1106
1107func (dMgr *DeviceManager) revertImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1108 log.Debugw("revertImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1109 var res interface{}
1110 var err error
1111 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1112 if res, err = agent.revertImage(ctx, img); err != nil {
1113 log.Debugw("revertImage-failed", log.Fields{"err": err, "imageName": img.Name})
1114 res = err
1115 }
1116 } else {
1117 res = status.Errorf(codes.NotFound, "%s", img.Id)
1118 }
1119 sendResponse(ctx, ch, res)
1120}
1121
1122func (dMgr *DeviceManager) getImageDownloadStatus(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1123 log.Debugw("getImageDownloadStatus", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1124 var res interface{}
1125 var err error
1126 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1127 if res, err = agent.getImageDownloadStatus(ctx, img); err != nil {
1128 log.Debugw("getImageDownloadStatus-failed", log.Fields{"err": err, "imageName": img.Name})
1129 res = err
1130 }
1131 } else {
1132 res = status.Errorf(codes.NotFound, "%s", img.Id)
1133 }
1134 sendResponse(ctx, ch, res)
1135}
1136
khenaidoof5a5bfa2019-01-23 22:20:29 -05001137func (dMgr *DeviceManager) updateImageDownload(deviceId string, img *voltha.ImageDownload) error {
1138 log.Debugw("updateImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1139 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
1140 if err := agent.updateImageDownload(img); err != nil {
1141 log.Debugw("updateImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
1142 return err
1143 }
1144 } else {
1145 return status.Errorf(codes.NotFound, "%s", img.Id)
1146 }
1147 return nil
1148}
1149
1150func (dMgr *DeviceManager) getImageDownload(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
1151 log.Debugw("getImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1152 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1153 return agent.getImageDownload(ctx, img)
1154 }
1155 return nil, status.Errorf(codes.NotFound, "%s", img.Id)
1156}
1157
1158func (dMgr *DeviceManager) listImageDownloads(ctx context.Context, deviceId string) (*voltha.ImageDownloads, error) {
1159 log.Debugw("listImageDownloads", log.Fields{"deviceId": deviceId})
1160 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
1161 return agent.listImageDownloads(ctx, deviceId)
1162 }
1163 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
1164}
1165
khenaidoo0a822f92019-05-08 15:15:57 -04001166func (dMgr *DeviceManager) SetAdminStateToEnable(cDevice *voltha.Device) error {
1167 log.Info("SetAdminStateToEnable")
1168 if agent := dMgr.getDeviceAgent(cDevice.Id); agent != nil {
1169 return agent.updateAdminState(voltha.AdminState_ENABLED)
1170 }
1171 return status.Errorf(codes.NotFound, "%s", cDevice.Id)
1172}
1173
khenaidoo92e62c52018-10-03 14:02:54 -04001174func (dMgr *DeviceManager) activateDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001175 log.Info("activateDevice")
1176 return nil
1177}
1178
khenaidoo92e62c52018-10-03 14:02:54 -04001179func (dMgr *DeviceManager) disableDeviceHandler(cDevice *voltha.Device) error {
1180 log.Info("disableDevice-donothing")
khenaidoob9203542018-09-17 22:56:37 -04001181 return nil
1182}
1183
khenaidoo92e62c52018-10-03 14:02:54 -04001184func (dMgr *DeviceManager) abandonDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001185 log.Info("abandonDevice")
1186 return nil
1187}
1188
khenaidoo92e62c52018-10-03 14:02:54 -04001189func (dMgr *DeviceManager) reEnableDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001190 log.Info("reEnableDevice")
1191 return nil
1192}
1193
khenaidoo92e62c52018-10-03 14:02:54 -04001194func (dMgr *DeviceManager) noOp(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001195 log.Info("noOp")
1196 return nil
1197}
1198
khenaidoo92e62c52018-10-03 14:02:54 -04001199func (dMgr *DeviceManager) notAllowed(pcDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001200 log.Info("notAllowed")
khenaidoo2c6a0992019-04-29 13:46:56 -04001201 return errors.New("transition-not-allowed")
khenaidoob9203542018-09-17 22:56:37 -04001202}
1203
khenaidoo0a822f92019-05-08 15:15:57 -04001204func (dMgr *DeviceManager) NotifyInvalidTransition(pcDevice *voltha.Device) error {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001205 log.Errorw("NotifyInvalidTransition", log.Fields{
1206 "device": pcDevice.Id,
1207 "adminState": pcDevice.AdminState,
1208 "operState": pcDevice.OperStatus,
1209 "connState": pcDevice.ConnectStatus,
1210 })
khenaidoo0a822f92019-05-08 15:15:57 -04001211 //TODO: notify over kafka?
1212 return nil
1213}
1214
khenaidoob9203542018-09-17 22:56:37 -04001215func funcName(f interface{}) string {
1216 p := reflect.ValueOf(f).Pointer()
1217 rf := runtime.FuncForPC(p)
1218 return rf.Name()
1219}
1220
1221func (dMgr *DeviceManager) UpdateDeviceAttribute(deviceId string, attribute string, value interface{}) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001222 if agent, ok := dMgr.deviceAgents.Load(deviceId); ok {
1223 agent.(*DeviceAgent).updateDeviceAttribute(attribute, value)
khenaidoob9203542018-09-17 22:56:37 -04001224 }
1225}
1226
1227func (dMgr *DeviceManager) GetParentDeviceId(deviceId string) *string {
khenaidoo19d7b632018-10-30 10:49:50 -04001228 if device, _ := dMgr.GetDevice(deviceId); device != nil {
khenaidoo92e62c52018-10-03 14:02:54 -04001229 log.Infow("GetParentDeviceId", log.Fields{"deviceId": device.Id, "parentId": device.ParentId})
khenaidoob9203542018-09-17 22:56:37 -04001230 return &device.ParentId
1231 }
1232 return nil
1233}
serkant.uluderya334479d2019-04-10 08:26:15 -07001234
1235func (dMgr *DeviceManager) simulateAlarm(ctx context.Context, simulatereq *voltha.SimulateAlarmRequest, ch chan interface{}) {
1236 log.Debugw("simulateAlarm", log.Fields{"id": simulatereq.Id, "Indicator": simulatereq.Indicator, "IntfId": simulatereq.IntfId,
1237 "PortTypeName": simulatereq.PortTypeName, "OnuDeviceId": simulatereq.OnuDeviceId, "InverseBitErrorRate": simulatereq.InverseBitErrorRate,
1238 "Drift": simulatereq.Drift, "NewEqd": simulatereq.NewEqd, "OnuSerialNumber": simulatereq.OnuSerialNumber, "Operation": simulatereq.Operation})
1239 var res interface{}
1240 if agent := dMgr.getDeviceAgent(simulatereq.Id); agent != nil {
1241 res = agent.simulateAlarm(ctx, simulatereq)
1242 log.Debugw("SimulateAlarm-result", log.Fields{"result": res})
1243 }
1244 //TODO CLI always get successful response
1245 sendResponse(ctx, ch, res)
1246}