blob: f64210754a68fa1447267a953a53bdabf1fd3096 [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"
khenaidoo79232702018-12-04 11:00:41 -050024 ic "github.com/opencord/voltha-go/protos/inter_container"
khenaidoo19d7b632018-10-30 10:49:50 -040025 ofp "github.com/opencord/voltha-go/protos/openflow_13"
khenaidoob9203542018-09-17 22:56:37 -040026 "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
khenaidoo297cd252019-02-07 22:10:23 -050037 adapterMgr *AdapterManager
khenaidoob9203542018-09-17 22:56:37 -040038 logicalDeviceMgr *LogicalDeviceManager
khenaidoo43c82122018-11-22 18:38:28 -050039 kafkaICProxy *kafka.InterContainerProxy
khenaidoob9203542018-09-17 22:56:37 -040040 stateTransitions *TransitionMap
khenaidoo9a468962018-09-19 15:33:13 -040041 clusterDataProxy *model.Proxy
khenaidood2b6df92018-12-13 16:37:20 -050042 coreInstanceId string
khenaidoob9203542018-09-17 22:56:37 -040043 exitChannel chan int
44 lockDeviceAgentsMap sync.RWMutex
45}
46
khenaidoo21d51152019-02-01 13:48:37 -050047func newDeviceManager(kafkaICProxy *kafka.InterContainerProxy, cdProxy *model.Proxy, adapterMgr *AdapterManager, coreInstanceId string) *DeviceManager {
khenaidoob9203542018-09-17 22:56:37 -040048 var deviceMgr DeviceManager
49 deviceMgr.exitChannel = make(chan int, 1)
50 deviceMgr.deviceAgents = make(map[string]*DeviceAgent)
khenaidoo43c82122018-11-22 18:38:28 -050051 deviceMgr.adapterProxy = NewAdapterProxy(kafkaICProxy)
52 deviceMgr.kafkaICProxy = kafkaICProxy
khenaidoo19374072018-12-11 11:05:15 -050053 deviceMgr.coreInstanceId = coreInstanceId
khenaidoo9a468962018-09-19 15:33:13 -040054 deviceMgr.clusterDataProxy = cdProxy
khenaidoo297cd252019-02-07 22:10:23 -050055 deviceMgr.adapterMgr = adapterMgr
khenaidoob9203542018-09-17 22:56:37 -040056 deviceMgr.lockDeviceAgentsMap = sync.RWMutex{}
57 return &deviceMgr
58}
59
khenaidoo4d4802d2018-10-04 21:59:49 -040060func (dMgr *DeviceManager) start(ctx context.Context, logicalDeviceMgr *LogicalDeviceManager) {
khenaidoob9203542018-09-17 22:56:37 -040061 log.Info("starting-device-manager")
62 dMgr.logicalDeviceMgr = logicalDeviceMgr
63 dMgr.stateTransitions = NewTransitionMap(dMgr)
64 log.Info("device-manager-started")
65}
66
khenaidoo4d4802d2018-10-04 21:59:49 -040067func (dMgr *DeviceManager) stop(ctx context.Context) {
khenaidoob9203542018-09-17 22:56:37 -040068 log.Info("stopping-device-manager")
69 dMgr.exitChannel <- 1
70 log.Info("device-manager-stopped")
71}
72
73func sendResponse(ctx context.Context, ch chan interface{}, result interface{}) {
74 if ctx.Err() == nil {
75 // Returned response only of the ctx has not been cancelled/timeout/etc
76 // Channel is automatically closed when a context is Done
77 ch <- result
78 log.Debugw("sendResponse", log.Fields{"result": result})
79 } else {
80 // Should the transaction be reverted back?
81 log.Debugw("sendResponse-context-error", log.Fields{"context-error": ctx.Err()})
82 }
83}
84
85func (dMgr *DeviceManager) addDeviceAgentToMap(agent *DeviceAgent) {
86 dMgr.lockDeviceAgentsMap.Lock()
87 defer dMgr.lockDeviceAgentsMap.Unlock()
88 if _, exist := dMgr.deviceAgents[agent.deviceId]; !exist {
89 dMgr.deviceAgents[agent.deviceId] = agent
90 }
91}
92
khenaidoo4d4802d2018-10-04 21:59:49 -040093func (dMgr *DeviceManager) deleteDeviceAgentToMap(agent *DeviceAgent) {
94 dMgr.lockDeviceAgentsMap.Lock()
95 defer dMgr.lockDeviceAgentsMap.Unlock()
96 delete(dMgr.deviceAgents, agent.deviceId)
97}
98
khenaidoo297cd252019-02-07 22:10:23 -050099// 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 -0400100func (dMgr *DeviceManager) getDeviceAgent(deviceId string) *DeviceAgent {
101 dMgr.lockDeviceAgentsMap.Lock()
khenaidoob9203542018-09-17 22:56:37 -0400102 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
khenaidoo297cd252019-02-07 22:10:23 -0500103 dMgr.lockDeviceAgentsMap.Unlock()
khenaidoob9203542018-09-17 22:56:37 -0400104 return agent
khenaidoo297cd252019-02-07 22:10:23 -0500105 } else {
106 // Try to load into memory - loading will also create the device agent
107 dMgr.lockDeviceAgentsMap.Unlock()
108 if err := dMgr.load(deviceId); err == nil {
109 dMgr.lockDeviceAgentsMap.Lock()
110 defer dMgr.lockDeviceAgentsMap.Unlock()
111 if agent, ok = dMgr.deviceAgents[deviceId]; ok {
112 return agent
113 }
114 }
khenaidoob9203542018-09-17 22:56:37 -0400115 }
116 return nil
117}
118
khenaidoo297cd252019-02-07 22:10:23 -0500119// listDeviceIdsFromMap returns the list of device IDs that are in memory
khenaidoo7ccedd52018-12-14 16:48:54 -0500120func (dMgr *DeviceManager) listDeviceIdsFromMap() *voltha.IDs {
121 dMgr.lockDeviceAgentsMap.Lock()
122 defer dMgr.lockDeviceAgentsMap.Unlock()
123 result := &voltha.IDs{Items: make([]*voltha.ID, 0)}
124 for key, _ := range dMgr.deviceAgents {
125 result.Items = append(result.Items, &voltha.ID{Id: key})
126 }
127 return result
128}
129
khenaidoob9203542018-09-17 22:56:37 -0400130func (dMgr *DeviceManager) createDevice(ctx context.Context, device *voltha.Device, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400131 log.Debugw("createDevice", log.Fields{"device": device, "aproxy": dMgr.adapterProxy})
khenaidoob9203542018-09-17 22:56:37 -0400132
khenaidoo5e677ae2019-02-28 17:26:29 -0500133 // Ensure this device is set as root
134 device.Root = true
khenaidoob9203542018-09-17 22:56:37 -0400135 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400136 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400137 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500138 agent.start(ctx, false)
khenaidoob9203542018-09-17 22:56:37 -0400139
khenaidoo92e62c52018-10-03 14:02:54 -0400140 sendResponse(ctx, ch, agent.lastData)
khenaidoob9203542018-09-17 22:56:37 -0400141}
142
143func (dMgr *DeviceManager) enableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400144 log.Debugw("enableDevice", log.Fields{"deviceid": id})
khenaidoob9203542018-09-17 22:56:37 -0400145 var res interface{}
146 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
147 res = agent.enableDevice(ctx)
148 log.Debugw("EnableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400149 }
150
151 sendResponse(ctx, ch, res)
152}
153
khenaidoo92e62c52018-10-03 14:02:54 -0400154func (dMgr *DeviceManager) disableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
155 log.Debugw("disableDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400156 var res interface{}
157 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
158 res = agent.disableDevice(ctx)
159 log.Debugw("disableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400160 } else {
khenaidoo92e62c52018-10-03 14:02:54 -0400161 res = status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoob9203542018-09-17 22:56:37 -0400162 }
khenaidoo92e62c52018-10-03 14:02:54 -0400163
164 sendResponse(ctx, ch, res)
165}
166
khenaidoo4d4802d2018-10-04 21:59:49 -0400167func (dMgr *DeviceManager) rebootDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
168 log.Debugw("rebootDevice", log.Fields{"deviceid": id})
169 var res interface{}
170 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
171 res = agent.rebootDevice(ctx)
172 log.Debugw("rebootDevice-result", log.Fields{"result": res})
173 } else {
174 res = status.Errorf(codes.NotFound, "%s", id.Id)
175 }
176 sendResponse(ctx, ch, res)
177}
178
179func (dMgr *DeviceManager) deleteDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
180 log.Debugw("deleteDevice", log.Fields{"deviceid": id})
181 var res interface{}
182 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
183 res = agent.deleteDevice(ctx)
184 if res == nil { //Success
185 agent.stop(ctx)
186 dMgr.deleteDeviceAgentToMap(agent)
187 }
188 log.Debugw("deleteDevice-result", log.Fields{"result": res})
189 } else {
190 res = status.Errorf(codes.NotFound, "%s", id.Id)
191 }
192 sendResponse(ctx, ch, res)
193}
194
khenaidoo297cd252019-02-07 22:10:23 -0500195// GetDevice will returns a device, either from memory or from the dB, if present
khenaidoo19d7b632018-10-30 10:49:50 -0400196func (dMgr *DeviceManager) GetDevice(id string) (*voltha.Device, error) {
197 log.Debugw("GetDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400198 if agent := dMgr.getDeviceAgent(id); agent != nil {
199 return agent.getDevice()
200 }
201 return nil, status.Errorf(codes.NotFound, "%s", id)
khenaidoob9203542018-09-17 22:56:37 -0400202}
203
Matt Jeanneret4e241952019-02-28 11:16:04 -0500204func (dMgr *DeviceManager) GetChildDevice(parentDeviceId string, serialNumber string, onuId int64, parentPortNo int64) (*voltha.Device, error) {
205 log.Debugw("GetChildDevice", log.Fields{"parentDeviceid": parentDeviceId, "serialNumber": serialNumber})
206
207 var parentDevice *voltha.Device
208 var err error
209 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
210 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
211 }
212 var childDeviceIds []string
213 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
214 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
215 }
216 if len(childDeviceIds) == 0 {
217 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id})
218 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
219 }
220
221 var foundChildDevice *voltha.Device
222 for _, childDeviceId := range childDeviceIds {
223 found := false
224 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
225
226 foundOnuId := false
227 if searchDevice.ProxyAddress.OnuId == uint32(onuId) {
228 if searchDevice.ParentPortNo == uint32(parentPortNo) {
229 log.Debugw("found-child-by-onuid", log.Fields{"parentDeviceId": parentDevice.Id, "onuId": onuId})
230 foundOnuId = true
231 }
232 }
233
234 foundSerialNumber := false
235 if searchDevice.SerialNumber == serialNumber {
236 log.Debugw("found-child-by-serialnumber", log.Fields{"parentDeviceId": parentDevice.Id, "serialNumber": serialNumber})
237 foundSerialNumber = true
238 }
239
240 // if both onuId and serialNumber are provided both must be true for the device to be found
241 // otherwise whichever one found a match is good enough
242 if onuId > 0 && serialNumber != "" {
243 found = foundOnuId && foundSerialNumber
244 } else {
245 found = foundOnuId || foundSerialNumber
246 }
247
248 if found == true {
249 foundChildDevice = searchDevice
250 break
251 }
252 }
253 }
254
255 if foundChildDevice != nil {
256 log.Debugw("child-device-found", log.Fields{"parentDeviceId": parentDevice.Id, "foundChildDevice": foundChildDevice})
257 return foundChildDevice, nil
258 }
259
260 log.Warnw("child-device-not-found", log.Fields{"parentDeviceId": parentDevice.Id,
261 "serialNumber": serialNumber, "onuId": onuId, "parentPortNo": parentPortNo})
262 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
263}
264
Matt Jeanneret2a20aaa2019-03-05 21:04:02 -0500265func (dMgr *DeviceManager) GetChildDeviceWithProxyAddress(proxyAddress *voltha.Device_ProxyAddress) (*voltha.Device, error) {
266 log.Debugw("GetChildDeviceWithProxyAddress", log.Fields{"proxyAddress": proxyAddress})
267
268 var parentDevice *voltha.Device
269 var err error
270 if parentDevice, err = dMgr.GetDevice(proxyAddress.DeviceId); err != nil {
271 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
272 }
273 var childDeviceIds []string
274 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
275 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
276 }
277 if len(childDeviceIds) == 0 {
278 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id})
279 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
280 }
281
282 var foundChildDevice *voltha.Device
283 for _, childDeviceId := range childDeviceIds {
284 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
285 if searchDevice.ProxyAddress == proxyAddress {
286 foundChildDevice = searchDevice
287 break
288 }
289 }
290 }
291
292 if foundChildDevice != nil {
293 log.Debugw("child-device-found", log.Fields{"proxyAddress": proxyAddress})
294 return foundChildDevice, nil
295 }
296
297 log.Warnw("child-device-not-found", log.Fields{"proxyAddress": proxyAddress})
298 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
299}
300
khenaidoo297cd252019-02-07 22:10:23 -0500301func (dMgr *DeviceManager) IsDeviceInCache(id string) bool {
302 dMgr.lockDeviceAgentsMap.Lock()
303 defer dMgr.lockDeviceAgentsMap.Unlock()
304 _, exist := dMgr.deviceAgents[id]
305 return exist
306}
307
khenaidoo19d7b632018-10-30 10:49:50 -0400308func (dMgr *DeviceManager) IsRootDevice(id string) (bool, error) {
309 device, err := dMgr.GetDevice(id)
310 if err != nil {
311 return false, err
312 }
313 return device.Root, nil
314}
315
Stephane Barbarieaa467942019-02-06 14:09:44 -0500316// ListDevices retrieves the latest devices from the data model
khenaidoob9203542018-09-17 22:56:37 -0400317func (dMgr *DeviceManager) ListDevices() (*voltha.Devices, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400318 log.Debug("ListDevices")
khenaidoob9203542018-09-17 22:56:37 -0400319 result := &voltha.Devices{}
Stephane Barbarieaa467942019-02-06 14:09:44 -0500320 if devices := dMgr.clusterDataProxy.List("/devices", 0, false, ""); devices != nil {
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500321 for _, device := range devices.([]interface{}) {
khenaidoo297cd252019-02-07 22:10:23 -0500322 // If device is not in memory then set it up
323 if !dMgr.IsDeviceInCache(device.(*voltha.Device).Id) {
324 agent := newDeviceAgent(dMgr.adapterProxy, device.(*voltha.Device), dMgr, dMgr.clusterDataProxy)
325 if err := agent.start(nil, true); err != nil {
326 log.Warnw("failure-starting-agent", log.Fields{"deviceId": device.(*voltha.Device).Id})
327 agent.stop(nil)
328 } else {
329 dMgr.addDeviceAgentToMap(agent)
330 }
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500331 }
332 result.Items = append(result.Items, device.(*voltha.Device))
khenaidoob9203542018-09-17 22:56:37 -0400333 }
334 }
335 return result, nil
336}
337
khenaidoo297cd252019-02-07 22:10:23 -0500338// loadDevice loads the deviceId in memory, if not present
339func (dMgr *DeviceManager) loadDevice(deviceId string) (*DeviceAgent, error) {
340 log.Debugw("loading-device", log.Fields{"deviceId": deviceId})
341 // Sanity check
342 if deviceId == "" {
343 return nil, status.Error(codes.InvalidArgument, "deviceId empty")
344 }
345 if !dMgr.IsDeviceInCache(deviceId) {
346 agent := newDeviceAgent(dMgr.adapterProxy, &voltha.Device{Id: deviceId}, dMgr, dMgr.clusterDataProxy)
347 if err := agent.start(nil, true); err != nil {
348 agent.stop(nil)
349 return nil, err
350 }
351 dMgr.addDeviceAgentToMap(agent)
352 }
353 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
354 return agent, nil
355 }
Matt Jeanneret4e241952019-02-28 11:16:04 -0500356 return nil, status.Error(codes.NotFound, deviceId) // This should not happen
khenaidoo297cd252019-02-07 22:10:23 -0500357}
358
359// loadRootDeviceParentAndChildren loads the children and parents of a root device in memory
360func (dMgr *DeviceManager) loadRootDeviceParentAndChildren(device *voltha.Device) error {
361 log.Debugw("loading-parent-and-children", log.Fields{"deviceId": device.Id})
362 if device.Root {
363 // Scenario A
364 if device.ParentId != "" {
365 // Load logical device if needed.
366 if err := dMgr.logicalDeviceMgr.load(device.ParentId); err != nil {
367 log.Warnw("failure-loading-logical-device", log.Fields{"lDeviceId": device.ParentId})
368 }
369 } else {
370 log.Debugw("no-parent-to-load", log.Fields{"deviceId": device.Id})
371 }
372 // Load all child devices, if needed
373 if childDeviceIds, err := dMgr.getAllChildDeviceIds(device); err == nil {
374 for _, childDeviceId := range childDeviceIds {
375 if _, err := dMgr.loadDevice(childDeviceId); err != nil {
376 log.Warnw("failure-loading-device", log.Fields{"deviceId": childDeviceId})
377 return err
378 }
379 }
380 log.Debugw("loaded-children", log.Fields{"deviceId": device.Id, "numChildren": len(childDeviceIds)})
381 } else {
382 log.Debugw("no-child-to-load", log.Fields{"deviceId": device.Id})
383 }
384 }
385 return nil
386}
387
388// load loads the deviceId in memory, if not present, and also loads its accompanying parents and children. Loading
389// in memory is for improved performance. It is not imperative that a device needs to be in memory when a request
390// acting on the device is received by the core. In such a scenario, the Core will load the device in memory first
391// and the proceed with the request.
392func (dMgr *DeviceManager) load(deviceId string) error {
393 log.Debug("load...")
394 // First load the device - this may fail in case the device was deleted intentionally by the other core
395 var dAgent *DeviceAgent
396 var err error
397 if dAgent, err = dMgr.loadDevice(deviceId); err != nil {
398 log.Warnw("failure-loading-device", log.Fields{"deviceId": deviceId})
399 return err
400 }
401 // Get the loaded device details
402 var device *voltha.Device
403 if device, err = dAgent.getDevice(); err != nil {
404 return err
405 }
406
407 // If the device is in Pre-provisioning or deleted state stop here
408 if device.AdminState == voltha.AdminState_PREPROVISIONED || device.AdminState == voltha.AdminState_DELETED {
409 return nil
410 }
411
412 // Now we face two scenarios
413 if device.Root {
414 // Load all children as well as the parent of this device (logical_device)
415 if err := dMgr.loadRootDeviceParentAndChildren(device); err != nil {
416 log.Warnw("failure-loading-device-parent-and-children", log.Fields{"deviceId": deviceId})
417 return err
418 }
419 log.Debugw("successfully-loaded-parent-and-children", log.Fields{"deviceId": deviceId})
420 } else {
421 // Scenario B - use the parentId of that device (root device) to trigger the loading
422 if device.ParentId != "" {
423 return dMgr.load(device.ParentId)
424 }
425 }
426 return nil
427}
428
khenaidoo7ccedd52018-12-14 16:48:54 -0500429// ListDeviceIds retrieves the latest device IDs information from the data model (memory data only)
430func (dMgr *DeviceManager) ListDeviceIds() (*voltha.IDs, error) {
431 log.Debug("ListDeviceIDs")
432 // Report only device IDs that are in the device agent map
433 return dMgr.listDeviceIdsFromMap(), nil
434}
435
436//ReconcileDevices is a request to a voltha core to managed a list of devices based on their IDs
437func (dMgr *DeviceManager) ReconcileDevices(ctx context.Context, ids *voltha.IDs, ch chan interface{}) {
438 log.Debug("ReconcileDevices")
439 var res interface{}
440 if ids != nil {
441 toReconcile := len(ids.Items)
442 reconciled := 0
443 for _, id := range ids.Items {
444 // Act on the device only if its not present in the agent map
khenaidoo297cd252019-02-07 22:10:23 -0500445 if !dMgr.IsDeviceInCache(id.Id) {
khenaidoo7ccedd52018-12-14 16:48:54 -0500446 // Device Id not in memory
447 log.Debugw("reconciling-device", log.Fields{"id": id.Id})
khenaidoo297cd252019-02-07 22:10:23 -0500448 // Load device from dB
Matt Jeanneret4e241952019-02-28 11:16:04 -0500449 agent := newDeviceAgent(dMgr.adapterProxy, &voltha.Device{Id: id.Id}, dMgr, dMgr.clusterDataProxy)
khenaidoo297cd252019-02-07 22:10:23 -0500450 if err := agent.start(nil, true); err != nil {
451 log.Warnw("failure-loading-device", log.Fields{"deviceId": id.Id})
452 agent.stop(nil)
khenaidoo7ccedd52018-12-14 16:48:54 -0500453 } else {
khenaidoo297cd252019-02-07 22:10:23 -0500454 dMgr.addDeviceAgentToMap(agent)
455 reconciled += 1
khenaidoo7ccedd52018-12-14 16:48:54 -0500456 }
457 } else {
458 reconciled += 1
459 }
460 }
461 if toReconcile != reconciled {
462 res = status.Errorf(codes.DataLoss, "less-device-reconciled:%d/%d", reconciled, toReconcile)
463 }
464 } else {
465 res = status.Errorf(codes.InvalidArgument, "empty-list-of-ids")
466 }
467 sendResponse(ctx, ch, res)
468}
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500469
khenaidoob9203542018-09-17 22:56:37 -0400470func (dMgr *DeviceManager) updateDevice(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400471 log.Debugw("updateDevice", log.Fields{"deviceid": device.Id, "device": device})
khenaidoob9203542018-09-17 22:56:37 -0400472 if agent := dMgr.getDeviceAgent(device.Id); agent != nil {
473 return agent.updateDevice(device)
474 }
475 return status.Errorf(codes.NotFound, "%s", device.Id)
476}
477
478func (dMgr *DeviceManager) addPort(deviceId string, port *voltha.Port) error {
479 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400480 if err := agent.addPort(port); err != nil {
481 return err
482 }
483 // Setup peer ports
484 meAsPeer := &voltha.Port_PeerPort{DeviceId: deviceId, PortNo: port.PortNo}
485 for _, peerPort := range port.Peers {
486 if agent := dMgr.getDeviceAgent(peerPort.DeviceId); agent != nil {
487 if err := agent.addPeerPort(meAsPeer); err != nil {
488 log.Errorw("failed-to-add-peer", log.Fields{"peer-device-id": peerPort.DeviceId})
489 return err
490 }
491 }
492 }
493 return nil
494 } else {
495 return status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoob9203542018-09-17 22:56:37 -0400496 }
khenaidoob9203542018-09-17 22:56:37 -0400497}
498
khenaidoo19d7b632018-10-30 10:49:50 -0400499func (dMgr *DeviceManager) updateFlows(deviceId string, flows []*ofp.OfpFlowStats) error {
500 log.Debugw("updateFlows", log.Fields{"deviceid": deviceId})
501 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
502 return agent.updateFlows(flows)
503 }
504 return status.Errorf(codes.NotFound, "%s", deviceId)
505}
506
507func (dMgr *DeviceManager) updateGroups(deviceId string, groups []*ofp.OfpGroupEntry) error {
508 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
509 return agent.updateGroups(groups)
510 }
511 return status.Errorf(codes.NotFound, "%s", deviceId)
512}
513
khenaidoob9203542018-09-17 22:56:37 -0400514func (dMgr *DeviceManager) updatePmConfigs(deviceId string, pmConfigs *voltha.PmConfigs) error {
515 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
516 return agent.updatePmConfigs(pmConfigs)
517 }
518 return status.Errorf(codes.NotFound, "%s", deviceId)
519}
520
khenaidoo79232702018-12-04 11:00:41 -0500521func (dMgr *DeviceManager) getSwitchCapability(ctx context.Context, deviceId string) (*ic.SwitchCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400522 log.Debugw("getSwitchCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400523 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
524 return agent.getSwitchCapability(ctx)
525 }
526 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
527}
528
khenaidoo92e62c52018-10-03 14:02:54 -0400529func (dMgr *DeviceManager) getPorts(ctx context.Context, deviceId string, portType voltha.Port_PortType) (*voltha.Ports, error) {
530 log.Debugw("getPorts", log.Fields{"deviceid": deviceId, "portType": portType})
khenaidoob9203542018-09-17 22:56:37 -0400531 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400532 return agent.getPorts(ctx, portType), nil
khenaidoob9203542018-09-17 22:56:37 -0400533 }
534 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoo92e62c52018-10-03 14:02:54 -0400535
khenaidoob9203542018-09-17 22:56:37 -0400536}
537
khenaidoo79232702018-12-04 11:00:41 -0500538func (dMgr *DeviceManager) getPortCapability(ctx context.Context, deviceId string, portNo uint32) (*ic.PortCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400539 log.Debugw("getPortCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400540 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
541 return agent.getPortCapability(ctx, portNo)
542 }
543 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
544}
545
khenaidoo92e62c52018-10-03 14:02:54 -0400546func (dMgr *DeviceManager) updateDeviceStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
547 log.Debugw("updateDeviceStatus", log.Fields{"deviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400548 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400549 return agent.updateDeviceStatus(operStatus, connStatus)
550 }
551 return status.Errorf(codes.NotFound, "%s", deviceId)
552}
553
khenaidoo4d4802d2018-10-04 21:59:49 -0400554func (dMgr *DeviceManager) updateChildrenStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
555 log.Debugw("updateChildrenStatus", log.Fields{"parentDeviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
556 var parentDevice *voltha.Device
557 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400558 if parentDevice, err = dMgr.GetDevice(deviceId); err != nil {
khenaidoo4d4802d2018-10-04 21:59:49 -0400559 return status.Errorf(codes.Aborted, "%s", err.Error())
560 }
561 var childDeviceIds []string
562 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
563 return status.Errorf(codes.Aborted, "%s", err.Error())
564 }
565 if len(childDeviceIds) == 0 {
566 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
567 }
568 for _, childDeviceId := range childDeviceIds {
569 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
570 if err = agent.updateDeviceStatus(operStatus, connStatus); err != nil {
571 return status.Errorf(codes.Aborted, "childDevice:%s, error:%s", childDeviceId, err.Error())
572 }
573 }
574 }
575 return nil
576}
577
khenaidoo92e62c52018-10-03 14:02:54 -0400578func (dMgr *DeviceManager) updatePortState(deviceId string, portType voltha.Port_PortType, portNo uint32, operStatus voltha.OperStatus_OperStatus) error {
579 log.Debugw("updatePortState", log.Fields{"deviceid": deviceId, "portType": portType, "portNo": portNo, "operStatus": operStatus})
580 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
581 return agent.updatePortState(portType, portNo, operStatus)
khenaidoob9203542018-09-17 22:56:37 -0400582 }
583 return status.Errorf(codes.NotFound, "%s", deviceId)
584}
585
Matt Jeanneret4e241952019-02-28 11:16:04 -0500586func (dMgr *DeviceManager) childDeviceDetected(parentDeviceId string, parentPortNo int64, deviceType string,
587 channelId int64, vendorId string, serialNumber string, onuId int64) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400588 log.Debugw("childDeviceDetected", log.Fields{"parentDeviceId": parentDeviceId})
khenaidoob9203542018-09-17 22:56:37 -0400589
590 // Create the ONU device
591 childDevice := &voltha.Device{}
khenaidoob9203542018-09-17 22:56:37 -0400592 childDevice.Type = deviceType
593 childDevice.ParentId = parentDeviceId
594 childDevice.ParentPortNo = uint32(parentPortNo)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500595 childDevice.VendorId = vendorId
596 childDevice.SerialNumber = serialNumber
khenaidoob9203542018-09-17 22:56:37 -0400597 childDevice.Root = false
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400598
599 //Get parent device type
600 parent, err := dMgr.GetDevice(parentDeviceId)
601 if err != nil {
khenaidoo43c82122018-11-22 18:38:28 -0500602 log.Error("no-parent-found", log.Fields{"parentId": parentDeviceId})
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400603 return status.Errorf(codes.NotFound, "%s", parentDeviceId)
604 }
605
Matt Jeanneret4e241952019-02-28 11:16:04 -0500606 if _, err := dMgr.GetChildDevice(parentDeviceId, serialNumber, onuId, parentPortNo); err == nil {
607 log.Warnw("child-device-exists", log.Fields{"parentId": parentDeviceId, "serialNumber": serialNumber})
608 return status.Errorf(codes.AlreadyExists, "%s", serialNumber)
609 }
610
611 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{DeviceId: parentDeviceId, DeviceType: parent.Type, ChannelId: uint32(channelId), OnuId: uint32(onuId)}
khenaidoob9203542018-09-17 22:56:37 -0400612
613 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400614 agent := newDeviceAgent(dMgr.adapterProxy, childDevice, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400615 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500616 agent.start(nil, false)
khenaidoob9203542018-09-17 22:56:37 -0400617
618 // Activate the child device
khenaidoo92e62c52018-10-03 14:02:54 -0400619 if agent := dMgr.getDeviceAgent(agent.deviceId); agent != nil {
khenaidoo79232702018-12-04 11:00:41 -0500620 go agent.enableDevice(nil)
khenaidoob9203542018-09-17 22:56:37 -0400621 }
622
khenaidoo79232702018-12-04 11:00:41 -0500623 // Publish on the messaging bus that we have discovered new devices
khenaidoo19374072018-12-11 11:05:15 -0500624 go dMgr.kafkaICProxy.DeviceDiscovered(agent.deviceId, deviceType, parentDeviceId, dMgr.coreInstanceId)
khenaidoo79232702018-12-04 11:00:41 -0500625
khenaidoob9203542018-09-17 22:56:37 -0400626 return nil
627}
628
629func (dMgr *DeviceManager) processTransition(previous *voltha.Device, current *voltha.Device) error {
630 // This will be triggered on every update to the device.
khenaidoo92e62c52018-10-03 14:02:54 -0400631 handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
632 if handlers == nil {
khenaidoo43c82122018-11-22 18:38:28 -0500633 log.Debugw("no-op-transition", log.Fields{"deviceId": current.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400634 return nil
khenaidoob9203542018-09-17 22:56:37 -0400635 }
khenaidoo92e62c52018-10-03 14:02:54 -0400636 for _, handler := range handlers {
637 log.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
638 if err := handler(current); err != nil {
639 return err
640 }
641 }
khenaidoob9203542018-09-17 22:56:37 -0400642 return nil
643}
644
khenaidoofdbad6e2018-11-06 22:26:38 -0500645func (dMgr *DeviceManager) packetOut(deviceId string, outPort uint32, packet *ofp.OfpPacketOut) error {
646 log.Debugw("packetOut", log.Fields{"deviceId": deviceId, "outPort": outPort})
647 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
648 return agent.packetOut(outPort, packet)
649 }
650 return status.Errorf(codes.NotFound, "%s", deviceId)
651}
652
khenaidoo297cd252019-02-07 22:10:23 -0500653func (dMgr *DeviceManager) PacketIn(deviceId string, port uint32, transactionId string, packet []byte) error {
khenaidoofdbad6e2018-11-06 22:26:38 -0500654 log.Debugw("PacketIn", log.Fields{"deviceId": deviceId, "port": port})
655 // Get the logical device Id based on the deviceId
656 var device *voltha.Device
657 var err error
658 if device, err = dMgr.GetDevice(deviceId); err != nil {
659 log.Errorw("device-not-found", log.Fields{"deviceId": deviceId})
660 return err
661 }
khenaidoo43c82122018-11-22 18:38:28 -0500662 if !device.Root {
khenaidoofdbad6e2018-11-06 22:26:38 -0500663 log.Errorw("device-not-root", log.Fields{"deviceId": deviceId})
664 return status.Errorf(codes.FailedPrecondition, "%s", deviceId)
665 }
666
khenaidoo297cd252019-02-07 22:10:23 -0500667 if err := dMgr.logicalDeviceMgr.packetIn(device.ParentId, port, transactionId, packet); err != nil {
khenaidoofdbad6e2018-11-06 22:26:38 -0500668 return err
669 }
670 return nil
671}
672
khenaidoo92e62c52018-10-03 14:02:54 -0400673func (dMgr *DeviceManager) createLogicalDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400674 log.Info("createLogicalDevice")
675 var logicalId *string
676 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400677 if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400678 log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
679 return err
680 }
681 // Update the parent device with the logical id
682 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
683 return nil
684}
685
khenaidoo92e62c52018-10-03 14:02:54 -0400686func (dMgr *DeviceManager) deleteLogicalDevice(cDevice *voltha.Device) error {
687 log.Info("deleteLogicalDevice")
688 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400689 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400690 log.Warnw("deleteLogical-device-error", log.Fields{"deviceId": cDevice.Id})
691 return err
692 }
693 // Remove the logical device Id from the parent device
694 logicalId := ""
695 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", logicalId)
696 return nil
697}
698
khenaidoo19d7b632018-10-30 10:49:50 -0400699func (dMgr *DeviceManager) deleteLogicalPort(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400700 log.Info("deleteLogicalPort")
701 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400702 // Get the logical port associated with this device
703 var lPortId *voltha.LogicalPortId
704 if lPortId, err = dMgr.logicalDeviceMgr.getLogicalPortId(device); err != nil {
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400705 log.Warnw("getLogical-port-error", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo19d7b632018-10-30 10:49:50 -0400706 return err
707 }
708 if err = dMgr.logicalDeviceMgr.deleteLogicalPort(nil, lPortId); err != nil {
709 log.Warnw("deleteLogical-port-error", log.Fields{"deviceId": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400710 return err
711 }
khenaidoo92e62c52018-10-03 14:02:54 -0400712 return nil
713}
714
715func (dMgr *DeviceManager) getParentDevice(childDevice *voltha.Device) *voltha.Device {
716 // Sanity check
717 if childDevice.Root {
718 // childDevice is the parent device
719 return childDevice
720 }
khenaidoo19d7b632018-10-30 10:49:50 -0400721 parentDevice, _ := dMgr.GetDevice(childDevice.ParentId)
khenaidoo92e62c52018-10-03 14:02:54 -0400722 return parentDevice
723}
724
khenaidoo4d4802d2018-10-04 21:59:49 -0400725/*
726All the functions below are callback functions where they are invoked with the latest and previous data. We can
727therefore use the data as is without trying to get the latest from the model.
728*/
729
730//disableAllChildDevices is invoked as a callback when the parent device is disabled
731func (dMgr *DeviceManager) disableAllChildDevices(parentDevice *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400732 log.Debug("disableAllChildDevices")
733 var childDeviceIds []string
734 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400735 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
736 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400737 }
738 if len(childDeviceIds) == 0 {
khenaidoo4d4802d2018-10-04 21:59:49 -0400739 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400740 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400741 allChildDisable := true
khenaidoo92e62c52018-10-03 14:02:54 -0400742 for _, childDeviceId := range childDeviceIds {
743 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
744 if err = agent.disableDevice(nil); err != nil {
745 log.Errorw("failure-disable-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
khenaidoo4d4802d2018-10-04 21:59:49 -0400746 allChildDisable = false
khenaidoo92e62c52018-10-03 14:02:54 -0400747 }
748 }
749 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400750 if !allChildDisable {
751 return err
752 }
khenaidoo92e62c52018-10-03 14:02:54 -0400753 return nil
754}
755
khenaidoo4d4802d2018-10-04 21:59:49 -0400756//deleteAllChildDevices is invoked as a callback when the parent device is deleted
757func (dMgr *DeviceManager) deleteAllChildDevices(parentDevice *voltha.Device) error {
758 log.Debug("deleteAllChildDevices")
759 var childDeviceIds []string
khenaidoo92e62c52018-10-03 14:02:54 -0400760 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400761 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
762 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400763 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400764 if len(childDeviceIds) == 0 {
765 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
766 }
767 allChildDeleted := true
768 for _, childDeviceId := range childDeviceIds {
769 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
770 if err = agent.deleteDevice(nil); err != nil {
771 log.Errorw("failure-delete-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
772 allChildDeleted = false
773 } else {
774 agent.stop(nil)
775 dMgr.deleteDeviceAgentToMap(agent)
776 }
777 }
778 }
779 if !allChildDeleted {
780 return err
781 }
782 return nil
783}
784
785//getAllChildDeviceIds is a helper method to get all the child device IDs from the device passed as parameter
786func (dMgr *DeviceManager) getAllChildDeviceIds(parentDevice *voltha.Device) ([]string, error) {
787 log.Debugw("getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400788 childDeviceIds := make([]string, 0)
khenaidoo4d4802d2018-10-04 21:59:49 -0400789 if parentDevice != nil {
790 for _, port := range parentDevice.Ports {
791 for _, peer := range port.Peers {
792 childDeviceIds = append(childDeviceIds, peer.DeviceId)
793 }
khenaidoo92e62c52018-10-03 14:02:54 -0400794 }
795 }
Matt Jeanneret4e241952019-02-28 11:16:04 -0500796 log.Debugw("returning-getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id, "childDeviceIds": childDeviceIds})
khenaidoo92e62c52018-10-03 14:02:54 -0400797 return childDeviceIds, nil
798}
799
khenaidoo297cd252019-02-07 22:10:23 -0500800//getAllChildDevices is a helper method to get all the child device IDs from the device passed as parameter
801func (dMgr *DeviceManager) getAllChildDevices(parentDeviceId string) (*voltha.Devices, error) {
802 log.Debugw("getAllChildDevices", log.Fields{"parentDeviceId": parentDeviceId})
803 if parentDevice, err := dMgr.GetDevice(parentDeviceId); err == nil {
804 childDevices := make([]*voltha.Device, 0)
805 if childDeviceIds, er := dMgr.getAllChildDeviceIds(parentDevice); er == nil {
806 for _, deviceId := range childDeviceIds {
807 if d, e := dMgr.GetDevice(deviceId); e == nil && d != nil {
808 childDevices = append(childDevices, d)
809 }
810 }
811 }
812 return &voltha.Devices{Items: childDevices}, nil
813 }
814 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
815}
816
khenaidoo92e62c52018-10-03 14:02:54 -0400817func (dMgr *DeviceManager) addUNILogicalPort(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400818 log.Info("addUNILogicalPort")
khenaidoo4d4802d2018-10-04 21:59:49 -0400819 if err := dMgr.logicalDeviceMgr.addUNILogicalPort(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400820 log.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
821 return err
822 }
823 return nil
824}
825
khenaidoof5a5bfa2019-01-23 22:20:29 -0500826func (dMgr *DeviceManager) downloadImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
827 log.Debugw("downloadImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
828 var res interface{}
829 var err error
830 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
831 if res, err = agent.downloadImage(ctx, img); err != nil {
832 log.Debugw("downloadImage-failed", log.Fields{"err": err, "imageName": img.Name})
833 res = err
834 }
835 } else {
836 res = status.Errorf(codes.NotFound, "%s", img.Id)
837 }
838 sendResponse(ctx, ch, res)
839}
840
841func (dMgr *DeviceManager) cancelImageDownload(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
842 log.Debugw("cancelImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
843 var res interface{}
844 var err error
845 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
846 if res, err = agent.cancelImageDownload(ctx, img); err != nil {
847 log.Debugw("cancelImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
848 res = err
849 }
850 } else {
851 res = status.Errorf(codes.NotFound, "%s", img.Id)
852 }
853 sendResponse(ctx, ch, res)
854}
855
856func (dMgr *DeviceManager) activateImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
857 log.Debugw("activateImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
858 var res interface{}
859 var err error
860 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
861 if res, err = agent.activateImage(ctx, img); err != nil {
862 log.Debugw("activateImage-failed", log.Fields{"err": err, "imageName": img.Name})
863 res = err
864 }
865 } else {
866 res = status.Errorf(codes.NotFound, "%s", img.Id)
867 }
868 sendResponse(ctx, ch, res)
869}
870
871func (dMgr *DeviceManager) revertImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
872 log.Debugw("revertImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
873 var res interface{}
874 var err error
875 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
876 if res, err = agent.revertImage(ctx, img); err != nil {
877 log.Debugw("revertImage-failed", log.Fields{"err": err, "imageName": img.Name})
878 res = err
879 }
880 } else {
881 res = status.Errorf(codes.NotFound, "%s", img.Id)
882 }
883 sendResponse(ctx, ch, res)
884}
885
886func (dMgr *DeviceManager) getImageDownloadStatus(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
887 log.Debugw("getImageDownloadStatus", log.Fields{"deviceid": img.Id, "imageName": img.Name})
888 var res interface{}
889 var err error
890 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
891 if res, err = agent.getImageDownloadStatus(ctx, img); err != nil {
892 log.Debugw("getImageDownloadStatus-failed", log.Fields{"err": err, "imageName": img.Name})
893 res = err
894 }
895 } else {
896 res = status.Errorf(codes.NotFound, "%s", img.Id)
897 }
898 sendResponse(ctx, ch, res)
899}
900
khenaidoof5a5bfa2019-01-23 22:20:29 -0500901func (dMgr *DeviceManager) updateImageDownload(deviceId string, img *voltha.ImageDownload) error {
902 log.Debugw("updateImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
903 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
904 if err := agent.updateImageDownload(img); err != nil {
905 log.Debugw("updateImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
906 return err
907 }
908 } else {
909 return status.Errorf(codes.NotFound, "%s", img.Id)
910 }
911 return nil
912}
913
914func (dMgr *DeviceManager) getImageDownload(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
915 log.Debugw("getImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
916 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
917 return agent.getImageDownload(ctx, img)
918 }
919 return nil, status.Errorf(codes.NotFound, "%s", img.Id)
920}
921
922func (dMgr *DeviceManager) listImageDownloads(ctx context.Context, deviceId string) (*voltha.ImageDownloads, error) {
923 log.Debugw("listImageDownloads", log.Fields{"deviceId": deviceId})
924 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
925 return agent.listImageDownloads(ctx, deviceId)
926 }
927 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
928}
929
khenaidoo92e62c52018-10-03 14:02:54 -0400930func (dMgr *DeviceManager) activateDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400931 log.Info("activateDevice")
932 return nil
933}
934
khenaidoo92e62c52018-10-03 14:02:54 -0400935func (dMgr *DeviceManager) disableDeviceHandler(cDevice *voltha.Device) error {
936 log.Info("disableDevice-donothing")
khenaidoob9203542018-09-17 22:56:37 -0400937 return nil
938}
939
khenaidoo92e62c52018-10-03 14:02:54 -0400940func (dMgr *DeviceManager) abandonDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400941 log.Info("abandonDevice")
942 return nil
943}
944
khenaidoo92e62c52018-10-03 14:02:54 -0400945func (dMgr *DeviceManager) reEnableDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400946 log.Info("reEnableDevice")
947 return nil
948}
949
khenaidoo92e62c52018-10-03 14:02:54 -0400950func (dMgr *DeviceManager) noOp(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400951 log.Info("noOp")
952 return nil
953}
954
khenaidoo92e62c52018-10-03 14:02:54 -0400955func (dMgr *DeviceManager) notAllowed(pcDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400956 log.Info("notAllowed")
957 return errors.New("Transition-not-allowed")
958}
959
960func funcName(f interface{}) string {
961 p := reflect.ValueOf(f).Pointer()
962 rf := runtime.FuncForPC(p)
963 return rf.Name()
964}
965
966func (dMgr *DeviceManager) UpdateDeviceAttribute(deviceId string, attribute string, value interface{}) {
967 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
968 agent.updateDeviceAttribute(attribute, value)
969 }
970}
971
972func (dMgr *DeviceManager) GetParentDeviceId(deviceId string) *string {
khenaidoo19d7b632018-10-30 10:49:50 -0400973 if device, _ := dMgr.GetDevice(deviceId); device != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400974 log.Infow("GetParentDeviceId", log.Fields{"deviceId": device.Id, "parentId": device.ParentId})
khenaidoob9203542018-09-17 22:56:37 -0400975 return &device.ParentId
976 }
977 return nil
978}