Skip to content
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

Traction Modem #807

Merged
merged 20 commits into from
Jan 27, 2025
Merged

Traction Modem #807

merged 20 commits into from
Jan 27, 2025

Conversation

bakerstu
Copy link
Owner

@bakerstu bakerstu commented Jan 13, 2025

Adds a modem protocol implementation.

  • TxFlow and RxFlow are in good shape.
  • Future work shall refactor the RxFlow "Receiver" to be more generic and utilize a dispatcher.
  • Future work shall incorporate a CRC 16 CCITT implementation in utils/Crc.hxx/cxx.
  • Future work may push the "ModemTrain" object to be application specific, possible with a bare bones example provided in the common platform tree.
  • Fixed some lcov build issues related to the latest lcov version.

@bakerstu bakerstu requested a review from balazsracz January 13, 2025 22:03
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're adding a new subdirectory, please run make on the toplevel to add these files to all targets.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

#include "openlcb/TrainInterface.hxx"
#include "utils/format_utils.hxx"

namespace tractionmodem
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you like to rename this namespace to traction_modem as well?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Why not.

src/traction_modem/TractionModem.hxx Show resolved Hide resolved
// which is the heap allocator, and that the heap allocator will
// allocate memory on (at least) the native machine size boundary.
// This is important in order to be able to cast payload_.data()
// to a Defs::Message type for easier decoding.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Otherwise if the architecture supports unaligned 32-bit reads, then we are fine for all allocators.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

crc3_crc16_ccitt(
payload_.data() + sizeof(uint32_t),
payload_.size() - (sizeof(uint32_t) + sizeof(crc_calc)),
crc_calc.crc);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is confusing that this does not need an & like &crc_calc.crc.
I understand why it doesn't, but it shows that the Defs::CRC is not a well encapsulated type.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I agree with the statement "Defs::CRC is not a well encapsulated type". However, I changed the way I pass this in to make it a bit more clear.

src/traction_modem/TractionModemDefs.cxxtest Outdated Show resolved Hide resolved
src/traction_modem/TractionModem.cxxtest Show resolved Hide resolved
class MockPacketFlowInterface : public TestPacketFlowInterface
{
public:
MOCK_METHOD2(send, void(std::string &, unsigned));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't need to be a separate class, but it can go straight into the TestPacketFlowInterface

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes. Good call. Fixed.


// Wait for exit.
wait_for_main_executor();
while (!g_executor.active_timers()->empty())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this code exists in async_if_test_helper.hxx already (called twait()), it would make sense to move it to test_main.hxx and call it wait_for_main_timers().

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

wait_for_main_executor();
testing::Mock::VerifyAndClearExpectations(&mPFI_);

// Send a message in pieces in order to exercise some of the other paths.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add another test where we send two packets in one ::write() command and expect both of those to arrive.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Added.

@bakerstu bakerstu requested a review from balazsracz January 26, 2025 17:43
@@ -116,6 +116,18 @@ void wait_for_main_executor()
guard->wait_for_notification();
}

/** Delays the current thread until all asynchronous processing and all
* pending timers have completed. */
void wait_for_main_timers()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also make twait() in async_if_test_helper.hxx call this function

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

src/traction_modem/TractionModem.hxx Show resolved Hide resolved
@@ -358,6 +390,11 @@ private:
// allocation.
memmove(&payload_[0], &payload_[idx], recvCnt_ - idx);
recvCnt_ -= idx;
size_t new_size =
recvCnt_ < MIN_MESSAGE_SIZE ? MIN_MESSAGE_SIZE : recvCnt_;
payload_.resize(new_size);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we resize here? The comment just above says that we are purposefully not resizing.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct. This is not needed. I had already made the necessary improvements elsewhere so that this is not needed. Removed.

@@ -364,10 +364,12 @@ struct Defs
/// @param p wire formatted payload
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assumption is that this is a valid (correctly formatted) message.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I improved the comment and...

  • removed the unused preamble_prepended parameter, which is not needed
  • added a "length" parameter for efficiency because it is already been extracted by the caller anyways

}

/// This is the memory space we will be using on the decoder.
uint8_t proxySpace_ = openlcb::MemoryConfigDefs::SPACE_DCC_CV;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this fix.

@bakerstu bakerstu merged commit e35c58d into master Jan 27, 2025
4 checks passed
@bakerstu bakerstu deleted the bakerstu-traction-modem branch January 27, 2025 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants