blob: f92645bdbc234b04b19dc0673130982deb104c90 [file] [log] [blame]
khenaidoob9203542018-09-17 22:56:37 -04001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package core
17
18import (
19 "context"
20 "errors"
21 "github.com/opencord/voltha-go/common/log"
22 "github.com/opencord/voltha-go/db/model"
23 "github.com/opencord/voltha-go/kafka"
khenaidoo3d3b8c22019-05-22 18:10:39 -040024 "github.com/opencord/voltha-go/rw_core/utils"
William Kurkiandaa6bb22019-03-07 12:26:28 -050025 ic "github.com/opencord/voltha-protos/go/inter_container"
26 ofp "github.com/opencord/voltha-protos/go/openflow_13"
27 "github.com/opencord/voltha-protos/go/voltha"
khenaidoob9203542018-09-17 22:56:37 -040028 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/status"
30 "reflect"
31 "runtime"
32 "sync"
33)
34
35type DeviceManager struct {
Stephane Barbarieef6650d2019-07-18 12:15:09 -040036 deviceAgents sync.Map
37 rootDevices map[string]bool
38 lockRootDeviceMap sync.RWMutex
39 core *Core
40 adapterProxy *AdapterProxy
41 adapterMgr *AdapterManager
42 logicalDeviceMgr *LogicalDeviceManager
43 kafkaICProxy *kafka.InterContainerProxy
44 stateTransitions *TransitionMap
45 clusterDataProxy *model.Proxy
46 coreInstanceId string
47 exitChannel chan int
48 defaultTimeout int64
khenaidoob9203542018-09-17 22:56:37 -040049}
50
Richard Jankowski199fd862019-03-18 14:49:51 -040051func newDeviceManager(core *Core) *DeviceManager {
khenaidoob9203542018-09-17 22:56:37 -040052 var deviceMgr DeviceManager
Richard Jankowski199fd862019-03-18 14:49:51 -040053 deviceMgr.core = core
khenaidoob9203542018-09-17 22:56:37 -040054 deviceMgr.exitChannel = make(chan int, 1)
khenaidoo2c6a0992019-04-29 13:46:56 -040055 deviceMgr.rootDevices = make(map[string]bool)
Richard Jankowski199fd862019-03-18 14:49:51 -040056 deviceMgr.kafkaICProxy = core.kmp
57 deviceMgr.adapterProxy = NewAdapterProxy(core.kmp)
58 deviceMgr.coreInstanceId = core.instanceId
59 deviceMgr.clusterDataProxy = core.clusterDataProxy
60 deviceMgr.adapterMgr = core.adapterMgr
khenaidoo2c6a0992019-04-29 13:46:56 -040061 deviceMgr.lockRootDeviceMap = sync.RWMutex{}
62 deviceMgr.defaultTimeout = core.config.DefaultCoreTimeout
khenaidoob9203542018-09-17 22:56:37 -040063 return &deviceMgr
64}
65
khenaidoo4d4802d2018-10-04 21:59:49 -040066func (dMgr *DeviceManager) start(ctx context.Context, logicalDeviceMgr *LogicalDeviceManager) {
khenaidoob9203542018-09-17 22:56:37 -040067 log.Info("starting-device-manager")
68 dMgr.logicalDeviceMgr = logicalDeviceMgr
69 dMgr.stateTransitions = NewTransitionMap(dMgr)
70 log.Info("device-manager-started")
71}
72
khenaidoo4d4802d2018-10-04 21:59:49 -040073func (dMgr *DeviceManager) stop(ctx context.Context) {
khenaidoob9203542018-09-17 22:56:37 -040074 log.Info("stopping-device-manager")
75 dMgr.exitChannel <- 1
76 log.Info("device-manager-stopped")
77}
78
79func sendResponse(ctx context.Context, ch chan interface{}, result interface{}) {
80 if ctx.Err() == nil {
81 // Returned response only of the ctx has not been cancelled/timeout/etc
82 // Channel is automatically closed when a context is Done
83 ch <- result
84 log.Debugw("sendResponse", log.Fields{"result": result})
85 } else {
86 // Should the transaction be reverted back?
87 log.Debugw("sendResponse-context-error", log.Fields{"context-error": ctx.Err()})
88 }
89}
90
91func (dMgr *DeviceManager) addDeviceAgentToMap(agent *DeviceAgent) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -040092 if _, exist := dMgr.deviceAgents.Load(agent.deviceId); !exist {
93 dMgr.deviceAgents.Store(agent.deviceId, agent)
khenaidoob9203542018-09-17 22:56:37 -040094 }
khenaidoo2c6a0992019-04-29 13:46:56 -040095 dMgr.lockRootDeviceMap.Lock()
96 defer dMgr.lockRootDeviceMap.Unlock()
97 dMgr.rootDevices[agent.deviceId] = agent.isRootdevice
98
khenaidoob9203542018-09-17 22:56:37 -040099}
100
khenaidoo4d4802d2018-10-04 21:59:49 -0400101func (dMgr *DeviceManager) deleteDeviceAgentToMap(agent *DeviceAgent) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400102 dMgr.deviceAgents.Delete(agent.deviceId)
khenaidoo2c6a0992019-04-29 13:46:56 -0400103 dMgr.lockRootDeviceMap.Lock()
104 defer dMgr.lockRootDeviceMap.Unlock()
105 delete(dMgr.rootDevices, agent.deviceId)
khenaidoo4d4802d2018-10-04 21:59:49 -0400106}
107
khenaidoo297cd252019-02-07 22:10:23 -0500108// getDeviceAgent returns the agent managing the device. If the device is not in memory, it will loads it, if it exists
khenaidoob9203542018-09-17 22:56:37 -0400109func (dMgr *DeviceManager) getDeviceAgent(deviceId string) *DeviceAgent {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400110 if agent, ok := dMgr.deviceAgents.Load(deviceId); ok {
111 return agent.(*DeviceAgent)
khenaidoo297cd252019-02-07 22:10:23 -0500112 } else {
khenaidoo3d3b8c22019-05-22 18:10:39 -0400113 // Try to load into memory - loading will also create the device agent and set the device ownership
khenaidoo297cd252019-02-07 22:10:23 -0500114 if err := dMgr.load(deviceId); err == nil {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400115 if agent, ok = dMgr.deviceAgents.Load(deviceId); !ok {
khenaidoo3d3b8c22019-05-22 18:10:39 -0400116 return nil
117 } else {
118 // Register this device for ownership tracking
119 go dMgr.core.deviceOwnership.OwnedByMe(&utils.DeviceID{Id: deviceId})
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400120 return agent.(*DeviceAgent)
khenaidoo297cd252019-02-07 22:10:23 -0500121 }
khenaidoo3d3b8c22019-05-22 18:10:39 -0400122 } else {
123 //TODO: Change the return params to return an error as well
124 log.Errorw("loading-device-failed", log.Fields{"deviceId": deviceId, "error": err})
khenaidoo297cd252019-02-07 22:10:23 -0500125 }
khenaidoob9203542018-09-17 22:56:37 -0400126 }
127 return nil
128}
129
khenaidoo297cd252019-02-07 22:10:23 -0500130// listDeviceIdsFromMap returns the list of device IDs that are in memory
khenaidoo7ccedd52018-12-14 16:48:54 -0500131func (dMgr *DeviceManager) listDeviceIdsFromMap() *voltha.IDs {
khenaidoo7ccedd52018-12-14 16:48:54 -0500132 result := &voltha.IDs{Items: make([]*voltha.ID, 0)}
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400133
134 dMgr.deviceAgents.Range(func(key, value interface{}) bool {
135 result.Items = append(result.Items, &voltha.ID{Id: key.(string)})
136 return true
137 })
138
khenaidoo7ccedd52018-12-14 16:48:54 -0500139 return result
140}
141
khenaidoob9203542018-09-17 22:56:37 -0400142func (dMgr *DeviceManager) createDevice(ctx context.Context, device *voltha.Device, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400143 log.Debugw("createDevice", log.Fields{"device": device, "aproxy": dMgr.adapterProxy})
khenaidoob9203542018-09-17 22:56:37 -0400144
khenaidoo5e677ae2019-02-28 17:26:29 -0500145 // Ensure this device is set as root
146 device.Root = true
khenaidoob9203542018-09-17 22:56:37 -0400147 // Create and start a device agent for that device
khenaidoo2c6a0992019-04-29 13:46:56 -0400148 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
khenaidoob9203542018-09-17 22:56:37 -0400149 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500150 agent.start(ctx, false)
khenaidoob9203542018-09-17 22:56:37 -0400151
khenaidoo92e62c52018-10-03 14:02:54 -0400152 sendResponse(ctx, ch, agent.lastData)
khenaidoob9203542018-09-17 22:56:37 -0400153}
154
155func (dMgr *DeviceManager) enableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
khenaidoo92e62c52018-10-03 14:02:54 -0400156 log.Debugw("enableDevice", log.Fields{"deviceid": id})
khenaidoob9203542018-09-17 22:56:37 -0400157 var res interface{}
158 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
159 res = agent.enableDevice(ctx)
160 log.Debugw("EnableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400161 }
162
163 sendResponse(ctx, ch, res)
164}
165
khenaidoo92e62c52018-10-03 14:02:54 -0400166func (dMgr *DeviceManager) disableDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
167 log.Debugw("disableDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400168 var res interface{}
169 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
170 res = agent.disableDevice(ctx)
171 log.Debugw("disableDevice-result", log.Fields{"result": res})
khenaidoob9203542018-09-17 22:56:37 -0400172 } else {
khenaidoo92e62c52018-10-03 14:02:54 -0400173 res = status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoob9203542018-09-17 22:56:37 -0400174 }
khenaidoo92e62c52018-10-03 14:02:54 -0400175
176 sendResponse(ctx, ch, res)
177}
178
khenaidoo4d4802d2018-10-04 21:59:49 -0400179func (dMgr *DeviceManager) rebootDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
180 log.Debugw("rebootDevice", log.Fields{"deviceid": id})
181 var res interface{}
182 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
183 res = agent.rebootDevice(ctx)
184 log.Debugw("rebootDevice-result", log.Fields{"result": res})
185 } else {
186 res = status.Errorf(codes.NotFound, "%s", id.Id)
187 }
188 sendResponse(ctx, ch, res)
189}
190
191func (dMgr *DeviceManager) deleteDevice(ctx context.Context, id *voltha.ID, ch chan interface{}) {
192 log.Debugw("deleteDevice", log.Fields{"deviceid": id})
193 var res interface{}
194 if agent := dMgr.getDeviceAgent(id.Id); agent != nil {
195 res = agent.deleteDevice(ctx)
khenaidoo4d4802d2018-10-04 21:59:49 -0400196 log.Debugw("deleteDevice-result", log.Fields{"result": res})
197 } else {
198 res = status.Errorf(codes.NotFound, "%s", id.Id)
199 }
200 sendResponse(ctx, ch, res)
201}
202
khenaidoo6d62c002019-05-15 21:57:03 -0400203// stopManagingDevice stops the management of the device as well as any of its reference device and logical device.
204// This function is called only in the Core that does not own this device. In the Core that owns this device then a
205// deletion deletion also includes removal of any reference of this device.
206func (dMgr *DeviceManager) stopManagingDevice(id string) {
207 log.Infow("stopManagingDevice", log.Fields{"deviceId": id})
208 if dMgr.IsDeviceInCache(id) { // Proceed only if an agent is present for this device
209 if root, _ := dMgr.IsRootDevice(id); root == true {
210 // stop managing the logical device
211 ldeviceId := dMgr.logicalDeviceMgr.stopManagingLogicalDeviceWithDeviceId(id)
212 if ldeviceId != "" { // Can happen if logical device agent was already stopped
213 dMgr.core.deviceOwnership.AbandonDevice(ldeviceId)
214 }
215 // stop managing the child devices
216 childDeviceIds := dMgr.getAllDeviceIdsWithDeviceParentId(id)
217 for _, cId := range childDeviceIds {
218 dMgr.stopManagingDevice(cId)
219 }
220 }
221 if agent := dMgr.getDeviceAgent(id); agent != nil {
222 agent.stop(nil)
223 dMgr.deleteDeviceAgentToMap(agent)
224 // Abandon the device ownership
225 dMgr.core.deviceOwnership.AbandonDevice(id)
226 }
227 }
228}
229
khenaidoo0a822f92019-05-08 15:15:57 -0400230func (dMgr *DeviceManager) RunPostDeviceDelete(cDevice *voltha.Device) error {
231 log.Infow("RunPostDeviceDelete", log.Fields{"deviceId": cDevice.Id})
khenaidoo6d62c002019-05-15 21:57:03 -0400232 dMgr.stopManagingDevice(cDevice.Id)
233 return nil
khenaidoo0a822f92019-05-08 15:15:57 -0400234}
235
khenaidoo297cd252019-02-07 22:10:23 -0500236// GetDevice will returns a device, either from memory or from the dB, if present
khenaidoo19d7b632018-10-30 10:49:50 -0400237func (dMgr *DeviceManager) GetDevice(id string) (*voltha.Device, error) {
238 log.Debugw("GetDevice", log.Fields{"deviceid": id})
khenaidoo92e62c52018-10-03 14:02:54 -0400239 if agent := dMgr.getDeviceAgent(id); agent != nil {
240 return agent.getDevice()
241 }
242 return nil, status.Errorf(codes.NotFound, "%s", id)
khenaidoob9203542018-09-17 22:56:37 -0400243}
244
Matt Jeanneret4e241952019-02-28 11:16:04 -0500245func (dMgr *DeviceManager) GetChildDevice(parentDeviceId string, serialNumber string, onuId int64, parentPortNo int64) (*voltha.Device, error) {
Matt Jeanneret0c5088c2019-04-22 16:16:19 -0400246 log.Debugw("GetChildDevice", log.Fields{"parentDeviceid": parentDeviceId, "serialNumber": serialNumber,
247 "parentPortNo": parentPortNo, "onuId": onuId})
Matt Jeanneret4e241952019-02-28 11:16:04 -0500248
249 var parentDevice *voltha.Device
250 var err error
251 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
252 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
253 }
254 var childDeviceIds []string
255 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
256 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
257 }
258 if len(childDeviceIds) == 0 {
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700259 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id, "serialNumber": serialNumber, "onuId": onuId})
Matt Jeanneret4e241952019-02-28 11:16:04 -0500260 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
261 }
262
263 var foundChildDevice *voltha.Device
264 for _, childDeviceId := range childDeviceIds {
265 found := false
266 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
267
268 foundOnuId := false
269 if searchDevice.ProxyAddress.OnuId == uint32(onuId) {
270 if searchDevice.ParentPortNo == uint32(parentPortNo) {
271 log.Debugw("found-child-by-onuid", log.Fields{"parentDeviceId": parentDevice.Id, "onuId": onuId})
272 foundOnuId = true
273 }
274 }
275
276 foundSerialNumber := false
277 if searchDevice.SerialNumber == serialNumber {
278 log.Debugw("found-child-by-serialnumber", log.Fields{"parentDeviceId": parentDevice.Id, "serialNumber": serialNumber})
279 foundSerialNumber = true
280 }
281
282 // if both onuId and serialNumber are provided both must be true for the device to be found
283 // otherwise whichever one found a match is good enough
284 if onuId > 0 && serialNumber != "" {
285 found = foundOnuId && foundSerialNumber
286 } else {
287 found = foundOnuId || foundSerialNumber
288 }
289
290 if found == true {
291 foundChildDevice = searchDevice
292 break
293 }
294 }
295 }
296
297 if foundChildDevice != nil {
298 log.Debugw("child-device-found", log.Fields{"parentDeviceId": parentDevice.Id, "foundChildDevice": foundChildDevice})
299 return foundChildDevice, nil
300 }
301
302 log.Warnw("child-device-not-found", log.Fields{"parentDeviceId": parentDevice.Id,
303 "serialNumber": serialNumber, "onuId": onuId, "parentPortNo": parentPortNo})
304 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
305}
306
Matt Jeanneret2a20aaa2019-03-05 21:04:02 -0500307func (dMgr *DeviceManager) GetChildDeviceWithProxyAddress(proxyAddress *voltha.Device_ProxyAddress) (*voltha.Device, error) {
308 log.Debugw("GetChildDeviceWithProxyAddress", log.Fields{"proxyAddress": proxyAddress})
309
310 var parentDevice *voltha.Device
311 var err error
312 if parentDevice, err = dMgr.GetDevice(proxyAddress.DeviceId); err != nil {
313 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
314 }
315 var childDeviceIds []string
316 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
317 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
318 }
319 if len(childDeviceIds) == 0 {
320 log.Debugw("no-child-devices", log.Fields{"parentDeviceId": parentDevice.Id})
321 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
322 }
323
324 var foundChildDevice *voltha.Device
325 for _, childDeviceId := range childDeviceIds {
326 if searchDevice, err := dMgr.GetDevice(childDeviceId); err == nil {
327 if searchDevice.ProxyAddress == proxyAddress {
328 foundChildDevice = searchDevice
329 break
330 }
331 }
332 }
333
334 if foundChildDevice != nil {
335 log.Debugw("child-device-found", log.Fields{"proxyAddress": proxyAddress})
336 return foundChildDevice, nil
337 }
338
339 log.Warnw("child-device-not-found", log.Fields{"proxyAddress": proxyAddress})
340 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
341}
342
khenaidoo297cd252019-02-07 22:10:23 -0500343func (dMgr *DeviceManager) IsDeviceInCache(id string) bool {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400344 _, exist := dMgr.deviceAgents.Load(id)
khenaidoo297cd252019-02-07 22:10:23 -0500345 return exist
346}
347
khenaidoo19d7b632018-10-30 10:49:50 -0400348func (dMgr *DeviceManager) IsRootDevice(id string) (bool, error) {
khenaidoo2c6a0992019-04-29 13:46:56 -0400349 dMgr.lockRootDeviceMap.RLock()
350 defer dMgr.lockRootDeviceMap.RUnlock()
351 if exist := dMgr.rootDevices[id]; exist {
352 return dMgr.rootDevices[id], nil
khenaidoo19d7b632018-10-30 10:49:50 -0400353 }
khenaidoo2c6a0992019-04-29 13:46:56 -0400354 return false, nil
khenaidoo19d7b632018-10-30 10:49:50 -0400355}
356
Stephane Barbarieaa467942019-02-06 14:09:44 -0500357// ListDevices retrieves the latest devices from the data model
khenaidoob9203542018-09-17 22:56:37 -0400358func (dMgr *DeviceManager) ListDevices() (*voltha.Devices, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400359 log.Debug("ListDevices")
khenaidoob9203542018-09-17 22:56:37 -0400360 result := &voltha.Devices{}
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400361 if devices := dMgr.clusterDataProxy.List(context.Background(), "/devices", 0, false, ""); devices != nil {
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500362 for _, device := range devices.([]interface{}) {
khenaidoo297cd252019-02-07 22:10:23 -0500363 // If device is not in memory then set it up
364 if !dMgr.IsDeviceInCache(device.(*voltha.Device).Id) {
khenaidoo6d62c002019-05-15 21:57:03 -0400365 log.Debugw("loading-device-from-Model", log.Fields{"id": device.(*voltha.Device).Id})
khenaidoo2c6a0992019-04-29 13:46:56 -0400366 agent := newDeviceAgent(dMgr.adapterProxy, device.(*voltha.Device), dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
khenaidoo297cd252019-02-07 22:10:23 -0500367 if err := agent.start(nil, true); err != nil {
368 log.Warnw("failure-starting-agent", log.Fields{"deviceId": device.(*voltha.Device).Id})
369 agent.stop(nil)
370 } else {
371 dMgr.addDeviceAgentToMap(agent)
372 }
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500373 }
374 result.Items = append(result.Items, device.(*voltha.Device))
khenaidoob9203542018-09-17 22:56:37 -0400375 }
376 }
khenaidoo6d62c002019-05-15 21:57:03 -0400377 log.Debugw("ListDevices-end", log.Fields{"len": len(result.Items)})
khenaidoob9203542018-09-17 22:56:37 -0400378 return result, nil
379}
380
khenaidoo6d62c002019-05-15 21:57:03 -0400381//getDeviceFromModelretrieves the device data from the model.
382func (dMgr *DeviceManager) getDeviceFromModel(deviceId string) (*voltha.Device, error) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400383 if device := dMgr.clusterDataProxy.Get(context.Background(), "/devices/"+deviceId, 0, false, ""); device != nil {
khenaidoo6d62c002019-05-15 21:57:03 -0400384 if d, ok := device.(*voltha.Device); ok {
385 return d, nil
386 }
387 }
388 return nil, status.Error(codes.NotFound, deviceId)
389}
390
khenaidoo297cd252019-02-07 22:10:23 -0500391// loadDevice loads the deviceId in memory, if not present
392func (dMgr *DeviceManager) loadDevice(deviceId string) (*DeviceAgent, error) {
393 log.Debugw("loading-device", log.Fields{"deviceId": deviceId})
394 // Sanity check
395 if deviceId == "" {
396 return nil, status.Error(codes.InvalidArgument, "deviceId empty")
397 }
398 if !dMgr.IsDeviceInCache(deviceId) {
khenaidoo6d62c002019-05-15 21:57:03 -0400399 // Proceed with the loading only if the device exist in the Model (could have been deleted)
400 if device, err := dMgr.getDeviceFromModel(deviceId); err == nil {
401 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
402 if err := agent.start(nil, true); err != nil {
403 agent.stop(nil)
404 return nil, err
405 }
406 dMgr.addDeviceAgentToMap(agent)
407 } else {
408 return nil, status.Error(codes.NotFound, deviceId)
khenaidoo297cd252019-02-07 22:10:23 -0500409 }
khenaidoo297cd252019-02-07 22:10:23 -0500410 }
411 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
412 return agent, nil
413 }
Matt Jeanneret4e241952019-02-28 11:16:04 -0500414 return nil, status.Error(codes.NotFound, deviceId) // This should not happen
khenaidoo297cd252019-02-07 22:10:23 -0500415}
416
417// loadRootDeviceParentAndChildren loads the children and parents of a root device in memory
418func (dMgr *DeviceManager) loadRootDeviceParentAndChildren(device *voltha.Device) error {
419 log.Debugw("loading-parent-and-children", log.Fields{"deviceId": device.Id})
420 if device.Root {
421 // Scenario A
422 if device.ParentId != "" {
423 // Load logical device if needed.
424 if err := dMgr.logicalDeviceMgr.load(device.ParentId); err != nil {
425 log.Warnw("failure-loading-logical-device", log.Fields{"lDeviceId": device.ParentId})
426 }
427 } else {
428 log.Debugw("no-parent-to-load", log.Fields{"deviceId": device.Id})
429 }
430 // Load all child devices, if needed
431 if childDeviceIds, err := dMgr.getAllChildDeviceIds(device); err == nil {
432 for _, childDeviceId := range childDeviceIds {
433 if _, err := dMgr.loadDevice(childDeviceId); err != nil {
434 log.Warnw("failure-loading-device", log.Fields{"deviceId": childDeviceId})
435 return err
436 }
437 }
438 log.Debugw("loaded-children", log.Fields{"deviceId": device.Id, "numChildren": len(childDeviceIds)})
439 } else {
440 log.Debugw("no-child-to-load", log.Fields{"deviceId": device.Id})
441 }
442 }
443 return nil
444}
445
446// load loads the deviceId in memory, if not present, and also loads its accompanying parents and children. Loading
447// in memory is for improved performance. It is not imperative that a device needs to be in memory when a request
448// acting on the device is received by the core. In such a scenario, the Core will load the device in memory first
449// and the proceed with the request.
450func (dMgr *DeviceManager) load(deviceId string) error {
451 log.Debug("load...")
452 // First load the device - this may fail in case the device was deleted intentionally by the other core
453 var dAgent *DeviceAgent
454 var err error
455 if dAgent, err = dMgr.loadDevice(deviceId); err != nil {
khenaidoo297cd252019-02-07 22:10:23 -0500456 return err
457 }
458 // Get the loaded device details
459 var device *voltha.Device
460 if device, err = dAgent.getDevice(); err != nil {
461 return err
462 }
463
464 // If the device is in Pre-provisioning or deleted state stop here
465 if device.AdminState == voltha.AdminState_PREPROVISIONED || device.AdminState == voltha.AdminState_DELETED {
466 return nil
467 }
468
469 // Now we face two scenarios
470 if device.Root {
471 // Load all children as well as the parent of this device (logical_device)
472 if err := dMgr.loadRootDeviceParentAndChildren(device); err != nil {
473 log.Warnw("failure-loading-device-parent-and-children", log.Fields{"deviceId": deviceId})
474 return err
475 }
476 log.Debugw("successfully-loaded-parent-and-children", log.Fields{"deviceId": deviceId})
477 } else {
478 // Scenario B - use the parentId of that device (root device) to trigger the loading
479 if device.ParentId != "" {
480 return dMgr.load(device.ParentId)
481 }
482 }
483 return nil
484}
485
khenaidoo7ccedd52018-12-14 16:48:54 -0500486// ListDeviceIds retrieves the latest device IDs information from the data model (memory data only)
487func (dMgr *DeviceManager) ListDeviceIds() (*voltha.IDs, error) {
488 log.Debug("ListDeviceIDs")
489 // Report only device IDs that are in the device agent map
490 return dMgr.listDeviceIdsFromMap(), nil
491}
492
493//ReconcileDevices is a request to a voltha core to managed a list of devices based on their IDs
494func (dMgr *DeviceManager) ReconcileDevices(ctx context.Context, ids *voltha.IDs, ch chan interface{}) {
495 log.Debug("ReconcileDevices")
496 var res interface{}
497 if ids != nil {
498 toReconcile := len(ids.Items)
499 reconciled := 0
500 for _, id := range ids.Items {
501 // Act on the device only if its not present in the agent map
khenaidoo297cd252019-02-07 22:10:23 -0500502 if !dMgr.IsDeviceInCache(id.Id) {
khenaidoo7ccedd52018-12-14 16:48:54 -0500503 // Device Id not in memory
504 log.Debugw("reconciling-device", log.Fields{"id": id.Id})
khenaidoo6d62c002019-05-15 21:57:03 -0400505 // Proceed with the loading only if the device exist in the Model (could have been deleted)
506 if device, err := dMgr.getDeviceFromModel(id.Id); err == nil {
507 agent := newDeviceAgent(dMgr.adapterProxy, device, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
508 if err := agent.start(nil, true); err != nil {
509 log.Warnw("failure-loading-device", log.Fields{"deviceId": id.Id})
510 agent.stop(nil)
511 } else {
512 dMgr.addDeviceAgentToMap(agent)
513 reconciled += 1
514 }
khenaidoo7ccedd52018-12-14 16:48:54 -0500515 } else {
khenaidoo297cd252019-02-07 22:10:23 -0500516 reconciled += 1
khenaidoo7ccedd52018-12-14 16:48:54 -0500517 }
khenaidoo7ccedd52018-12-14 16:48:54 -0500518 }
519 }
520 if toReconcile != reconciled {
521 res = status.Errorf(codes.DataLoss, "less-device-reconciled:%d/%d", reconciled, toReconcile)
522 }
523 } else {
524 res = status.Errorf(codes.InvalidArgument, "empty-list-of-ids")
525 }
526 sendResponse(ctx, ch, res)
527}
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500528
khenaidoob9203542018-09-17 22:56:37 -0400529func (dMgr *DeviceManager) updateDevice(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400530 log.Debugw("updateDevice", log.Fields{"deviceid": device.Id, "device": device})
khenaidoob9203542018-09-17 22:56:37 -0400531 if agent := dMgr.getDeviceAgent(device.Id); agent != nil {
532 return agent.updateDevice(device)
533 }
534 return status.Errorf(codes.NotFound, "%s", device.Id)
535}
536
537func (dMgr *DeviceManager) addPort(deviceId string, port *voltha.Port) error {
538 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400539 if err := agent.addPort(port); err != nil {
540 return err
541 }
542 // Setup peer ports
543 meAsPeer := &voltha.Port_PeerPort{DeviceId: deviceId, PortNo: port.PortNo}
544 for _, peerPort := range port.Peers {
545 if agent := dMgr.getDeviceAgent(peerPort.DeviceId); agent != nil {
546 if err := agent.addPeerPort(meAsPeer); err != nil {
547 log.Errorw("failed-to-add-peer", log.Fields{"peer-device-id": peerPort.DeviceId})
548 return err
549 }
550 }
551 }
khenaidoo2c6a0992019-04-29 13:46:56 -0400552 // Notify the logical device manager to setup a logical port, if needed. If the added port is an NNI or UNI
553 // then a logical port will be added to the logical device and the device graph generated. If the port is a
554 // PON port then only the device graph will be generated.
555 if device, err := dMgr.GetDevice(deviceId); err == nil {
556 go dMgr.logicalDeviceMgr.updateLogicalPort(device, port)
557 } else {
558 log.Errorw("failed-to-retrieve-device", log.Fields{"deviceId": deviceId})
559 return err
khenaidoofc1314d2019-03-14 09:34:21 -0400560 }
khenaidoo92e62c52018-10-03 14:02:54 -0400561 return nil
562 } else {
563 return status.Errorf(codes.NotFound, "%s", deviceId)
khenaidoob9203542018-09-17 22:56:37 -0400564 }
khenaidoob9203542018-09-17 22:56:37 -0400565}
566
khenaidoo0a822f92019-05-08 15:15:57 -0400567func (dMgr *DeviceManager) deletePeerPorts(fromDeviceId string, deviceId string) error {
568 log.Debugw("deletePeerPorts", log.Fields{"fromDeviceId": fromDeviceId, "deviceid": deviceId})
569 if agent := dMgr.getDeviceAgent(fromDeviceId); agent != nil {
570 return agent.deletePeerPorts(deviceId)
571 }
572 return status.Errorf(codes.NotFound, "%s", deviceId)
573}
574
khenaidoo2c6a0992019-04-29 13:46:56 -0400575func (dMgr *DeviceManager) addFlowsAndGroups(deviceId string, flows []*ofp.OfpFlowStats, groups []*ofp.OfpGroupEntry) error {
576 log.Debugw("addFlowsAndGroups", log.Fields{"deviceid": deviceId})
khenaidoo19d7b632018-10-30 10:49:50 -0400577 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo2c6a0992019-04-29 13:46:56 -0400578 return agent.addFlowsAndGroups(flows, groups)
khenaidoo0458db62019-06-20 08:50:36 -0400579 }
580 return status.Errorf(codes.NotFound, "%s", deviceId)
581}
582
583func (dMgr *DeviceManager) deleteFlowsAndGroups(deviceId string, flows []*ofp.OfpFlowStats, groups []*ofp.OfpGroupEntry) error {
584 log.Debugw("deleteFlowsAndGroups", log.Fields{"deviceid": deviceId})
585 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
586 return agent.deleteFlowsAndGroups(flows, groups)
587 }
588 return status.Errorf(codes.NotFound, "%s", deviceId)
589}
590
591func (dMgr *DeviceManager) updateFlowsAndGroups(deviceId string, flows []*ofp.OfpFlowStats, groups []*ofp.OfpGroupEntry) error {
592 log.Debugw("updateFlowsAndGroups", log.Fields{"deviceid": deviceId})
593 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
594 return agent.updateFlowsAndGroups(flows, groups)
khenaidoo19d7b632018-10-30 10:49:50 -0400595 }
596 return status.Errorf(codes.NotFound, "%s", deviceId)
597}
598
khenaidoob3127472019-07-24 21:04:55 -0400599// updatePmConfigs updates the PM configs. This is executed when the northbound gRPC API is invoked, typically
600// following a user action
601func (dMgr *DeviceManager) updatePmConfigs(ctx context.Context, pmConfigs *voltha.PmConfigs, ch chan interface{}) {
602 var res interface{}
603 if pmConfigs.Id == "" {
604 res = status.Errorf(codes.FailedPrecondition, "invalid-device-Id")
605 } else if agent := dMgr.getDeviceAgent(pmConfigs.Id); agent != nil {
606 res = agent.updatePmConfigs(ctx, pmConfigs)
607 } else {
608 res = status.Errorf(codes.NotFound, "%s", pmConfigs.Id)
609 }
610 sendResponse(ctx, ch, res)
611}
612
613// initPmConfigs initialize the pm configs as defined by the adapter.
614func (dMgr *DeviceManager) initPmConfigs(deviceId string, pmConfigs *voltha.PmConfigs) error {
615 if pmConfigs.Id == "" {
616 return status.Errorf(codes.FailedPrecondition, "invalid-device-Id")
617 }
khenaidoob9203542018-09-17 22:56:37 -0400618 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoob3127472019-07-24 21:04:55 -0400619 return agent.initPmConfigs(pmConfigs)
khenaidoob9203542018-09-17 22:56:37 -0400620 }
621 return status.Errorf(codes.NotFound, "%s", deviceId)
622}
623
khenaidoob3127472019-07-24 21:04:55 -0400624func (dMgr *DeviceManager) listPmConfigs(ctx context.Context, deviceId string) (*voltha.PmConfigs, error) {
625 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
626 return agent.listPmConfigs(ctx)
627 }
628 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
629}
630
khenaidoo79232702018-12-04 11:00:41 -0500631func (dMgr *DeviceManager) getSwitchCapability(ctx context.Context, deviceId string) (*ic.SwitchCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400632 log.Debugw("getSwitchCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400633 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
634 return agent.getSwitchCapability(ctx)
635 }
636 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
637}
638
khenaidoo92e62c52018-10-03 14:02:54 -0400639func (dMgr *DeviceManager) getPorts(ctx context.Context, deviceId string, portType voltha.Port_PortType) (*voltha.Ports, error) {
640 log.Debugw("getPorts", log.Fields{"deviceid": deviceId, "portType": portType})
khenaidoob9203542018-09-17 22:56:37 -0400641 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400642 return agent.getPorts(ctx, portType), nil
khenaidoob9203542018-09-17 22:56:37 -0400643 }
644 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
645}
646
khenaidoo79232702018-12-04 11:00:41 -0500647func (dMgr *DeviceManager) getPortCapability(ctx context.Context, deviceId string, portNo uint32) (*ic.PortCapability, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400648 log.Debugw("getPortCapability", log.Fields{"deviceid": deviceId})
khenaidoob9203542018-09-17 22:56:37 -0400649 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
650 return agent.getPortCapability(ctx, portNo)
651 }
652 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
653}
654
khenaidoo92e62c52018-10-03 14:02:54 -0400655func (dMgr *DeviceManager) updateDeviceStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
656 log.Debugw("updateDeviceStatus", log.Fields{"deviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400657 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400658 return agent.updateDeviceStatus(operStatus, connStatus)
659 }
660 return status.Errorf(codes.NotFound, "%s", deviceId)
661}
662
khenaidoo4d4802d2018-10-04 21:59:49 -0400663func (dMgr *DeviceManager) updateChildrenStatus(deviceId string, operStatus voltha.OperStatus_OperStatus, connStatus voltha.ConnectStatus_ConnectStatus) error {
664 log.Debugw("updateChildrenStatus", log.Fields{"parentDeviceid": deviceId, "operStatus": operStatus, "connStatus": connStatus})
665 var parentDevice *voltha.Device
666 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400667 if parentDevice, err = dMgr.GetDevice(deviceId); err != nil {
khenaidoo4d4802d2018-10-04 21:59:49 -0400668 return status.Errorf(codes.Aborted, "%s", err.Error())
669 }
670 var childDeviceIds []string
671 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
672 return status.Errorf(codes.Aborted, "%s", err.Error())
673 }
674 if len(childDeviceIds) == 0 {
675 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
676 }
677 for _, childDeviceId := range childDeviceIds {
678 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
679 if err = agent.updateDeviceStatus(operStatus, connStatus); err != nil {
680 return status.Errorf(codes.Aborted, "childDevice:%s, error:%s", childDeviceId, err.Error())
681 }
682 }
683 }
684 return nil
685}
686
khenaidoo92e62c52018-10-03 14:02:54 -0400687func (dMgr *DeviceManager) updatePortState(deviceId string, portType voltha.Port_PortType, portNo uint32, operStatus voltha.OperStatus_OperStatus) error {
688 log.Debugw("updatePortState", log.Fields{"deviceid": deviceId, "portType": portType, "portNo": portNo, "operStatus": operStatus})
689 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
690 return agent.updatePortState(portType, portNo, operStatus)
khenaidoob9203542018-09-17 22:56:37 -0400691 }
692 return status.Errorf(codes.NotFound, "%s", deviceId)
693}
694
khenaidoo0a822f92019-05-08 15:15:57 -0400695func (dMgr *DeviceManager) deleteAllPorts(deviceId string) error {
696 log.Debugw("DeleteAllPorts", log.Fields{"deviceid": deviceId})
697 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
698 if err := agent.deleteAllPorts(); err != nil {
699 return err
700 }
701 // Notify the logical device manager to remove all logical ports, if needed.
702 // At this stage the device itself may gave been deleted already at a deleteAllPorts
703 // typically is part of a device deletion phase.
704 if device, err := dMgr.GetDevice(deviceId); err == nil {
705 go dMgr.logicalDeviceMgr.deleteAllLogicalPorts(device)
706 } else {
707 log.Warnw("failed-to-retrieve-device", log.Fields{"deviceId": deviceId})
708 return err
709 }
710 return nil
711 }
712 return status.Errorf(codes.NotFound, "%s", deviceId)
713}
714
khenaidoo3ab34882019-05-02 21:33:30 -0400715//updatePortsState updates all ports on the device
716func (dMgr *DeviceManager) updatePortsState(deviceId string, state voltha.OperStatus_OperStatus) error {
717 log.Debugw("updatePortsState", log.Fields{"deviceid": deviceId})
718
719 var adminState voltha.AdminState_AdminState
720 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
721 switch state {
722 case voltha.OperStatus_ACTIVE:
723 adminState = voltha.AdminState_ENABLED
724 if err := agent.enablePorts(); err != nil {
725 log.Warnw("enable-all-ports-failed", log.Fields{"deviceId": deviceId, "error": err})
726 return err
727 }
728 case voltha.OperStatus_UNKNOWN:
729 adminState = voltha.AdminState_DISABLED
730 if err := agent.disablePorts(); err != nil {
731 log.Warnw("disable-all-ports-failed", log.Fields{"deviceId": deviceId, "error": err})
732 return err
733 }
734 default:
735 return status.Error(codes.Unimplemented, "state-change-not-implemented")
736 }
737 // Notify the logical device about the state change
738 if device, err := dMgr.GetDevice(deviceId); err != nil {
739 log.Warnw("non-existent-device", log.Fields{"deviceId": deviceId, "error": err})
740 return err
741 } else {
742 if err := dMgr.logicalDeviceMgr.updatePortsState(device, adminState); err != nil {
743 log.Warnw("failed-updating-ports-state", log.Fields{"deviceId": deviceId, "error": err})
744 return err
745 }
746 return nil
747 }
748 }
749 return status.Errorf(codes.NotFound, "%s", deviceId)
750}
751
Matt Jeanneret4e241952019-02-28 11:16:04 -0500752func (dMgr *DeviceManager) childDeviceDetected(parentDeviceId string, parentPortNo int64, deviceType string,
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700753 channelId int64, vendorId string, serialNumber string, onuId int64) (*voltha.Device, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400754 log.Debugw("childDeviceDetected", log.Fields{"parentDeviceId": parentDeviceId})
khenaidoob9203542018-09-17 22:56:37 -0400755
756 // Create the ONU device
757 childDevice := &voltha.Device{}
khenaidoob9203542018-09-17 22:56:37 -0400758 childDevice.Type = deviceType
759 childDevice.ParentId = parentDeviceId
760 childDevice.ParentPortNo = uint32(parentPortNo)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500761 childDevice.VendorId = vendorId
762 childDevice.SerialNumber = serialNumber
khenaidoob9203542018-09-17 22:56:37 -0400763 childDevice.Root = false
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400764
765 //Get parent device type
766 parent, err := dMgr.GetDevice(parentDeviceId)
767 if err != nil {
khenaidoo43c82122018-11-22 18:38:28 -0500768 log.Error("no-parent-found", log.Fields{"parentId": parentDeviceId})
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700769 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400770 }
771
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700772 if device, err := dMgr.GetChildDevice(parentDeviceId, serialNumber, onuId, parentPortNo); err == nil {
Matt Jeanneret4e241952019-02-28 11:16:04 -0500773 log.Warnw("child-device-exists", log.Fields{"parentId": parentDeviceId, "serialNumber": serialNumber})
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700774 return device, status.Errorf(codes.AlreadyExists, "%s", serialNumber)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500775 }
776
777 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{DeviceId: parentDeviceId, DeviceType: parent.Type, ChannelId: uint32(channelId), OnuId: uint32(onuId)}
khenaidoob9203542018-09-17 22:56:37 -0400778
779 // Create and start a device agent for that device
khenaidoo2c6a0992019-04-29 13:46:56 -0400780 agent := newDeviceAgent(dMgr.adapterProxy, childDevice, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
khenaidoob9203542018-09-17 22:56:37 -0400781 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500782 agent.start(nil, false)
khenaidoob9203542018-09-17 22:56:37 -0400783
784 // Activate the child device
khenaidoo92e62c52018-10-03 14:02:54 -0400785 if agent := dMgr.getDeviceAgent(agent.deviceId); agent != nil {
khenaidoo79232702018-12-04 11:00:41 -0500786 go agent.enableDevice(nil)
khenaidoob9203542018-09-17 22:56:37 -0400787 }
788
khenaidoo79232702018-12-04 11:00:41 -0500789 // Publish on the messaging bus that we have discovered new devices
khenaidoo19374072018-12-11 11:05:15 -0500790 go dMgr.kafkaICProxy.DeviceDiscovered(agent.deviceId, deviceType, parentDeviceId, dMgr.coreInstanceId)
khenaidoo79232702018-12-04 11:00:41 -0500791
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700792 return agent.lastData, nil
khenaidoob9203542018-09-17 22:56:37 -0400793}
794
795func (dMgr *DeviceManager) processTransition(previous *voltha.Device, current *voltha.Device) error {
796 // This will be triggered on every update to the device.
khenaidoo92e62c52018-10-03 14:02:54 -0400797 handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
798 if handlers == nil {
khenaidoo43c82122018-11-22 18:38:28 -0500799 log.Debugw("no-op-transition", log.Fields{"deviceId": current.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400800 return nil
khenaidoob9203542018-09-17 22:56:37 -0400801 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400802 log.Debugw("handler-found", log.Fields{"num-handlers": len(handlers), "isParent": current.Root, "current-data": current})
khenaidoo92e62c52018-10-03 14:02:54 -0400803 for _, handler := range handlers {
804 log.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
805 if err := handler(current); err != nil {
khenaidoo6d62c002019-05-15 21:57:03 -0400806 log.Warnw("handler-failed", log.Fields{"handler": funcName(handler), "error": err})
khenaidoo92e62c52018-10-03 14:02:54 -0400807 return err
808 }
809 }
khenaidoob9203542018-09-17 22:56:37 -0400810 return nil
811}
812
khenaidoofdbad6e2018-11-06 22:26:38 -0500813func (dMgr *DeviceManager) packetOut(deviceId string, outPort uint32, packet *ofp.OfpPacketOut) error {
814 log.Debugw("packetOut", log.Fields{"deviceId": deviceId, "outPort": outPort})
815 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
816 return agent.packetOut(outPort, packet)
817 }
818 return status.Errorf(codes.NotFound, "%s", deviceId)
819}
820
khenaidoo297cd252019-02-07 22:10:23 -0500821func (dMgr *DeviceManager) PacketIn(deviceId string, port uint32, transactionId string, packet []byte) error {
khenaidoofdbad6e2018-11-06 22:26:38 -0500822 log.Debugw("PacketIn", log.Fields{"deviceId": deviceId, "port": port})
823 // Get the logical device Id based on the deviceId
824 var device *voltha.Device
825 var err error
826 if device, err = dMgr.GetDevice(deviceId); err != nil {
827 log.Errorw("device-not-found", log.Fields{"deviceId": deviceId})
828 return err
829 }
khenaidoo43c82122018-11-22 18:38:28 -0500830 if !device.Root {
khenaidoofdbad6e2018-11-06 22:26:38 -0500831 log.Errorw("device-not-root", log.Fields{"deviceId": deviceId})
832 return status.Errorf(codes.FailedPrecondition, "%s", deviceId)
833 }
834
khenaidoo297cd252019-02-07 22:10:23 -0500835 if err := dMgr.logicalDeviceMgr.packetIn(device.ParentId, port, transactionId, packet); err != nil {
khenaidoofdbad6e2018-11-06 22:26:38 -0500836 return err
837 }
838 return nil
839}
840
khenaidoo0a822f92019-05-08 15:15:57 -0400841func (dMgr *DeviceManager) CreateLogicalDevice(cDevice *voltha.Device) error {
842 log.Info("CreateLogicalDevice")
khenaidoo59ef7be2019-06-21 12:40:28 -0400843 // Verify whether the logical device has already been created
844 if cDevice.ParentId != "" {
845 log.Debugw("Parent device already exist.", log.Fields{"deviceId": cDevice.Id, "logicalDeviceId": cDevice.Id})
846 return nil
847 }
khenaidoob9203542018-09-17 22:56:37 -0400848 var logicalId *string
849 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400850 if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400851 log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
852 return err
853 }
854 // Update the parent device with the logical id
855 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
856 return nil
857}
858
khenaidoo0a822f92019-05-08 15:15:57 -0400859func (dMgr *DeviceManager) DeleteLogicalDevice(cDevice *voltha.Device) error {
860 log.Info("DeleteLogicalDevice")
khenaidoo92e62c52018-10-03 14:02:54 -0400861 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400862 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400863 log.Warnw("deleteLogical-device-error", log.Fields{"deviceId": cDevice.Id})
864 return err
865 }
866 // Remove the logical device Id from the parent device
867 logicalId := ""
868 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", logicalId)
869 return nil
870}
871
khenaidoo0a822f92019-05-08 15:15:57 -0400872func (dMgr *DeviceManager) DeleteLogicalPort(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400873 log.Info("deleteLogicalPort")
874 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400875 // Get the logical port associated with this device
876 var lPortId *voltha.LogicalPortId
877 if lPortId, err = dMgr.logicalDeviceMgr.getLogicalPortId(device); err != nil {
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400878 log.Warnw("getLogical-port-error", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo19d7b632018-10-30 10:49:50 -0400879 return err
880 }
881 if err = dMgr.logicalDeviceMgr.deleteLogicalPort(nil, lPortId); err != nil {
882 log.Warnw("deleteLogical-port-error", log.Fields{"deviceId": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400883 return err
884 }
khenaidoo92e62c52018-10-03 14:02:54 -0400885 return nil
886}
887
khenaidoo0a822f92019-05-08 15:15:57 -0400888func (dMgr *DeviceManager) DeleteLogicalPorts(device *voltha.Device) error {
889 log.Info("deleteLogicalPorts")
890 if err := dMgr.logicalDeviceMgr.deleteLogicalPorts(device.Id); err != nil {
891 log.Warnw("deleteLogical-ports-error", log.Fields{"deviceId": device.Id})
892 return err
893 }
894 return nil
895}
896
khenaidoo59ef7be2019-06-21 12:40:28 -0400897func (dMgr *DeviceManager) MarkChildDevicesAsUnReachable(device *voltha.Device) error {
898 log.Info("MarkChildDevicesAsUnReachable")
899 // Set the connection status to unreachable
900 connStatus := voltha.ConnectStatus_UNREACHABLE
901 // Do not set the operational status. Setting it to -1 will do the trick
902 operStatus := voltha.OperStatus_OperStatus(-1)
903 if err := dMgr.updateChildrenStatus(device.Id, operStatus, connStatus); err != nil {
904 log.Warnw("deleteLogical-ports-error", log.Fields{"deviceId": device.Id})
905 return err
906 }
907 return nil
908}
909
khenaidoo92e62c52018-10-03 14:02:54 -0400910func (dMgr *DeviceManager) getParentDevice(childDevice *voltha.Device) *voltha.Device {
911 // Sanity check
912 if childDevice.Root {
913 // childDevice is the parent device
914 return childDevice
915 }
khenaidoo19d7b632018-10-30 10:49:50 -0400916 parentDevice, _ := dMgr.GetDevice(childDevice.ParentId)
khenaidoo92e62c52018-10-03 14:02:54 -0400917 return parentDevice
918}
919
khenaidoo0a822f92019-05-08 15:15:57 -0400920//childDevicesLost is invoked by an adapter to indicate that a parent device is in a state (Disabled) where it
921//cannot manage the child devices. This will trigger the Core to disable all the child devices.
922func (dMgr *DeviceManager) childDevicesLost(parentDeviceId string) error {
923 log.Debug("childDevicesLost")
924 var err error
925 var parentDevice *voltha.Device
926 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
927 log.Warnw("failed-getting-device", log.Fields{"deviceId": parentDeviceId, "error": err})
928 return err
929 }
930 return dMgr.DisableAllChildDevices(parentDevice)
931}
932
933//childDevicesDetected is invoked by an adapter when child devices are found, typically after after a
934// disable/enable sequence. This will trigger the Core to Enable all the child devices of that parent.
935func (dMgr *DeviceManager) childDevicesDetected(parentDeviceId string) error {
936 log.Debug("childDevicesDetected")
937 var err error
938 var parentDevice *voltha.Device
939 var childDeviceIds []string
940
941 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
942 log.Warnw("failed-getting-device", log.Fields{"deviceId": parentDeviceId, "error": err})
943 return err
944 }
945
946 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
947 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
948 }
949 if len(childDeviceIds) == 0 {
950 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
951 }
khenaidoo59ef7be2019-06-21 12:40:28 -0400952 allChildEnableRequestSent := true
khenaidoo0a822f92019-05-08 15:15:57 -0400953 for _, childDeviceId := range childDeviceIds {
954 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
khenaidoo59ef7be2019-06-21 12:40:28 -0400955 // Run the children re-registration in its own routine
956 go agent.enableDevice(nil)
957 } else {
958 err = status.Errorf(codes.Unavailable, "no agent for child device %s", childDeviceId)
959 log.Errorw("no-child-device-agent", log.Fields{"parentDeviceId": parentDevice.Id, "childId": childDeviceId})
960 allChildEnableRequestSent = false
khenaidoo0a822f92019-05-08 15:15:57 -0400961 }
962 }
khenaidoo59ef7be2019-06-21 12:40:28 -0400963 if !allChildEnableRequestSent {
khenaidoo0a822f92019-05-08 15:15:57 -0400964 return err
965 }
966 return nil
967}
968
khenaidoo4d4802d2018-10-04 21:59:49 -0400969/*
970All the functions below are callback functions where they are invoked with the latest and previous data. We can
971therefore use the data as is without trying to get the latest from the model.
972*/
973
khenaidoo0a822f92019-05-08 15:15:57 -0400974//DisableAllChildDevices is invoked as a callback when the parent device is disabled
975func (dMgr *DeviceManager) DisableAllChildDevices(parentDevice *voltha.Device) error {
976 log.Debug("DisableAllChildDevices")
khenaidoo92e62c52018-10-03 14:02:54 -0400977 var childDeviceIds []string
978 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400979 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
980 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -0400981 }
982 if len(childDeviceIds) == 0 {
khenaidoo4d4802d2018-10-04 21:59:49 -0400983 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400984 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400985 allChildDisable := true
khenaidoo92e62c52018-10-03 14:02:54 -0400986 for _, childDeviceId := range childDeviceIds {
987 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
988 if err = agent.disableDevice(nil); err != nil {
989 log.Errorw("failure-disable-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
khenaidoo4d4802d2018-10-04 21:59:49 -0400990 allChildDisable = false
khenaidoo92e62c52018-10-03 14:02:54 -0400991 }
992 }
993 }
khenaidoo4d4802d2018-10-04 21:59:49 -0400994 if !allChildDisable {
995 return err
996 }
khenaidoo92e62c52018-10-03 14:02:54 -0400997 return nil
998}
999
khenaidoo0a822f92019-05-08 15:15:57 -04001000//DeleteAllChildDevices is invoked as a callback when the parent device is deleted
1001func (dMgr *DeviceManager) DeleteAllChildDevices(parentDevice *voltha.Device) error {
1002 log.Debug("DeleteAllChildDevices")
khenaidoo4d4802d2018-10-04 21:59:49 -04001003 var childDeviceIds []string
khenaidoo92e62c52018-10-03 14:02:54 -04001004 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -04001005 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
1006 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -04001007 }
khenaidoo4d4802d2018-10-04 21:59:49 -04001008 if len(childDeviceIds) == 0 {
1009 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
1010 }
1011 allChildDeleted := true
1012 for _, childDeviceId := range childDeviceIds {
1013 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
1014 if err = agent.deleteDevice(nil); err != nil {
1015 log.Errorw("failure-delete-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
1016 allChildDeleted = false
1017 } else {
1018 agent.stop(nil)
1019 dMgr.deleteDeviceAgentToMap(agent)
1020 }
1021 }
1022 }
1023 if !allChildDeleted {
1024 return err
1025 }
1026 return nil
1027}
1028
khenaidoo6d62c002019-05-15 21:57:03 -04001029//getAllDeviceIdsWithDeviceParentId returns the list of device Ids which has id as parent Id. This function uses the
1030// data from the agent instead of using the data from the parent device as that data would disappear from a parent
1031// device during a delete device operation.
1032func (dMgr *DeviceManager) getAllDeviceIdsWithDeviceParentId(id string) []string {
1033 log.Debugw("getAllAgentsWithDeviceParentId", log.Fields{"parentDeviceId": id})
1034 deviceIds := make([]string, 0)
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001035 dMgr.deviceAgents.Range(func(key, value interface{}) bool {
1036 agent := value.(*DeviceAgent)
khenaidoo6d62c002019-05-15 21:57:03 -04001037 if agent.parentId == id {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001038 deviceIds = append(deviceIds, key.(string))
khenaidoo6d62c002019-05-15 21:57:03 -04001039 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001040 return true
1041 })
khenaidoo6d62c002019-05-15 21:57:03 -04001042 return deviceIds
1043}
1044
khenaidoo4d4802d2018-10-04 21:59:49 -04001045//getAllChildDeviceIds is a helper method to get all the child device IDs from the device passed as parameter
1046func (dMgr *DeviceManager) getAllChildDeviceIds(parentDevice *voltha.Device) ([]string, error) {
1047 log.Debugw("getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -04001048 childDeviceIds := make([]string, 0)
khenaidoo4d4802d2018-10-04 21:59:49 -04001049 if parentDevice != nil {
1050 for _, port := range parentDevice.Ports {
1051 for _, peer := range port.Peers {
1052 childDeviceIds = append(childDeviceIds, peer.DeviceId)
1053 }
khenaidoo92e62c52018-10-03 14:02:54 -04001054 }
khenaidoo2c6a0992019-04-29 13:46:56 -04001055 log.Debugw("returning-getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id, "childDeviceIds": childDeviceIds})
khenaidoo92e62c52018-10-03 14:02:54 -04001056 }
1057 return childDeviceIds, nil
1058}
1059
khenaidoo297cd252019-02-07 22:10:23 -05001060//getAllChildDevices is a helper method to get all the child device IDs from the device passed as parameter
1061func (dMgr *DeviceManager) getAllChildDevices(parentDeviceId string) (*voltha.Devices, error) {
1062 log.Debugw("getAllChildDevices", log.Fields{"parentDeviceId": parentDeviceId})
1063 if parentDevice, err := dMgr.GetDevice(parentDeviceId); err == nil {
1064 childDevices := make([]*voltha.Device, 0)
1065 if childDeviceIds, er := dMgr.getAllChildDeviceIds(parentDevice); er == nil {
1066 for _, deviceId := range childDeviceIds {
1067 if d, e := dMgr.GetDevice(deviceId); e == nil && d != nil {
1068 childDevices = append(childDevices, d)
1069 }
1070 }
1071 }
1072 return &voltha.Devices{Items: childDevices}, nil
1073 }
1074 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
1075}
1076
khenaidoo0a822f92019-05-08 15:15:57 -04001077func (dMgr *DeviceManager) SetupUNILogicalPorts(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001078 log.Info("addUNILogicalPort")
khenaidoofc1314d2019-03-14 09:34:21 -04001079 if err := dMgr.logicalDeviceMgr.setupUNILogicalPorts(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -04001080 log.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
1081 return err
1082 }
1083 return nil
1084}
1085
khenaidoof5a5bfa2019-01-23 22:20:29 -05001086func (dMgr *DeviceManager) downloadImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1087 log.Debugw("downloadImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1088 var res interface{}
1089 var err error
1090 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1091 if res, err = agent.downloadImage(ctx, img); err != nil {
1092 log.Debugw("downloadImage-failed", log.Fields{"err": err, "imageName": img.Name})
1093 res = err
1094 }
1095 } else {
1096 res = status.Errorf(codes.NotFound, "%s", img.Id)
1097 }
1098 sendResponse(ctx, ch, res)
1099}
1100
1101func (dMgr *DeviceManager) cancelImageDownload(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1102 log.Debugw("cancelImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1103 var res interface{}
1104 var err error
1105 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1106 if res, err = agent.cancelImageDownload(ctx, img); err != nil {
1107 log.Debugw("cancelImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
1108 res = err
1109 }
1110 } else {
1111 res = status.Errorf(codes.NotFound, "%s", img.Id)
1112 }
1113 sendResponse(ctx, ch, res)
1114}
1115
1116func (dMgr *DeviceManager) activateImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1117 log.Debugw("activateImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1118 var res interface{}
1119 var err error
1120 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1121 if res, err = agent.activateImage(ctx, img); err != nil {
1122 log.Debugw("activateImage-failed", log.Fields{"err": err, "imageName": img.Name})
1123 res = err
1124 }
1125 } else {
1126 res = status.Errorf(codes.NotFound, "%s", img.Id)
1127 }
1128 sendResponse(ctx, ch, res)
1129}
1130
1131func (dMgr *DeviceManager) revertImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1132 log.Debugw("revertImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1133 var res interface{}
1134 var err error
1135 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1136 if res, err = agent.revertImage(ctx, img); err != nil {
1137 log.Debugw("revertImage-failed", log.Fields{"err": err, "imageName": img.Name})
1138 res = err
1139 }
1140 } else {
1141 res = status.Errorf(codes.NotFound, "%s", img.Id)
1142 }
1143 sendResponse(ctx, ch, res)
1144}
1145
1146func (dMgr *DeviceManager) getImageDownloadStatus(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1147 log.Debugw("getImageDownloadStatus", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1148 var res interface{}
1149 var err error
1150 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1151 if res, err = agent.getImageDownloadStatus(ctx, img); err != nil {
1152 log.Debugw("getImageDownloadStatus-failed", log.Fields{"err": err, "imageName": img.Name})
1153 res = err
1154 }
1155 } else {
1156 res = status.Errorf(codes.NotFound, "%s", img.Id)
1157 }
1158 sendResponse(ctx, ch, res)
1159}
1160
khenaidoof5a5bfa2019-01-23 22:20:29 -05001161func (dMgr *DeviceManager) updateImageDownload(deviceId string, img *voltha.ImageDownload) error {
1162 log.Debugw("updateImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1163 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
1164 if err := agent.updateImageDownload(img); err != nil {
1165 log.Debugw("updateImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
1166 return err
1167 }
1168 } else {
1169 return status.Errorf(codes.NotFound, "%s", img.Id)
1170 }
1171 return nil
1172}
1173
1174func (dMgr *DeviceManager) getImageDownload(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
1175 log.Debugw("getImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1176 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1177 return agent.getImageDownload(ctx, img)
1178 }
1179 return nil, status.Errorf(codes.NotFound, "%s", img.Id)
1180}
1181
1182func (dMgr *DeviceManager) listImageDownloads(ctx context.Context, deviceId string) (*voltha.ImageDownloads, error) {
1183 log.Debugw("listImageDownloads", log.Fields{"deviceId": deviceId})
1184 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
1185 return agent.listImageDownloads(ctx, deviceId)
1186 }
1187 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
1188}
1189
khenaidoo0a822f92019-05-08 15:15:57 -04001190func (dMgr *DeviceManager) SetAdminStateToEnable(cDevice *voltha.Device) error {
1191 log.Info("SetAdminStateToEnable")
1192 if agent := dMgr.getDeviceAgent(cDevice.Id); agent != nil {
1193 return agent.updateAdminState(voltha.AdminState_ENABLED)
1194 }
1195 return status.Errorf(codes.NotFound, "%s", cDevice.Id)
1196}
1197
khenaidoo92e62c52018-10-03 14:02:54 -04001198func (dMgr *DeviceManager) activateDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001199 log.Info("activateDevice")
1200 return nil
1201}
1202
khenaidoo92e62c52018-10-03 14:02:54 -04001203func (dMgr *DeviceManager) disableDeviceHandler(cDevice *voltha.Device) error {
1204 log.Info("disableDevice-donothing")
khenaidoob9203542018-09-17 22:56:37 -04001205 return nil
1206}
1207
khenaidoo92e62c52018-10-03 14:02:54 -04001208func (dMgr *DeviceManager) abandonDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001209 log.Info("abandonDevice")
1210 return nil
1211}
1212
khenaidoo92e62c52018-10-03 14:02:54 -04001213func (dMgr *DeviceManager) reEnableDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001214 log.Info("reEnableDevice")
1215 return nil
1216}
1217
khenaidoo92e62c52018-10-03 14:02:54 -04001218func (dMgr *DeviceManager) noOp(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001219 log.Info("noOp")
1220 return nil
1221}
1222
khenaidoo92e62c52018-10-03 14:02:54 -04001223func (dMgr *DeviceManager) notAllowed(pcDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001224 log.Info("notAllowed")
khenaidoo2c6a0992019-04-29 13:46:56 -04001225 return errors.New("transition-not-allowed")
khenaidoob9203542018-09-17 22:56:37 -04001226}
1227
khenaidoo0a822f92019-05-08 15:15:57 -04001228func (dMgr *DeviceManager) NotifyInvalidTransition(pcDevice *voltha.Device) error {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001229 log.Errorw("NotifyInvalidTransition", log.Fields{
1230 "device": pcDevice.Id,
1231 "adminState": pcDevice.AdminState,
1232 "operState": pcDevice.OperStatus,
1233 "connState": pcDevice.ConnectStatus,
1234 })
khenaidoo0a822f92019-05-08 15:15:57 -04001235 //TODO: notify over kafka?
1236 return nil
1237}
1238
khenaidoob9203542018-09-17 22:56:37 -04001239func funcName(f interface{}) string {
1240 p := reflect.ValueOf(f).Pointer()
1241 rf := runtime.FuncForPC(p)
1242 return rf.Name()
1243}
1244
1245func (dMgr *DeviceManager) UpdateDeviceAttribute(deviceId string, attribute string, value interface{}) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001246 if agent, ok := dMgr.deviceAgents.Load(deviceId); ok {
1247 agent.(*DeviceAgent).updateDeviceAttribute(attribute, value)
khenaidoob9203542018-09-17 22:56:37 -04001248 }
1249}
1250
1251func (dMgr *DeviceManager) GetParentDeviceId(deviceId string) *string {
khenaidoo19d7b632018-10-30 10:49:50 -04001252 if device, _ := dMgr.GetDevice(deviceId); device != nil {
khenaidoo92e62c52018-10-03 14:02:54 -04001253 log.Infow("GetParentDeviceId", log.Fields{"deviceId": device.Id, "parentId": device.ParentId})
khenaidoob9203542018-09-17 22:56:37 -04001254 return &device.ParentId
1255 }
1256 return nil
1257}
serkant.uluderya334479d2019-04-10 08:26:15 -07001258
1259func (dMgr *DeviceManager) simulateAlarm(ctx context.Context, simulatereq *voltha.SimulateAlarmRequest, ch chan interface{}) {
1260 log.Debugw("simulateAlarm", log.Fields{"id": simulatereq.Id, "Indicator": simulatereq.Indicator, "IntfId": simulatereq.IntfId,
1261 "PortTypeName": simulatereq.PortTypeName, "OnuDeviceId": simulatereq.OnuDeviceId, "InverseBitErrorRate": simulatereq.InverseBitErrorRate,
1262 "Drift": simulatereq.Drift, "NewEqd": simulatereq.NewEqd, "OnuSerialNumber": simulatereq.OnuSerialNumber, "Operation": simulatereq.Operation})
1263 var res interface{}
1264 if agent := dMgr.getDeviceAgent(simulatereq.Id); agent != nil {
1265 res = agent.simulateAlarm(ctx, simulatereq)
1266 log.Debugw("SimulateAlarm-result", log.Fields{"result": res})
1267 }
1268 //TODO CLI always get successful response
1269 sendResponse(ctx, ch, res)
1270}