blob: dcf65996812d5a85c9e98e5b454a0663194f8ac3 [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001/*
2 * Copyright 2021-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 device
17
18import (
19 "context"
20
21 "github.com/golang/protobuf/ptypes/empty"
22 "github.com/opencord/voltha-go/rw_core/utils"
23 "github.com/opencord/voltha-lib-go/v7/pkg/log"
24 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo9beaaf12021-10-19 17:32:01 -040025 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo25057da2021-12-08 14:40:45 -050026 "github.com/opencord/voltha-protos/v5/go/health"
khenaidood948f772021-08-11 17:49:24 -040027 "github.com/opencord/voltha-protos/v5/go/voltha"
28 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/status"
30)
31
khenaidoo25057da2021-12-08 14:40:45 -050032func (dMgr *Manager) GetHealthStatus(ctx context.Context, clientConn *common.Connection) (*health.HealthStatus, error) {
33 logger.Debugw(ctx, "get-health-status-from-remote", log.Fields{"remote-client": clientConn})
34 return &health.HealthStatus{State: health.HealthStatus_HEALTHY}, nil
35}
36
khenaidood948f772021-08-11 17:49:24 -040037func (dMgr *Manager) PortCreated(ctx context.Context, port *voltha.Port) (*empty.Empty, error) {
38 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "PortCreated")
39
40 logger.Debugw(ctx, "port-created", log.Fields{"port": port})
41
42 agent := dMgr.getDeviceAgent(ctx, port.DeviceId)
43 if agent != nil {
44 if err := agent.addPort(ctx, port); err != nil {
45 return nil, err
46 }
47 // Setup peer ports in its own routine
48 go func() {
49 if err := dMgr.addPeerPort(log.WithSpanFromContext(context.Background(), ctx), port.DeviceId, port); err != nil {
50 logger.Errorw(ctx, "unable-to-add-peer-port", log.Fields{"error": err, "device-id": port.DeviceId})
51 }
52 }()
53 return &empty.Empty{}, nil
54 }
55 return nil, status.Errorf(codes.NotFound, "%s", port.DeviceId)
56}
57
58func (dMgr *Manager) DeviceUpdate(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
59 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "DeviceUpdate")
60 logger.Debugw(ctx, "device-update", log.Fields{"device-id": device.Id, "device": device})
61
62 if agent := dMgr.getDeviceAgent(ctx, device.Id); agent != nil {
63 if err := agent.updateDeviceUsingAdapterData(ctx, device); err != nil {
64 return nil, err
65 }
66 return &empty.Empty{}, nil
67 }
68 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
69}
70
khenaidoo9beaaf12021-10-19 17:32:01 -040071func (dMgr *Manager) DeviceStateUpdate(ctx context.Context, ds *ca.DeviceStateFilter) (*empty.Empty, error) {
khenaidood948f772021-08-11 17:49:24 -040072 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "DeviceStateUpdate")
73 logger.Debugw(ctx, "device-state-update", log.Fields{"device-id": ds.DeviceId, "operStatus": ds.OperStatus, "connStatus": ds.ConnStatus})
74
75 if agent := dMgr.getDeviceAgent(ctx, ds.DeviceId); agent != nil {
76 if err := agent.updateDeviceStatus(ctx, ds.OperStatus, ds.ConnStatus); err != nil {
77 return nil, err
78 }
79 return &empty.Empty{}, nil
80 }
81 return nil, status.Errorf(codes.NotFound, "%s", ds.DeviceId)
82}
83
khenaidoo9beaaf12021-10-19 17:32:01 -040084func (dMgr *Manager) ChildDeviceDetected(ctx context.Context, dd *ca.DeviceDiscovery) (*voltha.Device, error) {
khenaidood948f772021-08-11 17:49:24 -040085 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "ChildDeviceDetected")
86 logger.Debugw(ctx, "child-device-detected",
87 log.Fields{
88 "parent-device-id": dd.ParentId,
89 "parentPortNo": dd.ParentPortNo,
90 "deviceType": dd.ChildDeviceType,
91 "channelId": dd.ChannelId,
92 "vendorId": dd.VendorId,
93 "serialNumber": dd.SerialNumber,
94 "onuId": dd.OnuId,
95 })
96
97 var err error
98 if dd.ChildDeviceType == "" && dd.VendorId != "" {
99 logger.Debug(ctx, "device-type-is-nil-fetching-device-type")
100 if dd.ChildDeviceType, err = dMgr.adapterMgr.GetAdapterTypeByVendorID(dd.VendorId); err != nil {
101 return nil, err
102 }
103 }
104 //if no match found for the vendorid,report adapter with the custom error message
105 if dd.ChildDeviceType == "" {
106 logger.Errorw(ctx, "failed-to-fetch-adapter-name ", log.Fields{"vendorId": dd.VendorId})
107 return nil, status.Errorf(codes.NotFound, "%s", dd.VendorId)
108 }
109
110 // Create the ONU device
111 childDevice := &voltha.Device{}
112 childDevice.Type = dd.ChildDeviceType
113 childDevice.ParentId = dd.ParentId
114 childDevice.ParentPortNo = uint32(dd.ParentPortNo)
115 childDevice.VendorId = dd.VendorId
116 childDevice.SerialNumber = dd.SerialNumber
117 childDevice.Root = false
118
119 // Get parent device type
120 pAgent := dMgr.getDeviceAgent(ctx, dd.ParentId)
121 if pAgent == nil {
122 return nil, status.Errorf(codes.NotFound, "%s", dd.ParentId)
123 }
124 if pAgent.deviceType == "" {
125 pDevice, err := pAgent.getDeviceReadOnly(ctx)
126 logger.Errorw(ctx, "device-type-not-set", log.Fields{"parent-device": pDevice, "error": err})
127 return nil, status.Errorf(codes.FailedPrecondition, "device Type not set %s", dd.ParentId)
128 }
129
khenaidoo9beaaf12021-10-19 17:32:01 -0400130 if device, err := dMgr.GetChildDevice(ctx, &ca.ChildDeviceFilter{
khenaidood948f772021-08-11 17:49:24 -0400131 ParentId: dd.ParentId,
132 SerialNumber: dd.SerialNumber,
133 OnuId: dd.OnuId,
134 ParentPortNo: dd.ParentPortNo}); err == nil {
135 logger.Warnw(ctx, "child-device-exists", log.Fields{"parent-device-id": dd.ParentId, "serialNumber": dd.SerialNumber})
136 return device, status.Errorf(codes.AlreadyExists, "%s", dd.SerialNumber)
137 }
138
139 //Get parent endpoint
140 pEndPoint, err := dMgr.adapterMgr.GetAdapterEndpoint(ctx, pAgent.deviceID, pAgent.deviceType)
141 if err != nil {
142 logger.Errorw(ctx, "endpoint-error", log.Fields{"error": err, "parent-id": pAgent.deviceID, "parent-device-type": pAgent.deviceType})
143 return nil, status.Errorf(codes.NotFound, "parent-endpoint-%s", dd.ParentId)
144 }
145
146 childDevice.ProxyAddress = &voltha.Device_ProxyAddress{DeviceId: dd.ParentId, DeviceType: pAgent.deviceType, ChannelId: dd.ChannelId, OnuId: dd.OnuId, AdapterEndpoint: pEndPoint}
147
148 // Set child device ID -- needed to get the device endpoint
149 childDevice.Id = utils.CreateDeviceID()
150
151 // Set the child adapter endpoint
152 childDevice.AdapterEndpoint, err = dMgr.adapterMgr.GetAdapterEndpoint(ctx, childDevice.Id, childDevice.Type)
153 if err != nil {
154 return nil, status.Errorf(codes.NotFound, "child-endpoint-%s", childDevice.Id)
155 }
156
157 // Create and start a device agent for that device
Himani Chawla4b4bd252021-11-08 15:59:40 +0530158 agent := newAgent(childDevice, dMgr, dMgr.dbPath, dMgr.dProxy, dMgr.internalTimeout, dMgr.rpcTimeout, dMgr.flowTimeout)
khenaidood948f772021-08-11 17:49:24 -0400159 insertedChildDevice, err := agent.start(ctx, false, childDevice)
160 if err != nil {
161 logger.Errorw(ctx, "error-starting-child-device", log.Fields{"parent-device-id": childDevice.ParentId, "child-device-id": agent.deviceID, "error": err})
162 return nil, err
163 }
164 dMgr.addDeviceAgentToMap(agent)
165
166 // Activate the child device
167 if agent = dMgr.getDeviceAgent(ctx, agent.deviceID); agent != nil {
168 go func() {
169 err := agent.enableDevice(utils.WithSpanAndRPCMetadataFromContext(ctx))
170 if err != nil {
171 logger.Errorw(ctx, "unable-to-enable-device", log.Fields{"error": err, "device-id": agent.deviceID})
172 }
173 }()
174 }
175
176 return insertedChildDevice, nil
177}
178
khenaidoo9beaaf12021-10-19 17:32:01 -0400179func (dMgr *Manager) GetChildDevice(ctx context.Context, df *ca.ChildDeviceFilter) (*voltha.Device, error) {
khenaidood948f772021-08-11 17:49:24 -0400180 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "GetChildDevice")
181 logger.Debugw(ctx, "get-child-device", log.Fields{"filter": df})
182
183 parentDevicePorts, err := dMgr.listDevicePorts(ctx, df.ParentId)
184 if err != nil {
185 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
186 }
187 childDeviceIds := dMgr.getAllChildDeviceIds(ctx, parentDevicePorts)
188 if len(childDeviceIds) == 0 {
189 logger.Debugw(ctx, "no-child-devices", log.Fields{"parent-device-id": df.ParentId, "serial-number": df.SerialNumber, "onu-id": df.OnuId})
190 return nil, status.Errorf(codes.NotFound, "%s", df.ParentId)
191 }
192
193 var foundChildDevice *voltha.Device
194 for childDeviceID := range childDeviceIds {
195 var found bool
196 if searchDevice, err := dMgr.getDeviceReadOnly(ctx, childDeviceID); err == nil {
197
198 foundOnuID := false
199 if searchDevice.ProxyAddress.OnuId == uint32(df.OnuId) {
200 if searchDevice.ParentPortNo == uint32(df.ParentPortNo) {
201 logger.Debugw(ctx, "found-child-by-onu-id", log.Fields{"parent-device-id": df.ParentId, "onuId": df.OnuId})
202 foundOnuID = true
203 }
204 }
205
206 foundSerialNumber := false
207 if searchDevice.SerialNumber == df.SerialNumber {
208 logger.Debugw(ctx, "found-child-by-serial-number", log.Fields{"parent-device-id": df.ParentId, "serialNumber": df.SerialNumber})
209 foundSerialNumber = true
210 }
211
212 // if both onuId and serialNumber are provided both must be true for the device to be found
213 // otherwise whichever one found a match is good enough
214 if df.OnuId > 0 && df.SerialNumber != "" {
215 found = foundOnuID && foundSerialNumber
216 } else {
217 found = foundOnuID || foundSerialNumber
218 }
219
220 if found {
221 foundChildDevice = searchDevice
222 break
223 }
224 }
225 }
226
227 if foundChildDevice != nil {
228 logger.Debugw(ctx, "child-device-found", log.Fields{"parent-device-id": df.ParentId, "foundChildDevice": foundChildDevice})
229 return foundChildDevice, nil
230 }
231
232 logger.Debugw(ctx, "child-device-not-found", log.Fields{"parent-device-id": df.ParentId,
233 "serialNumber": df.SerialNumber, "onuId": df.OnuId, "parentPortNo": df.ParentPortNo})
234 return nil, status.Errorf(codes.NotFound, "%s", df.ParentId)
235}
236
237// PortsStateUpdate updates the operational status of all ports on the device
khenaidoo9beaaf12021-10-19 17:32:01 -0400238func (dMgr *Manager) PortsStateUpdate(ctx context.Context, ps *ca.PortStateFilter) (*empty.Empty, error) {
khenaidood948f772021-08-11 17:49:24 -0400239 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "PortsStateUpdate")
240 logger.Debugw(ctx, "ports-state-update", log.Fields{"device-id": ps.DeviceId})
241
242 agent := dMgr.getDeviceAgent(ctx, ps.DeviceId)
243 if agent == nil {
244 return nil, status.Errorf(codes.NotFound, "%s", ps.DeviceId)
245 }
246 if ps.OperStatus != voltha.OperStatus_ACTIVE && ps.OperStatus != voltha.OperStatus_UNKNOWN {
247 return nil, status.Error(codes.Unimplemented, "state-change-not-implemented")
248 }
249 if err := agent.updatePortsOperState(ctx, ps.PortTypeFilter, ps.OperStatus); err != nil {
250 logger.Warnw(ctx, "ports-state-update-failed", log.Fields{"device-id": ps.DeviceId, "error": err})
251 return nil, err
252 }
253 return &empty.Empty{}, nil
254}
255
256//ChildDevicesLost is invoked by an adapter to indicate that a parent device is in a state (Disabled) where it
257//cannot manage the child devices. This will trigger the Core to disable all the child devices.
258func (dMgr *Manager) ChildDevicesLost(ctx context.Context, parentID *common.ID) (*empty.Empty, error) {
259 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "ChildDevicesLost")
260 logger.Debugw(ctx, "child-devices-lost", log.Fields{"parent-id": parentID.Id})
261
262 parentDevice, err := dMgr.getDeviceReadOnly(ctx, parentID.Id)
263 if err != nil {
264 logger.Warnw(ctx, "failed-getting-device", log.Fields{"parent-device-id": parentID.Id, "error": err})
265 return nil, err
266 }
267 if err = dMgr.DisableAllChildDevices(ctx, parentDevice); err != nil {
268 return nil, err
269 }
270 return &empty.Empty{}, nil
271}
272
273//ChildDevicesDetected is invoked by an adapter when child devices are found, typically after after a
274// disable/enable sequence. This will trigger the Core to Enable all the child devices of that parent.
275func (dMgr *Manager) ChildDevicesDetected(ctx context.Context, parentDeviceID *common.ID) (*empty.Empty, error) {
276 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "ChildDevicesDetected")
277 logger.Debugw(ctx, "child-devices-detected", log.Fields{"parent-device-id": parentDeviceID})
278
279 parentDevicePorts, err := dMgr.listDevicePorts(ctx, parentDeviceID.Id)
280 if err != nil {
281 logger.Warnw(ctx, "failed-getting-device", log.Fields{"device-id": parentDeviceID.Id, "error": err})
282 return nil, err
283 }
284 childDeviceIds := dMgr.getAllChildDeviceIds(ctx, parentDevicePorts)
285 if len(childDeviceIds) == 0 {
286 logger.Debugw(ctx, "no-child-device", log.Fields{"parent-device-id": parentDeviceID.Id})
287 }
288 allChildEnableRequestSent := true
289 for childDeviceID := range childDeviceIds {
290 if agent := dMgr.getDeviceAgent(ctx, childDeviceID); agent != nil {
291 // Run the children re-registration in its own routine
292 go func(ctx context.Context) {
293 err = agent.enableDevice(ctx)
294 if err != nil {
295 logger.Errorw(ctx, "unable-to-enable-device", log.Fields{"error": err})
296 }
297 }(log.WithSpanFromContext(context.Background(), ctx))
298 } else {
299 err = status.Errorf(codes.Unavailable, "no agent for child device %s", childDeviceID)
300 logger.Errorw(ctx, "no-child-device-agent", log.Fields{"parent-device-id": parentDeviceID.Id, "childId": childDeviceID})
301 allChildEnableRequestSent = false
302 }
303 }
304 if !allChildEnableRequestSent {
305 return nil, err
306 }
307 return &empty.Empty{}, nil
308}
309
310// GetChildDeviceWithProxyAddress will return a device based on proxy address
311func (dMgr *Manager) GetChildDeviceWithProxyAddress(ctx context.Context, proxyAddress *voltha.Device_ProxyAddress) (*voltha.Device, error) {
312 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "GetChildDeviceWithProxyAddress")
313
314 logger.Debugw(ctx, "get-child-device-with-proxy-address", log.Fields{"proxyAddress": proxyAddress})
315
316 parentDevicePorts, err := dMgr.listDevicePorts(ctx, proxyAddress.DeviceId)
317 if err != nil {
318 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
319 }
320 childDeviceIds := dMgr.getAllChildDeviceIds(ctx, parentDevicePorts)
321 if len(childDeviceIds) == 0 {
322 logger.Debugw(ctx, "no-child-devices", log.Fields{"parent-device-id": proxyAddress.DeviceId})
323 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
324 }
325
326 var foundChildDevice *voltha.Device
327 for childDeviceID := range childDeviceIds {
328 if searchDevice, err := dMgr.getDeviceReadOnly(ctx, childDeviceID); err == nil {
329 if searchDevice.ProxyAddress == proxyAddress {
330 foundChildDevice = searchDevice
331 break
332 }
333 }
334 }
335
336 if foundChildDevice != nil {
337 logger.Debugw(ctx, "child-device-found", log.Fields{"proxyAddress": proxyAddress})
338 return foundChildDevice, nil
339 }
340
341 logger.Warnw(ctx, "child-device-not-found", log.Fields{"proxyAddress": proxyAddress})
342 return nil, status.Errorf(codes.NotFound, "%s", proxyAddress)
343}
344
khenaidoo9beaaf12021-10-19 17:32:01 -0400345func (dMgr *Manager) GetPorts(ctx context.Context, pf *ca.PortFilter) (*voltha.Ports, error) {
khenaidood948f772021-08-11 17:49:24 -0400346 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "GetPorts")
347 logger.Debugw(ctx, "get-ports", log.Fields{"device-id": pf.DeviceId, "portType": pf.PortType})
348
349 agent := dMgr.getDeviceAgent(ctx, pf.DeviceId)
350 if agent == nil {
351 return nil, status.Errorf(codes.NotFound, "%s", pf.DeviceId)
352 }
353 return agent.getPorts(ctx, pf.PortType), nil
354}
355
356func (dMgr *Manager) GetChildDevices(ctx context.Context, parentDeviceID *common.ID) (*voltha.Devices, error) {
357 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "GetChildDevices")
358
359 logger.Debugw(ctx, "get-child-devices", log.Fields{"parent-device-id": parentDeviceID.Id})
360 return dMgr.getAllChildDevices(ctx, parentDeviceID.Id)
361}
362
khenaidoo9beaaf12021-10-19 17:32:01 -0400363func (dMgr *Manager) ChildrenStateUpdate(ctx context.Context, ds *ca.DeviceStateFilter) (*empty.Empty, error) {
khenaidood948f772021-08-11 17:49:24 -0400364 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "ChildrenStateUpdate")
365 logger.Debugw(ctx, "children-state-update", log.Fields{"parent-device-id": ds.ParentDeviceId, "operStatus": ds.OperStatus, "connStatus": ds.ConnStatus})
366
367 parentDevicePorts, err := dMgr.listDevicePorts(ctx, ds.ParentDeviceId)
368 if err != nil {
369 return nil, status.Errorf(codes.Aborted, "%s", err.Error())
370 }
371 for childDeviceID := range dMgr.getAllChildDeviceIds(ctx, parentDevicePorts) {
372 if agent := dMgr.getDeviceAgent(ctx, childDeviceID); agent != nil {
373 if err = agent.updateDeviceStatus(ctx, ds.OperStatus, ds.ConnStatus); err != nil {
374 return nil, status.Errorf(codes.Aborted, "childDevice:%s, error:%s", childDeviceID, err.Error())
375 }
376 }
377 }
378 return &empty.Empty{}, nil
379}
380
khenaidoo9beaaf12021-10-19 17:32:01 -0400381func (dMgr *Manager) PortStateUpdate(ctx context.Context, ps *ca.PortState) (*empty.Empty, error) {
khenaidood948f772021-08-11 17:49:24 -0400382 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "PortStateUpdate")
383 logger.Debugw(ctx, "port-state-update", log.Fields{"device-id": ps.DeviceId, "portType": ps.PortType, "portNo": ps.PortNo, "operStatus": ps.OperStatus})
384
385 if agent := dMgr.getDeviceAgent(ctx, ps.DeviceId); agent != nil {
386 if err := agent.updatePortState(ctx, ps.PortType, ps.PortNo, ps.OperStatus); err != nil {
387 logger.Errorw(ctx, "updating-port-state-failed", log.Fields{"device-id": ps.DeviceId, "portNo": ps.PortNo, "error": err})
388 return nil, err
389 }
390 // Notify the logical device manager to change the port state
391 // Do this for NNI and UNIs only. PON ports are not known by logical device
392 if ps.PortType == voltha.Port_ETHERNET_NNI || ps.PortType == voltha.Port_ETHERNET_UNI {
393 go func() {
394 err := dMgr.logicalDeviceMgr.updatePortState(log.WithSpanFromContext(context.Background(), ctx), ps.DeviceId, ps.PortNo, ps.OperStatus)
395 if err != nil {
396 // While we want to handle (catch) and log when
397 // an update to a port was not able to be
398 // propagated to the logical port, we can report
399 // it as a warning and not an error because it
400 // doesn't stop or modify processing.
401 // TODO: VOL-2707
402 logger.Warnw(ctx, "unable-to-update-logical-port-state", log.Fields{"error": err})
403 }
404 }()
405 }
406 return &empty.Empty{}, nil
407 }
408 return nil, status.Errorf(codes.NotFound, "%s", ps.DeviceId)
409}
410
411func (dMgr *Manager) DeleteAllPorts(ctx context.Context, deviceID *common.ID) (*empty.Empty, error) {
412 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "DeleteAllPorts")
413 logger.Debugw(ctx, "delete-all-ports", log.Fields{"device-id": deviceID.Id})
414
415 if agent := dMgr.getDeviceAgent(ctx, deviceID.Id); agent != nil {
416 if err := agent.deleteAllPorts(ctx); err != nil {
417 return nil, err
418 }
419 // Notify the logical device manager to remove all logical ports, if needed.
420 // At this stage the device itself may gave been deleted already at a DeleteAllPorts
421 // typically is part of a device deletion phase.
422 if device, err := dMgr.getDeviceReadOnly(ctx, deviceID.Id); err == nil {
423 go func() {
424 subCtx := utils.WithSpanAndRPCMetadataFromContext(ctx)
425 if err := dMgr.logicalDeviceMgr.deleteAllLogicalPorts(subCtx, device); err != nil {
426 logger.Errorw(ctx, "unable-to-delete-logical-ports", log.Fields{"error": err})
427 }
428 }()
429 } else {
430 logger.Warnw(ctx, "failed-to-retrieve-device", log.Fields{"device-id": deviceID.Id})
431 return nil, err
432 }
433 return &empty.Empty{}, nil
434 }
435 return nil, status.Errorf(codes.NotFound, "%s", deviceID.Id)
436}
437
438// GetDevicePort returns the port details for a specific device port entry
khenaidoo9beaaf12021-10-19 17:32:01 -0400439func (dMgr *Manager) GetDevicePort(ctx context.Context, pf *ca.PortFilter) (*voltha.Port, error) {
khenaidood948f772021-08-11 17:49:24 -0400440 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "GetDevicePort")
441 logger.Debugw(ctx, "get-device-port", log.Fields{"device-id": pf.DeviceId})
442
443 agent := dMgr.getDeviceAgent(ctx, pf.DeviceId)
444 if agent == nil {
445 return nil, status.Errorf(codes.NotFound, "device-%s", pf.DeviceId)
446 }
447 return agent.getDevicePort(pf.Port)
448}
449
450// DevicePMConfigUpdate updates the pm configs as defined by the adapter.
451func (dMgr *Manager) DevicePMConfigUpdate(ctx context.Context, pc *voltha.PmConfigs) (*empty.Empty, error) {
452 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "DevicePMConfigUpdate")
453 logger.Debugw(ctx, "device-pm-config-update", log.Fields{"device-id": pc.Id})
454
455 if pc.Id == "" {
456 return nil, status.Errorf(codes.FailedPrecondition, "invalid-device-Id")
457 }
458 if agent := dMgr.getDeviceAgent(ctx, pc.Id); agent != nil {
459 if err := agent.initPmConfigs(ctx, pc); err != nil {
460 return nil, err
461 }
462 return &empty.Empty{}, nil
463 }
464 return nil, status.Errorf(codes.NotFound, "%s", pc.Id)
465}
466
467// SendPacketIn receives packetIn request from adapter
khenaidoo9beaaf12021-10-19 17:32:01 -0400468func (dMgr *Manager) SendPacketIn(ctx context.Context, pi *ca.PacketIn) (*empty.Empty, error) {
khenaidood948f772021-08-11 17:49:24 -0400469 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "SendPacketIn")
470 logger.Debugw(ctx, "packet-in", log.Fields{"device-id": pi.DeviceId, "port": pi.Port})
471
472 // Get the logical device Id based on the deviceId
473 var device *voltha.Device
474 var err error
475 if device, err = dMgr.getDeviceReadOnly(ctx, pi.DeviceId); err != nil {
476 logger.Errorw(ctx, "device-not-found", log.Fields{"device-id": pi.DeviceId})
477 return nil, err
478 }
479 if !device.Root {
480 logger.Errorw(ctx, "device-not-root", log.Fields{"device-id": pi.DeviceId})
481 return nil, status.Errorf(codes.FailedPrecondition, "%s", pi.DeviceId)
482 }
483
484 if err := dMgr.logicalDeviceMgr.packetIn(ctx, device.ParentId, pi.Port, pi.Packet); err != nil {
485 return nil, err
486 }
487 return &empty.Empty{}, nil
488}
489
khenaidoo9beaaf12021-10-19 17:32:01 -0400490func (dMgr *Manager) DeviceReasonUpdate(ctx context.Context, dr *ca.DeviceReason) (*empty.Empty, error) {
khenaidood948f772021-08-11 17:49:24 -0400491 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "DeviceReasonUpdate")
492 logger.Debugw(ctx, "update-device-reason", log.Fields{"device-id": dr.DeviceId, "reason": dr.Reason})
493
494 if agent := dMgr.getDeviceAgent(ctx, dr.DeviceId); agent != nil {
495 if err := agent.updateDeviceReason(ctx, dr.Reason); err != nil {
496 return nil, err
497 }
498 return &empty.Empty{}, nil
499 }
500 return nil, status.Errorf(codes.NotFound, "%s", dr.DeviceId)
501}
502
503func (dMgr *Manager) ReconcileChildDevices(ctx context.Context, parentDeviceID *common.ID) (*empty.Empty, error) {
504 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "ReconcileChildDevices")
505 logger.Debugw(ctx, "reconcile-child-devices", log.Fields{"device-id": parentDeviceID.Id})
506
507 numberOfDevicesToReconcile := 0
508 dMgr.deviceAgents.Range(func(key, value interface{}) bool {
509 deviceAgent, ok := value.(*Agent)
510 if ok && deviceAgent.parentID == parentDeviceID.Id {
511 go deviceAgent.ReconcileDevice(utils.WithNewSpanAndRPCMetadataContext(ctx, "ReconcileChildDevices"))
512 numberOfDevicesToReconcile++
513 }
514 return true
515 })
516 logger.Debugw(ctx, "reconciling-child-devices-initiated", log.Fields{"parent-device-id": parentDeviceID.Id, "number-of-child-devices-to-reconcile": numberOfDevicesToReconcile})
517 return &empty.Empty{}, nil
518}
519
520func (dMgr *Manager) UpdateImageDownload(ctx context.Context, img *voltha.ImageDownload) (*empty.Empty, error) {
521 ctx = utils.WithNewSpanAndRPCMetadataContext(ctx, "UpdateImageDownload")
522 log.EnrichSpan(ctx, log.Fields{"device-id": img.Id})
523
524 logger.Debugw(ctx, "update-image-download", log.Fields{"device-id": img.Id, "image-name": img.Name})
525
526 if agent := dMgr.getDeviceAgent(ctx, img.Id); agent != nil {
527 if err := agent.updateImageDownload(ctx, img); err != nil {
528 logger.Debugw(ctx, "update-image-download-failed", log.Fields{"err": err, "image-name": img.Name})
529 return nil, err
530 }
531 } else {
532 return nil, status.Errorf(codes.NotFound, "%s", img.Id)
533 }
534 return &empty.Empty{}, nil
535}