|
|
| F´ Version |
v4.2.2 |
| Affected Component |
Svc::FileDownlink |
Problem Description
If a component receives a cancel packet from Fw::FilePacket, and tries to deserialize using filePacket.fromBuffer(fwBuffer), it will fail with error status FW_DESERIALIZE_SIZE_MISMATCH.
The reason this occurs is because FileDownlink fails to set the buffer size specifically when generating cancel packets.
Svc::FileDownlink serializes four kinds of Fw::FilePacket packets into Fw::Buffer buffers, in order to send them downstream. For Start, Data, and End packets, the sendFilePacket() helper function properly sets the reused buffer size to bufferSize, then sets it back to FILEDOWNLINK_INTERNAL_BUFFER_SIZE after the downstream port call returns. However, for Cancel packets, which don't use the sendFilePacket() helper function, no call to setSize() occurs. This means it is sent downstream as size FILEDOWNLINK_INTERNAL_BUFFER_SIZE, rather than the correct size (5).
Context / Environment
I first hit this problem in v3.6, but it seems (by inspection) that the same behavior exists in dev.
How to Reproduce
- Connect a component to the
Svc::FileDownlink bufferSendOut output port
- Component should try to deserialize each incoming
FilePacket using filePacket.fromBuffer(fwBuffer)
- Send a file using
SendFile command (large enough that there is time to send Cancel command before it finishes)
- Send
Cancel command
Start and Data packets should be deserialized properly, but Cancel packet deserialization fails with status FW_DESERIALIZE_SIZE_MISMATCH
Expected Behavior
Buffers sent via Svc::FileDownlink bufferSendOut output port should first be set to the correct size to match the serialized Fw::FilePacket.
Notes
I have been trying to understand why Cancel packets are handled differently than Start, Data, and End packets. The latter all utilize a single reused m_buffer, while Cancel packets utilize a more tightly-scoped buffer in the sendCancelPacket() function. m_buffer points to m_memoryStore[0] and buffer (cancel buffer) points to m_memoryStore[1].
m_buffer has its size reset and data re-pointed to m_memoryStore[0] whenever a new file is downlinked. Whereas buffer (cancel buffer) gets size+data reset every time a new cancel packet is generated.
My best guess as to why Cancel packets use a separate underlying buffer is that this may have been a useful distinction prior to the removal of the "timeout" functionality with its ambiguous buffer ownership bug. I don't currently see a reason why the buffers need to be separate, so I cautiously propose refactoring how Cancel packets are generated, to use the same code and underlying buffer as the other types of file packets.
v4.2.2Svc::FileDownlinkProblem Description
If a component receives a cancel packet from
Fw::FilePacket, and tries to deserialize usingfilePacket.fromBuffer(fwBuffer), it will fail with error statusFW_DESERIALIZE_SIZE_MISMATCH.The reason this occurs is because
FileDownlinkfails to set the buffer size specifically when generating cancel packets.Svc::FileDownlinkserializes four kinds ofFw::FilePacketpackets intoFw::Bufferbuffers, in order to send them downstream. ForStart,Data, andEndpackets, thesendFilePacket()helper function properly sets the reused buffer size tobufferSize, then sets it back toFILEDOWNLINK_INTERNAL_BUFFER_SIZEafter the downstream port call returns. However, forCancelpackets, which don't use thesendFilePacket()helper function, no call tosetSize()occurs. This means it is sent downstream as sizeFILEDOWNLINK_INTERNAL_BUFFER_SIZE, rather than the correct size (5).Context / Environment
I first hit this problem in
v3.6, but it seems (by inspection) that the same behavior exists indev.How to Reproduce
Svc::FileDownlinkbufferSendOutoutput portFilePacketusingfilePacket.fromBuffer(fwBuffer)SendFilecommand (large enough that there is time to sendCancelcommand before it finishes)CancelcommandStartandDatapackets should be deserialized properly, butCancelpacket deserialization fails with statusFW_DESERIALIZE_SIZE_MISMATCHExpected Behavior
Buffers sent via
Svc::FileDownlinkbufferSendOutoutput port should first be set to the correct size to match the serializedFw::FilePacket.Notes
I have been trying to understand why
Cancelpackets are handled differently thanStart,Data, andEndpackets. The latter all utilize a single reusedm_buffer, whileCancelpackets utilize a more tightly-scopedbufferin thesendCancelPacket()function.m_bufferpoints tom_memoryStore[0]andbuffer(cancel buffer) points tom_memoryStore[1].m_bufferhas its size reset and data re-pointed tom_memoryStore[0]whenever a new file is downlinked. Whereasbuffer(cancel buffer) gets size+data reset every time a new cancel packet is generated.My best guess as to why
Cancelpackets use a separate underlying buffer is that this may have been a useful distinction prior to the removal of the "timeout" functionality with its ambiguous buffer ownership bug. I don't currently see a reason why the buffers need to be separate, so I cautiously propose refactoring howCancelpackets are generated, to use the same code and underlying buffer as the other types of file packets.