diff --git a/src/traction_modem/Link.cxxtest b/src/traction_modem/Link.cxxtest index ffa6f0b7d..4365641c2 100644 --- a/src/traction_modem/Link.cxxtest +++ b/src/traction_modem/Link.cxxtest @@ -298,6 +298,7 @@ TEST_F(LinkTest, LinkUpMaxDelay) Defs::append_uint8(&b->data()->payload, 0); Defs::append_uint8(&b->data()->payload, 0); Defs::append_crc(&b->data()->payload); + mRxFlow_.trigger_packet_rx_callback(); static_cast(&linkManager_)->send(b); wait_for_main_executor(); testing::Mock::VerifyAndClearExpectations(&mTxFlow_); diff --git a/src/traction_modem/Link.hxx b/src/traction_modem/Link.hxx index 1757e8f70..2ac7bf563 100644 --- a/src/traction_modem/Link.hxx +++ b/src/traction_modem/Link.hxx @@ -205,6 +205,8 @@ public: , useDefaultBaud_(use_default_baud) { link_->register_link_status(this); + link_->get_rx_iface()->register_packet_rx_callback( + std::bind(&LinkManager::packet_rx_callback, this)); } #if defined(GTEST) @@ -227,6 +229,19 @@ private: /// Alias for short response timeout used during link establishment. static constexpr long long RESP_TIMEOUT = Defs::RESP_TIMEOUT_SHORT; + // Callback for when any packet is received. + void packet_rx_callback() + { + if (link_->is_link_up()) + { + // Note: link_is_down() is technically the "next" state, if + // the link fails (timer_ expires without pong). + HASSERT(is_state(STATE(link_is_down))); + // Everything is good, don't trigger an early timer_ wakeup. + timer_.restart(); + } + } + /// Called when the link is started. void on_link_start() override { @@ -338,14 +353,10 @@ private: switch(buf->data()->command()) { case Defs::RESP_PING: + /// @todo This is a good place to extract the revision info. if (link_->is_link_up()) { - // Note: link_is_down() is technically the "next" state, if - // the link fails (timer_ expires without pong). - HASSERT(is_state(STATE(link_is_down))); - // Everything is good, don't trigger an early timer_ wakeup. - timer_.restart(); - return; + return; } break; case Defs::RESP_BAUD_RATE_QUERY: diff --git a/src/traction_modem/RxFlow.hxx b/src/traction_modem/RxFlow.hxx index d2e7940cb..947aabd54 100644 --- a/src/traction_modem/RxFlow.hxx +++ b/src/traction_modem/RxFlow.hxx @@ -83,9 +83,18 @@ public: { return resyncCount_; } + + /// Register for a callback when any packet is received. + virtual void register_packet_rx_callback(std::function callback) + { + pktRxCallback_ = callback; + } + protected: /// Track the number of times that we try to resync. unsigned resyncCount_{0}; + /// Callback for when any packet is received. + std::function pktRxCallback_; }; /// Object responsible for reading in a stream of bytes over the modem @@ -323,6 +332,10 @@ private: auto *b = dispatcher_.alloc(); b->data()->payload = std::move(payload_); + if (pktRxCallback_) + { + pktRxCallback_(); + } dispatcher_.send(b); if (payload_tmp.size()) diff --git a/src/traction_modem/modem_test_helper.hxx b/src/traction_modem/modem_test_helper.hxx index 10ca513ab..09deaabfd 100644 --- a/src/traction_modem/modem_test_helper.hxx +++ b/src/traction_modem/modem_test_helper.hxx @@ -19,6 +19,14 @@ public: void(PacketFlowInterface*, Message::id_type, Message::id_type)); MOCK_METHOD1(unregister_handler_all, void(PacketFlowInterface*)); MOCK_METHOD1(register_fallback_handler, void(PacketFlowInterface*)); + + void trigger_packet_rx_callback() + { + if (pktRxCallback_) + { + pktRxCallback_(); + } + } }; class MyMockRxFlow : public MockRxFlow @@ -104,6 +112,7 @@ protected: Defs::append_uint8(&b->data()->payload, 0); Defs::append_uint8(&b->data()->payload, 0); Defs::append_crc(&b->data()->payload); + mRxFlow_.trigger_packet_rx_callback(); static_cast(&linkManager_)->send(b); } } @@ -147,6 +156,7 @@ protected: Defs::append_uint8(&b->data()->payload, 0); Defs::append_uint8(&b->data()->payload, 0); Defs::append_crc(&b->data()->payload); + mRxFlow_.trigger_packet_rx_callback(); static_cast(&linkManager_)->send(b); wait_for_main_executor(); EXPECT_TRUE(link_.is_link_up());