blob: f9da623b18be1f157cfad01ec66c1749b0bf40fe [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"
William Kurkiandaa6bb22019-03-07 12:26:28 -050024 ic "github.com/opencord/voltha-protos/go/inter_container"
25 ofp "github.com/opencord/voltha-protos/go/openflow_13"
26 "github.com/opencord/voltha-protos/go/voltha"
khenaidoob9203542018-09-17 22:56:37 -040027 "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 {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400103 dMgr.lockDeviceAgentsMap.RLock()
khenaidoob9203542018-09-17 22:56:37 -0400104 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400105 dMgr.lockDeviceAgentsMap.RUnlock()
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
khenaidoo1ce37ad2019-03-24 22:07:24 -0400109 dMgr.lockDeviceAgentsMap.RUnlock()
khenaidoo297cd252019-02-07 22:10:23 -0500110 if err := dMgr.load(deviceId); err == nil {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400111 dMgr.lockDeviceAgentsMap.RLock()
112 defer dMgr.lockDeviceAgentsMap.RUnlock()
khenaidoo297cd252019-02-07 22:10:23 -0500113 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 {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400123 dMgr.lockDeviceAgentsMap.RLock()
124 defer dMgr.lockDeviceAgentsMap.RUnlock()
khenaidoo7ccedd52018-12-14 16:48:54 -0500125 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) {
Matt Jeanneret0c5088c2019-04-22 16:16:19 -0400208 log.Debugw("GetChildDevice", log.Fields{"parentDeviceid": parentDeviceId, "serialNumber": serialNumber,
209 "parentPortNo": parentPortNo, "onuId": onuId})
Matt Jeanneret4e241952019-02-28 11:16:04 -0500210
211 var parentDevice *voltha.Device
212 var err error
213 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
214 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
215 }
216 var childDeviceIds []string
217 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
218 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
219 }
220 if len(childDeviceIds) == 0 {
221 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id})
222 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
223 }
224
225 var foundChildDevice *voltha.Device
226 for _, childDeviceId := range childDeviceIds {
227 found := false
228 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
229
230 foundOnuId := false
231 if searchDevice.ProxyAddress.OnuId == uint32(onuId) {
232 if searchDevice.ParentPortNo == uint32(parentPortNo) {
233 log.Debugw("found-child-by-onuid", log.Fields{"parentDeviceId": parentDevice.Id, "onuId": onuId})
234 foundOnuId = true
235 }
236 }
237
238 foundSerialNumber := false
239 if searchDevice.SerialNumber == serialNumber {
240 log.Debugw("found-child-by-serialnumber", log.Fields{"parentDeviceId": parentDevice.Id, "serialNumber": serialNumber})
241 foundSerialNumber = true
242 }
243
244 // if both onuId and serialNumber are provided both must be true for the device to be found
245 // otherwise whichever one found a match is good enough
246 if onuId > 0 && serialNumber != "" {
247 found = foundOnuId && foundSerialNumber
248 } else {
249 found = foundOnuId || foundSerialNumber
250 }
251
252 if found == true {
253 foundChildDevice = searchDevice
254 break
255 }
256 }
257 }
258
259 if foundChildDevice != nil {
260 log.Debugw("child-device-found", log.Fields{"parentDeviceId": parentDevice.Id, "foundChildDevice": foundChildDevice})
261 return foundChildDevice, nil
262 }
263
264 log.Warnw("child-device-not-found", log.Fields{"parentDeviceId": parentDevice.Id,
265 "serialNumber": serialNumber, "onuId": onuId, "parentPortNo": parentPortNo})
266 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
267}
268
Matt Jeanneret2a20aaa2019-03-05 21:04:02 -0500269func (dMgr *DeviceManager) GetChildDeviceWithProxyAddress(proxyAddress *voltha.Device_ProxyAddress) (*voltha.Device, error) {
270 log.Debugw("GetChildDeviceWithProxyAddress", log.Fields{"proxyAddress": proxyAddress})
271
272 var parentDevice *voltha.Device
273 var err error
274 if parentDevice, err = dMgr.GetDevice(proxyAddress.DeviceId); err != nil {
275 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
276 }
277 var childDeviceIds []string
278 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
279 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
280 }
281 if len(childDeviceIds) == 0 {
282 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id})
283 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
284 }
285
286 var foundChildDevice *voltha.Device
287 for _, childDeviceId := range childDeviceIds {
288 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
289 if searchDevice.ProxyAddress == proxyAddress {
290 foundChildDevice = searchDevice
291 break
292 }
293 }
294 }
295
296 if foundChildDevice != nil {
297 log.Debugw("child-device-found", log.Fields{"proxyAddress": proxyAddress})
298 return foundChildDevice, nil
299 }
300
301 log.Warnw("child-device-not-found", log.Fields{"proxyAddress": proxyAddress})
302 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
303}
304
khenaidoo297cd252019-02-07 22:10:23 -0500305func (dMgr *DeviceManager) IsDeviceInCache(id string) bool {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400306 dMgr.lockDeviceAgentsMap.RLock()
307 defer dMgr.lockDeviceAgentsMap.RUnlock()
khenaidoo297cd252019-02-07 22:10:23 -0500308 _, exist := dMgr.deviceAgents[id]
309 return exist
310}
311
khenaidoo19d7b632018-10-30 10:49:50 -0400312func (dMgr *DeviceManager) IsRootDevice(id string) (bool, error) {
313 device, err := dMgr.GetDevice(id)
314 if err != nil {
315 return false, err
316 }
317 return device.Root, nil
318}
319
Stephane Barbarieaa467942019-02-06 14:09:44 -0500320// ListDevices retrieves the latest devices from the data model
khenaidoob9203542018-09-17 22:56:37 -0400321func (dMgr *DeviceManager) ListDevices() (*voltha.Devices, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400322 log.Debug("ListDevices")
khenaidoob9203542018-09-17 22:56:37 -0400323 result := &voltha.Devices{}
Stephane Barbarieaa467942019-02-06 14:09:44 -0500324 if devices := dMgr.clusterDataProxy.List("/devices", 0, false, ""); devices != nil {
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500325 for _, device := range devices.([]interface{}) {
khenaidoo297cd252019-02-07 22:10:23 -0500326 // If device is not in memory then set it up
327 if !dMgr.IsDeviceInCache(device.(*voltha.Device).Id) {
328 agent := newDeviceAgent(dMgr.adapterProxy, device.(*voltha.Device), dMgr, dMgr.clusterDataProxy)
329 if err := agent.start(nil, true); err != nil {
330 log.Warnw("failure-starting-agent", log.Fields{"deviceId": device.(*voltha.Device).Id})
331 agent.stop(nil)
332 } else {
333 dMgr.addDeviceAgentToMap(agent)
334 }
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500335 }
336 result.Items = append(result.Items, device.(*voltha.Device))
khenaidoob9203542018-09-17 22:56:37 -0400337 }
338 }
339 return result, nil
340}
341
khenaidoo297cd252019-02-07 22:10:23 -0500342// loadDevice loads the deviceId in memory, if not present
343func (dMgr *DeviceManager) loadDevice(deviceId string) (*DeviceAgent, error) {
344 log.Debugw("loading-device", log.Fields{"deviceId": deviceId})
345 // Sanity check
346 if deviceId == "" {
347 return nil, status.Error(codes.InvalidArgument, "deviceId empty")
348 }
349 if !dMgr.IsDeviceInCache(deviceId) {
350 agent := newDeviceAgent(dMgr.adapterProxy, &voltha.Device{Id: deviceId}, dMgr, dMgr.clusterDataProxy)
351 if err := agent.start(nil, true); err != nil {
352 agent.stop(nil)
353 return nil, err
354 }
355 dMgr.addDeviceAgentToMap(agent)
356 }
357 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
358 return agent, nil
359 }
Matt Jeanneret4e241952019-02-28 11:16:04 -0500360 return nil, status.Error(codes.NotFound, deviceId) // This should not happen
khenaidoo297cd252019-02-07 22:10:23 -0500361}
362
363// loadRootDeviceParentAndChildren loads the children and parents of a root device in memory
364func (dMgr *DeviceManager) loadRootDeviceParentAndChildren(device *voltha.Device) error {
365 log.Debugw("loading-parent-and-children", log.Fields{"deviceId": device.Id})
366 if device.Root {
367 // Scenario A
368 if device.ParentId != "" {
369 // Load logical device if needed.
370 if err := dMgr.logicalDeviceMgr.load(device.ParentId); err != nil {
371 log.Warnw("failure-loading-logical-device", log.Fields{"lDeviceId": device.ParentId})
372 }
373 } else {
374 log.Debugw("no-parent-to-load", log.Fields{"deviceId": device.Id})
375 }
376 // Load all child devices, if needed
377 if childDeviceIds, err := dMgr.getAllChildDeviceIds(device); err == nil {
378 for _, childDeviceId := range childDeviceIds {
379 if _, err := dMgr.loadDevice(childDeviceId); err != nil {
380 log.Warnw("failure-loading-device", log.Fields{"deviceId": childDeviceId})
381 return err
382 }
383 }
384 log.Debugw("loaded-children", log.Fields{"deviceId": device.Id, "numChildren": len(childDeviceIds)})
385 } else {
386 log.Debugw("no-child-to-load", log.Fields{"deviceId": device.Id})
387 }
388 }
389 return nil
390}
391
392// load loads the deviceId in memory, if not present, and also loads its accompanying parents and children. Loading
393// in memory is for improved performance. It is not imperative that a device needs to be in memory when a request
394// acting on the device is received by the core. In such a scenario, the Core will load the device in memory first
395// and the proceed with the request.
396func (dMgr *DeviceManager) load(deviceId string) error {
397 log.Debug("load...")
398 // First load the device - this may fail in case the device was deleted intentionally by the other core
399 var dAgent *DeviceAgent
400 var err error
401 if dAgent, err = dMgr.loadDevice(deviceId); err != nil {
402 log.Warnw("failure-loading-device", log.Fields{"deviceId": deviceId})
403 return err
404 }
405 // Get the loaded device details
406 var device *voltha.Device
407 if device, err = dAgent.getDevice(); err != nil {
408 return err
409 }
410
411 // If the device is in Pre-provisioning or deleted state stop here
412 if device.AdminState == voltha.AdminState_PREPROVISIONED || device.AdminState == voltha.AdminState_DELETED {
413 return nil
414 }
415
416 // Now we face two scenarios
417 if device.Root {
418 // Load all children as well as the parent of this device (logical_device)
419 if err := dMgr.loadRootDeviceParentAndChildren(device); err != nil {
420 log.Warnw("failure-loading-device-parent-and-children", log.Fields{"deviceId": deviceId})
421 return err
422 }
423 log.Debugw("successfully-loaded-parent-and-children", log.Fields{"deviceId": deviceId})
424 } else {
425 // Scenario B - use the parentId of that device (root device) to trigger the loading
426 if device.ParentId != "" {
427 return dMgr.load(device.ParentId)
428 }
429 }
430 return nil
431}
432
khenaidoo7ccedd52018-12-14 16:48:54 -0500433// ListDeviceIds retrieves the latest device IDs information from the data model (memory data only)
434func (dMgr *DeviceManager) ListDeviceIds() (*voltha.IDs, error) {
435 log.Debug("ListDeviceIDs")
436 // Report only device IDs that are in the device agent map
437 return dMgr.listDeviceIdsFromMap(), nil
438}
439
440//ReconcileDevices is a request to a voltha core to managed a list of devices based on their IDs
441func (dMgr *DeviceManager) ReconcileDevices(ctx context.Context, ids *voltha.IDs, ch chan interface{}) {
442 log.Debug("ReconcileDevices")
443 var res interface{}
444 if ids != nil {
445 toReconcile := len(ids.Items)
446 reconciled := 0
447 for _, id := range ids.Items {
448 // Act on the device only if its not present in the agent map
khenaidoo297cd252019-02-07 22:10:23 -0500449 if !dMgr.IsDeviceInCache(id.Id) {
khenaidoo7ccedd52018-12-14 16:48:54 -0500450 // Device Id not in memory
451 log.Debugw("reconciling-device", log.Fields{"id": id.Id})
khenaidoo297cd252019-02-07 22:10:23 -0500452 // Load device from dB
Matt Jeanneret4e241952019-02-28 11:16:04 -0500453 agent := newDeviceAgent(dMgr.adapterProxy, &voltha.Device{Id: id.Id}, dMgr, dMgr.clusterDataProxy)
khenaidoo297cd252019-02-07 22:10:23 -0500454 if err := agent.start(nil, true); err != nil {
455 log.Warnw("failure-loading-device", log.Fields{"deviceId": id.Id})
456 agent.stop(nil)
khenaidoo7ccedd52018-12-14 16:48:54 -0500457 } else {
khenaidoo297cd252019-02-07 22:10:23 -0500458 dMgr.addDeviceAgentToMap(agent)
459 reconciled += 1
khenaidoo7ccedd52018-12-14 16:48:54 -0500460 }
461 } else {
462 reconciled += 1
463 }
464 }
465 if toReconcile != reconciled {
466 res = status.Errorf(codes.DataLoss, "less-device-reconciled:%d/%d", reconciled, toReconcile)
467 }
468 } else {
469 res = status.Errorf(codes.InvalidArgument, "empty-list-of-ids")
470 }
471 sendResponse(ctx, ch, res)
472}
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500473
khenaidoob9203542018-09-17 22:56:37 -0400474func (dMgr *DeviceManager) updateDevice(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400475 log.Debugw("updateDevice", log.Fields{"deviceid": device.Id, "device": device})
khenaidoob9203542018-09-17 22:56:37 -0400476 if agent := dMgr.getDeviceAgent(device.Id); agent != nil {
477 return agent.updateDevice(device)
478 }
479 return status.Errorf(codes.NotFound, "%s", device.Id)
480}
481
482func (dMgr *DeviceManager) addPort(deviceId string, port *voltha.Port) error {
483 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400484 if err := agent.addPort(port); err != nil {
485 return err
486 }
487 // Setup peer ports
488 meAsPeer := &voltha.Port_PeerPort{DeviceId: deviceId, PortNo: port.PortNo}
489 for _, peerPort := range port.Peers {
490 if agent := dMgr.getDeviceAgent(peerPort.DeviceId); agent != nil {
491 if err := agent.addPeerPort(meAsPeer); err != nil {
492 log.Errorw("failed-to-add-peer", log.Fields{"peer-device-id": peerPort.DeviceId})
493 return err
494 }
495 }
496 }
khenaidoofc1314d2019-03-14 09:34:21 -0400497 // Notify the logical device manager to setup a logical port if needed
498 if port.Type == voltha.Port_ETHERNET_NNI || port.Type == voltha.Port_ETHERNET_UNI {
serkant.uluderya334479d2019-04-10 08:26:15 -0700499 if device, err := dMgr.GetDevice(deviceId); err == nil {
khenaidoofc1314d2019-03-14 09:34:21 -0400500 go dMgr.logicalDeviceMgr.addLogicalPort(device, port)
501 } else {
502 log.Errorw("failed-to-retrieve-device", log.Fields{"deviceId": deviceId})
503 return err
504 }
505 }
khenaidoo92e62c52018-10-03 14:02:54 -0400506 return nil
507 } else {
508 return status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoob9203542018-09-17 22:56:37 -0400509 }
khenaidoob9203542018-09-17 22:56:37 -0400510}
511
khenaidoo19d7b632018-10-30 10:49:50 -0400512func (dMgr *DeviceManager) updateFlows(deviceId string, flows []*ofp.OfpFlowStats) error {
513 log.Debugw("updateFlows", log.Fields{"deviceid": deviceId})
514 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
515 return agent.updateFlows(flows)
516 }
517 return status.Errorf(codes.NotFound, "%s", deviceId)
518}
519
520func (dMgr *DeviceManager) updateGroups(deviceId string, groups []*ofp.OfpGroupEntry) error {
521 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
522 return agent.updateGroups(groups)
523 }
524 return status.Errorf(codes.NotFound, "%s", deviceId)
525}
526
khenaidoob9203542018-09-17 22:56:37 -0400527func (dMgr *DeviceManager) updatePmConfigs(deviceId string, pmConfigs *voltha.PmConfigs) error {
528 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
529 return agent.updatePmConfigs(pmConfigs)
530 }
531 return status.Errorf(codes.NotFound, "%s", deviceId)
532}
533
khenaidoo79232702018-12-04 11:00:41 -0500534func (dMgr *DeviceManager) getSwitchCapability(ctx context.Context, deviceId string) (*ic.SwitchCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400535 log.Debugw("getSwitchCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400536 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
537 return agent.getSwitchCapability(ctx)
538 }
539 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
540}
541
khenaidoo92e62c52018-10-03 14:02:54 -0400542func (dMgr *DeviceManager) getPorts(ctx context.Context, deviceId string, portType voltha.Port_PortType) (*voltha.Ports, error) {
543 log.Debugw("getPorts", log.Fields{"deviceid": deviceId, "portType": portType})
khenaidoob9203542018-09-17 22:56:37 -0400544 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400545 return agent.getPorts(ctx, portType), nil
khenaidoob9203542018-09-17 22:56:37 -0400546 }
547 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoo92e62c52018-10-03 14:02:54 -0400548
khenaidoob9203542018-09-17 22:56:37 -0400549}
550
khenaidoo79232702018-12-04 11:00:41 -0500551func (dMgr *DeviceManager) getPortCapability(ctx context.Context, deviceId string, portNo uint32) (*ic.PortCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400552 log.Debugw("getPortCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400553 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
554 return agent.getPortCapability(ctx, portNo)
555 }
556 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
557}
558
khenaidoo92e62c52018-10-03 14:02:54 -0400559func (dMgr *DeviceManager) updateDeviceStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
560 log.Debugw("updateDeviceStatus", log.Fields{"deviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400561 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400562 return agent.updateDeviceStatus(operStatus, connStatus)
563 }
564 return status.Errorf(codes.NotFound, "%s", deviceId)
565}
566
khenaidoo4d4802d2018-10-04 21:59:49 -0400567func (dMgr *DeviceManager) updateChildrenStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
568 log.Debugw("updateChildrenStatus", log.Fields{"parentDeviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
569 var parentDevice *voltha.Device
570 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400571 if parentDevice, err = dMgr.GetDevice(deviceId); err != nil {
khenaidoo4d4802d2018-10-04 21:59:49 -0400572 return status.Errorf(codes.Aborted, "%s", err.Error())
573 }
574 var childDeviceIds []string
575 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
576 return status.Errorf(codes.Aborted, "%s", err.Error())
577 }
578 if len(childDeviceIds) == 0 {
579 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
580 }
581 for _, childDeviceId := range childDeviceIds {
582 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
583 if err = agent.updateDeviceStatus(operStatus, connStatus); err != nil {
584 return status.Errorf(codes.Aborted, "childDevice:%s, error:%s", childDeviceId, err.Error())
585 }
586 }
587 }
588 return nil
589}
590
khenaidoo92e62c52018-10-03 14:02:54 -0400591func (dMgr *DeviceManager) updatePortState(deviceId string, portType voltha.Port_PortType, portNo uint32, operStatus voltha.OperStatus_OperStatus) error {
592 log.Debugw("updatePortState", log.Fields{"deviceid": deviceId, "portType": portType, "portNo": portNo, "operStatus": operStatus})
593 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
594 return agent.updatePortState(portType, portNo, operStatus)
khenaidoob9203542018-09-17 22:56:37 -0400595 }
596 return status.Errorf(codes.NotFound, "%s", deviceId)
597}
598
Matt Jeanneret4e241952019-02-28 11:16:04 -0500599func (dMgr *DeviceManager) childDeviceDetected(parentDeviceId string, parentPortNo int64, deviceType string,
600 channelId int64, vendorId string, serialNumber string, onuId int64) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400601 log.Debugw("childDeviceDetected", log.Fields{"parentDeviceId": parentDeviceId})
khenaidoob9203542018-09-17 22:56:37 -0400602
603 // Create the ONU device
604 childDevice := &voltha.Device{}
khenaidoob9203542018-09-17 22:56:37 -0400605 childDevice.Type = deviceType
606 childDevice.ParentId = parentDeviceId
607 childDevice.ParentPortNo = uint32(parentPortNo)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500608 childDevice.VendorId = vendorId
609 childDevice.SerialNumber = serialNumber
khenaidoob9203542018-09-17 22:56:37 -0400610 childDevice.Root = false
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400611
612 //Get parent device type
613 parent, err := dMgr.GetDevice(parentDeviceId)
614 if err != nil {
khenaidoo43c82122018-11-22 18:38:28 -0500615 log.Error("no-parent-found", log.Fields{"parentId": parentDeviceId})
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400616 return status.Errorf(codes.NotFound, "%s", parentDeviceId)
617 }
618
Matt Jeanneret4e241952019-02-28 11:16:04 -0500619 if _, err := dMgr.GetChildDevice(parentDeviceId, serialNumber, onuId, parentPortNo); err == nil {
620 log.Warnw("child-device-exists", log.Fields{"parentId": parentDeviceId, "serialNumber": serialNumber})
621 return status.Errorf(codes.AlreadyExists, "%s", serialNumber)
622 }
623
624 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{DeviceId: parentDeviceId, DeviceType: parent.Type, ChannelId: uint32(channelId), OnuId: uint32(onuId)}
khenaidoob9203542018-09-17 22:56:37 -0400625
626 // Create and start a device agent for that device
khenaidoo9a468962018-09-19 15:33:13 -0400627 agent := newDeviceAgent(dMgr.adapterProxy, childDevice, dMgr, dMgr.clusterDataProxy)
khenaidoob9203542018-09-17 22:56:37 -0400628 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500629 agent.start(nil, false)
khenaidoob9203542018-09-17 22:56:37 -0400630
khenaidoo1ce37ad2019-03-24 22:07:24 -0400631 //// Set device ownership
632 //dMgr.core.deviceOwnership.OwnedByMe(agent.deviceId)
Richard Jankowski199fd862019-03-18 14:49:51 -0400633
khenaidoob9203542018-09-17 22:56:37 -0400634 // Activate the child device
khenaidoo92e62c52018-10-03 14:02:54 -0400635 if agent := dMgr.getDeviceAgent(agent.deviceId); agent != nil {
khenaidoo79232702018-12-04 11:00:41 -0500636 go agent.enableDevice(nil)
khenaidoob9203542018-09-17 22:56:37 -0400637 }
638
khenaidoo79232702018-12-04 11:00:41 -0500639 // Publish on the messaging bus that we have discovered new devices
khenaidoo19374072018-12-11 11:05:15 -0500640 go dMgr.kafkaICProxy.DeviceDiscovered(agent.deviceId, deviceType, parentDeviceId, dMgr.coreInstanceId)
khenaidoo79232702018-12-04 11:00:41 -0500641
khenaidoob9203542018-09-17 22:56:37 -0400642 return nil
643}
644
645func (dMgr *DeviceManager) processTransition(previous *voltha.Device, current *voltha.Device) error {
646 // This will be triggered on every update to the device.
khenaidoo92e62c52018-10-03 14:02:54 -0400647 handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
648 if handlers == nil {
khenaidoo43c82122018-11-22 18:38:28 -0500649 log.Debugw("no-op-transition", log.Fields{"deviceId": current.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400650 return nil
khenaidoob9203542018-09-17 22:56:37 -0400651 }
khenaidoo92e62c52018-10-03 14:02:54 -0400652 for _, handler := range handlers {
653 log.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
654 if err := handler(current); err != nil {
655 return err
656 }
657 }
khenaidoob9203542018-09-17 22:56:37 -0400658 return nil
659}
660
khenaidoofdbad6e2018-11-06 22:26:38 -0500661func (dMgr *DeviceManager) packetOut(deviceId string, outPort uint32, packet *ofp.OfpPacketOut) error {
662 log.Debugw("packetOut", log.Fields{"deviceId": deviceId, "outPort": outPort})
663 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
664 return agent.packetOut(outPort, packet)
665 }
666 return status.Errorf(codes.NotFound, "%s", deviceId)
667}
668
khenaidoo297cd252019-02-07 22:10:23 -0500669func (dMgr *DeviceManager) PacketIn(deviceId string, port uint32, transactionId string, packet []byte) error {
khenaidoofdbad6e2018-11-06 22:26:38 -0500670 log.Debugw("PacketIn", log.Fields{"deviceId": deviceId, "port": port})
671 // Get the logical device Id based on the deviceId
672 var device *voltha.Device
673 var err error
674 if device, err = dMgr.GetDevice(deviceId); err != nil {
675 log.Errorw("device-not-found", log.Fields{"deviceId": deviceId})
676 return err
677 }
khenaidoo43c82122018-11-22 18:38:28 -0500678 if !device.Root {
khenaidoofdbad6e2018-11-06 22:26:38 -0500679 log.Errorw("device-not-root", log.Fields{"deviceId": deviceId})
680 return status.Errorf(codes.FailedPrecondition, "%s", deviceId)
681 }
682
khenaidoo297cd252019-02-07 22:10:23 -0500683 if err := dMgr.logicalDeviceMgr.packetIn(device.ParentId, port, transactionId, packet); err != nil {
khenaidoofdbad6e2018-11-06 22:26:38 -0500684 return err
685 }
686 return nil
687}
688
khenaidoo92e62c52018-10-03 14:02:54 -0400689func (dMgr *DeviceManager) createLogicalDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400690 log.Info("createLogicalDevice")
691 var logicalId *string
692 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400693 if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400694 log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
695 return err
696 }
697 // Update the parent device with the logical id
698 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
699 return nil
700}
701
khenaidoo92e62c52018-10-03 14:02:54 -0400702func (dMgr *DeviceManager) deleteLogicalDevice(cDevice *voltha.Device) error {
703 log.Info("deleteLogicalDevice")
704 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400705 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400706 log.Warnw("deleteLogical-device-error", log.Fields{"deviceId": cDevice.Id})
707 return err
708 }
709 // Remove the logical device Id from the parent device
710 logicalId := ""
711 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", logicalId)
712 return nil
713}
714
khenaidoo19d7b632018-10-30 10:49:50 -0400715func (dMgr *DeviceManager) deleteLogicalPort(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400716 log.Info("deleteLogicalPort")
717 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400718 // Get the logical port associated with this device
719 var lPortId *voltha.LogicalPortId
720 if lPortId, err = dMgr.logicalDeviceMgr.getLogicalPortId(device); err != nil {
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400721 log.Warnw("getLogical-port-error", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo19d7b632018-10-30 10:49:50 -0400722 return err
723 }
724 if err = dMgr.logicalDeviceMgr.deleteLogicalPort(nil, lPortId); err != nil {
725 log.Warnw("deleteLogical-port-error", log.Fields{"deviceId": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400726 return err
727 }
khenaidoo92e62c52018-10-03 14:02:54 -0400728 return nil
729}
730
731func (dMgr *DeviceManager) getParentDevice(childDevice *voltha.Device) *voltha.Device {
732 // Sanity check
733 if childDevice.Root {
734 // childDevice is the parent device
735 return childDevice
736 }
khenaidoo19d7b632018-10-30 10:49:50 -0400737 parentDevice, _ := dMgr.GetDevice(childDevice.ParentId)
khenaidoo92e62c52018-10-03 14:02:54 -0400738 return parentDevice
739}
740
khenaidoo4d4802d2018-10-04 21:59:49 -0400741/*
742All the functions below are callback functions where they are invoked with the latest and previous data. We can
743therefore use the data as is without trying to get the latest from the model.
744*/
745
746//disableAllChildDevices is invoked as a callback when the parent device is disabled
747func (dMgr *DeviceManager) disableAllChildDevices(parentDevice *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400748 log.Debug("disableAllChildDevices")
749 var childDeviceIds []string
750 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400751 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
752 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400753 }
754 if len(childDeviceIds) == 0 {
khenaidoo4d4802d2018-10-04 21:59:49 -0400755 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400756 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400757 allChildDisable := true
khenaidoo92e62c52018-10-03 14:02:54 -0400758 for _, childDeviceId := range childDeviceIds {
759 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
760 if err = agent.disableDevice(nil); err != nil {
761 log.Errorw("failure-disable-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
khenaidoo4d4802d2018-10-04 21:59:49 -0400762 allChildDisable = false
khenaidoo92e62c52018-10-03 14:02:54 -0400763 }
764 }
765 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400766 if !allChildDisable {
767 return err
768 }
khenaidoo92e62c52018-10-03 14:02:54 -0400769 return nil
770}
771
khenaidoo4d4802d2018-10-04 21:59:49 -0400772//deleteAllChildDevices is invoked as a callback when the parent device is deleted
773func (dMgr *DeviceManager) deleteAllChildDevices(parentDevice *voltha.Device) error {
774 log.Debug("deleteAllChildDevices")
775 var childDeviceIds []string
khenaidoo92e62c52018-10-03 14:02:54 -0400776 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400777 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
778 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400779 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400780 if len(childDeviceIds) == 0 {
781 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
782 }
783 allChildDeleted := true
784 for _, childDeviceId := range childDeviceIds {
785 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
786 if err = agent.deleteDevice(nil); err != nil {
787 log.Errorw("failure-delete-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
788 allChildDeleted = false
789 } else {
790 agent.stop(nil)
791 dMgr.deleteDeviceAgentToMap(agent)
792 }
793 }
794 }
795 if !allChildDeleted {
796 return err
797 }
798 return nil
799}
800
801//getAllChildDeviceIds is a helper method to get all the child device IDs from the device passed as parameter
802func (dMgr *DeviceManager) getAllChildDeviceIds(parentDevice *voltha.Device) ([]string, error) {
803 log.Debugw("getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400804 childDeviceIds := make([]string, 0)
khenaidoo4d4802d2018-10-04 21:59:49 -0400805 if parentDevice != nil {
806 for _, port := range parentDevice.Ports {
807 for _, peer := range port.Peers {
808 childDeviceIds = append(childDeviceIds, peer.DeviceId)
809 }
khenaidoo92e62c52018-10-03 14:02:54 -0400810 }
811 }
Matt Jeanneret4e241952019-02-28 11:16:04 -0500812 log.Debugw("returning-getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id, "childDeviceIds": childDeviceIds})
khenaidoo92e62c52018-10-03 14:02:54 -0400813 return childDeviceIds, nil
814}
815
khenaidoo297cd252019-02-07 22:10:23 -0500816//getAllChildDevices is a helper method to get all the child device IDs from the device passed as parameter
817func (dMgr *DeviceManager) getAllChildDevices(parentDeviceId string) (*voltha.Devices, error) {
818 log.Debugw("getAllChildDevices", log.Fields{"parentDeviceId": parentDeviceId})
819 if parentDevice, err := dMgr.GetDevice(parentDeviceId); err == nil {
820 childDevices := make([]*voltha.Device, 0)
821 if childDeviceIds, er := dMgr.getAllChildDeviceIds(parentDevice); er == nil {
822 for _, deviceId := range childDeviceIds {
823 if d, e := dMgr.GetDevice(deviceId); e == nil && d != nil {
824 childDevices = append(childDevices, d)
825 }
826 }
827 }
828 return &voltha.Devices{Items: childDevices}, nil
829 }
830 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
831}
832
khenaidoofc1314d2019-03-14 09:34:21 -0400833func (dMgr *DeviceManager) setupUNILogicalPorts(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400834 log.Info("addUNILogicalPort")
khenaidoofc1314d2019-03-14 09:34:21 -0400835 if err := dMgr.logicalDeviceMgr.setupUNILogicalPorts(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400836 log.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
837 return err
838 }
839 return nil
840}
841
khenaidoof5a5bfa2019-01-23 22:20:29 -0500842func (dMgr *DeviceManager) downloadImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
843 log.Debugw("downloadImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
844 var res interface{}
845 var err error
846 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
847 if res, err = agent.downloadImage(ctx, img); err != nil {
848 log.Debugw("downloadImage-failed", log.Fields{"err": err, "imageName": img.Name})
849 res = err
850 }
851 } else {
852 res = status.Errorf(codes.NotFound, "%s", img.Id)
853 }
854 sendResponse(ctx, ch, res)
855}
856
857func (dMgr *DeviceManager) cancelImageDownload(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
858 log.Debugw("cancelImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
859 var res interface{}
860 var err error
861 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
862 if res, err = agent.cancelImageDownload(ctx, img); err != nil {
863 log.Debugw("cancelImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
864 res = err
865 }
866 } else {
867 res = status.Errorf(codes.NotFound, "%s", img.Id)
868 }
869 sendResponse(ctx, ch, res)
870}
871
872func (dMgr *DeviceManager) activateImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
873 log.Debugw("activateImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
874 var res interface{}
875 var err error
876 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
877 if res, err = agent.activateImage(ctx, img); err != nil {
878 log.Debugw("activateImage-failed", log.Fields{"err": err, "imageName": img.Name})
879 res = err
880 }
881 } else {
882 res = status.Errorf(codes.NotFound, "%s", img.Id)
883 }
884 sendResponse(ctx, ch, res)
885}
886
887func (dMgr *DeviceManager) revertImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
888 log.Debugw("revertImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
889 var res interface{}
890 var err error
891 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
892 if res, err = agent.revertImage(ctx, img); err != nil {
893 log.Debugw("revertImage-failed", log.Fields{"err": err, "imageName": img.Name})
894 res = err
895 }
896 } else {
897 res = status.Errorf(codes.NotFound, "%s", img.Id)
898 }
899 sendResponse(ctx, ch, res)
900}
901
902func (dMgr *DeviceManager) getImageDownloadStatus(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
903 log.Debugw("getImageDownloadStatus", log.Fields{"deviceid": img.Id, "imageName": img.Name})
904 var res interface{}
905 var err error
906 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
907 if res, err = agent.getImageDownloadStatus(ctx, img); err != nil {
908 log.Debugw("getImageDownloadStatus-failed", log.Fields{"err": err, "imageName": img.Name})
909 res = err
910 }
911 } else {
912 res = status.Errorf(codes.NotFound, "%s", img.Id)
913 }
914 sendResponse(ctx, ch, res)
915}
916
khenaidoof5a5bfa2019-01-23 22:20:29 -0500917func (dMgr *DeviceManager) updateImageDownload(deviceId string, img *voltha.ImageDownload) error {
918 log.Debugw("updateImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
919 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
920 if err := agent.updateImageDownload(img); err != nil {
921 log.Debugw("updateImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
922 return err
923 }
924 } else {
925 return status.Errorf(codes.NotFound, "%s", img.Id)
926 }
927 return nil
928}
929
930func (dMgr *DeviceManager) getImageDownload(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
931 log.Debugw("getImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
932 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
933 return agent.getImageDownload(ctx, img)
934 }
935 return nil, status.Errorf(codes.NotFound, "%s", img.Id)
936}
937
938func (dMgr *DeviceManager) listImageDownloads(ctx context.Context, deviceId string) (*voltha.ImageDownloads, error) {
939 log.Debugw("listImageDownloads", log.Fields{"deviceId": deviceId})
940 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
941 return agent.listImageDownloads(ctx, deviceId)
942 }
943 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
944}
945
khenaidoo92e62c52018-10-03 14:02:54 -0400946func (dMgr *DeviceManager) activateDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400947 log.Info("activateDevice")
948 return nil
949}
950
khenaidoo92e62c52018-10-03 14:02:54 -0400951func (dMgr *DeviceManager) disableDeviceHandler(cDevice *voltha.Device) error {
952 log.Info("disableDevice-donothing")
khenaidoob9203542018-09-17 22:56:37 -0400953 return nil
954}
955
khenaidoo92e62c52018-10-03 14:02:54 -0400956func (dMgr *DeviceManager) abandonDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400957 log.Info("abandonDevice")
958 return nil
959}
960
khenaidoo92e62c52018-10-03 14:02:54 -0400961func (dMgr *DeviceManager) reEnableDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400962 log.Info("reEnableDevice")
963 return nil
964}
965
khenaidoo92e62c52018-10-03 14:02:54 -0400966func (dMgr *DeviceManager) noOp(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400967 log.Info("noOp")
968 return nil
969}
970
khenaidoo92e62c52018-10-03 14:02:54 -0400971func (dMgr *DeviceManager) notAllowed(pcDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -0400972 log.Info("notAllowed")
973 return errors.New("Transition-not-allowed")
974}
975
976func funcName(f interface{}) string {
977 p := reflect.ValueOf(f).Pointer()
978 rf := runtime.FuncForPC(p)
979 return rf.Name()
980}
981
982func (dMgr *DeviceManager) UpdateDeviceAttribute(deviceId string, attribute string, value interface{}) {
983 if agent, ok := dMgr.deviceAgents[deviceId]; ok {
984 agent.updateDeviceAttribute(attribute, value)
985 }
986}
987
988func (dMgr *DeviceManager) GetParentDeviceId(deviceId string) *string {
khenaidoo19d7b632018-10-30 10:49:50 -0400989 if device, _ := dMgr.GetDevice(deviceId); device != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400990 log.Infow("GetParentDeviceId", log.Fields{"deviceId": device.Id, "parentId": device.ParentId})
khenaidoob9203542018-09-17 22:56:37 -0400991 return &device.ParentId
992 }
993 return nil
994}
serkant.uluderya334479d2019-04-10 08:26:15 -0700995
996func (dMgr *DeviceManager) simulateAlarm(ctx context.Context, simulatereq *voltha.SimulateAlarmRequest, ch chan interface{}) {
997 log.Debugw("simulateAlarm", log.Fields{"id": simulatereq.Id, "Indicator": simulatereq.Indicator, "IntfId": simulatereq.IntfId,
998 "PortTypeName": simulatereq.PortTypeName, "OnuDeviceId": simulatereq.OnuDeviceId, "InverseBitErrorRate": simulatereq.InverseBitErrorRate,
999 "Drift": simulatereq.Drift, "NewEqd": simulatereq.NewEqd, "OnuSerialNumber": simulatereq.OnuSerialNumber, "Operation": simulatereq.Operation})
1000 var res interface{}
1001 if agent := dMgr.getDeviceAgent(simulatereq.Id); agent != nil {
1002 res = agent.simulateAlarm(ctx, simulatereq)
1003 log.Debugw("SimulateAlarm-result", log.Fields{"result": res})
1004 }
1005 //TODO CLI always get successful response
1006 sendResponse(ctx, ch, res)
1007}