Skip to content

Commit

Permalink
Ensure broadcast time sync (#656)
Browse files Browse the repository at this point in the history
* Provide an API for asynchronous Broadcast Time query.

* Add a Broadcast Time sync when a time consumer (range) is identified.

* Add unit test.
  • Loading branch information
bakerstu authored Sep 22, 2022
1 parent 769c62a commit 54fa437
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
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

0 comments on commit 54fa437

Please sign in to comment.