blob: 06d3bd4894ab9eb7f83e0e72802882ab9071d1ec [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
Richard Jankowski199fd862019-03-18 14:49:51 -040036 core *Core
khenaidoob9203542018-09-17 22:56:37 -040037 adapterProxy *AdapterProxy
khenaidoo297cd252019-02-07 22:10:23 -050038 adapterMgr *AdapterManager
khenaidoob9203542018-09-17 22:56:37 -040039 logicalDeviceMgr *LogicalDeviceManager
khenaidoo43c82122018-11-22 18:38:28 -050040 kafkaICProxy *kafka.InterContainerProxy
khenaidoob9203542018-09-17 22:56:37 -040041 stateTransitions *TransitionMap
khenaidoo9a468962018-09-19 15:33:13 -040042 clusterDataProxy *model.Proxy
khenaidood2b6df92018-12-13 16:37:20 -050043 coreInstanceId string
khenaidoob9203542018-09-17 22:56:37 -040044 exitChannel chan int
45 lockDeviceAgentsMap sync.RWMutex
46}
47
Richard Jankowski199fd862019-03-18 14:49:51 -040048func newDeviceManager(core *Core) *DeviceManager {
khenaidoob9203542018-09-17 22:56:37 -040049 var deviceMgr DeviceManager
Richard Jankowski199fd862019-03-18 14:49:51 -040050 deviceMgr.core = core
khenaidoob9203542018-09-17 22:56:37 -040051 deviceMgr.exitChannel = make(chan int, 1)
52 deviceMgr.deviceAgents = make(map[string]*DeviceAgent)
Richard Jankowski199fd862019-03-18 14:49:51 -040053 deviceMgr.kafkaICProxy = core.kmp
54 deviceMgr.adapterProxy = NewAdapterProxy(core.kmp)
55 deviceMgr.coreInstanceId = core.instanceId
56 deviceMgr.clusterDataProxy = core.clusterDataProxy
57 deviceMgr.adapterMgr = core.adapterMgr
khenaidoob9203542018-09-17 22:56:37 -040058 deviceMgr.lockDeviceAgentsMap = sync.RWMutex{}
59 return &deviceMgr
60}
61
khenaidoo4d4802d2018-10-04 21:59:49 -040062func (dMgr *DeviceManager) start(ctx context.Context, logicalDeviceMgr *LogicalDeviceManager) {
khenaidoob9203542018-09-17 22:56:37 -040063 log.Info("starting-device-manager")
64 dMgr.logicalDeviceMgr = logicalDeviceMgr
65 dMgr.stateTransitions = NewTransitionMap(dMgr)
66 log.Info("device-manager-started")
67}
68
khenaidoo4d4802d2018-10-04 21:59:49 -040069func (dMgr *DeviceManager) stop(ctx context.Context) {
khenaidoob9203542018-09-17 22:56:37 -040070 log.Info("stopping-device-manager")
71 dMgr.exitChannel <- 1
72 log.Info("device-manager-stopped")
73}
74
75func sendResponse(ctx context.Context, ch chan interface{}, result interface{}) {
76 if ctx.Err() == nil {
77 // Returned response only of the ctx has not been cancelled/timeout/etc
78 // Channel is automatically closed when a context is Done
79 ch <- result
80 log.Debugw("sendResponse", log.Fields{"result": result})
81 } else {
82 // Should the transaction be reverted back?
83 log.Debugw("sendResponse-context-error", log.Fields{"context-error": ctx.Err()})
84 }
85}
86
87func (dMgr *DeviceManager) addDeviceAgentToMap(agent *DeviceAgent) {
88 dMgr.lockDeviceAgentsMap.Lock()
89 defer dMgr.lockDeviceAgentsMap.Unlock()
90 if _, exist := dMgr.deviceAgents[agent.deviceId]; !exist {
91 dMgr.deviceAgents[agent.deviceId] = agent
92 }
93}
94
khenaidoo4d4802d2018-10-04 21:59:49 -040095func (dMgr *DeviceManager) deleteDeviceAgentToMap(agent *DeviceAgent) {
96 dMgr.lockDeviceAgentsMap.Lock()
97 defer dMgr.lockDeviceAgentsMap.Unlock()
98 delete(dMgr.deviceAgents, agent.deviceId)
99}
100
khenaidoo297cd252019-02-07 22:10:23 -0500101// 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 -0400102func (dMgr *DeviceManager) getDeviceAgent(deviceId string) *DeviceAgent {
103 dMgr.lockDeviceAgentsMap.Lock()
khenaidoob9203542018-09-17 22:56:37 -0400104 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
khenaidoo297cd252019-02-07 22:10:23 -0500105 dMgr.lockDeviceAgentsMap.Unlock()
khenaidoob9203542018-09-17 22:56:37 -0400106 return agent
khenaidoo297cd252019-02-07 22:10:23 -0500107 } else {
108 // Try to load into memory - loading will also create the device agent
109 dMgr.lockDeviceAgentsMap.Unlock()
110 if err := dMgr.load(deviceId); err == nil {
111 dMgr.lockDeviceAgentsMap.Lock()
112 defer dMgr.lockDeviceAgentsMap.Unlock()
113 if agent, ok = dMgr.deviceAgents[deviceId]; ok {
114 return agent
115 }
116 }
khenaidoob9203542018-09-17 22:56:37 -0400117 }
118 return nil
119}
120
khenaidoo297cd252019-02-07 22:10:23 -0500121// listDeviceIdsFromMap returns the list of device IDs that are in memory
khenaidoo7ccedd52018-12-14 16:48:54 -0500122func (dMgr *DeviceManager) listDeviceIdsFromMap() *voltha.IDs {
123 dMgr.lockDeviceAgentsMap.Lock()
124 defer dMgr.lockDeviceAgentsMap.Unlock()
125 result := &voltha.IDs{Items: make([]*voltha.ID, 0)}
126 for key, _ := range dMgr.deviceAgents {
127 result.Items = append(result.Items, &voltha.ID{Id: key})
128 }
129 return result
130}
131
khenaidoob9203542018-09-17 22:56:37 -0400132func (dMgr *DeviceManager) createDevice(ctx context.Context, device *voltha.Device, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400133 log.Debugw("createDevice", log.Fields{"device": device, "aproxy": dMgr.adapterProxy})
khenaidoob9203542018-09-17 22:56:37 -0400134
khenaidoo5e677ae2019-02-28 17:26:29 -0500135 // Ensure this device is set as root
136 device.Root = true
khenaidoob9203542018-09-17 22:56:37 -0400137 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400138 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400139 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500140 agent.start(ctx, false)
khenaidoob9203542018-09-17 22:56:37 -0400141
khenaidoo92e62c52018-10-03 14:02:54 -0400142 sendResponse(ctx, ch, agent.lastData)
khenaidoob9203542018-09-17 22:56:37 -0400143}
144
145func (dMgr *DeviceManager) enableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400146 log.Debugw("enableDevice", log.Fields{"deviceid": id})
khenaidoob9203542018-09-17 22:56:37 -0400147 var res interface{}
148 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
149 res = agent.enableDevice(ctx)
150 log.Debugw("EnableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400151 }
152
153 sendResponse(ctx, ch, res)
154}
155
khenaidoo92e62c52018-10-03 14:02:54 -0400156func (dMgr *DeviceManager) disableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
157 log.Debugw("disableDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400158 var res interface{}
159 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
160 res = agent.disableDevice(ctx)
161 log.Debugw("disableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400162 } else {
khenaidoo92e62c52018-10-03 14:02:54 -0400163 res = status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoob9203542018-09-17 22:56:37 -0400164 }
khenaidoo92e62c52018-10-03 14:02:54 -0400165
166 sendResponse(ctx, ch, res)
167}
168
khenaidoo4d4802d2018-10-04 21:59:49 -0400169func (dMgr *DeviceManager) rebootDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
170 log.Debugw("rebootDevice", log.Fields{"deviceid": id})
171 var res interface{}
172 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
173 res = agent.rebootDevice(ctx)
174 log.Debugw("rebootDevice-result", log.Fields{"result": res})
175 } else {
176 res = status.Errorf(codes.NotFound, "%s", id.Id)
177 }
178 sendResponse(ctx, ch, res)
179}
180
181func (dMgr *DeviceManager) deleteDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
182 log.Debugw("deleteDevice", log.Fields{"deviceid": id})
183 var res interface{}
184 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
185 res = agent.deleteDevice(ctx)
186 if res == nil { //Success
187 agent.stop(ctx)
188 dMgr.deleteDeviceAgentToMap(agent)
Richard Jankowski199fd862019-03-18 14:49:51 -0400189 dMgr.core.deviceOwnership.AbandonDevice(id.Id)
khenaidoo4d4802d2018-10-04 21:59:49 -0400190 }
191 log.Debugw("deleteDevice-result", log.Fields{"result": res})
192 } else {
193 res = status.Errorf(codes.NotFound, "%s", id.Id)
194 }
195 sendResponse(ctx, ch, res)
196}
197
khenaidoo297cd252019-02-07 22:10:23 -0500198// GetDevice will returns a device, either from memory or from the dB, if present
khenaidoo19d7b632018-10-30 10:49:50 -0400199func (dMgr *DeviceManager) GetDevice(id string) (*voltha.Device, error) {
200 log.Debugw("GetDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400201 if agent := dMgr.getDeviceAgent(id); agent != nil {
202 return agent.getDevice()
203 }
204 return nil, status.Errorf(codes.NotFound, "%s", id)
khenaidoob9203542018-09-17 22:56:37 -0400205}
206
Matt Jeanneret4e241952019-02-28 11:16:04 -0500207func (dMgr *DeviceManager) GetChildDevice(parentDeviceId string, serialNumber string, onuId int64, parentPortNo int64) (*voltha.Device, error) {
208 log.Debugw("GetChildDevice", log.Fields{"parentDeviceid": parentDeviceId, "serialNumber": serialNumber})
209
210 var parentDevice *voltha.Device
211 var err error
212 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
213 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
214 }
215 var childDeviceIds []string
216 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
217 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
218 }
219 if len(childDeviceIds) == 0 {
220 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id})
221 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
222 }
223
224 var foundChildDevice *voltha.Device
225 for _, childDeviceId := range childDeviceIds {
226 found := false
227 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
228
229 foundOnuId := false
230 if searchDevice.ProxyAddress.OnuId == uint32(onuId) {
231 if searchDevice.ParentPortNo == uint32(parentPortNo) {
232 log.Debugw("found-child-by-onuid", log.Fields{"parentDeviceId": parentDevice.Id, "onuId": onuId})
233 foundOnuId = true
234 }
235 }
236
237 foundSerialNumber := false
238 if searchDevice.SerialNumber == serialNumber {
239 log.Debugw("found-child-by-serialnumber", log.Fields{"parentDeviceId": parentDevice.Id, "serialNumber": serialNumber})
240 foundSerialNumber = true
241 }
242
243 // if both onuId and serialNumber are provided both must be true for the device to be found
244 // otherwise whichever one found a match is good enough
245 if onuId > 0 && serialNumber != "" {
246 found = foundOnuId && foundSerialNumber
247 } else {
248 found = foundOnuId || foundSerialNumber
249 }
250
251 if found == true {
252 foundChildDevice = searchDevice
253 break
254 }
255 }
256 }
257
258 if foundChildDevice != nil {
259 log.Debugw("child-device-found", log.Fields{"parentDeviceId": parentDevice.Id, "foundChildDevice": foundChildDevice})
260 return foundChildDevice, nil
261 }
262
263 log.Warnw("child-device-not-found", log.Fields{"parentDeviceId": parentDevice.Id,
264 "serialNumber": serialNumber, "onuId": onuId, "parentPortNo": parentPortNo})
265 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
266}
267
Matt Jeanneret2a20aaa2019-03-05 21:04:02 -0500268func (dMgr *DeviceManager) GetChildDeviceWithProxyAddress(proxyAddress *voltha.Device_ProxyAddress) (*voltha.Device, error) {
269 log.Debugw("GetChildDeviceWithProxyAddress", log.Fields{"proxyAddress": proxyAddress})
270
271 var parentDevice *voltha.Device
272 var err error
273 if parentDevice, err = dMgr.GetDevice(proxyAddress.DeviceId); err != nil {
274 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
275 }
276 var childDeviceIds []string
277 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
278 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
279 }
280 if len(childDeviceIds) == 0 {
281 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id})
282 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
283 }
284
285 var foundChildDevice *voltha.Device
286 for _, childDeviceId := range childDeviceIds {
287 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
288 if searchDevice.ProxyAddress == proxyAddress {
289 foundChildDevice = searchDevice
290 break
291 }
292 }
293 }
294
295 if foundChildDevice != nil {
296 log.Debugw("child-device-found", log.Fields{"proxyAddress": proxyAddress})
297 return foundChildDevice, nil
298 }
299
300 log.Warnw("child-device-not-found", log.Fields{"proxyAddress": proxyAddress})
301 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
302}
303
khenaidoo297cd252019-02-07 22:10:23 -0500304func (dMgr *DeviceManager) IsDeviceInCache(id string) bool {
305 dMgr.lockDeviceAgentsMap.Lock()
306 defer dMgr.lockDeviceAgentsMap.Unlock()
307 _, exist := dMgr.deviceAgents[id]
308 return exist
309}
310
khenaidoo19d7b632018-10-30 10:49:50 -0400311func (dMgr *DeviceManager) IsRootDevice(id string) (bool, error) {
312 device, err := dMgr.GetDevice(id)
313 if err != nil {
314 return false, err
315 }
316 return device.Root, nil
317}
318
Stephane Barbarieaa467942019-02-06 14:09:44 -0500319// ListDevices retrieves the latest devices from the data model
khenaidoob9203542018-09-17 22:56:37 -0400320func (dMgr *DeviceManager) ListDevices() (*voltha.Devices, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400321 log.Debug("ListDevices")
khenaidoob9203542018-09-17 22:56:37 -0400322 result := &voltha.Devices{}
Stephane Barbarieaa467942019-02-06 14:09:44 -0500323 if devices := dMgr.clusterDataProxy.List("/devices", 0, false, ""); devices != nil {
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500324 for _, device := range devices.([]interface{}) {
khenaidoo297cd252019-02-07 22:10:23 -0500325 // If device is not in memory then set it up
326 if !dMgr.IsDeviceInCache(device.(*voltha.Device).Id) {
327 agent := newDeviceAgent(dMgr.adapterProxy, device.(*voltha.Device), dMgr, dMgr.clusterDataProxy)
328 if err := agent.start(nil, true); err != nil {
329 log.Warnw("failure-starting-agent", log.Fields{"deviceId": device.(*voltha.Device).Id})
330 agent.stop(nil)
331 } else {
332 dMgr.addDeviceAgentToMap(agent)
333 }
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500334 }
335 result.Items = append(result.Items, device.(*voltha.Device))
khenaidoob9203542018-09-17 22:56:37 -0400336 }
337 }
338 return result, nil
339}
340
khenaidoo297cd252019-02-07 22:10:23 -0500341// loadDevice loads the deviceId in memory, if not present
342func (dMgr *DeviceManager) loadDevice(deviceId string) (*DeviceAgent, error) {
343 log.Debugw("loading-device", log.Fields{"deviceId": deviceId})
344 // Sanity check
345 if deviceId == "" {
346 return nil, status.Error(codes.InvalidArgument, "deviceId empty")
347 }
348 if !dMgr.IsDeviceInCache(deviceId) {
349 agent := newDeviceAgent(dMgr.adapterProxy, &voltha.Device{Id: deviceId}, dMgr, dMgr.clusterDataProxy)
350 if err := agent.start(nil, true); err != nil {
351 agent.stop(nil)
352 return nil, err
353 }
354 dMgr.addDeviceAgentToMap(agent)
355 }
356 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
357 return agent, nil
358 }
Matt Jeanneret4e241952019-02-28 11:16:04 -0500359 return nil, status.Error(codes.NotFound, deviceId) // This should not happen
khenaidoo297cd252019-02-07 22:10:23 -0500360}
361
362// loadRootDeviceParentAndChildren loads the children and parents of a root device in memory
363func (dMgr *DeviceManager) loadRootDeviceParentAndChildren(device *voltha.Device) error {
364 log.Debugw("loading-parent-and-children", log.Fields{"deviceId": device.Id})
365 if device.Root {
366 // Scenario A
367 if device.ParentId != "" {
368 // Load logical device if needed.
369 if err := dMgr.logicalDeviceMgr.load(device.ParentId); err != nil {
370 log.Warnw("failure-loading-logical-device", log.Fields{"lDeviceId": device.ParentId})
371 }
372 } else {
373 log.Debugw("no-parent-to-load", log.Fields{"deviceId": device.Id})
374 }
375 // Load all child devices, if needed
376 if childDeviceIds, err := dMgr.getAllChildDeviceIds(device); err == nil {
377 for _, childDeviceId := range childDeviceIds {
378 if _, err := dMgr.loadDevice(childDeviceId); err != nil {
379 log.Warnw("failure-loading-device", log.Fields{"deviceId": childDeviceId})
380 return err
381 }
382 }
383 log.Debugw("loaded-children", log.Fields{"deviceId": device.Id, "numChildren": len(childDeviceIds)})
384 } else {
385 log.Debugw("no-child-to-load", log.Fields{"deviceId": device.Id})
386 }
387 }
388 return nil
389}
390
391// load loads the deviceId in memory, if not present, and also loads its accompanying parents and children. Loading
392// in memory is for improved performance. It is not imperative that a device needs to be in memory when a request
393// acting on the device is received by the core. In such a scenario, the Core will load the device in memory first
394// and the proceed with the request.
395func (dMgr *DeviceManager) load(deviceId string) error {
396 log.Debug("load...")
397 // First load the device - this may fail in case the device was deleted intentionally by the other core
398 var dAgent *DeviceAgent
399 var err error
400 if dAgent, err = dMgr.loadDevice(deviceId); err != nil {
401 log.Warnw("failure-loading-device", log.Fields{"deviceId": deviceId})
402 return err
403 }
404 // Get the loaded device details
405 var device *voltha.Device
406 if device, err = dAgent.getDevice(); err != nil {
407 return err
408 }
409
410 // If the device is in Pre-provisioning or deleted state stop here
411 if device.AdminState == voltha.AdminState_PREPROVISIONED || device.AdminState == voltha.AdminState_DELETED {
412 return nil
413 }
414
415 // Now we face two scenarios
416 if device.Root {
417 // Load all children as well as the parent of this device (logical_device)
418 if err := dMgr.loadRootDeviceParentAndChildren(device); err != nil {
419 log.Warnw("failure-loading-device-parent-and-children", log.Fields{"deviceId": deviceId})
420 return err
421 }
422 log.Debugw("successfully-loaded-parent-and-children", log.Fields{"deviceId": deviceId})
423 } else {
424 // Scenario B - use the parentId of that device (root device) to trigger the loading
425 if device.ParentId != "" {
426 return dMgr.load(device.ParentId)
427 }
428 }
429 return nil
430}
431
khenaidoo7ccedd52018-12-14 16:48:54 -0500432// ListDeviceIds retrieves the latest device IDs information from the data model (memory data only)
433func (dMgr *DeviceManager) ListDeviceIds() (*voltha.IDs, error) {
434 log.Debug("ListDeviceIDs")
435 // Report only device IDs that are in the device agent map
436 return dMgr.listDeviceIdsFromMap(), nil
437}
438
439//ReconcileDevices is a request to a voltha core to managed a list of devices based on their IDs
440func (dMgr *DeviceManager) ReconcileDevices(ctx context.Context, ids *voltha.IDs, ch chan interface{}) {
441 log.Debug("ReconcileDevices")
442 var res interface{}
443 if ids != nil {
444 toReconcile := len(ids.Items)
445 reconciled := 0
446 for _, id := range ids.Items {
447 // Act on the device only if its not present in the agent map
khenaidoo297cd252019-02-07 22:10:23 -0500448 if !dMgr.IsDeviceInCache(id.Id) {
khenaidoo7ccedd52018-12-14 16:48:54 -0500449 // Device Id not in memory
450 log.Debugw("reconciling-device", log.Fields{"id": id.Id})
khenaidoo297cd252019-02-07 22:10:23 -0500451 // Load device from dB
Matt Jeanneret4e241952019-02-28 11:16:04 -0500452 agent := newDeviceAgent(dMgr.adapterProxy, &voltha.Device{Id: id.Id}, dMgr, dMgr.clusterDataProxy)
khenaidoo297cd252019-02-07 22:10:23 -0500453 if err := agent.start(nil, true); err != nil {
454 log.Warnw("failure-loading-device", log.Fields{"deviceId": id.Id})
455 agent.stop(nil)
khenaidoo7ccedd52018-12-14 16:48:54 -0500456 } else {
khenaidoo297cd252019-02-07 22:10:23 -0500457 dMgr.addDeviceAgentToMap(agent)
458 reconciled += 1
khenaidoo7ccedd52018-12-14 16:48:54 -0500459 }
460 } else {
461 reconciled += 1
462 }
463 }
464 if toReconcile != reconciled {
465 res = status.Errorf(codes.DataLoss, "less-device-reconciled:%d/%d", reconciled, toReconcile)
466 }
467 } else {
468 res = status.Errorf(codes.InvalidArgument, "empty-list-of-ids")
469 }
470 sendResponse(ctx, ch, res)
471}
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500472
khenaidoob9203542018-09-17 22:56:37 -0400473func (dMgr *DeviceManager) updateDevice(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400474 log.Debugw("updateDevice", log.Fields{"deviceid": device.Id, "device": device})
khenaidoob9203542018-09-17 22:56:37 -0400475 if agent := dMgr.getDeviceAgent(device.Id); agent != nil {
476 return agent.updateDevice(device)
477 }
478 return status.Errorf(codes.NotFound, "%s", device.Id)
479}
480
481func (dMgr *DeviceManager) addPort(deviceId string, port *voltha.Port) error {
482 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400483 if err := agent.addPort(port); err != nil {
484 return err
485 }
486 // Setup peer ports
487 meAsPeer := &voltha.Port_PeerPort{DeviceId: deviceId, PortNo: port.PortNo}
488 for _, peerPort := range port.Peers {
489 if agent := dMgr.getDeviceAgent(peerPort.DeviceId); agent != nil {
490 if err := agent.addPeerPort(meAsPeer); err != nil {
491 log.Errorw("failed-to-add-peer", log.Fields{"peer-device-id": peerPort.DeviceId})
492 return err
493 }
494 }
495 }
khenaidoofc1314d2019-03-14 09:34:21 -0400496 // Notify the logical device manager to setup a logical port if needed
497 if port.Type == voltha.Port_ETHERNET_NNI || port.Type == voltha.Port_ETHERNET_UNI {
498 if device , err := dMgr.GetDevice(deviceId); err == nil {
499 go dMgr.logicalDeviceMgr.addLogicalPort(device, port)
500 } else {
501 log.Errorw("failed-to-retrieve-device", log.Fields{"deviceId": deviceId})
502 return err
503 }
504 }
khenaidoo92e62c52018-10-03 14:02:54 -0400505 return nil
506 } else {
507 return status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoob9203542018-09-17 22:56:37 -0400508 }
khenaidoob9203542018-09-17 22:56:37 -0400509}
510
khenaidoo19d7b632018-10-30 10:49:50 -0400511func (dMgr *DeviceManager) updateFlows(deviceId string, flows []*ofp.OfpFlowStats) error {
512 log.Debugw("updateFlows", log.Fields{"deviceid": deviceId})
513 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
514 return agent.updateFlows(flows)
515 }
516 return status.Errorf(codes.NotFound, "%s", deviceId)
517}
518
519func (dMgr *DeviceManager) updateGroups(deviceId string, groups []*ofp.OfpGroupEntry) error {
520 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
521 return agent.updateGroups(groups)
522 }
523 return status.Errorf(codes.NotFound, "%s", deviceId)
524}
525
khenaidoob9203542018-09-17 22:56:37 -0400526func (dMgr *DeviceManager) updatePmConfigs(deviceId string, pmConfigs *voltha.PmConfigs) error {
527 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
528 return agent.updatePmConfigs(pmConfigs)
529 }
530 return status.Errorf(codes.NotFound, "%s", deviceId)
531}
532
khenaidoo79232702018-12-04 11:00:41 -0500533func (dMgr *DeviceManager) getSwitchCapability(ctx context.Context, deviceId string) (*ic.SwitchCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400534 log.Debugw("getSwitchCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400535 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
536 return agent.getSwitchCapability(ctx)
537 }
538 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
539}
540
khenaidoo92e62c52018-10-03 14:02:54 -0400541func (dMgr *DeviceManager) getPorts(ctx context.Context, deviceId string, portType voltha.Port_PortType) (*voltha.Ports, error) {
542 log.Debugw("getPorts", log.Fields{"deviceid": deviceId, "portType": portType})
khenaidoob9203542018-09-17 22:56:37 -0400543 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400544 return agent.getPorts(ctx, portType), nil
khenaidoob9203542018-09-17 22:56:37 -0400545 }
546 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoo92e62c52018-10-03 14:02:54 -0400547
khenaidoob9203542018-09-17 22:56:37 -0400548}
549
khenaidoo79232702018-12-04 11:00:41 -0500550func (dMgr *DeviceManager) getPortCapability(ctx context.Context, deviceId string, portNo uint32) (*ic.PortCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400551 log.Debugw("getPortCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400552 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
553 return agent.getPortCapability(ctx, portNo)
554 }
555 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
556}
557
khenaidoo92e62c52018-10-03 14:02:54 -0400558func (dMgr *DeviceManager) updateDeviceStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
559 log.Debugw("updateDeviceStatus", log.Fields{"deviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400560 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400561 return agent.updateDeviceStatus(operStatus, connStatus)
562 }
563 return status.Errorf(codes.NotFound, "%s", deviceId)
564}
565
khenaidoo4d4802d2018-10-04 21:59:49 -0400566func (dMgr *DeviceManager) updateChildrenStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
567 log.Debugw("updateChildrenStatus", log.Fields{"parentDeviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
568 var parentDevice *voltha.Device
569 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400570 if parentDevice, err = dMgr.GetDevice(deviceId); err != nil {
khenaidoo4d4802d2018-10-04 21:59:49 -0400571 return status.Errorf(codes.Aborted, "%s", err.Error())
572 }
573 var childDeviceIds []string
574 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
575 return status.Errorf(codes.Aborted, "%s", err.Error())
576 }
577 if len(childDeviceIds) == 0 {
578 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
579 }
580 for _, childDeviceId := range childDeviceIds {
581 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
582 if err = agent.updateDeviceStatus(operStatus, connStatus); err != nil {
583 return status.Errorf(codes.Aborted, "childDevice:%s, error:%s", childDeviceId, err.Error())
584 }
585 }
586 }
587 return nil
588}
589
khenaidoo92e62c52018-10-03 14:02:54 -0400590func (dMgr *DeviceManager) updatePortState(deviceId string, portType voltha.Port_PortType, portNo uint32, operStatus voltha.OperStatus_OperStatus) error {
591 log.Debugw("updatePortState", log.Fields{"deviceid": deviceId, "portType": portType, "portNo": portNo, "operStatus": operStatus})
592 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
593 return agent.updatePortState(portType, portNo, operStatus)
khenaidoob9203542018-09-17 22:56:37 -0400594 }
595 return status.Errorf(codes.NotFound, "%s", deviceId)
596}
597
Matt Jeanneret4e241952019-02-28 11:16:04 -0500598func (dMgr *DeviceManager) childDeviceDetected(parentDeviceId string, parentPortNo int64, deviceType string,
599 channelId int64, vendorId string, serialNumber string, onuId int64) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400600 log.Debugw("childDeviceDetected", log.Fields{"parentDeviceId": parentDeviceId})
khenaidoob9203542018-09-17 22:56:37 -0400601
602 // Create the ONU device
603 childDevice := &voltha.Device{}
khenaidoob9203542018-09-17 22:56:37 -0400604 childDevice.Type = deviceType
605 childDevice.ParentId = parentDeviceId
606 childDevice.ParentPortNo = uint32(parentPortNo)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500607 childDevice.VendorId = vendorId
608 childDevice.SerialNumber = serialNumber
khenaidoob9203542018-09-17 22:56:37 -0400609 childDevice.Root = false
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400610
611 //Get parent device type
612 parent, err := dMgr.GetDevice(parentDeviceId)
613 if err != nil {
khenaidoo43c82122018-11-22 18:38:28 -0500614 log.Error("no-parent-found", log.Fields{"parentId": parentDeviceId})
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400615 return status.Errorf(codes.NotFound, "%s", parentDeviceId)
616 }
617
Matt Jeanneret4e241952019-02-28 11:16:04 -0500618 if _, err := dMgr.GetChildDevice(parentDeviceId, serialNumber, onuId, parentPortNo); err == nil {
619 log.Warnw("child-device-exists", log.Fields{"parentId": parentDeviceId, "serialNumber": serialNumber})
620 return status.Errorf(codes.AlreadyExists, "%s", serialNumber)
621 }
622
623 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{DeviceId: parentDeviceId, DeviceType: parent.Type, ChannelId: uint32(channelId), OnuId: uint32(onuId)}
khenaidoob9203542018-09-17 22:56:37 -0400624
625 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400626 agent := newDeviceAgent(dMgr.adapterProxy, childDevice, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400627 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500628 agent.start(nil, false)
khenaidoob9203542018-09-17 22:56:37 -0400629
Richard Jankowski199fd862019-03-18 14:49:51 -0400630 // Set device ownership
631 dMgr.core.deviceOwnership.OwnedByMe(agent.deviceId)
632
khenaidoob9203542018-09-17 22:56:37 -0400633 // Activate the child device
khenaidoo92e62c52018-10-03 14:02:54 -0400634 if agent := dMgr.getDeviceAgent(agent.deviceId); agent != nil {
khenaidoo79232702018-12-04 11:00:41 -0500635 go agent.enableDevice(nil)
khenaidoob9203542018-09-17 22:56:37 -0400636 }
637
khenaidoo79232702018-12-04 11:00:41 -0500638 // Publish on the messaging bus that we have discovered new devices
khenaidoo19374072018-12-11 11:05:15 -0500639 go dMgr.kafkaICProxy.DeviceDiscovered(agent.deviceId, deviceType, parentDeviceId, dMgr.coreInstanceId)
khenaidoo79232702018-12-04 11:00:41 -0500640
khenaidoob9203542018-09-17 22:56:37 -0400641 return nil
642}
643
644func (dMgr *DeviceManager) processTransition(previous *voltha.Device, current *voltha.Device) error {
645 // This will be triggered on every update to the device.
khenaidoo92e62c52018-10-03 14:02:54 -0400646 handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
647 if handlers == nil {
khenaidoo43c82122018-11-22 18:38:28 -0500648 log.Debugw("no-op-transition", log.Fields{"deviceId": current.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400649 return nil
khenaidoob9203542018-09-17 22:56:37 -0400650 }
khenaidoo92e62c52018-10-03 14:02:54 -0400651 for _, handler := range handlers {
652 log.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
653 if err := handler(current); err != nil {
654 return err
655 }
656 }
khenaidoob9203542018-09-17 22:56:37 -0400657 return nil
658}
659
khenaidoofdbad6e2018-11-06 22:26:38 -0500660func (dMgr *DeviceManager) packetOut(deviceId string, outPort uint32, packet *ofp.OfpPacketOut) error {
661 log.Debugw("packetOut", log.Fields{"deviceId": deviceId, "outPort": outPort})
662 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
663 return agent.packetOut(outPort, packet)
664 }
665 return status.Errorf(codes.NotFound, "%s", deviceId)
666}
667
khenaidoo297cd252019-02-07 22:10:23 -0500668func (dMgr *DeviceManager) PacketIn(deviceId string, port uint32, transactionId string, packet []byte) error {
khenaidoofdbad6e2018-11-06 22:26:38 -0500669 log.Debugw("PacketIn", log.Fields{"deviceId": deviceId, "port": port})
670 // Get the logical device Id based on the deviceId
671 var device *voltha.Device
672 var err error
673 if device, err = dMgr.GetDevice(deviceId); err != nil {
674 log.Errorw("device-not-found", log.Fields{"deviceId": deviceId})
675 return err
676 }
khenaidoo43c82122018-11-22 18:38:28 -0500677 if !device.Root {
khenaidoofdbad6e2018-11-06 22:26:38 -0500678 log.Errorw("device-not-root", log.Fields{"deviceId": deviceId})
679 return status.Errorf(codes.FailedPrecondition, "%s", deviceId)
680 }
681
khenaidoo297cd252019-02-07 22:10:23 -0500682 if err := dMgr.logicalDeviceMgr.packetIn(device.ParentId, port, transactionId, packet); err != nil {
khenaidoofdbad6e2018-11-06 22:26:38 -0500683 return err
684 }
685 return nil
686}
687
khenaidoo92e62c52018-10-03 14:02:54 -0400688func (dMgr *DeviceManager) createLogicalDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400689 log.Info("createLogicalDevice")
690 var logicalId *string
691 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400692 if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400693 log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
694 return err
695 }
696 // Update the parent device with the logical id
697 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
698 return nil
699}
700
khenaidoo92e62c52018-10-03 14:02:54 -0400701func (dMgr *DeviceManager) deleteLogicalDevice(cDevice *voltha.Device) error {
702 log.Info("deleteLogicalDevice")
703 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400704 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400705 log.Warnw("deleteLogical-device-error", log.Fields{"deviceId": cDevice.Id})
706 return err
707 }
708 // Remove the logical device Id from the parent device
709 logicalId := ""
710 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", logicalId)
711 return nil
712}
713
khenaidoo19d7b632018-10-30 10:49:50 -0400714func (dMgr *DeviceManager) deleteLogicalPort(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400715 log.Info("deleteLogicalPort")
716 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400717 // Get the logical port associated with this device
718 var lPortId *voltha.LogicalPortId
719 if lPortId, err = dMgr.logicalDeviceMgr.getLogicalPortId(device); err != nil {
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400720 log.Warnw("getLogical-port-error", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo19d7b632018-10-30 10:49:50 -0400721 return err
722 }
723 if err = dMgr.logicalDeviceMgr.deleteLogicalPort(nil, lPortId); err != nil {
724 log.Warnw("deleteLogical-port-error", log.Fields{"deviceId": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400725 return err
726 }
khenaidoo92e62c52018-10-03 14:02:54 -0400727 return nil
728}
729
730func (dMgr *DeviceManager) getParentDevice(childDevice *voltha.Device) *voltha.Device {
731 // Sanity check
732 if childDevice.Root {
733 // childDevice is the parent device
734 return childDevice
735 }
khenaidoo19d7b632018-10-30 10:49:50 -0400736 parentDevice, _ := dMgr.GetDevice(childDevice.ParentId)
khenaidoo92e62c52018-10-03 14:02:54 -0400737 return parentDevice
738}
739
khenaidoo4d4802d2018-10-04 21:59:49 -0400740/*
741All the functions below are callback functions where they are invoked with the latest and previous data. We can
742therefore use the data as is without trying to get the latest from the model.
743*/
744
745//disableAllChildDevices is invoked as a callback when the parent device is disabled
746func (dMgr *DeviceManager) disableAllChildDevices(parentDevice *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400747 log.Debug("disableAllChildDevices")
748 var childDeviceIds []string
749 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400750 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
751 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400752 }
753 if len(childDeviceIds) == 0 {
khenaidoo4d4802d2018-10-04 21:59:49 -0400754 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400755 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400756 allChildDisable := true
khenaidoo92e62c52018-10-03 14:02:54 -0400757 for _, childDeviceId := range childDeviceIds {
758 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
759 if err = agent.disableDevice(nil); err != nil {
760 log.Errorw("failure-disable-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
khenaidoo4d4802d2018-10-04 21:59:49 -0400761 allChildDisable = false
khenaidoo92e62c52018-10-03 14:02:54 -0400762 }
763 }
764 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400765 if !allChildDisable {
766 return err
767 }
khenaidoo92e62c52018-10-03 14:02:54 -0400768 return nil
769}
770
khenaidoo4d4802d2018-10-04 21:59:49 -0400771//deleteAllChildDevices is invoked as a callback when the parent device is deleted
772func (dMgr *DeviceManager) deleteAllChildDevices(parentDevice *voltha.Device) error {
773 log.Debug("deleteAllChildDevices")
774 var childDeviceIds []string
khenaidoo92e62c52018-10-03 14:02:54 -0400775 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400776 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
777 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400778 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400779 if len(childDeviceIds) == 0 {
780 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
781 }
782 allChildDeleted := true
783 for _, childDeviceId := range childDeviceIds {
784 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
785 if err = agent.deleteDevice(nil); err != nil {
786 log.Errorw("failure-delete-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
787 allChildDeleted = false
788 } else {
789 agent.stop(nil)
790 dMgr.deleteDeviceAgentToMap(agent)
791 }
792 }
793 }
794 if !allChildDeleted {
795 return err
796 }
797 return nil
798}
799
800//getAllChildDeviceIds is a helper method to get all the child device IDs from the device passed as parameter
801func (dMgr *DeviceManager) getAllChildDeviceIds(parentDevice *voltha.Device) ([]string, error) {
802 log.Debugw("getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400803 childDeviceIds := make([]string, 0)
khenaidoo4d4802d2018-10-04 21:59:49 -0400804 if parentDevice != nil {
805 for _, port := range parentDevice.Ports {
806 for _, peer := range port.Peers {
807 childDeviceIds = append(childDeviceIds, peer.DeviceId)
808 }
khenaidoo92e62c52018-10-03 14:02:54 -0400809 }
810 }
Matt Jeanneret4e241952019-02-28 11:16:04 -0500811 log.Debugw("returning-getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id, "childDeviceIds": childDeviceIds})
khenaidoo92e62c52018-10-03 14:02:54 -0400812 return childDeviceIds, nil
813}
814
khenaidoo297cd252019-02-07 22:10:23 -0500815//getAllChildDevices is a helper method to get all the child device IDs from the device passed as parameter
816func (dMgr *DeviceManager) getAllChildDevices(parentDeviceId string) (*voltha.Devices, error) {
817 log.Debugw("getAllChildDevices", log.Fields{"parentDeviceId": parentDeviceId})
818 if parentDevice, err := dMgr.GetDevice(parentDeviceId); err == nil {
819 childDevices := make([]*voltha.Device, 0)
820 if childDeviceIds, er := dMgr.getAllChildDeviceIds(parentDevice); er == nil {
821 for _, deviceId := range childDeviceIds {
822 if d, e := dMgr.GetDevice(deviceId); e == nil && d != nil {
823 childDevices = append(childDevices, d)
824 }
825 }
826 }
827 return &voltha.Devices{Items: childDevices}, nil
828 }
829 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
830}
831
khenaidoofc1314d2019-03-14 09:34:21 -0400832func (dMgr *DeviceManager) setupUNILogicalPorts(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400833 log.Info("addUNILogicalPort")
khenaidoofc1314d2019-03-14 09:34:21 -0400834 if err := dMgr.logicalDeviceMgr.setupUNILogicalPorts(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400835 log.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
836 return err
837 }
838 return nil
839}
840
khenaidoof5a5bfa2019-01-23 22:20:29 -0500841func (dMgr *DeviceManager) downloadImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
842 log.Debugw("downloadImage", 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.downloadImage(ctx, img); err != nil {
847 log.Debugw("downloadImage-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) cancelImageDownload(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
857 log.Debugw("cancelImageDownload", 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.cancelImageDownload(ctx, img); err != nil {
862 log.Debugw("cancelImageDownload-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) activateImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
872 log.Debugw("activateImage", 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.activateImage(ctx, img); err != nil {
877 log.Debugw("activateImage-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) revertImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
887 log.Debugw("revertImage", 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.revertImage(ctx, img); err != nil {
892 log.Debugw("revertImage-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
901func (dMgr *DeviceManager) getImageDownloadStatus(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
902 log.Debugw("getImageDownloadStatus", log.Fields{"deviceid": img.Id, "imageName": img.Name})
903 var res interface{}
904 var err error
905 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
906 if res, err = agent.getImageDownloadStatus(ctx, img); err != nil {
907 log.Debugw("getImageDownloadStatus-failed", log.Fields{"err": err, "imageName": img.Name})
908 res = err
909 }
910 } else {
911 res = status.Errorf(codes.NotFound, "%s", img.Id)
912 }
913 sendResponse(ctx, ch, res)
914}
915
khenaidoof5a5bfa2019-01-23 22:20:29 -0500916func (dMgr *DeviceManager) updateImageDownload(deviceId string, img *voltha.ImageDownload) error {
917 log.Debugw("updateImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
918 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
919 if err := agent.updateImageDownload(img); err != nil {
920 log.Debugw("updateImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
921 return err
922 }
923 } else {
924 return status.Errorf(codes.NotFound, "%s", img.Id)
925 }
926 return nil
927}
928
929func (dMgr *DeviceManager) getImageDownload(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
930 log.Debugw("getImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
931 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
932 return agent.getImageDownload(ctx, img)
933 }
934 return nil, status.Errorf(codes.NotFound, "%s", img.Id)
935}
936
937func (dMgr *DeviceManager) listImageDownloads(ctx context.Context, deviceId string) (*voltha.ImageDownloads, error) {
938 log.Debugw("listImageDownloads", log.Fields{"deviceId": deviceId})
939 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
940 return agent.listImageDownloads(ctx, deviceId)
941 }
942 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
943}
944
khenaidoo92e62c52018-10-03 14:02:54 -0400945func (dMgr *DeviceManager) activateDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400946 log.Info("activateDevice")
947 return nil
948}
949
khenaidoo92e62c52018-10-03 14:02:54 -0400950func (dMgr *DeviceManager) disableDeviceHandler(cDevice *voltha.Device) error {
951 log.Info("disableDevice-donothing")
khenaidoob9203542018-09-17 22:56:37 -0400952 return nil
953}
954
khenaidoo92e62c52018-10-03 14:02:54 -0400955func (dMgr *DeviceManager) abandonDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400956 log.Info("abandonDevice")
957 return nil
958}
959
khenaidoo92e62c52018-10-03 14:02:54 -0400960func (dMgr *DeviceManager) reEnableDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400961 log.Info("reEnableDevice")
962 return nil
963}
964
khenaidoo92e62c52018-10-03 14:02:54 -0400965func (dMgr *DeviceManager) noOp(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400966 log.Info("noOp")
967 return nil
968}
969
khenaidoo92e62c52018-10-03 14:02:54 -0400970func (dMgr *DeviceManager) notAllowed(pcDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400971 log.Info("notAllowed")
972 return errors.New("Transition-not-allowed")
973}
974
975func funcName(f interface{}) string {
976 p := reflect.ValueOf(f).Pointer()
977 rf := runtime.FuncForPC(p)
978 return rf.Name()
979}
980
981func (dMgr *DeviceManager) UpdateDeviceAttribute(deviceId string, attribute string, value interface{}) {
982 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
983 agent.updateDeviceAttribute(attribute, value)
984 }
985}
986
987func (dMgr *DeviceManager) GetParentDeviceId(deviceId string) *string {
khenaidoo19d7b632018-10-30 10:49:50 -0400988 if device, _ := dMgr.GetDevice(deviceId); device != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400989 log.Infow("GetParentDeviceId", log.Fields{"deviceId": device.Id, "parentId": device.ParentId})
khenaidoob9203542018-09-17 22:56:37 -0400990 return &device.ParentId
991 }
992 return nil
993}