blob: 570b44561db8bc8e87381833a0100bd9f0a58c35 [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 "errors"
khenaidoo19d7b632018-10-30 10:49:50 -040020 "github.com/gogo/protobuf/proto"
khenaidoob9203542018-09-17 22:56:37 -040021 "github.com/golang/protobuf/ptypes"
22 "github.com/golang/protobuf/ptypes/empty"
23 "github.com/opencord/voltha-go/common/log"
24 "github.com/opencord/voltha-go/db/model"
25 ca "github.com/opencord/voltha-go/protos/core_adapter"
26 "github.com/opencord/voltha-go/protos/voltha"
27 "google.golang.org/grpc/codes"
28 "google.golang.org/grpc/status"
29)
30
31type AdapterRequestHandlerProxy struct {
32 TestMode bool
khenaidoo91ecfd62018-11-04 17:13:42 -050033 coreInstanceId string
khenaidoob9203542018-09-17 22:56:37 -040034 deviceMgr *DeviceManager
35 lDeviceMgr *LogicalDeviceManager
36 localDataProxy *model.Proxy
37 clusterDataProxy *model.Proxy
38}
39
khenaidoo91ecfd62018-11-04 17:13:42 -050040func NewAdapterRequestHandlerProxy(coreInstanceId string, dMgr *DeviceManager, ldMgr *LogicalDeviceManager, cdProxy *model.Proxy, ldProxy *model.Proxy) *AdapterRequestHandlerProxy {
khenaidoob9203542018-09-17 22:56:37 -040041 var proxy AdapterRequestHandlerProxy
khenaidoo91ecfd62018-11-04 17:13:42 -050042 proxy.coreInstanceId = coreInstanceId
khenaidoob9203542018-09-17 22:56:37 -040043 proxy.deviceMgr = dMgr
44 proxy.lDeviceMgr = ldMgr
45 proxy.clusterDataProxy = cdProxy
46 proxy.localDataProxy = ldProxy
47 return &proxy
48}
49
50func (rhp *AdapterRequestHandlerProxy) Register(args []*ca.Argument) (*voltha.CoreInstance, error) {
khenaidoo91ecfd62018-11-04 17:13:42 -050051 if len(args) != 2 {
khenaidoob9203542018-09-17 22:56:37 -040052 log.Warn("invalid-number-of-args", log.Fields{"args": args})
53 err := errors.New("invalid-number-of-args")
54 return nil, err
55 }
56 adapter := &voltha.Adapter{}
khenaidoo91ecfd62018-11-04 17:13:42 -050057 deviceTypes := &voltha.DeviceTypes{}
58 for _, arg := range args {
59 switch arg.Key {
60 case "adapter":
61 if err := ptypes.UnmarshalAny(arg.Value, adapter); err != nil {
62 log.Warnw("cannot-unmarshal-adapter", log.Fields{"error": err})
63 return nil, err
64 }
65 case "deviceTypes":
66 if err := ptypes.UnmarshalAny(arg.Value, deviceTypes); err != nil {
67 log.Warnw("cannot-unmarshal-device-types", log.Fields{"error": err})
68 return nil, err
69 }
70 }
khenaidoob9203542018-09-17 22:56:37 -040071 }
khenaidoo91ecfd62018-11-04 17:13:42 -050072 log.Debugw("Register", log.Fields{"Adapter": *adapter, "DeviceTypes": deviceTypes, "coreId": rhp.coreInstanceId})
khenaidoob9203542018-09-17 22:56:37 -040073 // TODO process the request and store the data in the KV store
74
75 if rhp.TestMode { // Execute only for test cases
76 return &voltha.CoreInstance{InstanceId: "CoreInstance"}, nil
77 }
khenaidoo91ecfd62018-11-04 17:13:42 -050078 return &voltha.CoreInstance{InstanceId: rhp.coreInstanceId}, nil
khenaidoob9203542018-09-17 22:56:37 -040079}
80
81func (rhp *AdapterRequestHandlerProxy) GetDevice(args []*ca.Argument) (*voltha.Device, error) {
82 if len(args) != 1 {
83 log.Warn("invalid-number-of-args", log.Fields{"args": args})
84 err := errors.New("invalid-number-of-args")
85 return nil, err
86 }
87 pID := &voltha.ID{}
88 if err := ptypes.UnmarshalAny(args[0].Value, pID); err != nil {
89 log.Warnw("cannot-unmarshal-ID", log.Fields{"error": err})
90 return nil, err
91 }
92 log.Debugw("GetDevice", log.Fields{"deviceId": pID.Id})
93
94 if rhp.TestMode { // Execute only for test cases
95 return &voltha.Device{Id: pID.Id}, nil
96 }
97
98 // Get the device via the device manager
khenaidoo19d7b632018-10-30 10:49:50 -040099 if device, err := rhp.deviceMgr.GetDevice(pID.Id); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400100 return nil, status.Errorf(codes.NotFound, "%s", err.Error())
101 } else {
102 return device, nil
103 }
104}
105
khenaidoo92e62c52018-10-03 14:02:54 -0400106// updatePartialDeviceData updates a subset of a device that an Adapter can update.
107// TODO: May need a specific proto to handle only a subset of a device that can be changed by an adapter
108func (rhp *AdapterRequestHandlerProxy) mergeDeviceInfoFromAdapter(device *voltha.Device) (*voltha.Device, error) {
109 // First retrieve the most up to date device info
110 var currentDevice *voltha.Device
111 var err error
khenaidoo19d7b632018-10-30 10:49:50 -0400112 if currentDevice, err = rhp.deviceMgr.GetDevice(device.Id); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400113 return nil, err
114 }
khenaidoo19d7b632018-10-30 10:49:50 -0400115 cloned := proto.Clone(currentDevice).(*voltha.Device)
khenaidoo92e62c52018-10-03 14:02:54 -0400116 cloned.Root = device.Root
117 cloned.Vendor = device.Vendor
118 cloned.Model = device.Model
119 cloned.SerialNumber = device.SerialNumber
120 cloned.MacAddress = device.MacAddress
khenaidoo19d7b632018-10-30 10:49:50 -0400121 cloned.Vlan = device.Vlan
122 return cloned, nil
khenaidoo92e62c52018-10-03 14:02:54 -0400123}
124
khenaidoob9203542018-09-17 22:56:37 -0400125func (rhp *AdapterRequestHandlerProxy) DeviceUpdate(args []*ca.Argument) (*empty.Empty, error) {
126 if len(args) != 1 {
127 log.Warn("invalid-number-of-args", log.Fields{"args": args})
128 err := errors.New("invalid-number-of-args")
129 return nil, err
130 }
131 device := &voltha.Device{}
132 if err := ptypes.UnmarshalAny(args[0].Value, device); err != nil {
133 log.Warnw("cannot-unmarshal-device", log.Fields{"error": err})
134 return nil, err
135 }
khenaidoo92e62c52018-10-03 14:02:54 -0400136 log.Debugw("DeviceUpdate", log.Fields{"deviceId": device.Id})
khenaidoob9203542018-09-17 22:56:37 -0400137
138 if rhp.TestMode { // Execute only for test cases
139 return new(empty.Empty), nil
140 }
khenaidoo92e62c52018-10-03 14:02:54 -0400141
142 //Merge the adapter device info (only the ones an adapter can change) with the latest device data
143 if updatedDevice, err := rhp.mergeDeviceInfoFromAdapter(device); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400144 return nil, status.Errorf(codes.Internal, "%s", err.Error())
khenaidoo92e62c52018-10-03 14:02:54 -0400145 } else {
146 // An adapter request needs an Ack without having to wait for the update to be
147 // completed. We therefore run the update in its own routine.
148 go rhp.deviceMgr.updateDevice(updatedDevice)
khenaidoob9203542018-09-17 22:56:37 -0400149 }
khenaidoo92e62c52018-10-03 14:02:54 -0400150
khenaidoob9203542018-09-17 22:56:37 -0400151 return new(empty.Empty), nil
152}
153
154func (rhp *AdapterRequestHandlerProxy) GetChildDevice(args []*ca.Argument) (*voltha.Device, error) {
155 if len(args) < 1 {
156 log.Warn("invalid-number-of-args", log.Fields{"args": args})
157 err := errors.New("invalid-number-of-args")
158 return nil, err
159 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400160 pID := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400161 if err := ptypes.UnmarshalAny(args[0].Value, pID); err != nil {
162 log.Warnw("cannot-unmarshal-ID", log.Fields{"error": err})
163 return nil, err
164 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400165 log.Debugw("GetChildDevice", log.Fields{"deviceId": pID.Id})
khenaidoob9203542018-09-17 22:56:37 -0400166
167 if rhp.TestMode { // Execute only for test cases
khenaidoo2c6f1672018-09-20 23:14:41 -0400168 return &voltha.Device{Id: pID.Id}, nil
khenaidoob9203542018-09-17 22:56:37 -0400169 }
170 return nil, nil
171}
172
173func (rhp *AdapterRequestHandlerProxy) GetPorts(args []*ca.Argument) (*voltha.Ports, error) {
174 if len(args) != 2 {
175 log.Warn("invalid-number-of-args", log.Fields{"args": args})
176 err := errors.New("invalid-number-of-args")
177 return nil, err
178 }
khenaidoo92e62c52018-10-03 14:02:54 -0400179 deviceId := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400180 pt := &ca.IntType{}
khenaidoo92e62c52018-10-03 14:02:54 -0400181 for _, arg := range args {
182 switch arg.Key {
183 case "device_id":
184 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
185 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
186 return nil, err
187 }
188 case "port_type":
189 if err := ptypes.UnmarshalAny(arg.Value, pt); err != nil {
190 log.Warnw("cannot-unmarshal-porttype", log.Fields{"error": err})
191 return nil, err
192 }
193 }
khenaidoob9203542018-09-17 22:56:37 -0400194 }
khenaidoo92e62c52018-10-03 14:02:54 -0400195 log.Debugw("GetPorts", log.Fields{"deviceID": deviceId.Id, "portype": pt.Val})
khenaidoob9203542018-09-17 22:56:37 -0400196 if rhp.TestMode { // Execute only for test cases
197 aPort := &voltha.Port{Label: "test_port"}
198 allPorts := &voltha.Ports{}
199 allPorts.Items = append(allPorts.Items, aPort)
200 return allPorts, nil
201 }
khenaidoo92e62c52018-10-03 14:02:54 -0400202 return rhp.deviceMgr.getPorts(nil, deviceId.Id, voltha.Port_PortType(pt.Val))
khenaidoob9203542018-09-17 22:56:37 -0400203}
204
205func (rhp *AdapterRequestHandlerProxy) GetChildDevices(args []*ca.Argument) (*voltha.Device, error) {
206 if len(args) != 1 {
207 log.Warn("invalid-number-of-args", log.Fields{"args": args})
208 err := errors.New("invalid-number-of-args")
209 return nil, err
210 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400211 pID := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400212 if err := ptypes.UnmarshalAny(args[0].Value, pID); err != nil {
213 log.Warnw("cannot-unmarshal-ID", log.Fields{"error": err})
214 return nil, err
215 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400216 log.Debugw("GetChildDevice", log.Fields{"deviceId": pID.Id})
khenaidoob9203542018-09-17 22:56:37 -0400217
218 if rhp.TestMode { // Execute only for test cases
khenaidoo2c6f1672018-09-20 23:14:41 -0400219 return &voltha.Device{Id: pID.Id}, nil
khenaidoob9203542018-09-17 22:56:37 -0400220 }
221 //TODO: Complete
222 return nil, nil
223}
224
225// ChildDeviceDetected is invoked when a child device is detected. The following
226// parameters are expected:
227// {parent_device_id, parent_port_no, child_device_type, proxy_address, admin_state, **kw)
228func (rhp *AdapterRequestHandlerProxy) ChildDeviceDetected(args []*ca.Argument) (*empty.Empty, error) {
229 if len(args) < 4 {
230 log.Warn("invalid-number-of-args", log.Fields{"args": args})
231 err := errors.New("invalid-number-of-args")
232 return nil, err
233 }
234
235 pID := &voltha.ID{}
236 portNo := &ca.IntType{}
237 dt := &ca.StrType{}
238 chnlId := &ca.IntType{}
239 for _, arg := range args {
240 switch arg.Key {
241 case "parent_device_id":
242 if err := ptypes.UnmarshalAny(arg.Value, pID); err != nil {
243 log.Warnw("cannot-unmarshal-parent-device-id", log.Fields{"error": err})
244 return nil, err
245 }
246 case "parent_port_no":
247 if err := ptypes.UnmarshalAny(arg.Value, portNo); err != nil {
248 log.Warnw("cannot-unmarshal-parent-port", log.Fields{"error": err})
249 return nil, err
250 }
251 case "child_device_type":
252 if err := ptypes.UnmarshalAny(arg.Value, dt); err != nil {
253 log.Warnw("cannot-unmarshal-child-device-type", log.Fields{"error": err})
254 return nil, err
255 }
256 case "channel_id":
257 if err := ptypes.UnmarshalAny(arg.Value, chnlId); err != nil {
258 log.Warnw("cannot-unmarshal-channel-id", log.Fields{"error": err})
259 return nil, err
260 }
261 }
262 }
khenaidoob9203542018-09-17 22:56:37 -0400263 log.Debugw("ChildDeviceDetected", log.Fields{"parentDeviceId": pID.Id, "parentPortNo": portNo.Val,
264 "deviceType": dt.Val, "channelId": chnlId.Val})
265
266 if rhp.TestMode { // Execute only for test cases
267 return nil, nil
268 }
khenaidoob9203542018-09-17 22:56:37 -0400269 // Run child detection in it's own go routine as it can be a lengthy process
270 go rhp.deviceMgr.childDeviceDetected(pID.Id, portNo.Val, dt.Val, chnlId.Val)
271
272 return new(empty.Empty), nil
273}
274
275func (rhp *AdapterRequestHandlerProxy) DeviceStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
276 if len(args) < 2 {
277 log.Warn("invalid-number-of-args", log.Fields{"args": args})
278 err := errors.New("invalid-number-of-args")
279 return nil, err
280 }
281 deviceId := &voltha.ID{}
282 operStatus := &ca.IntType{}
283 connStatus := &ca.IntType{}
284 for _, arg := range args {
285 switch arg.Key {
286 case "device_id":
287 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
288 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
289 return nil, err
290 }
291 case "oper_status":
292 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
293 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
294 return nil, err
295 }
khenaidoob9203542018-09-17 22:56:37 -0400296 case "connect_status":
297 if err := ptypes.UnmarshalAny(arg.Value, connStatus); err != nil {
298 log.Warnw("cannot-unmarshal-connStatus", log.Fields{"error": err})
299 return nil, err
300 }
khenaidoob9203542018-09-17 22:56:37 -0400301 }
302 }
khenaidoob9203542018-09-17 22:56:37 -0400303 log.Debugw("DeviceStateUpdate", log.Fields{"deviceId": deviceId.Id, "oper-status": operStatus, "conn-status": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400304 if rhp.TestMode { // Execute only for test cases
305 return nil, nil
306 }
khenaidoo92e62c52018-10-03 14:02:54 -0400307 // When the enum is not set (i.e. -1), Go still convert to the Enum type with the value being -1
308 go rhp.deviceMgr.updateDeviceStatus(deviceId.Id, voltha.OperStatus_OperStatus(operStatus.Val), voltha.ConnectStatus_ConnectStatus(connStatus.Val))
309 return new(empty.Empty), nil
310}
311
khenaidoo4d4802d2018-10-04 21:59:49 -0400312func (rhp *AdapterRequestHandlerProxy) ChildrenStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
313 if len(args) < 2 {
314 log.Warn("invalid-number-of-args", log.Fields{"args": args})
315 err := errors.New("invalid-number-of-args")
316 return nil, err
317 }
318 deviceId := &voltha.ID{}
319 operStatus := &ca.IntType{}
320 connStatus := &ca.IntType{}
321 for _, arg := range args {
322 switch arg.Key {
323 case "device_id":
324 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
325 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
326 return nil, err
327 }
328 case "oper_status":
329 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
330 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
331 return nil, err
332 }
333 case "connect_status":
334 if err := ptypes.UnmarshalAny(arg.Value, connStatus); err != nil {
335 log.Warnw("cannot-unmarshal-connStatus", log.Fields{"error": err})
336 return nil, err
337 }
338 }
339 }
340 log.Debugw("ChildrenStateUpdate", log.Fields{"deviceId": deviceId.Id, "oper-status": operStatus, "conn-status": connStatus})
341 if rhp.TestMode { // Execute only for test cases
342 return nil, nil
343 }
344
345 // When the enum is not set (i.e. -1), Go still convert to the Enum type with the value being -1
346 go rhp.deviceMgr.updateChildrenStatus(deviceId.Id, voltha.OperStatus_OperStatus(operStatus.Val), voltha.ConnectStatus_ConnectStatus(connStatus.Val))
347 return new(empty.Empty), nil
348}
349
khenaidoo92e62c52018-10-03 14:02:54 -0400350func (rhp *AdapterRequestHandlerProxy) PortStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
351 if len(args) < 2 {
352 log.Warn("invalid-number-of-args", log.Fields{"args": args})
353 err := errors.New("invalid-number-of-args")
354 return nil, err
khenaidoob9203542018-09-17 22:56:37 -0400355 }
khenaidoo92e62c52018-10-03 14:02:54 -0400356 deviceId := &voltha.ID{}
357 portType := &ca.IntType{}
358 portNo := &ca.IntType{}
359 operStatus := &ca.IntType{}
360 for _, arg := range args {
361 switch arg.Key {
362 case "device_id":
363 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
364 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
365 return nil, err
366 }
367 case "oper_status":
368 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
369 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
370 return nil, err
371 }
372 case "port_type":
373 if err := ptypes.UnmarshalAny(arg.Value, portType); err != nil {
374 log.Warnw("cannot-unmarshal-porttype", log.Fields{"error": err})
375 return nil, err
376 }
377 case "port_no":
378 if err := ptypes.UnmarshalAny(arg.Value, portNo); err != nil {
379 log.Warnw("cannot-unmarshal-portno", log.Fields{"error": err})
380 return nil, err
381 }
382
383 }
384 }
385 log.Debugw("PortStateUpdate", log.Fields{"deviceId": deviceId.Id, "operStatus": operStatus, "portType": portType, "portNo": portNo})
386 if rhp.TestMode { // Execute only for test cases
387 return nil, nil
388 }
389 go rhp.deviceMgr.updatePortState(deviceId.Id, voltha.Port_PortType(portType.Val), uint32(portNo.Val), voltha.OperStatus_OperStatus(operStatus.Val))
khenaidoob9203542018-09-17 22:56:37 -0400390 return new(empty.Empty), nil
391}
392
393func (rhp *AdapterRequestHandlerProxy) PortCreated(args []*ca.Argument) (*empty.Empty, error) {
394 if len(args) != 2 {
395 log.Warn("invalid-number-of-args", log.Fields{"args": args})
396 err := errors.New("invalid-number-of-args")
397 return nil, err
398 }
399 deviceId := &voltha.ID{}
400 port := &voltha.Port{}
401 for _, arg := range args {
402 switch arg.Key {
403 case "device_id":
404 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
405 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
406 return nil, err
407 }
408 case "port":
409 if err := ptypes.UnmarshalAny(arg.Value, port); err != nil {
410 log.Warnw("cannot-unmarshal-port", log.Fields{"error": err})
411 return nil, err
412 }
413 }
414 }
khenaidoob9203542018-09-17 22:56:37 -0400415 log.Debugw("PortCreated", log.Fields{"deviceId": deviceId.Id, "port": port})
416
417 if rhp.TestMode { // Execute only for test cases
418 return nil, nil
419 }
khenaidoo92e62c52018-10-03 14:02:54 -0400420 // Run port creation in its own go routine
421 go rhp.deviceMgr.addPort(deviceId.Id, port)
422
khenaidoob9203542018-09-17 22:56:37 -0400423 return new(empty.Empty), nil
424}
425
426func (rhp *AdapterRequestHandlerProxy) DevicePMConfigUpdate(args []*ca.Argument) (*empty.Empty, error) {
427 if len(args) != 2 {
428 log.Warn("invalid-number-of-args", log.Fields{"args": args})
429 err := errors.New("invalid-number-of-args")
430 return nil, err
431 }
432 pmConfigs := &voltha.PmConfigs{}
433 init := &ca.BoolType{}
434 for _, arg := range args {
435 switch arg.Key {
436 case "device_pm_config":
437 if err := ptypes.UnmarshalAny(arg.Value, pmConfigs); err != nil {
438 log.Warnw("cannot-unmarshal-pm-config", log.Fields{"error": err})
439 return nil, err
440 }
441 case "init":
442 if err := ptypes.UnmarshalAny(arg.Value, init); err != nil {
443 log.Warnw("cannot-unmarshal-boolean", log.Fields{"error": err})
444 return nil, err
445 }
446 }
447 }
khenaidoob9203542018-09-17 22:56:37 -0400448 log.Debugw("DevicePMConfigUpdate", log.Fields{"deviceId": pmConfigs.Id, "configs": pmConfigs,
449 "init": init})
450
451 if rhp.TestMode { // Execute only for test cases
452 return nil, nil
453 }
454
khenaidoo92e62c52018-10-03 14:02:54 -0400455 // Run PM config update in its own go routine
456 go rhp.deviceMgr.updatePmConfigs(pmConfigs.Id, pmConfigs)
457
khenaidoob9203542018-09-17 22:56:37 -0400458 return new(empty.Empty), nil
khenaidoob9203542018-09-17 22:56:37 -0400459}