blob: 0c0609efaaefb78fa47ac835a14235ca968ecead [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"
20 "github.com/golang/protobuf/ptypes"
21 "github.com/golang/protobuf/ptypes/empty"
22 "github.com/opencord/voltha-go/common/log"
23 "github.com/opencord/voltha-go/db/model"
24 ca "github.com/opencord/voltha-go/protos/core_adapter"
25 "github.com/opencord/voltha-go/protos/voltha"
26 "google.golang.org/grpc/codes"
27 "google.golang.org/grpc/status"
khenaidoo92e62c52018-10-03 14:02:54 -040028 "reflect"
khenaidoob9203542018-09-17 22:56:37 -040029)
30
31type AdapterRequestHandlerProxy struct {
32 TestMode bool
33 deviceMgr *DeviceManager
34 lDeviceMgr *LogicalDeviceManager
35 localDataProxy *model.Proxy
36 clusterDataProxy *model.Proxy
37}
38
39func NewAdapterRequestHandlerProxy(dMgr *DeviceManager, ldMgr *LogicalDeviceManager, cdProxy *model.Proxy, ldProxy *model.Proxy) *AdapterRequestHandlerProxy {
40 var proxy AdapterRequestHandlerProxy
41 proxy.deviceMgr = dMgr
42 proxy.lDeviceMgr = ldMgr
43 proxy.clusterDataProxy = cdProxy
44 proxy.localDataProxy = ldProxy
45 return &proxy
46}
47
48func (rhp *AdapterRequestHandlerProxy) Register(args []*ca.Argument) (*voltha.CoreInstance, error) {
49 if len(args) != 1 {
50 log.Warn("invalid-number-of-args", log.Fields{"args": args})
51 err := errors.New("invalid-number-of-args")
52 return nil, err
53 }
54 adapter := &voltha.Adapter{}
55 if err := ptypes.UnmarshalAny(args[0].Value, adapter); err != nil {
56 log.Warnw("cannot-unmarshal-adapter", log.Fields{"error": err})
57 return nil, err
58 }
59 log.Debugw("Register", log.Fields{"Adapter": *adapter})
60 // TODO process the request and store the data in the KV store
61
62 if rhp.TestMode { // Execute only for test cases
63 return &voltha.CoreInstance{InstanceId: "CoreInstance"}, nil
64 }
65 return &voltha.CoreInstance{InstanceId: "CoreInstance"}, nil
66}
67
68func (rhp *AdapterRequestHandlerProxy) GetDevice(args []*ca.Argument) (*voltha.Device, error) {
69 if len(args) != 1 {
70 log.Warn("invalid-number-of-args", log.Fields{"args": args})
71 err := errors.New("invalid-number-of-args")
72 return nil, err
73 }
74 pID := &voltha.ID{}
75 if err := ptypes.UnmarshalAny(args[0].Value, pID); err != nil {
76 log.Warnw("cannot-unmarshal-ID", log.Fields{"error": err})
77 return nil, err
78 }
79 log.Debugw("GetDevice", log.Fields{"deviceId": pID.Id})
80
81 if rhp.TestMode { // Execute only for test cases
82 return &voltha.Device{Id: pID.Id}, nil
83 }
84
85 // Get the device via the device manager
86 if device, err := rhp.deviceMgr.getDevice(pID.Id); err != nil {
87 return nil, status.Errorf(codes.NotFound, "%s", err.Error())
88 } else {
89 return device, nil
90 }
91}
92
khenaidoo92e62c52018-10-03 14:02:54 -040093// updatePartialDeviceData updates a subset of a device that an Adapter can update.
94// TODO: May need a specific proto to handle only a subset of a device that can be changed by an adapter
95func (rhp *AdapterRequestHandlerProxy) mergeDeviceInfoFromAdapter(device *voltha.Device) (*voltha.Device, error) {
96 // First retrieve the most up to date device info
97 var currentDevice *voltha.Device
98 var err error
99 if currentDevice, err = rhp.deviceMgr.getDevice(device.Id); err != nil {
100 return nil, err
101 }
102 cloned := reflect.ValueOf(currentDevice).Elem().Interface().(voltha.Device)
103 cloned.Root = device.Root
104 cloned.Vendor = device.Vendor
105 cloned.Model = device.Model
106 cloned.SerialNumber = device.SerialNumber
107 cloned.MacAddress = device.MacAddress
108 return &cloned, nil
109}
110
khenaidoob9203542018-09-17 22:56:37 -0400111func (rhp *AdapterRequestHandlerProxy) DeviceUpdate(args []*ca.Argument) (*empty.Empty, error) {
112 if len(args) != 1 {
113 log.Warn("invalid-number-of-args", log.Fields{"args": args})
114 err := errors.New("invalid-number-of-args")
115 return nil, err
116 }
117 device := &voltha.Device{}
118 if err := ptypes.UnmarshalAny(args[0].Value, device); err != nil {
119 log.Warnw("cannot-unmarshal-device", log.Fields{"error": err})
120 return nil, err
121 }
khenaidoo92e62c52018-10-03 14:02:54 -0400122 log.Debugw("DeviceUpdate", log.Fields{"deviceId": device.Id})
khenaidoob9203542018-09-17 22:56:37 -0400123
124 if rhp.TestMode { // Execute only for test cases
125 return new(empty.Empty), nil
126 }
khenaidoo92e62c52018-10-03 14:02:54 -0400127
128 //Merge the adapter device info (only the ones an adapter can change) with the latest device data
129 if updatedDevice, err := rhp.mergeDeviceInfoFromAdapter(device); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400130 return nil, status.Errorf(codes.Internal, "%s", err.Error())
khenaidoo92e62c52018-10-03 14:02:54 -0400131 } else {
132 // An adapter request needs an Ack without having to wait for the update to be
133 // completed. We therefore run the update in its own routine.
134 go rhp.deviceMgr.updateDevice(updatedDevice)
khenaidoob9203542018-09-17 22:56:37 -0400135 }
khenaidoo92e62c52018-10-03 14:02:54 -0400136
khenaidoob9203542018-09-17 22:56:37 -0400137 return new(empty.Empty), nil
138}
139
140func (rhp *AdapterRequestHandlerProxy) GetChildDevice(args []*ca.Argument) (*voltha.Device, error) {
141 if len(args) < 1 {
142 log.Warn("invalid-number-of-args", log.Fields{"args": args})
143 err := errors.New("invalid-number-of-args")
144 return nil, err
145 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400146 pID := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400147 if err := ptypes.UnmarshalAny(args[0].Value, pID); err != nil {
148 log.Warnw("cannot-unmarshal-ID", log.Fields{"error": err})
149 return nil, err
150 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400151 log.Debugw("GetChildDevice", log.Fields{"deviceId": pID.Id})
khenaidoob9203542018-09-17 22:56:37 -0400152
153 if rhp.TestMode { // Execute only for test cases
khenaidoo2c6f1672018-09-20 23:14:41 -0400154 return &voltha.Device{Id: pID.Id}, nil
khenaidoob9203542018-09-17 22:56:37 -0400155 }
156 return nil, nil
157}
158
159func (rhp *AdapterRequestHandlerProxy) GetPorts(args []*ca.Argument) (*voltha.Ports, error) {
160 if len(args) != 2 {
161 log.Warn("invalid-number-of-args", log.Fields{"args": args})
162 err := errors.New("invalid-number-of-args")
163 return nil, err
164 }
khenaidoo92e62c52018-10-03 14:02:54 -0400165 deviceId := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400166 pt := &ca.IntType{}
khenaidoo92e62c52018-10-03 14:02:54 -0400167 for _, arg := range args {
168 switch arg.Key {
169 case "device_id":
170 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
171 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
172 return nil, err
173 }
174 case "port_type":
175 if err := ptypes.UnmarshalAny(arg.Value, pt); err != nil {
176 log.Warnw("cannot-unmarshal-porttype", log.Fields{"error": err})
177 return nil, err
178 }
179 }
khenaidoob9203542018-09-17 22:56:37 -0400180 }
khenaidoo92e62c52018-10-03 14:02:54 -0400181 log.Debugw("GetPorts", log.Fields{"deviceID": deviceId.Id, "portype": pt.Val})
khenaidoob9203542018-09-17 22:56:37 -0400182 if rhp.TestMode { // Execute only for test cases
183 aPort := &voltha.Port{Label: "test_port"}
184 allPorts := &voltha.Ports{}
185 allPorts.Items = append(allPorts.Items, aPort)
186 return allPorts, nil
187 }
khenaidoo92e62c52018-10-03 14:02:54 -0400188 return rhp.deviceMgr.getPorts(nil, deviceId.Id, voltha.Port_PortType(pt.Val))
khenaidoob9203542018-09-17 22:56:37 -0400189}
190
191func (rhp *AdapterRequestHandlerProxy) GetChildDevices(args []*ca.Argument) (*voltha.Device, error) {
192 if len(args) != 1 {
193 log.Warn("invalid-number-of-args", log.Fields{"args": args})
194 err := errors.New("invalid-number-of-args")
195 return nil, err
196 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400197 pID := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400198 if err := ptypes.UnmarshalAny(args[0].Value, pID); err != nil {
199 log.Warnw("cannot-unmarshal-ID", log.Fields{"error": err})
200 return nil, err
201 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400202 log.Debugw("GetChildDevice", log.Fields{"deviceId": pID.Id})
khenaidoob9203542018-09-17 22:56:37 -0400203
204 if rhp.TestMode { // Execute only for test cases
khenaidoo2c6f1672018-09-20 23:14:41 -0400205 return &voltha.Device{Id: pID.Id}, nil
khenaidoob9203542018-09-17 22:56:37 -0400206 }
207 //TODO: Complete
208 return nil, nil
209}
210
211// ChildDeviceDetected is invoked when a child device is detected. The following
212// parameters are expected:
213// {parent_device_id, parent_port_no, child_device_type, proxy_address, admin_state, **kw)
214func (rhp *AdapterRequestHandlerProxy) ChildDeviceDetected(args []*ca.Argument) (*empty.Empty, error) {
215 if len(args) < 4 {
216 log.Warn("invalid-number-of-args", log.Fields{"args": args})
217 err := errors.New("invalid-number-of-args")
218 return nil, err
219 }
220
221 pID := &voltha.ID{}
222 portNo := &ca.IntType{}
223 dt := &ca.StrType{}
224 chnlId := &ca.IntType{}
225 for _, arg := range args {
226 switch arg.Key {
227 case "parent_device_id":
228 if err := ptypes.UnmarshalAny(arg.Value, pID); err != nil {
229 log.Warnw("cannot-unmarshal-parent-device-id", log.Fields{"error": err})
230 return nil, err
231 }
232 case "parent_port_no":
233 if err := ptypes.UnmarshalAny(arg.Value, portNo); err != nil {
234 log.Warnw("cannot-unmarshal-parent-port", log.Fields{"error": err})
235 return nil, err
236 }
237 case "child_device_type":
238 if err := ptypes.UnmarshalAny(arg.Value, dt); err != nil {
239 log.Warnw("cannot-unmarshal-child-device-type", log.Fields{"error": err})
240 return nil, err
241 }
242 case "channel_id":
243 if err := ptypes.UnmarshalAny(arg.Value, chnlId); err != nil {
244 log.Warnw("cannot-unmarshal-channel-id", log.Fields{"error": err})
245 return nil, err
246 }
247 }
248 }
khenaidoob9203542018-09-17 22:56:37 -0400249 log.Debugw("ChildDeviceDetected", log.Fields{"parentDeviceId": pID.Id, "parentPortNo": portNo.Val,
250 "deviceType": dt.Val, "channelId": chnlId.Val})
251
252 if rhp.TestMode { // Execute only for test cases
253 return nil, nil
254 }
khenaidoob9203542018-09-17 22:56:37 -0400255 // Run child detection in it's own go routine as it can be a lengthy process
256 go rhp.deviceMgr.childDeviceDetected(pID.Id, portNo.Val, dt.Val, chnlId.Val)
257
258 return new(empty.Empty), nil
259}
260
261func (rhp *AdapterRequestHandlerProxy) DeviceStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
262 if len(args) < 2 {
263 log.Warn("invalid-number-of-args", log.Fields{"args": args})
264 err := errors.New("invalid-number-of-args")
265 return nil, err
266 }
267 deviceId := &voltha.ID{}
268 operStatus := &ca.IntType{}
269 connStatus := &ca.IntType{}
270 for _, arg := range args {
271 switch arg.Key {
272 case "device_id":
273 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
274 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
275 return nil, err
276 }
277 case "oper_status":
278 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
279 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
280 return nil, err
281 }
khenaidoob9203542018-09-17 22:56:37 -0400282 case "connect_status":
283 if err := ptypes.UnmarshalAny(arg.Value, connStatus); err != nil {
284 log.Warnw("cannot-unmarshal-connStatus", log.Fields{"error": err})
285 return nil, err
286 }
khenaidoob9203542018-09-17 22:56:37 -0400287 }
288 }
khenaidoob9203542018-09-17 22:56:37 -0400289 log.Debugw("DeviceStateUpdate", log.Fields{"deviceId": deviceId.Id, "oper-status": operStatus, "conn-status": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400290 if rhp.TestMode { // Execute only for test cases
291 return nil, nil
292 }
khenaidoo92e62c52018-10-03 14:02:54 -0400293 // When the enum is not set (i.e. -1), Go still convert to the Enum type with the value being -1
294 go rhp.deviceMgr.updateDeviceStatus(deviceId.Id, voltha.OperStatus_OperStatus(operStatus.Val), voltha.ConnectStatus_ConnectStatus(connStatus.Val))
295 return new(empty.Empty), nil
296}
297
khenaidoo4d4802d2018-10-04 21:59:49 -0400298func (rhp *AdapterRequestHandlerProxy) ChildrenStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
299 if len(args) < 2 {
300 log.Warn("invalid-number-of-args", log.Fields{"args": args})
301 err := errors.New("invalid-number-of-args")
302 return nil, err
303 }
304 deviceId := &voltha.ID{}
305 operStatus := &ca.IntType{}
306 connStatus := &ca.IntType{}
307 for _, arg := range args {
308 switch arg.Key {
309 case "device_id":
310 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
311 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
312 return nil, err
313 }
314 case "oper_status":
315 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
316 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
317 return nil, err
318 }
319 case "connect_status":
320 if err := ptypes.UnmarshalAny(arg.Value, connStatus); err != nil {
321 log.Warnw("cannot-unmarshal-connStatus", log.Fields{"error": err})
322 return nil, err
323 }
324 }
325 }
326 log.Debugw("ChildrenStateUpdate", log.Fields{"deviceId": deviceId.Id, "oper-status": operStatus, "conn-status": connStatus})
327 if rhp.TestMode { // Execute only for test cases
328 return nil, nil
329 }
330
331 // When the enum is not set (i.e. -1), Go still convert to the Enum type with the value being -1
332 go rhp.deviceMgr.updateChildrenStatus(deviceId.Id, voltha.OperStatus_OperStatus(operStatus.Val), voltha.ConnectStatus_ConnectStatus(connStatus.Val))
333 return new(empty.Empty), nil
334}
335
khenaidoo92e62c52018-10-03 14:02:54 -0400336func (rhp *AdapterRequestHandlerProxy) PortStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
337 if len(args) < 2 {
338 log.Warn("invalid-number-of-args", log.Fields{"args": args})
339 err := errors.New("invalid-number-of-args")
340 return nil, err
khenaidoob9203542018-09-17 22:56:37 -0400341 }
khenaidoo92e62c52018-10-03 14:02:54 -0400342 deviceId := &voltha.ID{}
343 portType := &ca.IntType{}
344 portNo := &ca.IntType{}
345 operStatus := &ca.IntType{}
346 for _, arg := range args {
347 switch arg.Key {
348 case "device_id":
349 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
350 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
351 return nil, err
352 }
353 case "oper_status":
354 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
355 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
356 return nil, err
357 }
358 case "port_type":
359 if err := ptypes.UnmarshalAny(arg.Value, portType); err != nil {
360 log.Warnw("cannot-unmarshal-porttype", log.Fields{"error": err})
361 return nil, err
362 }
363 case "port_no":
364 if err := ptypes.UnmarshalAny(arg.Value, portNo); err != nil {
365 log.Warnw("cannot-unmarshal-portno", log.Fields{"error": err})
366 return nil, err
367 }
368
369 }
370 }
371 log.Debugw("PortStateUpdate", log.Fields{"deviceId": deviceId.Id, "operStatus": operStatus, "portType": portType, "portNo": portNo})
372 if rhp.TestMode { // Execute only for test cases
373 return nil, nil
374 }
375 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 -0400376 return new(empty.Empty), nil
377}
378
379func (rhp *AdapterRequestHandlerProxy) PortCreated(args []*ca.Argument) (*empty.Empty, error) {
380 if len(args) != 2 {
381 log.Warn("invalid-number-of-args", log.Fields{"args": args})
382 err := errors.New("invalid-number-of-args")
383 return nil, err
384 }
385 deviceId := &voltha.ID{}
386 port := &voltha.Port{}
387 for _, arg := range args {
388 switch arg.Key {
389 case "device_id":
390 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
391 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
392 return nil, err
393 }
394 case "port":
395 if err := ptypes.UnmarshalAny(arg.Value, port); err != nil {
396 log.Warnw("cannot-unmarshal-port", log.Fields{"error": err})
397 return nil, err
398 }
399 }
400 }
khenaidoob9203542018-09-17 22:56:37 -0400401 log.Debugw("PortCreated", log.Fields{"deviceId": deviceId.Id, "port": port})
402
403 if rhp.TestMode { // Execute only for test cases
404 return nil, nil
405 }
khenaidoo92e62c52018-10-03 14:02:54 -0400406 // Run port creation in its own go routine
407 go rhp.deviceMgr.addPort(deviceId.Id, port)
408
khenaidoob9203542018-09-17 22:56:37 -0400409 return new(empty.Empty), nil
410}
411
412func (rhp *AdapterRequestHandlerProxy) DevicePMConfigUpdate(args []*ca.Argument) (*empty.Empty, error) {
413 if len(args) != 2 {
414 log.Warn("invalid-number-of-args", log.Fields{"args": args})
415 err := errors.New("invalid-number-of-args")
416 return nil, err
417 }
418 pmConfigs := &voltha.PmConfigs{}
419 init := &ca.BoolType{}
420 for _, arg := range args {
421 switch arg.Key {
422 case "device_pm_config":
423 if err := ptypes.UnmarshalAny(arg.Value, pmConfigs); err != nil {
424 log.Warnw("cannot-unmarshal-pm-config", log.Fields{"error": err})
425 return nil, err
426 }
427 case "init":
428 if err := ptypes.UnmarshalAny(arg.Value, init); err != nil {
429 log.Warnw("cannot-unmarshal-boolean", log.Fields{"error": err})
430 return nil, err
431 }
432 }
433 }
khenaidoob9203542018-09-17 22:56:37 -0400434 log.Debugw("DevicePMConfigUpdate", log.Fields{"deviceId": pmConfigs.Id, "configs": pmConfigs,
435 "init": init})
436
437 if rhp.TestMode { // Execute only for test cases
438 return nil, nil
439 }
440
khenaidoo92e62c52018-10-03 14:02:54 -0400441 // Run PM config update in its own go routine
442 go rhp.deviceMgr.updatePmConfigs(pmConfigs.Id, pmConfigs)
443
khenaidoob9203542018-09-17 22:56:37 -0400444 return new(empty.Empty), nil
khenaidoob9203542018-09-17 22:56:37 -0400445}