blob: 37c12597712ba523dd67d52fb02af6009aa64ab7 [file] [log] [blame]
khenaidoo21d51152019-02-01 13:48:37 -05001/*
2 * Copyright 2019-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 "fmt"
22 "github.com/gogo/protobuf/proto"
sbarbari17d7e222019-11-05 10:02:29 -050023 "github.com/opencord/voltha-go/db/model"
Scott Baker807addd2019-10-24 15:16:21 -070024 "github.com/opencord/voltha-lib-go/v2/pkg/log"
25 "github.com/opencord/voltha-lib-go/v2/pkg/probe"
Scott Baker555307d2019-11-04 08:58:01 -080026 "github.com/opencord/voltha-protos/v2/go/voltha"
khenaidoo21d51152019-02-01 13:48:37 -050027 "reflect"
28 "sync"
29)
30
31const (
khenaidoo1ce37ad2019-03-24 22:07:24 -040032 SENTINEL_ADAPTER_ID = "adapter_sentinel"
khenaidoo21d51152019-02-01 13:48:37 -050033 SENTINEL_DEVICETYPE_ID = "device_type_sentinel"
khenaidoo21d51152019-02-01 13:48:37 -050034)
35
36type AdapterAgent struct {
khenaidoo1ce37ad2019-03-24 22:07:24 -040037 adapter *voltha.Adapter
khenaidoo21d51152019-02-01 13:48:37 -050038 deviceTypes map[string]*voltha.DeviceType
khenaidoo1ce37ad2019-03-24 22:07:24 -040039 lock sync.RWMutex
khenaidoo21d51152019-02-01 13:48:37 -050040}
41
42func newAdapterAgent(adapter *voltha.Adapter, deviceTypes *voltha.DeviceTypes) *AdapterAgent {
43 var adapterAgent AdapterAgent
44 adapterAgent.adapter = adapter
45 adapterAgent.lock = sync.RWMutex{}
46 adapterAgent.deviceTypes = make(map[string]*voltha.DeviceType)
47 if deviceTypes != nil {
48 for _, dType := range deviceTypes.Items {
49 adapterAgent.deviceTypes[dType.Id] = dType
50 }
51 }
52 return &adapterAgent
53}
54
55// Returns true if this device agent can handle this device Type
56func (aa *AdapterAgent) handlesDeviceType(deviceType string) bool {
57 aa.lock.RLock()
58 defer aa.lock.RUnlock()
59 _, exist := aa.deviceTypes[deviceType]
60 return exist
61}
62
63func (aa *AdapterAgent) getDeviceType(deviceType string) *voltha.DeviceType {
64 aa.lock.RLock()
65 defer aa.lock.RUnlock()
66 if _, exist := aa.deviceTypes[deviceType]; exist {
67 return aa.deviceTypes[deviceType]
68 }
69 return nil
70}
71
72func (aa *AdapterAgent) getAdapter() *voltha.Adapter {
73 aa.lock.RLock()
74 defer aa.lock.RUnlock()
75 log.Debugw("getAdapter", log.Fields{"adapter": aa.adapter})
76 return aa.adapter
77}
78
79func (aa *AdapterAgent) updateAdapter(adapter *voltha.Adapter) {
khenaidoo1ce37ad2019-03-24 22:07:24 -040080 aa.lock.Lock()
81 defer aa.lock.Unlock()
khenaidoo21d51152019-02-01 13:48:37 -050082 aa.adapter = adapter
83}
84
khenaidoo1ce37ad2019-03-24 22:07:24 -040085func (aa *AdapterAgent) updateDeviceType(deviceType *voltha.DeviceType) {
86 aa.lock.Lock()
87 defer aa.lock.Unlock()
khenaidoo21d51152019-02-01 13:48:37 -050088 aa.deviceTypes[deviceType.Id] = deviceType
89}
90
91type AdapterManager struct {
92 adapterAgents map[string]*AdapterAgent
93 deviceTypeToAdapterMap map[string]string
94 clusterDataProxy *model.Proxy
95 adapterProxy *model.Proxy
96 deviceTypeProxy *model.Proxy
khenaidooba6b6c42019-08-02 09:11:56 -040097 deviceMgr *DeviceManager
khenaidoo21d51152019-02-01 13:48:37 -050098 coreInstanceId string
99 exitChannel chan int
100 lockAdaptersMap sync.RWMutex
101 lockdDeviceTypeToAdapterMap sync.RWMutex
102}
103
khenaidooba6b6c42019-08-02 09:11:56 -0400104func newAdapterManager(cdProxy *model.Proxy, coreInstanceId string, deviceMgr *DeviceManager) *AdapterManager {
khenaidoo21d51152019-02-01 13:48:37 -0500105 var adapterMgr AdapterManager
106 adapterMgr.exitChannel = make(chan int, 1)
107 adapterMgr.coreInstanceId = coreInstanceId
108 adapterMgr.clusterDataProxy = cdProxy
109 adapterMgr.adapterAgents = make(map[string]*AdapterAgent)
110 adapterMgr.deviceTypeToAdapterMap = make(map[string]string)
111 adapterMgr.lockAdaptersMap = sync.RWMutex{}
112 adapterMgr.lockdDeviceTypeToAdapterMap = sync.RWMutex{}
khenaidooba6b6c42019-08-02 09:11:56 -0400113 adapterMgr.deviceMgr = deviceMgr
khenaidoo21d51152019-02-01 13:48:37 -0500114 return &adapterMgr
115}
116
khenaidoo1ce37ad2019-03-24 22:07:24 -0400117func (aMgr *AdapterManager) start(ctx context.Context) {
khenaidoo21d51152019-02-01 13:48:37 -0500118 log.Info("starting-adapter-manager")
119
120 // Load the existing adapterAgents and device types - this will also ensure the correct paths have been
121 // created if there are no data in the dB to start
122 aMgr.loadAdaptersAndDevicetypesInMemory()
123
124 //// Create the proxies
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400125 aMgr.adapterProxy = aMgr.clusterDataProxy.CreateProxy(context.Background(), "/adapters", false)
126 aMgr.deviceTypeProxy = aMgr.clusterDataProxy.CreateProxy(context.Background(), "/device_types", false)
khenaidoo21d51152019-02-01 13:48:37 -0500127
128 // Register the callbacks
129 aMgr.adapterProxy.RegisterCallback(model.POST_UPDATE, aMgr.adapterUpdated)
130 aMgr.deviceTypeProxy.RegisterCallback(model.POST_UPDATE, aMgr.deviceTypesUpdated)
David K. Bainbridgeb4a9ab02019-09-20 15:12:16 -0700131 probe.UpdateStatusFromContext(ctx, "adapter-manager", probe.ServiceStatusRunning)
khenaidoo21d51152019-02-01 13:48:37 -0500132 log.Info("adapter-manager-started")
133}
134
135func (aMgr *AdapterManager) stop(ctx context.Context) {
136 log.Info("stopping-device-manager")
137 aMgr.exitChannel <- 1
David K. Bainbridgeb4a9ab02019-09-20 15:12:16 -0700138 probe.UpdateStatusFromContext(ctx, "adapter-manager", probe.ServiceStatusStopped)
khenaidoo21d51152019-02-01 13:48:37 -0500139 log.Info("device-manager-stopped")
140}
141
142//loadAdaptersAndDevicetypesInMemory loads the existing set of adapters and device types in memory
143func (aMgr *AdapterManager) loadAdaptersAndDevicetypesInMemory() {
144 // Load the adapters
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400145 if adaptersIf := aMgr.clusterDataProxy.List(context.Background(), "/adapters", 0, false, ""); adaptersIf != nil {
khenaidoo21d51152019-02-01 13:48:37 -0500146 for _, adapterIf := range adaptersIf.([]interface{}) {
147 if adapter, ok := adapterIf.(*voltha.Adapter); ok {
148 log.Debugw("found-existing-adapter", log.Fields{"adapterId": adapter.Id})
149 aMgr.addAdapter(adapter, false)
150 }
151 }
152 } else {
153 log.Debug("no-existing-adapter-found")
154 // No adapter data. In order to have a proxy setup for that path let's create a fake adapter
155 aMgr.addAdapter(&voltha.Adapter{Id: SENTINEL_ADAPTER_ID}, true)
156 }
157
158 // Load the device types
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400159 if deviceTypesIf := aMgr.clusterDataProxy.List(context.Background(), "/device_types", 0, false, ""); deviceTypesIf != nil {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400160 dTypes := &voltha.DeviceTypes{Items: []*voltha.DeviceType{}}
khenaidoo21d51152019-02-01 13:48:37 -0500161 for _, deviceTypeIf := range deviceTypesIf.([]interface{}) {
162 if dType, ok := deviceTypeIf.(*voltha.DeviceType); ok {
163 log.Debugw("found-existing-device-types", log.Fields{"deviceTypes": dTypes})
164 dTypes.Items = append(dTypes.Items, dType)
165 }
166 }
167 aMgr.addDeviceTypes(dTypes, false)
168 } else {
169 log.Debug("no-existing-device-type-found")
170 // No device types data. In order to have a proxy setup for that path let's create a fake device type
khenaidoo2c6a0992019-04-29 13:46:56 -0400171 aMgr.addDeviceTypes(&voltha.DeviceTypes{Items: []*voltha.DeviceType{{Id: SENTINEL_DEVICETYPE_ID, Adapter: SENTINEL_ADAPTER_ID}}}, true)
khenaidoo21d51152019-02-01 13:48:37 -0500172 }
173}
174
khenaidoo297cd252019-02-07 22:10:23 -0500175//updateAdaptersAndDevicetypesInMemory loads the existing set of adapters and device types in memory
khenaidooba6b6c42019-08-02 09:11:56 -0400176func (aMgr *AdapterManager) updateAdaptersAndDevicetypesInMemory(adapter *voltha.Adapter) {
A R Karthicked2a77b2019-10-08 01:40:51 +0000177 aMgr.lockAdaptersMap.Lock()
178 defer aMgr.lockAdaptersMap.Unlock()
179
180 if adapterAgent, ok := aMgr.adapterAgents[adapter.Id]; ok {
181 if adapterAgent.getAdapter() != nil {
182 // Already registered - Adapter may have restarted. Trigger the reconcile process for that adapter
183 go aMgr.deviceMgr.adapterRestarted(adapter)
184 return
185 }
khenaidooba6b6c42019-08-02 09:11:56 -0400186 }
187
khenaidoo297cd252019-02-07 22:10:23 -0500188 // Update the adapters
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400189 if adaptersIf := aMgr.clusterDataProxy.List(context.Background(), "/adapters", 0, false, ""); adaptersIf != nil {
khenaidoo297cd252019-02-07 22:10:23 -0500190 for _, adapterIf := range adaptersIf.([]interface{}) {
191 if adapter, ok := adapterIf.(*voltha.Adapter); ok {
192 log.Debugw("found-existing-adapter", log.Fields{"adapterId": adapter.Id})
A R Karthicked2a77b2019-10-08 01:40:51 +0000193 aMgr.updateAdapterWithoutLock(adapter)
khenaidoo297cd252019-02-07 22:10:23 -0500194 }
195 }
196 }
A R Karthicked2a77b2019-10-08 01:40:51 +0000197 aMgr.lockdDeviceTypeToAdapterMap.Lock()
198 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
khenaidoo297cd252019-02-07 22:10:23 -0500199 // Update the device types
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400200 if deviceTypesIf := aMgr.clusterDataProxy.List(context.Background(), "/device_types", 0, false, ""); deviceTypesIf != nil {
khenaidoo297cd252019-02-07 22:10:23 -0500201 dTypes := &voltha.DeviceTypes{Items: []*voltha.DeviceType{}}
202 for _, deviceTypeIf := range deviceTypesIf.([]interface{}) {
203 if dType, ok := deviceTypeIf.(*voltha.DeviceType); ok {
204 log.Debugw("found-existing-device-types", log.Fields{"deviceTypes": dTypes})
A R Karthicked2a77b2019-10-08 01:40:51 +0000205 aMgr.updateDeviceTypeWithoutLock(dType)
khenaidoo297cd252019-02-07 22:10:23 -0500206 }
207 }
208 }
209}
210
khenaidoo21d51152019-02-01 13:48:37 -0500211func (aMgr *AdapterManager) addAdapter(adapter *voltha.Adapter, saveToDb bool) {
212 aMgr.lockAdaptersMap.Lock()
213 defer aMgr.lockAdaptersMap.Unlock()
214 log.Debugw("adding-adapter", log.Fields{"adapter": adapter})
215 if _, exist := aMgr.adapterAgents[adapter.Id]; !exist {
216 clonedAdapter := (proto.Clone(adapter)).(*voltha.Adapter)
217 aMgr.adapterAgents[adapter.Id] = newAdapterAgent(clonedAdapter, nil)
218 if saveToDb {
219 // Save the adapter to the KV store - first check if it already exist
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400220 if kvAdapter := aMgr.clusterDataProxy.Get(context.Background(), "/adapters/"+adapter.Id, 0, false, ""); kvAdapter == nil {
221 if added := aMgr.clusterDataProxy.AddWithID(context.Background(), "/adapters", adapter.Id, clonedAdapter, ""); added == nil {
khenaidoo21d51152019-02-01 13:48:37 -0500222 //TODO: Errors when saving to KV would require a separate go routine to be launched and try the saving again
223 log.Errorw("failed-to-save-adapter", log.Fields{"adapter": adapter})
224 } else {
225 log.Debugw("adapter-saved-to-KV-Store", log.Fields{"adapter": adapter})
226 }
227 }
228 }
229 }
230}
231
khenaidoo21d51152019-02-01 13:48:37 -0500232func (aMgr *AdapterManager) addDeviceTypes(deviceTypes *voltha.DeviceTypes, saveToDb bool) {
233 if deviceTypes == nil {
234 return
235 }
236 log.Debugw("adding-device-types", log.Fields{"deviceTypes": deviceTypes})
237 aMgr.lockAdaptersMap.Lock()
238 defer aMgr.lockAdaptersMap.Unlock()
239 aMgr.lockdDeviceTypeToAdapterMap.Lock()
240 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
241 for _, deviceType := range deviceTypes.Items {
242 clonedDType := (proto.Clone(deviceType)).(*voltha.DeviceType)
243 if adapterAgent, exist := aMgr.adapterAgents[clonedDType.Adapter]; exist {
244 adapterAgent.updateDeviceType(clonedDType)
245 } else {
246 log.Debugw("adapter-not-exist", log.Fields{"deviceTypes": deviceTypes, "adapterId": clonedDType.Adapter})
khenaidoo1ce37ad2019-03-24 22:07:24 -0400247 aMgr.adapterAgents[clonedDType.Adapter] = newAdapterAgent(&voltha.Adapter{Id: clonedDType.Adapter}, deviceTypes)
khenaidoo21d51152019-02-01 13:48:37 -0500248 }
249 aMgr.deviceTypeToAdapterMap[clonedDType.Id] = clonedDType.Adapter
250 }
251 if saveToDb {
252 // Save the device types to the KV store as well
253 for _, deviceType := range deviceTypes.Items {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400254 if dType := aMgr.clusterDataProxy.Get(context.Background(), "/device_types/"+deviceType.Id, 0, false, ""); dType == nil {
khenaidoo21d51152019-02-01 13:48:37 -0500255 // Does not exist - save it
256 clonedDType := (proto.Clone(deviceType)).(*voltha.DeviceType)
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400257 if added := aMgr.clusterDataProxy.AddWithID(context.Background(), "/device_types", deviceType.Id, clonedDType, ""); added == nil {
khenaidoo21d51152019-02-01 13:48:37 -0500258 log.Errorw("failed-to-save-deviceType", log.Fields{"deviceType": deviceType})
259 } else {
260 log.Debugw("device-type-saved-to-KV-Store", log.Fields{"deviceType": deviceType})
261 }
262 }
263 }
264 }
265}
266
267func (aMgr *AdapterManager) listAdapters(ctx context.Context) (*voltha.Adapters, error) {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400268 result := &voltha.Adapters{Items: []*voltha.Adapter{}}
269 aMgr.lockAdaptersMap.RLock()
270 defer aMgr.lockAdaptersMap.RUnlock()
khenaidoo21d51152019-02-01 13:48:37 -0500271 for _, adapterAgent := range aMgr.adapterAgents {
272 if a := adapterAgent.getAdapter(); a != nil {
khenaidoo297cd252019-02-07 22:10:23 -0500273 if a.Id != SENTINEL_ADAPTER_ID { // don't report the sentinel
274 result.Items = append(result.Items, (proto.Clone(a)).(*voltha.Adapter))
275 }
khenaidoo21d51152019-02-01 13:48:37 -0500276 }
277 }
278 return result, nil
279}
280
281func (aMgr *AdapterManager) deleteAdapter(adapterId string) {
282 aMgr.lockAdaptersMap.Lock()
283 defer aMgr.lockAdaptersMap.Unlock()
284 delete(aMgr.adapterAgents, adapterId)
285}
286
287func (aMgr *AdapterManager) getAdapter(adapterId string) *voltha.Adapter {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400288 aMgr.lockAdaptersMap.RLock()
289 defer aMgr.lockAdaptersMap.RUnlock()
khenaidoo21d51152019-02-01 13:48:37 -0500290 if adapterAgent, ok := aMgr.adapterAgents[adapterId]; ok {
291 return adapterAgent.getAdapter()
292 }
293 return nil
294}
295
296//updateAdapter updates an adapter if it exist. Otherwise, it creates it.
khenaidoo1ce37ad2019-03-24 22:07:24 -0400297func (aMgr *AdapterManager) updateAdapter(adapter *voltha.Adapter) {
khenaidoo21d51152019-02-01 13:48:37 -0500298 aMgr.lockAdaptersMap.Lock()
299 defer aMgr.lockAdaptersMap.Unlock()
A R Karthicked2a77b2019-10-08 01:40:51 +0000300 aMgr.updateAdapterWithoutLock(adapter)
301}
302
303func (aMgr *AdapterManager) updateAdapterWithoutLock(adapter *voltha.Adapter) {
khenaidoo21d51152019-02-01 13:48:37 -0500304 if adapterAgent, ok := aMgr.adapterAgents[adapter.Id]; ok {
305 adapterAgent.updateAdapter(adapter)
306 } else {
307 aMgr.adapterAgents[adapter.Id] = newAdapterAgent(adapter, nil)
308 }
309}
310
311//updateDeviceType updates an adapter if it exist. Otherwise, it creates it.
khenaidoo1ce37ad2019-03-24 22:07:24 -0400312func (aMgr *AdapterManager) updateDeviceType(deviceType *voltha.DeviceType) {
khenaidoo21d51152019-02-01 13:48:37 -0500313 aMgr.lockAdaptersMap.Lock()
314 defer aMgr.lockAdaptersMap.Unlock()
315 aMgr.lockdDeviceTypeToAdapterMap.Lock()
316 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
A R Karthicked2a77b2019-10-08 01:40:51 +0000317 aMgr.updateDeviceTypeWithoutLock(deviceType)
318}
319
320func (aMgr *AdapterManager) updateDeviceTypeWithoutLock(deviceType *voltha.DeviceType) {
khenaidoo297cd252019-02-07 22:10:23 -0500321 if adapterAgent, exist := aMgr.adapterAgents[deviceType.Adapter]; exist {
khenaidoo21d51152019-02-01 13:48:37 -0500322 adapterAgent.updateDeviceType(deviceType)
323 } else {
324 aMgr.adapterAgents[deviceType.Adapter] = newAdapterAgent(&voltha.Adapter{Id: deviceType.Adapter},
khenaidoo1ce37ad2019-03-24 22:07:24 -0400325 &voltha.DeviceTypes{Items: []*voltha.DeviceType{deviceType}})
khenaidoo21d51152019-02-01 13:48:37 -0500326 }
327 aMgr.deviceTypeToAdapterMap[deviceType.Id] = deviceType.Adapter
328}
329
khenaidoo1ce37ad2019-03-24 22:07:24 -0400330func (aMgr *AdapterManager) registerAdapter(adapter *voltha.Adapter, deviceTypes *voltha.DeviceTypes) *voltha.CoreInstance {
khenaidoo21d51152019-02-01 13:48:37 -0500331 log.Debugw("registerAdapter", log.Fields{"adapter": adapter, "deviceTypes": deviceTypes.Items})
332
333 if aMgr.getAdapter(adapter.Id) != nil {
khenaidooba6b6c42019-08-02 09:11:56 -0400334 // Already registered - Adapter may have restarted. Trigger the reconcile process for that adapter
335 go aMgr.deviceMgr.adapterRestarted(adapter)
khenaidoo1ce37ad2019-03-24 22:07:24 -0400336 return &voltha.CoreInstance{InstanceId: aMgr.coreInstanceId}
khenaidoo21d51152019-02-01 13:48:37 -0500337 }
338 // Save the adapter and the device types
339 aMgr.addAdapter(adapter, true)
340 aMgr.addDeviceTypes(deviceTypes, true)
341
342 log.Debugw("adapter-registered", log.Fields{"adapter": adapter.Id})
343
khenaidoo1ce37ad2019-03-24 22:07:24 -0400344 return &voltha.CoreInstance{InstanceId: aMgr.coreInstanceId}
khenaidoo21d51152019-02-01 13:48:37 -0500345}
346
347//getAdapterName returns the name of the device adapter that service this device type
348func (aMgr *AdapterManager) getAdapterName(deviceType string) (string, error) {
349 aMgr.lockdDeviceTypeToAdapterMap.Lock()
350 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
351 if adapterId, exist := aMgr.deviceTypeToAdapterMap[deviceType]; exist {
352 return adapterId, nil
353 }
354 return "", errors.New(fmt.Sprintf("Adapter-not-registered-for-device-type %s", deviceType))
355}
356
357// getDeviceType returns the device type proto definition given the name of the device type
khenaidoo1ce37ad2019-03-24 22:07:24 -0400358func (aMgr *AdapterManager) getDeviceType(deviceType string) *voltha.DeviceType {
khenaidoo21d51152019-02-01 13:48:37 -0500359 aMgr.lockdDeviceTypeToAdapterMap.Lock()
360 defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
361 if adapterId, exist := aMgr.deviceTypeToAdapterMap[deviceType]; exist {
362 if adapterAgent, _ := aMgr.adapterAgents[adapterId]; adapterAgent != nil {
363 return adapterAgent.getDeviceType(deviceType)
364 }
365 }
366 return nil
367}
368
369//adapterUpdated is a callback invoked when an adapter change has been noticed
370func (aMgr *AdapterManager) adapterUpdated(args ...interface{}) interface{} {
371 log.Debugw("updateAdapter-callback", log.Fields{"argsLen": len(args)})
372
373 var previousData *voltha.Adapters
374 var latestData *voltha.Adapters
375
376 var ok bool
377 if previousData, ok = args[0].(*voltha.Adapters); !ok {
378 log.Errorw("invalid-args", log.Fields{"args0": args[0]})
khenaidoo433f54a2019-02-05 14:02:57 -0500379 return nil
khenaidoo21d51152019-02-01 13:48:37 -0500380 }
381 if latestData, ok = args[1].(*voltha.Adapters); !ok {
382 log.Errorw("invalid-args", log.Fields{"args1": args[1]})
khenaidoo21d51152019-02-01 13:48:37 -0500383 return nil
384 }
385
khenaidoo433f54a2019-02-05 14:02:57 -0500386 if previousData != nil && latestData != nil {
387 if reflect.DeepEqual(previousData.Items, latestData.Items) {
388 log.Debug("update-not-required")
389 return nil
390 }
khenaidoo21d51152019-02-01 13:48:37 -0500391 }
khenaidoo433f54a2019-02-05 14:02:57 -0500392
393 if latestData != nil {
394 for _, adapter := range latestData.Items {
395 aMgr.updateAdapter(adapter)
396 }
397 }
398
khenaidoo21d51152019-02-01 13:48:37 -0500399 return nil
400}
401
402//deviceTypesUpdated is a callback invoked when a device type change has been noticed
403func (aMgr *AdapterManager) deviceTypesUpdated(args ...interface{}) interface{} {
404 log.Debugw("deviceTypesUpdated-callback", log.Fields{"argsLen": len(args)})
405
406 var previousData *voltha.DeviceTypes
407 var latestData *voltha.DeviceTypes
408
409 var ok bool
410 if previousData, ok = args[0].(*voltha.DeviceTypes); !ok {
411 log.Errorw("invalid-args", log.Fields{"args0": args[0]})
khenaidoo21d51152019-02-01 13:48:37 -0500412 return nil
413 }
414
khenaidoo433f54a2019-02-05 14:02:57 -0500415 if latestData, ok = args[1].(*voltha.DeviceTypes); !ok {
416 log.Errorw("invalid-args", log.Fields{"args1": args[1]})
417 return nil
418 }
419
420 if previousData != nil && latestData != nil {
421 if reflect.DeepEqual(previousData.Items, latestData.Items) {
422 log.Debug("update-not-required")
423 return nil
424 }
425 }
426
427 if latestData != nil {
428 for _, dType := range latestData.Items {
429 aMgr.updateDeviceType(dType)
430 }
khenaidoo21d51152019-02-01 13:48:37 -0500431 }
432 return nil
khenaidoo1ce37ad2019-03-24 22:07:24 -0400433}