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

Ensure broadcast time sync #656

Merged
merged 3 commits into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/openlcb/BroadcastTime.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ public:
new SetFlow(this, SetFlow::Command::STOP);
}

/// Query the current time.
void query()
{
new SetFlow(this, SetFlow::Command::QUERY);
}

/// Get the time as a value of seconds relative to the system epoch. At the
/// same time get an atomic matching pair of the rate
/// @return pair<time in seconds relative to the system epoch, rate>
Expand Down Expand Up @@ -416,6 +422,7 @@ protected:
SET_RATE, ///< set rate request
START, ///< stop request
STOP, ///< start request
QUERY, ///< issue a query
};

/// Constructor.
Expand Down Expand Up @@ -471,6 +478,10 @@ protected:
event_id = clock_->event_base() |
BroadcastTimeDefs::STOP_EVENT_SUFFIX;
break;
case QUERY:
event_id = clock_->event_base() |
BroadcastTimeDefs::QUERY_EVENT_SUFFIX;
break;
default:
// should never get here.
LOG_ERROR("Unhanded SetFlow command");
Expand Down
17 changes: 17 additions & 0 deletions src/openlcb/BroadcastTimeServer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,23 @@ void BroadcastTimeServer::handle_consumer_identified(
}
}

/// Called on another node sending ConsumerRangeIdentified. @param event
/// stores information about the incoming message. Filled: event id, mask
/// (!= 1), src_node. Not filled: state. @param registry_entry gives the
/// registry entry for which the current handler is being called. @param
/// done must be notified when the processing is done.
void BroadcastTimeServer::handle_consumer_range_identified(
const EventRegistryEntry &registry_entry, EventReport *event,
BarrierNotifiable *done)
{
done->notify();
if (event->event == eventBase_ && event->mask == 0xFFFF)
{
// A new time client was identified, send a time sync.
sync_->request_sync();
}
}

//
// BroadcastTimeServer::handle_event_report()
//
Expand Down
23 changes: 23 additions & 0 deletions src/openlcb/BroadcastTimeServer.cxxtest
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,29 @@ TEST_F(BroadcastTimeServerTest, Query)
EXPECT_EQ(server_->day_of_year(), 0);
};

TEST_F(BroadcastTimeServerTest, DiscoverConsumerRange)
{
FakeClock clk;
::testing::Sequence s1;

clear_expect(true);

// sync response
expect_packet(":X1954422AN010100000100F001;").InSequence(s1);
expect_packet(":X1954422AN0101000001004000;").InSequence(s1);
expect_packet(":X1954422AN01010000010037B2;").InSequence(s1);
expect_packet(":X1954422AN0101000001002101;").InSequence(s1);
expect_packet(":X1954422AN0101000001000000;").InSequence(s1);

send_packet(":X194A4001N010100000100FFFF;"); // consumer range identified
wait();

// time is not setup, clock is not running, expect 0 as default
EXPECT_EQ(server_->time(), 0);
EXPECT_EQ(server_->day_of_week(), BroadcastTimeDefs::THURSDAY);
EXPECT_EQ(server_->day_of_year(), 0);
}

TEST_F(BroadcastTimeServerTest, StartSetTime)
{
FakeClock clk;
Expand Down
10 changes: 10 additions & 0 deletions src/openlcb/BroadcastTimeServer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ private:
EventReport *event,
BarrierNotifiable *done) override;


/// Called on another node sending ConsumerRangeIdentified. @param event
/// stores information about the incoming message. Filled: event id, mask
/// (!= 1), src_node. Not filled: state. @param registry_entry gives the
/// registry entry for which the current handler is being called. @param
/// done must be notified when the processing is done.
void handle_consumer_range_identified(
const EventRegistryEntry &registry_entry, EventReport *event,
BarrierNotifiable *done) override;

/// Handle an incoming event report.
/// @param entry registry entry for the event range
/// @param event information about the incoming message
Expand Down