-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split Deframer into FrameAccumulator Deframer and Router #3250
base: devel
Are you sure you want to change the base?
Conversation
// Component construction and destruction | ||
// ---------------------------------------------------------------------- | ||
|
||
FprimeDeframer ::FprimeDeframer(const char* const compName) : FprimeDeframerComponentBase(compName) {} |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
// Handler implementations for user-defined typed input ports | ||
// ---------------------------------------------------------------------- | ||
|
||
void FprimeDeframer ::framedIn_handler(FwIndexType portNum, Fw::Buffer& data, Fw::Buffer& context) { |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
namespace Svc { | ||
namespace FrameDetectors { | ||
|
||
FrameDetector::Status FprimeFrameDetector::detect(const Types::CircularBuffer& data, FwSizeType& size_out) const { |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
// Component construction and destruction | ||
// ---------------------------------------------------------------------- | ||
|
||
Router ::Router(const char* const compName) : RouterComponentBase(compName) {} |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
// Handler implementations for user-defined typed input ports | ||
// ---------------------------------------------------------------------- | ||
|
||
void Router ::dataIn_handler(NATIVE_INT_TYPE portNum, Fw::Buffer& packetBuffer, Fw::Buffer& contextBuffer) { |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
} | ||
|
||
// Whether to deallocate the packet buffer | ||
bool deallocate = true; |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
} | ||
} | ||
|
||
void Router ::cmdResponseIn_handler(NATIVE_INT_TYPE portNum, |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
// Component construction and destruction | ||
// ---------------------------------------------------------------------- | ||
|
||
FprimeDeframer ::FprimeDeframer(const char* const compName) : FprimeDeframerComponentBase(compName) {} |
Check notice
Code scanning / CodeQL
More than one statement per line Note
|
||
FprimeDeframer ::FprimeDeframer(const char* const compName) : FprimeDeframerComponentBase(compName) {} | ||
|
||
FprimeDeframer ::~FprimeDeframer() {} |
Check notice
Code scanning / CodeQL
More than one statement per line Note
} | ||
// Deallocate the buffer | ||
this->bufferDeallocate_out(0, buffer); | ||
} |
Check notice
Code scanning / CodeQL
Long function without assertion Note
namespace Svc { | ||
namespace FrameDetectors { | ||
|
||
FrameDetector::Status FprimeFrameDetector::detect(const Types::CircularBuffer& data, FwSizeType& size_out) const { |
Check notice
Code scanning / CodeQL
Long function without assertion Note
// Component construction and destruction | ||
// ---------------------------------------------------------------------- | ||
|
||
Router ::Router(const char* const compName) : RouterComponentBase(compName) {} |
Check notice
Code scanning / CodeQL
More than one statement per line Note
|
||
Router ::Router(const char* const compName) : RouterComponentBase(compName) {} | ||
|
||
Router ::~Router() {} |
Check notice
Code scanning / CodeQL
More than one statement per line Note
// Handler implementations for user-defined typed input ports | ||
// ---------------------------------------------------------------------- | ||
|
||
void Router ::dataIn_handler(NATIVE_INT_TYPE portNum, Fw::Buffer& packetBuffer, Fw::Buffer& contextBuffer) { |
Check notice
Code scanning / CodeQL
Function too long Note
// Handler implementations for user-defined typed input ports | ||
// ---------------------------------------------------------------------- | ||
|
||
void Router ::dataIn_handler(NATIVE_INT_TYPE portNum, Fw::Buffer& packetBuffer, Fw::Buffer& contextBuffer) { |
Check notice
Code scanning / CodeQL
Long function without assertion Note
data.setData(data.getData() + FprimeProtocol::FrameHeader::SERIALIZED_SIZE); | ||
data.setSize(data.getSize() - FprimeProtocol::FrameHeader::SERIALIZED_SIZE - FprimeProtocol::FrameTrailer::SERIALIZED_SIZE); | ||
|
||
this->deframedOut_out(0, data, context); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
bool recoverable = false; | ||
FW_ASSERT(std::numeric_limits<NATIVE_INT_TYPE>::max() >= store_size, static_cast<FwAssertArgType>(store_size)); | ||
NATIVE_UINT_TYPE store_size_int = static_cast<NATIVE_UINT_TYPE>(store_size); | ||
void* data_void = allocator.allocate(allocationId, store_size_int, recoverable); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
bool recoverable = false; | ||
FW_ASSERT(std::numeric_limits<NATIVE_INT_TYPE>::max() >= store_size, static_cast<FwAssertArgType>(store_size)); | ||
NATIVE_UINT_TYPE store_size_int = static_cast<NATIVE_UINT_TYPE>(store_size); | ||
void* data_void = allocator.allocate(allocationId, store_size_int, recoverable); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
U8* data = new(data_void) U8[store_size_int]; | ||
FW_ASSERT(data != nullptr); | ||
FW_ASSERT(store_size_int >= store_size); | ||
m_inRing.setup(data, store_size_int); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
// Check whether there is data to process | ||
if (status.e == Drv::RecvStatus::RECV_OK) { | ||
// There is: process the data | ||
this->processBuffer(buffer); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
FwPacketDescriptorType packetType = Fw::ComPacket::FW_PACKET_UNKNOWN; | ||
Fw::SerializeStatus status = Fw::FW_SERIALIZE_OK; | ||
{ | ||
Fw::SerializeBufferBase& serial = packetBuffer.getSerializeRepr(); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
Utils::HashBuffer hashBuffer; | ||
|
||
// Compute CRC over the transmitted data (header + body) | ||
FwSizeType hash_field_size = header.getlength() + FprimeProtocol::FrameHeader::SERIALIZED_SIZE; |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
// Component construction and destruction | ||
// ---------------------------------------------------------------------- | ||
|
||
FrameAccumulator ::FrameAccumulator(const char* const compName) |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
} | ||
|
||
void FrameAccumulator ::configure(const FrameDetector& detector, | ||
NATIVE_UINT_TYPE allocationId, |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
void FrameAccumulator ::configure(const FrameDetector& detector, | ||
NATIVE_UINT_TYPE allocationId, | ||
Fw::MemAllocator& allocator, | ||
FwSizeType store_size) { |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
break; | ||
} | ||
// Compute the size of data to serialize | ||
const NATIVE_UINT_TYPE ringFreeSize = this->m_inRing.get_free_size(); |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
} | ||
// Compute the size of data to serialize | ||
const NATIVE_UINT_TYPE ringFreeSize = this->m_inRing.get_free_size(); | ||
const NATIVE_UINT_TYPE serSize = |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
// The protocol status | ||
FrameDetector::Status status = FrameDetector::Status::FRAME_DETECTED; | ||
// The ring buffer capacity | ||
const NATIVE_UINT_TYPE ringCapacity = this->m_inRing.get_capacity(); |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
break; | ||
} | ||
// size_out is a return variable we initialize to zero, but it should be overwritten | ||
FwSizeType size_out = 0; |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
U8* m_memory; | ||
|
||
//! Identification used with the memory allocator | ||
NATIVE_UINT_TYPE m_allocatorId; |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
FW_ASSERT(this->m_inRing.peek(buffer.getData(), static_cast<NATIVE_UINT_TYPE>(size_out)) == | ||
Fw::SerializeStatus::FW_SERIALIZE_OK); |
Check warning
Code scanning / CodeQL
Side effect in a Boolean expression Warning
FW_ASSERT(this->m_inRing.peek(buffer.getData(), static_cast<NATIVE_UINT_TYPE>(size_out)) == | ||
Fw::SerializeStatus::FW_SERIALIZE_OK); | ||
buffer.setSize(static_cast<U32>(size_out)); | ||
m_inRing.rotate(static_cast<U32>(size_out)); |
Check warning
Code scanning / CodeQL
Unchecked return value Warning
rotate
// If the deserialized length token can't fit in current allocated size -> MORE_DATA_NEEDED | ||
if (data.get_allocated_size() < FprimeProtocol::FrameHeader::SERIALIZED_SIZE + header.getlength() + | ||
FprimeProtocol::FrameTrailer::SERIALIZED_SIZE) { | ||
size_out = header.getlength() + FprimeProtocol::FrameHeader::SERIALIZED_SIZE + |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
// Add Status::DATA_ERROR , and use it for deserialization errors as well? | ||
return Status::NO_FRAME_DETECTED; | ||
} | ||
size_out = header.getlength() + FprimeProtocol::FrameHeader::SERIALIZED_SIZE + |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
m_detector(nullptr), | ||
m_memoryAllocator(nullptr), | ||
m_memory(nullptr), | ||
m_allocatorId(0) {} |
Check notice
Code scanning / CodeQL
More than one statement per line Note
} | ||
} | ||
|
||
void FrameAccumulator ::configure(const FrameDetector& detector, |
Check notice
Code scanning / CodeQL
Long function without assertion Note
FW_ASSERT(remaining == 0 || this->m_inRing.get_free_size() == 0, static_cast<FwAssertArgType>(remaining)); | ||
} | ||
|
||
void FrameAccumulator ::processRing() { |
Check notice
Code scanning / CodeQL
Function too long Note
FW_ASSERT(remaining == 0 || this->m_inRing.get_free_size() == 0, static_cast<FwAssertArgType>(remaining)); | ||
} | ||
|
||
void FrameAccumulator ::processRing() { |
Check notice
Code scanning / CodeQL
Long function without assertion Note
break; | ||
} | ||
// Take no action for other packet types | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to emit these on a third output port so that custom routing can be extended easily?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do like that. Send everything else unknown to a third output port and if connected. WARNING_HI if not connected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of minor changes, but this is looking to be in really good shape!
@@ -13,6 +13,7 @@ module Ref { | |||
enum Ports_StaticMemory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You aren't using this anymore. Delete it.
) | ||
|
||
set(MOD_DEPS | ||
Svc/FramingProtocol |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a dependency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not be anymore - will remove. We should probably capture a follow-up ticket to look into whether we can do some cleanup in the FramingProtocol itself
@@ -119,6 +119,11 @@ typedef U32 FwDpIdType; | |||
typedef U32 FwDpPriorityType; | |||
#define PRI_FwDpPriorityType PRIu32 | |||
|
|||
// Type for start word and length word used in fprime framing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this.
@@ -0,0 +1,8 @@ | |||
@ Receiving data (Fw::Buffer) to be routed with optional context to help with routing | |||
guarded input port dataIn: Fw.DataWithContext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the data is just routed. This could be sync
as no modifications of internal data is done. Right?
if (status == Fw::FW_SERIALIZE_OK) { | ||
// Send the com buffer | ||
commandOut_out(0, com, 0); | ||
// REVIEW NOTE: Deframer did not check if the output port was connected, should it? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was done because it was presumed to be an error if data paths weren't connected. Since this is critical for base functionality, leave a comment. Users could always add in a dev-null "cap" component to explicitly discard.
@@ -0,0 +1,17 @@ | |||
module Svc { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For completeness, should this be an interface too?
title: "F Prime Frame Format" | ||
--- | ||
packet-beta | ||
0-31: "Start word: 0xDEADBEEF [4 bytes]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically aren't these intended to be configurable?
@@ -0,0 +1,166 @@ | |||
// ====================================================================== |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might need to reimport this code, if and when my PR merges that changes types.
FW_ASSERT(size_out != 0); | ||
FW_ASSERT(size_out <= remaining, static_cast<FwAssertArgType>(size_out), | ||
static_cast<FwAssertArgType>(remaining)); | ||
Fw::Buffer buffer = this->bufferAllocate_out(0, static_cast<U32>(size_out)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to check for overflow from FwSizeType to U32
Fw::Buffer nullContext; | ||
this->frameOut_out(0, buffer, nullContext); | ||
} else { | ||
// No buffer is available, we need to exit and try again later |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should produce an event in this case. Probably a WARNING_HI
Change Description
(GitHub doesn't let me re-open #2900 for some reason..., so re-opening here)
Implements #2763
Split up Deframer into 3 components:
Rationale
Better reusability and chaining of deframers, preliminary work for CCSDS integrations
TODO
!!! UPDATE
fprime-util new --deployment
To discuss