blob: 43d21f2432863a714d5b09e530633b0ec49853f5 [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
Kent Hagermana6d0c362019-07-30 12:50:21 -040057 deviceMgr.adapterProxy = NewAdapterProxy(core.kmp, core.config.CorePairTopic)
Richard Jankowski199fd862019-03-18 14:49:51 -040058 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) {
Chaitrashree G S4b3fada2019-07-28 23:55:25 -0700754 log.Debugw("childDeviceDetected", log.Fields{"parentDeviceId": parentDeviceId, "parentPortNo": parentPortNo, "deviceType": deviceType, "channelId": channelId, "vendorId": vendorId, "serialNumber": serialNumber, "onuId": onuId})
755
756 if deviceType == "" && vendorId != "" {
757 log.Debug("device-type-is-nil-fetching-device-type")
758 if deviceTypesIf := dMgr.adapterMgr.clusterDataProxy.List(context.Background(), "/device_types", 0, false, ""); deviceTypesIf != nil {
759 OLoop:
760 for _, deviceTypeIf := range deviceTypesIf.([]interface{}) {
761 if dType, ok := deviceTypeIf.(*voltha.DeviceType); ok {
762 for _, v := range dType.VendorIds {
763 if v == vendorId {
764 deviceType = dType.Adapter
765 break OLoop
766 }
767 }
768 }
769 }
770 }
771 }
772 //if no match found for the vendorid,report adapter with the custom error message
773 if deviceType == "" {
774 log.Errorw("failed-to-fetch-adapter-name ", log.Fields{"vendorId": vendorId})
775 return nil, status.Errorf(codes.NotFound, "%s", vendorId)
776 }
khenaidoob9203542018-09-17 22:56:37 -0400777
778 // Create the ONU device
779 childDevice := &voltha.Device{}
khenaidoob9203542018-09-17 22:56:37 -0400780 childDevice.Type = deviceType
781 childDevice.ParentId = parentDeviceId
782 childDevice.ParentPortNo = uint32(parentPortNo)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500783 childDevice.VendorId = vendorId
784 childDevice.SerialNumber = serialNumber
khenaidoob9203542018-09-17 22:56:37 -0400785 childDevice.Root = false
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400786
787 //Get parent device type
788 parent, err := dMgr.GetDevice(parentDeviceId)
789 if err != nil {
khenaidoo43c82122018-11-22 18:38:28 -0500790 log.Error("no-parent-found", log.Fields{"parentId": parentDeviceId})
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700791 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400792 }
793
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700794 if device, err := dMgr.GetChildDevice(parentDeviceId, serialNumber, onuId, parentPortNo); err == nil {
Matt Jeanneret4e241952019-02-28 11:16:04 -0500795 log.Warnw("child-device-exists", log.Fields{"parentId": parentDeviceId, "serialNumber": serialNumber})
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700796 return device, status.Errorf(codes.AlreadyExists, "%s", serialNumber)
Matt Jeanneret4e241952019-02-28 11:16:04 -0500797 }
798
799 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{DeviceId: parentDeviceId, DeviceType: parent.Type, ChannelId: uint32(channelId), OnuId: uint32(onuId)}
khenaidoob9203542018-09-17 22:56:37 -0400800
801 // Create and start a device agent for that device
khenaidoo2c6a0992019-04-29 13:46:56 -0400802 agent := newDeviceAgent(dMgr.adapterProxy, childDevice, dMgr, dMgr.clusterDataProxy, dMgr.defaultTimeout)
khenaidoob9203542018-09-17 22:56:37 -0400803 dMgr.addDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500804 agent.start(nil, false)
khenaidoob9203542018-09-17 22:56:37 -0400805
806 // Activate the child device
khenaidoo92e62c52018-10-03 14:02:54 -0400807 if agent := dMgr.getDeviceAgent(agent.deviceId); agent != nil {
khenaidoo79232702018-12-04 11:00:41 -0500808 go agent.enableDevice(nil)
khenaidoob9203542018-09-17 22:56:37 -0400809 }
810
khenaidoo79232702018-12-04 11:00:41 -0500811 // Publish on the messaging bus that we have discovered new devices
khenaidoo19374072018-12-11 11:05:15 -0500812 go dMgr.kafkaICProxy.DeviceDiscovered(agent.deviceId, deviceType, parentDeviceId, dMgr.coreInstanceId)
khenaidoo79232702018-12-04 11:00:41 -0500813
Mahir Gunyel6deaa242019-06-27 04:53:33 -0700814 return agent.lastData, nil
khenaidoob9203542018-09-17 22:56:37 -0400815}
816
817func (dMgr *DeviceManager) processTransition(previous *voltha.Device, current *voltha.Device) error {
818 // This will be triggered on every update to the device.
khenaidoo92e62c52018-10-03 14:02:54 -0400819 handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
820 if handlers == nil {
khenaidoo43c82122018-11-22 18:38:28 -0500821 log.Debugw("no-op-transition", log.Fields{"deviceId": current.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400822 return nil
khenaidoob9203542018-09-17 22:56:37 -0400823 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400824 log.Debugw("handler-found", log.Fields{"num-handlers": len(handlers), "isParent": current.Root, "current-data": current})
khenaidoo92e62c52018-10-03 14:02:54 -0400825 for _, handler := range handlers {
826 log.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
827 if err := handler(current); err != nil {
khenaidoo6d62c002019-05-15 21:57:03 -0400828 log.Warnw("handler-failed", log.Fields{"handler": funcName(handler), "error": err})
khenaidoo92e62c52018-10-03 14:02:54 -0400829 return err
830 }
831 }
khenaidoob9203542018-09-17 22:56:37 -0400832 return nil
833}
834
khenaidoofdbad6e2018-11-06 22:26:38 -0500835func (dMgr *DeviceManager) packetOut(deviceId string, outPort uint32, packet *ofp.OfpPacketOut) error {
836 log.Debugw("packetOut", log.Fields{"deviceId": deviceId, "outPort": outPort})
837 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
838 return agent.packetOut(outPort, packet)
839 }
840 return status.Errorf(codes.NotFound, "%s", deviceId)
841}
842
khenaidoo297cd252019-02-07 22:10:23 -0500843func (dMgr *DeviceManager) PacketIn(deviceId string, port uint32, transactionId string, packet []byte) error {
khenaidoofdbad6e2018-11-06 22:26:38 -0500844 log.Debugw("PacketIn", log.Fields{"deviceId": deviceId, "port": port})
845 // Get the logical device Id based on the deviceId
846 var device *voltha.Device
847 var err error
848 if device, err = dMgr.GetDevice(deviceId); err != nil {
849 log.Errorw("device-not-found", log.Fields{"deviceId": deviceId})
850 return err
851 }
khenaidoo43c82122018-11-22 18:38:28 -0500852 if !device.Root {
khenaidoofdbad6e2018-11-06 22:26:38 -0500853 log.Errorw("device-not-root", log.Fields{"deviceId": deviceId})
854 return status.Errorf(codes.FailedPrecondition, "%s", deviceId)
855 }
856
khenaidoo297cd252019-02-07 22:10:23 -0500857 if err := dMgr.logicalDeviceMgr.packetIn(device.ParentId, port, transactionId, packet); err != nil {
khenaidoofdbad6e2018-11-06 22:26:38 -0500858 return err
859 }
860 return nil
861}
862
khenaidoo0a822f92019-05-08 15:15:57 -0400863func (dMgr *DeviceManager) CreateLogicalDevice(cDevice *voltha.Device) error {
864 log.Info("CreateLogicalDevice")
khenaidoo59ef7be2019-06-21 12:40:28 -0400865 // Verify whether the logical device has already been created
866 if cDevice.ParentId != "" {
867 log.Debugw("Parent device already exist.", log.Fields{"deviceId": cDevice.Id, "logicalDeviceId": cDevice.Id})
868 return nil
869 }
khenaidoob9203542018-09-17 22:56:37 -0400870 var logicalId *string
871 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400872 if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400873 log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
874 return err
875 }
876 // Update the parent device with the logical id
877 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
878 return nil
879}
880
khenaidoo0a822f92019-05-08 15:15:57 -0400881func (dMgr *DeviceManager) DeleteLogicalDevice(cDevice *voltha.Device) error {
882 log.Info("DeleteLogicalDevice")
khenaidoo92e62c52018-10-03 14:02:54 -0400883 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -0400884 if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(nil, cDevice); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400885 log.Warnw("deleteLogical-device-error", log.Fields{"deviceId": cDevice.Id})
886 return err
887 }
888 // Remove the logical device Id from the parent device
889 logicalId := ""
890 dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", logicalId)
891 return nil
892}
893
khenaidoo0a822f92019-05-08 15:15:57 -0400894func (dMgr *DeviceManager) DeleteLogicalPort(device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400895 log.Info("deleteLogicalPort")
896 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400897 // Get the logical port associated with this device
898 var lPortId *voltha.LogicalPortId
899 if lPortId, err = dMgr.logicalDeviceMgr.getLogicalPortId(device); err != nil {
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400900 log.Warnw("getLogical-port-error", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo19d7b632018-10-30 10:49:50 -0400901 return err
902 }
903 if err = dMgr.logicalDeviceMgr.deleteLogicalPort(nil, lPortId); err != nil {
904 log.Warnw("deleteLogical-port-error", log.Fields{"deviceId": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400905 return err
906 }
khenaidoo92e62c52018-10-03 14:02:54 -0400907 return nil
908}
909
khenaidoo0a822f92019-05-08 15:15:57 -0400910func (dMgr *DeviceManager) DeleteLogicalPorts(device *voltha.Device) error {
911 log.Info("deleteLogicalPorts")
912 if err := dMgr.logicalDeviceMgr.deleteLogicalPorts(device.Id); err != nil {
913 log.Warnw("deleteLogical-ports-error", log.Fields{"deviceId": device.Id})
914 return err
915 }
916 return nil
917}
918
khenaidoo59ef7be2019-06-21 12:40:28 -0400919func (dMgr *DeviceManager) MarkChildDevicesAsUnReachable(device *voltha.Device) error {
920 log.Info("MarkChildDevicesAsUnReachable")
921 // Set the connection status to unreachable
922 connStatus := voltha.ConnectStatus_UNREACHABLE
923 // Do not set the operational status. Setting it to -1 will do the trick
924 operStatus := voltha.OperStatus_OperStatus(-1)
925 if err := dMgr.updateChildrenStatus(device.Id, operStatus, connStatus); err != nil {
926 log.Warnw("deleteLogical-ports-error", log.Fields{"deviceId": device.Id})
927 return err
928 }
929 return nil
930}
931
khenaidoo92e62c52018-10-03 14:02:54 -0400932func (dMgr *DeviceManager) getParentDevice(childDevice *voltha.Device) *voltha.Device {
933 // Sanity check
934 if childDevice.Root {
935 // childDevice is the parent device
936 return childDevice
937 }
khenaidoo19d7b632018-10-30 10:49:50 -0400938 parentDevice, _ := dMgr.GetDevice(childDevice.ParentId)
khenaidoo92e62c52018-10-03 14:02:54 -0400939 return parentDevice
940}
941
khenaidoo0a822f92019-05-08 15:15:57 -0400942//childDevicesLost is invoked by an adapter to indicate that a parent device is in a state (Disabled) where it
943//cannot manage the child devices. This will trigger the Core to disable all the child devices.
944func (dMgr *DeviceManager) childDevicesLost(parentDeviceId string) error {
945 log.Debug("childDevicesLost")
946 var err error
947 var parentDevice *voltha.Device
948 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
949 log.Warnw("failed-getting-device", log.Fields{"deviceId": parentDeviceId, "error": err})
950 return err
951 }
952 return dMgr.DisableAllChildDevices(parentDevice)
953}
954
955//childDevicesDetected is invoked by an adapter when child devices are found, typically after after a
956// disable/enable sequence. This will trigger the Core to Enable all the child devices of that parent.
957func (dMgr *DeviceManager) childDevicesDetected(parentDeviceId string) error {
958 log.Debug("childDevicesDetected")
959 var err error
960 var parentDevice *voltha.Device
961 var childDeviceIds []string
962
963 if parentDevice, err = dMgr.GetDevice(parentDeviceId); err != nil {
964 log.Warnw("failed-getting-device", log.Fields{"deviceId": parentDeviceId, "error": err})
965 return err
966 }
967
968 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
969 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
970 }
971 if len(childDeviceIds) == 0 {
972 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
973 }
khenaidoo59ef7be2019-06-21 12:40:28 -0400974 allChildEnableRequestSent := true
khenaidoo0a822f92019-05-08 15:15:57 -0400975 for _, childDeviceId := range childDeviceIds {
976 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
khenaidoo59ef7be2019-06-21 12:40:28 -0400977 // Run the children re-registration in its own routine
978 go agent.enableDevice(nil)
979 } else {
980 err = status.Errorf(codes.Unavailable, "no agent for child device %s", childDeviceId)
981 log.Errorw("no-child-device-agent", log.Fields{"parentDeviceId": parentDevice.Id, "childId": childDeviceId})
982 allChildEnableRequestSent = false
khenaidoo0a822f92019-05-08 15:15:57 -0400983 }
984 }
khenaidoo59ef7be2019-06-21 12:40:28 -0400985 if !allChildEnableRequestSent {
khenaidoo0a822f92019-05-08 15:15:57 -0400986 return err
987 }
988 return nil
989}
990
khenaidoo4d4802d2018-10-04 21:59:49 -0400991/*
992All the functions below are callback functions where they are invoked with the latest and previous data. We can
993therefore use the data as is without trying to get the latest from the model.
994*/
995
khenaidoo0a822f92019-05-08 15:15:57 -0400996//DisableAllChildDevices is invoked as a callback when the parent device is disabled
997func (dMgr *DeviceManager) DisableAllChildDevices(parentDevice *voltha.Device) error {
998 log.Debug("DisableAllChildDevices")
khenaidoo92e62c52018-10-03 14:02:54 -0400999 var childDeviceIds []string
1000 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -04001001 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
1002 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -04001003 }
1004 if len(childDeviceIds) == 0 {
khenaidoo4d4802d2018-10-04 21:59:49 -04001005 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -04001006 }
khenaidoo4d4802d2018-10-04 21:59:49 -04001007 allChildDisable := true
khenaidoo92e62c52018-10-03 14:02:54 -04001008 for _, childDeviceId := range childDeviceIds {
1009 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
1010 if err = agent.disableDevice(nil); err != nil {
1011 log.Errorw("failure-disable-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
khenaidoo4d4802d2018-10-04 21:59:49 -04001012 allChildDisable = false
khenaidoo92e62c52018-10-03 14:02:54 -04001013 }
1014 }
1015 }
khenaidoo4d4802d2018-10-04 21:59:49 -04001016 if !allChildDisable {
1017 return err
1018 }
khenaidoo92e62c52018-10-03 14:02:54 -04001019 return nil
1020}
1021
khenaidoo0a822f92019-05-08 15:15:57 -04001022//DeleteAllChildDevices is invoked as a callback when the parent device is deleted
1023func (dMgr *DeviceManager) DeleteAllChildDevices(parentDevice *voltha.Device) error {
1024 log.Debug("DeleteAllChildDevices")
khenaidoo4d4802d2018-10-04 21:59:49 -04001025 var childDeviceIds []string
khenaidoo92e62c52018-10-03 14:02:54 -04001026 var err error
khenaidoo4d4802d2018-10-04 21:59:49 -04001027 if childDeviceIds, err = dMgr.getAllChildDeviceIds(parentDevice); err != nil {
1028 return status.Errorf(codes.NotFound, "%s", parentDevice.Id)
khenaidoo92e62c52018-10-03 14:02:54 -04001029 }
khenaidoo4d4802d2018-10-04 21:59:49 -04001030 if len(childDeviceIds) == 0 {
1031 log.Debugw("no-child-device", log.Fields{"parentDeviceId": parentDevice.Id})
1032 }
1033 allChildDeleted := true
1034 for _, childDeviceId := range childDeviceIds {
1035 if agent := dMgr.getDeviceAgent(childDeviceId); agent != nil {
1036 if err = agent.deleteDevice(nil); err != nil {
1037 log.Errorw("failure-delete-device", log.Fields{"deviceId": childDeviceId, "error": err.Error()})
1038 allChildDeleted = false
1039 } else {
1040 agent.stop(nil)
1041 dMgr.deleteDeviceAgentToMap(agent)
1042 }
1043 }
1044 }
1045 if !allChildDeleted {
1046 return err
1047 }
1048 return nil
1049}
1050
khenaidoo6d62c002019-05-15 21:57:03 -04001051//getAllDeviceIdsWithDeviceParentId returns the list of device Ids which has id as parent Id. This function uses the
1052// data from the agent instead of using the data from the parent device as that data would disappear from a parent
1053// device during a delete device operation.
1054func (dMgr *DeviceManager) getAllDeviceIdsWithDeviceParentId(id string) []string {
1055 log.Debugw("getAllAgentsWithDeviceParentId", log.Fields{"parentDeviceId": id})
1056 deviceIds := make([]string, 0)
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001057 dMgr.deviceAgents.Range(func(key, value interface{}) bool {
1058 agent := value.(*DeviceAgent)
khenaidoo6d62c002019-05-15 21:57:03 -04001059 if agent.parentId == id {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001060 deviceIds = append(deviceIds, key.(string))
khenaidoo6d62c002019-05-15 21:57:03 -04001061 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001062 return true
1063 })
khenaidoo6d62c002019-05-15 21:57:03 -04001064 return deviceIds
1065}
1066
khenaidoo4d4802d2018-10-04 21:59:49 -04001067//getAllChildDeviceIds is a helper method to get all the child device IDs from the device passed as parameter
1068func (dMgr *DeviceManager) getAllChildDeviceIds(parentDevice *voltha.Device) ([]string, error) {
1069 log.Debugw("getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id})
khenaidoo92e62c52018-10-03 14:02:54 -04001070 childDeviceIds := make([]string, 0)
khenaidoo4d4802d2018-10-04 21:59:49 -04001071 if parentDevice != nil {
1072 for _, port := range parentDevice.Ports {
1073 for _, peer := range port.Peers {
1074 childDeviceIds = append(childDeviceIds, peer.DeviceId)
1075 }
khenaidoo92e62c52018-10-03 14:02:54 -04001076 }
khenaidoo2c6a0992019-04-29 13:46:56 -04001077 log.Debugw("returning-getAllChildDeviceIds", log.Fields{"parentDeviceId": parentDevice.Id, "childDeviceIds": childDeviceIds})
khenaidoo92e62c52018-10-03 14:02:54 -04001078 }
1079 return childDeviceIds, nil
1080}
1081
khenaidoo297cd252019-02-07 22:10:23 -05001082//getAllChildDevices is a helper method to get all the child device IDs from the device passed as parameter
1083func (dMgr *DeviceManager) getAllChildDevices(parentDeviceId string) (*voltha.Devices, error) {
1084 log.Debugw("getAllChildDevices", log.Fields{"parentDeviceId": parentDeviceId})
1085 if parentDevice, err := dMgr.GetDevice(parentDeviceId); err == nil {
1086 childDevices := make([]*voltha.Device, 0)
1087 if childDeviceIds, er := dMgr.getAllChildDeviceIds(parentDevice); er == nil {
1088 for _, deviceId := range childDeviceIds {
1089 if d, e := dMgr.GetDevice(deviceId); e == nil && d != nil {
1090 childDevices = append(childDevices, d)
1091 }
1092 }
1093 }
1094 return &voltha.Devices{Items: childDevices}, nil
1095 }
1096 return nil, status.Errorf(codes.NotFound, "%s", parentDeviceId)
1097}
1098
khenaidoo0a822f92019-05-08 15:15:57 -04001099func (dMgr *DeviceManager) SetupUNILogicalPorts(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001100 log.Info("addUNILogicalPort")
khenaidoofc1314d2019-03-14 09:34:21 -04001101 if err := dMgr.logicalDeviceMgr.setupUNILogicalPorts(nil, cDevice); err != nil {
khenaidoob9203542018-09-17 22:56:37 -04001102 log.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
1103 return err
1104 }
1105 return nil
1106}
1107
khenaidoof5a5bfa2019-01-23 22:20:29 -05001108func (dMgr *DeviceManager) downloadImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1109 log.Debugw("downloadImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1110 var res interface{}
1111 var err error
1112 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1113 if res, err = agent.downloadImage(ctx, img); err != nil {
1114 log.Debugw("downloadImage-failed", log.Fields{"err": err, "imageName": img.Name})
1115 res = err
1116 }
1117 } else {
1118 res = status.Errorf(codes.NotFound, "%s", img.Id)
1119 }
1120 sendResponse(ctx, ch, res)
1121}
1122
1123func (dMgr *DeviceManager) cancelImageDownload(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1124 log.Debugw("cancelImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1125 var res interface{}
1126 var err error
1127 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1128 if res, err = agent.cancelImageDownload(ctx, img); err != nil {
1129 log.Debugw("cancelImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
1130 res = err
1131 }
1132 } else {
1133 res = status.Errorf(codes.NotFound, "%s", img.Id)
1134 }
1135 sendResponse(ctx, ch, res)
1136}
1137
1138func (dMgr *DeviceManager) activateImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1139 log.Debugw("activateImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1140 var res interface{}
1141 var err error
1142 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1143 if res, err = agent.activateImage(ctx, img); err != nil {
1144 log.Debugw("activateImage-failed", log.Fields{"err": err, "imageName": img.Name})
1145 res = err
1146 }
1147 } else {
1148 res = status.Errorf(codes.NotFound, "%s", img.Id)
1149 }
1150 sendResponse(ctx, ch, res)
1151}
1152
1153func (dMgr *DeviceManager) revertImage(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1154 log.Debugw("revertImage", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1155 var res interface{}
1156 var err error
1157 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1158 if res, err = agent.revertImage(ctx, img); err != nil {
1159 log.Debugw("revertImage-failed", log.Fields{"err": err, "imageName": img.Name})
1160 res = err
1161 }
1162 } else {
1163 res = status.Errorf(codes.NotFound, "%s", img.Id)
1164 }
1165 sendResponse(ctx, ch, res)
1166}
1167
1168func (dMgr *DeviceManager) getImageDownloadStatus(ctx context.Context, img *voltha.ImageDownload, ch chan interface{}) {
1169 log.Debugw("getImageDownloadStatus", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1170 var res interface{}
1171 var err error
1172 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1173 if res, err = agent.getImageDownloadStatus(ctx, img); err != nil {
1174 log.Debugw("getImageDownloadStatus-failed", log.Fields{"err": err, "imageName": img.Name})
1175 res = err
1176 }
1177 } else {
1178 res = status.Errorf(codes.NotFound, "%s", img.Id)
1179 }
1180 sendResponse(ctx, ch, res)
1181}
1182
khenaidoof5a5bfa2019-01-23 22:20:29 -05001183func (dMgr *DeviceManager) updateImageDownload(deviceId string, img *voltha.ImageDownload) error {
1184 log.Debugw("updateImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1185 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
1186 if err := agent.updateImageDownload(img); err != nil {
1187 log.Debugw("updateImageDownload-failed", log.Fields{"err": err, "imageName": img.Name})
1188 return err
1189 }
1190 } else {
1191 return status.Errorf(codes.NotFound, "%s", img.Id)
1192 }
1193 return nil
1194}
1195
1196func (dMgr *DeviceManager) getImageDownload(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
1197 log.Debugw("getImageDownload", log.Fields{"deviceid": img.Id, "imageName": img.Name})
1198 if agent := dMgr.getDeviceAgent(img.Id); agent != nil {
1199 return agent.getImageDownload(ctx, img)
1200 }
1201 return nil, status.Errorf(codes.NotFound, "%s", img.Id)
1202}
1203
1204func (dMgr *DeviceManager) listImageDownloads(ctx context.Context, deviceId string) (*voltha.ImageDownloads, error) {
1205 log.Debugw("listImageDownloads", log.Fields{"deviceId": deviceId})
1206 if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
1207 return agent.listImageDownloads(ctx, deviceId)
1208 }
1209 return nil, status.Errorf(codes.NotFound, "%s", deviceId)
1210}
1211
khenaidoo0a822f92019-05-08 15:15:57 -04001212func (dMgr *DeviceManager) SetAdminStateToEnable(cDevice *voltha.Device) error {
1213 log.Info("SetAdminStateToEnable")
1214 if agent := dMgr.getDeviceAgent(cDevice.Id); agent != nil {
1215 return agent.updateAdminState(voltha.AdminState_ENABLED)
1216 }
1217 return status.Errorf(codes.NotFound, "%s", cDevice.Id)
1218}
1219
khenaidoo92e62c52018-10-03 14:02:54 -04001220func (dMgr *DeviceManager) activateDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001221 log.Info("activateDevice")
1222 return nil
1223}
1224
khenaidoo92e62c52018-10-03 14:02:54 -04001225func (dMgr *DeviceManager) disableDeviceHandler(cDevice *voltha.Device) error {
1226 log.Info("disableDevice-donothing")
khenaidoob9203542018-09-17 22:56:37 -04001227 return nil
1228}
1229
khenaidoo92e62c52018-10-03 14:02:54 -04001230func (dMgr *DeviceManager) abandonDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001231 log.Info("abandonDevice")
1232 return nil
1233}
1234
khenaidoo92e62c52018-10-03 14:02:54 -04001235func (dMgr *DeviceManager) reEnableDevice(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001236 log.Info("reEnableDevice")
1237 return nil
1238}
1239
khenaidoo92e62c52018-10-03 14:02:54 -04001240func (dMgr *DeviceManager) noOp(cDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001241 log.Info("noOp")
1242 return nil
1243}
1244
khenaidoo92e62c52018-10-03 14:02:54 -04001245func (dMgr *DeviceManager) notAllowed(pcDevice *voltha.Device) error {
khenaidoob9203542018-09-17 22:56:37 -04001246 log.Info("notAllowed")
khenaidoo2c6a0992019-04-29 13:46:56 -04001247 return errors.New("transition-not-allowed")
khenaidoob9203542018-09-17 22:56:37 -04001248}
1249
khenaidoo0a822f92019-05-08 15:15:57 -04001250func (dMgr *DeviceManager) NotifyInvalidTransition(pcDevice *voltha.Device) error {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001251 log.Errorw("NotifyInvalidTransition", log.Fields{
1252 "device": pcDevice.Id,
1253 "adminState": pcDevice.AdminState,
1254 "operState": pcDevice.OperStatus,
1255 "connState": pcDevice.ConnectStatus,
1256 })
khenaidoo0a822f92019-05-08 15:15:57 -04001257 //TODO: notify over kafka?
1258 return nil
1259}
1260
khenaidoob9203542018-09-17 22:56:37 -04001261func funcName(f interface{}) string {
1262 p := reflect.ValueOf(f).Pointer()
1263 rf := runtime.FuncForPC(p)
1264 return rf.Name()
1265}
1266
1267func (dMgr *DeviceManager) UpdateDeviceAttribute(deviceId string, attribute string, value interface{}) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -04001268 if agent, ok := dMgr.deviceAgents.Load(deviceId); ok {
1269 agent.(*DeviceAgent).updateDeviceAttribute(attribute, value)
khenaidoob9203542018-09-17 22:56:37 -04001270 }
1271}
1272
1273func (dMgr *DeviceManager) GetParentDeviceId(deviceId string) *string {
khenaidoo19d7b632018-10-30 10:49:50 -04001274 if device, _ := dMgr.GetDevice(deviceId); device != nil {
khenaidoo92e62c52018-10-03 14:02:54 -04001275 log.Infow("GetParentDeviceId", log.Fields{"deviceId": device.Id, "parentId": device.ParentId})
khenaidoob9203542018-09-17 22:56:37 -04001276 return &device.ParentId
1277 }
1278 return nil
1279}
serkant.uluderya334479d2019-04-10 08:26:15 -07001280
1281func (dMgr *DeviceManager) simulateAlarm(ctx context.Context, simulatereq *voltha.SimulateAlarmRequest, ch chan interface{}) {
1282 log.Debugw("simulateAlarm", log.Fields{"id": simulatereq.Id, "Indicator": simulatereq.Indicator, "IntfId": simulatereq.IntfId,
1283 "PortTypeName": simulatereq.PortTypeName, "OnuDeviceId": simulatereq.OnuDeviceId, "InverseBitErrorRate": simulatereq.InverseBitErrorRate,
1284 "Drift": simulatereq.Drift, "NewEqd": simulatereq.NewEqd, "OnuSerialNumber": simulatereq.OnuSerialNumber, "Operation": simulatereq.Operation})
1285 var res interface{}
1286 if agent := dMgr.getDeviceAgent(simulatereq.Id); agent != nil {
1287 res = agent.simulateAlarm(ctx, simulatereq)
1288 log.Debugw("SimulateAlarm-result", log.Fields{"result": res})
1289 }
1290 //TODO CLI always get successful response
1291 sendResponse(ctx, ch, res)
1292}