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