blob: e7f69f59f37c3408af2d81dfbd9ee6fdfbec1daa [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
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
khenaidoo19d7b632018-10-30 10:49:50 -040086 if device, err := rhp.deviceMgr.GetDevice(pID.Id); err != nil {
khenaidoob9203542018-09-17 22:56:37 -040087 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
khenaidoo19d7b632018-10-30 10:49:50 -040099 if currentDevice, err = rhp.deviceMgr.GetDevice(device.Id); err != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400100 return nil, err
101 }
khenaidoo19d7b632018-10-30 10:49:50 -0400102 cloned := proto.Clone(currentDevice).(*voltha.Device)
khenaidoo92e62c52018-10-03 14:02:54 -0400103 cloned.Root = device.Root
104 cloned.Vendor = device.Vendor
105 cloned.Model = device.Model
106 cloned.SerialNumber = device.SerialNumber
107 cloned.MacAddress = device.MacAddress
khenaidoo19d7b632018-10-30 10:49:50 -0400108 cloned.Vlan = device.Vlan
109 return cloned, nil
khenaidoo92e62c52018-10-03 14:02:54 -0400110}
111
khenaidoob9203542018-09-17 22:56:37 -0400112func (rhp *AdapterRequestHandlerProxy) DeviceUpdate(args []*ca.Argument) (*empty.Empty, error) {
113 if len(args) != 1 {
114 log.Warn("invalid-number-of-args", log.Fields{"args": args})
115 err := errors.New("invalid-number-of-args")
116 return nil, err
117 }
118 device := &voltha.Device{}
119 if err := ptypes.UnmarshalAny(args[0].Value, device); err != nil {
120 log.Warnw("cannot-unmarshal-device", log.Fields{"error": err})
121 return nil, err
122 }
khenaidoo92e62c52018-10-03 14:02:54 -0400123 log.Debugw("DeviceUpdate", log.Fields{"deviceId": device.Id})
khenaidoob9203542018-09-17 22:56:37 -0400124
125 if rhp.TestMode { // Execute only for test cases
126 return new(empty.Empty), nil
127 }
khenaidoo92e62c52018-10-03 14:02:54 -0400128
129 //Merge the adapter device info (only the ones an adapter can change) with the latest device data
130 if updatedDevice, err := rhp.mergeDeviceInfoFromAdapter(device); err != nil {
khenaidoob9203542018-09-17 22:56:37 -0400131 return nil, status.Errorf(codes.Internal, "%s", err.Error())
khenaidoo92e62c52018-10-03 14:02:54 -0400132 } else {
133 // An adapter request needs an Ack without having to wait for the update to be
134 // completed. We therefore run the update in its own routine.
135 go rhp.deviceMgr.updateDevice(updatedDevice)
khenaidoob9203542018-09-17 22:56:37 -0400136 }
khenaidoo92e62c52018-10-03 14:02:54 -0400137
khenaidoob9203542018-09-17 22:56:37 -0400138 return new(empty.Empty), nil
139}
140
141func (rhp *AdapterRequestHandlerProxy) GetChildDevice(args []*ca.Argument) (*voltha.Device, error) {
142 if len(args) < 1 {
143 log.Warn("invalid-number-of-args", log.Fields{"args": args})
144 err := errors.New("invalid-number-of-args")
145 return nil, err
146 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400147 pID := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400148 if err := ptypes.UnmarshalAny(args[0].Value, pID); err != nil {
149 log.Warnw("cannot-unmarshal-ID", log.Fields{"error": err})
150 return nil, err
151 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400152 log.Debugw("GetChildDevice", log.Fields{"deviceId": pID.Id})
khenaidoob9203542018-09-17 22:56:37 -0400153
154 if rhp.TestMode { // Execute only for test cases
khenaidoo2c6f1672018-09-20 23:14:41 -0400155 return &voltha.Device{Id: pID.Id}, nil
khenaidoob9203542018-09-17 22:56:37 -0400156 }
157 return nil, nil
158}
159
160func (rhp *AdapterRequestHandlerProxy) GetPorts(args []*ca.Argument) (*voltha.Ports, error) {
161 if len(args) != 2 {
162 log.Warn("invalid-number-of-args", log.Fields{"args": args})
163 err := errors.New("invalid-number-of-args")
164 return nil, err
165 }
khenaidoo92e62c52018-10-03 14:02:54 -0400166 deviceId := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400167 pt := &ca.IntType{}
khenaidoo92e62c52018-10-03 14:02:54 -0400168 for _, arg := range args {
169 switch arg.Key {
170 case "device_id":
171 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
172 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
173 return nil, err
174 }
175 case "port_type":
176 if err := ptypes.UnmarshalAny(arg.Value, pt); err != nil {
177 log.Warnw("cannot-unmarshal-porttype", log.Fields{"error": err})
178 return nil, err
179 }
180 }
khenaidoob9203542018-09-17 22:56:37 -0400181 }
khenaidoo92e62c52018-10-03 14:02:54 -0400182 log.Debugw("GetPorts", log.Fields{"deviceID": deviceId.Id, "portype": pt.Val})
khenaidoob9203542018-09-17 22:56:37 -0400183 if rhp.TestMode { // Execute only for test cases
184 aPort := &voltha.Port{Label: "test_port"}
185 allPorts := &voltha.Ports{}
186 allPorts.Items = append(allPorts.Items, aPort)
187 return allPorts, nil
188 }
khenaidoo92e62c52018-10-03 14:02:54 -0400189 return rhp.deviceMgr.getPorts(nil, deviceId.Id, voltha.Port_PortType(pt.Val))
khenaidoob9203542018-09-17 22:56:37 -0400190}
191
192func (rhp *AdapterRequestHandlerProxy) GetChildDevices(args []*ca.Argument) (*voltha.Device, error) {
193 if len(args) != 1 {
194 log.Warn("invalid-number-of-args", log.Fields{"args": args})
195 err := errors.New("invalid-number-of-args")
196 return nil, err
197 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400198 pID := &voltha.ID{}
khenaidoob9203542018-09-17 22:56:37 -0400199 if err := ptypes.UnmarshalAny(args[0].Value, pID); err != nil {
200 log.Warnw("cannot-unmarshal-ID", log.Fields{"error": err})
201 return nil, err
202 }
khenaidoo2c6f1672018-09-20 23:14:41 -0400203 log.Debugw("GetChildDevice", log.Fields{"deviceId": pID.Id})
khenaidoob9203542018-09-17 22:56:37 -0400204
205 if rhp.TestMode { // Execute only for test cases
khenaidoo2c6f1672018-09-20 23:14:41 -0400206 return &voltha.Device{Id: pID.Id}, nil
khenaidoob9203542018-09-17 22:56:37 -0400207 }
208 //TODO: Complete
209 return nil, nil
210}
211
212// ChildDeviceDetected is invoked when a child device is detected. The following
213// parameters are expected:
214// {parent_device_id, parent_port_no, child_device_type, proxy_address, admin_state, **kw)
215func (rhp *AdapterRequestHandlerProxy) ChildDeviceDetected(args []*ca.Argument) (*empty.Empty, error) {
216 if len(args) < 4 {
217 log.Warn("invalid-number-of-args", log.Fields{"args": args})
218 err := errors.New("invalid-number-of-args")
219 return nil, err
220 }
221
222 pID := &voltha.ID{}
223 portNo := &ca.IntType{}
224 dt := &ca.StrType{}
225 chnlId := &ca.IntType{}
226 for _, arg := range args {
227 switch arg.Key {
228 case "parent_device_id":
229 if err := ptypes.UnmarshalAny(arg.Value, pID); err != nil {
230 log.Warnw("cannot-unmarshal-parent-device-id", log.Fields{"error": err})
231 return nil, err
232 }
233 case "parent_port_no":
234 if err := ptypes.UnmarshalAny(arg.Value, portNo); err != nil {
235 log.Warnw("cannot-unmarshal-parent-port", log.Fields{"error": err})
236 return nil, err
237 }
238 case "child_device_type":
239 if err := ptypes.UnmarshalAny(arg.Value, dt); err != nil {
240 log.Warnw("cannot-unmarshal-child-device-type", log.Fields{"error": err})
241 return nil, err
242 }
243 case "channel_id":
244 if err := ptypes.UnmarshalAny(arg.Value, chnlId); err != nil {
245 log.Warnw("cannot-unmarshal-channel-id", log.Fields{"error": err})
246 return nil, err
247 }
248 }
249 }
khenaidoob9203542018-09-17 22:56:37 -0400250 log.Debugw("ChildDeviceDetected", log.Fields{"parentDeviceId": pID.Id, "parentPortNo": portNo.Val,
251 "deviceType": dt.Val, "channelId": chnlId.Val})
252
253 if rhp.TestMode { // Execute only for test cases
254 return nil, nil
255 }
khenaidoob9203542018-09-17 22:56:37 -0400256 // Run child detection in it's own go routine as it can be a lengthy process
257 go rhp.deviceMgr.childDeviceDetected(pID.Id, portNo.Val, dt.Val, chnlId.Val)
258
259 return new(empty.Empty), nil
260}
261
262func (rhp *AdapterRequestHandlerProxy) DeviceStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
263 if len(args) < 2 {
264 log.Warn("invalid-number-of-args", log.Fields{"args": args})
265 err := errors.New("invalid-number-of-args")
266 return nil, err
267 }
268 deviceId := &voltha.ID{}
269 operStatus := &ca.IntType{}
270 connStatus := &ca.IntType{}
271 for _, arg := range args {
272 switch arg.Key {
273 case "device_id":
274 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
275 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
276 return nil, err
277 }
278 case "oper_status":
279 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
280 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
281 return nil, err
282 }
khenaidoob9203542018-09-17 22:56:37 -0400283 case "connect_status":
284 if err := ptypes.UnmarshalAny(arg.Value, connStatus); err != nil {
285 log.Warnw("cannot-unmarshal-connStatus", log.Fields{"error": err})
286 return nil, err
287 }
khenaidoob9203542018-09-17 22:56:37 -0400288 }
289 }
khenaidoob9203542018-09-17 22:56:37 -0400290 log.Debugw("DeviceStateUpdate", log.Fields{"deviceId": deviceId.Id, "oper-status": operStatus, "conn-status": connStatus})
khenaidoob9203542018-09-17 22:56:37 -0400291 if rhp.TestMode { // Execute only for test cases
292 return nil, nil
293 }
khenaidoo92e62c52018-10-03 14:02:54 -0400294 // When the enum is not set (i.e. -1), Go still convert to the Enum type with the value being -1
295 go rhp.deviceMgr.updateDeviceStatus(deviceId.Id, voltha.OperStatus_OperStatus(operStatus.Val), voltha.ConnectStatus_ConnectStatus(connStatus.Val))
296 return new(empty.Empty), nil
297}
298
khenaidoo4d4802d2018-10-04 21:59:49 -0400299func (rhp *AdapterRequestHandlerProxy) ChildrenStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
300 if len(args) < 2 {
301 log.Warn("invalid-number-of-args", log.Fields{"args": args})
302 err := errors.New("invalid-number-of-args")
303 return nil, err
304 }
305 deviceId := &voltha.ID{}
306 operStatus := &ca.IntType{}
307 connStatus := &ca.IntType{}
308 for _, arg := range args {
309 switch arg.Key {
310 case "device_id":
311 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
312 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
313 return nil, err
314 }
315 case "oper_status":
316 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
317 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
318 return nil, err
319 }
320 case "connect_status":
321 if err := ptypes.UnmarshalAny(arg.Value, connStatus); err != nil {
322 log.Warnw("cannot-unmarshal-connStatus", log.Fields{"error": err})
323 return nil, err
324 }
325 }
326 }
327 log.Debugw("ChildrenStateUpdate", log.Fields{"deviceId": deviceId.Id, "oper-status": operStatus, "conn-status": connStatus})
328 if rhp.TestMode { // Execute only for test cases
329 return nil, nil
330 }
331
332 // When the enum is not set (i.e. -1), Go still convert to the Enum type with the value being -1
333 go rhp.deviceMgr.updateChildrenStatus(deviceId.Id, voltha.OperStatus_OperStatus(operStatus.Val), voltha.ConnectStatus_ConnectStatus(connStatus.Val))
334 return new(empty.Empty), nil
335}
336
khenaidoo92e62c52018-10-03 14:02:54 -0400337func (rhp *AdapterRequestHandlerProxy) PortStateUpdate(args []*ca.Argument) (*empty.Empty, error) {
338 if len(args) < 2 {
339 log.Warn("invalid-number-of-args", log.Fields{"args": args})
340 err := errors.New("invalid-number-of-args")
341 return nil, err
khenaidoob9203542018-09-17 22:56:37 -0400342 }
khenaidoo92e62c52018-10-03 14:02:54 -0400343 deviceId := &voltha.ID{}
344 portType := &ca.IntType{}
345 portNo := &ca.IntType{}
346 operStatus := &ca.IntType{}
347 for _, arg := range args {
348 switch arg.Key {
349 case "device_id":
350 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
351 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
352 return nil, err
353 }
354 case "oper_status":
355 if err := ptypes.UnmarshalAny(arg.Value, operStatus); err != nil {
356 log.Warnw("cannot-unmarshal-operStatus", log.Fields{"error": err})
357 return nil, err
358 }
359 case "port_type":
360 if err := ptypes.UnmarshalAny(arg.Value, portType); err != nil {
361 log.Warnw("cannot-unmarshal-porttype", log.Fields{"error": err})
362 return nil, err
363 }
364 case "port_no":
365 if err := ptypes.UnmarshalAny(arg.Value, portNo); err != nil {
366 log.Warnw("cannot-unmarshal-portno", log.Fields{"error": err})
367 return nil, err
368 }
369
370 }
371 }
372 log.Debugw("PortStateUpdate", log.Fields{"deviceId": deviceId.Id, "operStatus": operStatus, "portType": portType, "portNo": portNo})
373 if rhp.TestMode { // Execute only for test cases
374 return nil, nil
375 }
376 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 -0400377 return new(empty.Empty), nil
378}
379
380func (rhp *AdapterRequestHandlerProxy) PortCreated(args []*ca.Argument) (*empty.Empty, error) {
381 if len(args) != 2 {
382 log.Warn("invalid-number-of-args", log.Fields{"args": args})
383 err := errors.New("invalid-number-of-args")
384 return nil, err
385 }
386 deviceId := &voltha.ID{}
387 port := &voltha.Port{}
388 for _, arg := range args {
389 switch arg.Key {
390 case "device_id":
391 if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
392 log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
393 return nil, err
394 }
395 case "port":
396 if err := ptypes.UnmarshalAny(arg.Value, port); err != nil {
397 log.Warnw("cannot-unmarshal-port", log.Fields{"error": err})
398 return nil, err
399 }
400 }
401 }
khenaidoob9203542018-09-17 22:56:37 -0400402 log.Debugw("PortCreated", log.Fields{"deviceId": deviceId.Id, "port": port})
403
404 if rhp.TestMode { // Execute only for test cases
405 return nil, nil
406 }
khenaidoo92e62c52018-10-03 14:02:54 -0400407 // Run port creation in its own go routine
408 go rhp.deviceMgr.addPort(deviceId.Id, port)
409
khenaidoob9203542018-09-17 22:56:37 -0400410 return new(empty.Empty), nil
411}
412
413func (rhp *AdapterRequestHandlerProxy) DevicePMConfigUpdate(args []*ca.Argument) (*empty.Empty, error) {
414 if len(args) != 2 {
415 log.Warn("invalid-number-of-args", log.Fields{"args": args})
416 err := errors.New("invalid-number-of-args")
417 return nil, err
418 }
419 pmConfigs := &voltha.PmConfigs{}
420 init := &ca.BoolType{}
421 for _, arg := range args {
422 switch arg.Key {
423 case "device_pm_config":
424 if err := ptypes.UnmarshalAny(arg.Value, pmConfigs); err != nil {
425 log.Warnw("cannot-unmarshal-pm-config", log.Fields{"error": err})
426 return nil, err
427 }
428 case "init":
429 if err := ptypes.UnmarshalAny(arg.Value, init); err != nil {
430 log.Warnw("cannot-unmarshal-boolean", log.Fields{"error": err})
431 return nil, err
432 }
433 }
434 }
khenaidoob9203542018-09-17 22:56:37 -0400435 log.Debugw("DevicePMConfigUpdate", log.Fields{"deviceId": pmConfigs.Id, "configs": pmConfigs,
436 "init": init})
437
438 if rhp.TestMode { // Execute only for test cases
439 return nil, nil
440 }
441
khenaidoo92e62c52018-10-03 14:02:54 -0400442 // Run PM config update in its own go routine
443 go rhp.deviceMgr.updatePmConfigs(pmConfigs.Id, pmConfigs)
444
khenaidoob9203542018-09-17 22:56:37 -0400445 return new(empty.Empty), nil
khenaidoob9203542018-09-17 22:56:37 -0400446}