blob: 778c2e72121cde2d1f8ca83bfc574f2bc272b41f [file] [log] [blame]
Austin Schuh36a2c3e2021-02-18 22:28:38 -08001#include "aos/network/timestamp_channel.h"
2
3#include "absl/strings/str_cat.h"
4
Austin Schuh349e7ad2022-04-02 21:12:26 -07005DEFINE_bool(combined_timestamp_channel_fallback, true,
6 "If true, fall back to using the combined timestamp channel if the "
7 "single timestamp channel doesn't exist for a timestamp.");
James Kuszmaule339c852023-02-13 14:54:03 -08008DEFINE_bool(check_timestamp_channel_frequencies, true,
9 "If true, include a debug CHECK to ensure that remote timestamp "
10 "channels are configured to have at least as great a frequency as "
11 "the corresponding data channel.");
Austin Schuh349e7ad2022-04-02 21:12:26 -070012
Stephan Pleinesf63bde82024-01-13 15:59:33 -080013namespace aos::message_bridge {
Austin Schuh36a2c3e2021-02-18 22:28:38 -080014
Austin Schuh61e973f2021-02-21 21:43:56 -080015ChannelTimestampFinder::ChannelTimestampFinder(
16 const Configuration *configuration, const std::string_view name,
17 const Node *node)
18 : configuration_(configuration), name_(name), node_(node) {}
19
20std::string ChannelTimestampFinder::SplitChannelName(
21 const Channel *channel, const Connection *connection) {
Austin Schuh349e7ad2022-04-02 21:12:26 -070022 return SplitChannelName(channel->name()->string_view(),
23 channel->type()->str(), connection);
Austin Schuh006a9f52021-04-07 16:24:18 -070024}
25
26std::string ChannelTimestampFinder::SplitChannelName(
27 std::string_view name, std::string type, const Connection *connection) {
Austin Schuh61e973f2021-02-21 21:43:56 -080028 std::replace(type.begin(), type.end(), '.', '-');
29 return absl::StrCat("/aos/remote_timestamps/",
Austin Schuh006a9f52021-04-07 16:24:18 -070030 connection->name()->string_view(), name, "/", type);
Austin Schuh61e973f2021-02-21 21:43:56 -080031}
32
33std::string ChannelTimestampFinder::CombinedChannelName(
34 std::string_view remote_node) {
35 return absl::StrCat("/aos/remote_timestamps/", remote_node);
36}
37
Austin Schuh01f3b392022-01-25 20:03:09 -080038const Channel *ChannelTimestampFinder::SplitChannelForChannel(
39 const Channel *channel, const Connection *connection) {
40 const std::string split_timestamp_channel_name =
41 SplitChannelName(channel, connection);
42 return configuration::GetChannel(configuration_, split_timestamp_channel_name,
43 RemoteMessage::GetFullyQualifiedName(),
44 name_, node_, true);
45}
46
Austin Schuh61e973f2021-02-21 21:43:56 -080047const Channel *ChannelTimestampFinder::ForChannel(
48 const Channel *channel, const Connection *connection) {
49 const std::string split_timestamp_channel_name =
50 SplitChannelName(channel, connection);
51 const Channel *split_timestamp_channel = configuration::GetChannel(
52 configuration_, split_timestamp_channel_name,
53 RemoteMessage::GetFullyQualifiedName(), name_, node_, true);
54 if (split_timestamp_channel != nullptr) {
55 return split_timestamp_channel;
56 }
57
Austin Schuh349e7ad2022-04-02 21:12:26 -070058 if (!FLAGS_combined_timestamp_channel_fallback) {
59 LOG(FATAL) << "Failed to find new timestamp channel {\"name\": \""
60 << split_timestamp_channel_name << "\", \"type\": \""
61 << RemoteMessage::GetFullyQualifiedName() << "\"} for "
62 << configuration::CleanedChannelToString(channel)
63 << " connection " << aos::FlatbufferToJson(connection)
64 << " and --nocombined_timestamp_channel_fallback is set";
65 }
66
Austin Schuh61e973f2021-02-21 21:43:56 -080067 const std::string shared_timestamp_channel_name =
68 CombinedChannelName(connection->name()->string_view());
69 const Channel *shared_timestamp_channel = configuration::GetChannel(
70 configuration_, shared_timestamp_channel_name,
71 RemoteMessage::GetFullyQualifiedName(), name_, node_, true);
72 if (shared_timestamp_channel != nullptr) {
73 LOG(WARNING) << "Failed to find timestamp channel {\"name\": \""
James Kuszmaul9c128122021-03-22 22:24:36 -070074 << split_timestamp_channel_name << "\", \"type\": \""
Austin Schuh61e973f2021-02-21 21:43:56 -080075 << RemoteMessage::GetFullyQualifiedName()
76 << "\"}, falling back to old version.";
77 return shared_timestamp_channel;
78 }
79
80 CHECK(shared_timestamp_channel != nullptr)
81 << ": Remote timestamp channel { \"name\": \""
82 << split_timestamp_channel_name << "\", \"type\": \""
83 << RemoteMessage::GetFullyQualifiedName()
84 << "\" } not found in config for " << name_
85 << (configuration::MultiNode(configuration_)
86 ? absl::StrCat(" on node ", node_->name()->string_view())
87 : ".");
88
89 return nullptr;
90}
91
Austin Schuh36a2c3e2021-02-18 22:28:38 -080092ChannelTimestampSender::ChannelTimestampSender(aos::EventLoop *event_loop)
93 : event_loop_(event_loop) {
Austin Schuh58646e22021-08-23 23:51:46 -070094 if (event_loop_) {
95 CHECK(configuration::MultiNode(event_loop_->configuration()));
96 }
Austin Schuh36a2c3e2021-02-18 22:28:38 -080097}
98
99aos::Sender<RemoteMessage> *ChannelTimestampSender::SenderForChannel(
100 const Channel *channel, const Connection *connection) {
Austin Schuh58646e22021-08-23 23:51:46 -0700101 CHECK(event_loop_);
102
Austin Schuh61e973f2021-02-21 21:43:56 -0800103 ChannelTimestampFinder finder(event_loop_);
Austin Schuh36a2c3e2021-02-18 22:28:38 -0800104 // Look at any pre-created channel/connection pairs.
Austin Schuh61e973f2021-02-21 21:43:56 -0800105 {
106 auto it =
107 channel_timestamp_loggers_.find(std::make_pair(channel, connection));
108 if (it != channel_timestamp_loggers_.end()) {
109 return it->second.get();
110 }
Austin Schuh36a2c3e2021-02-18 22:28:38 -0800111 }
112
Austin Schuh61e973f2021-02-21 21:43:56 -0800113 const Channel *timestamp_channel = finder.ForChannel(channel, connection);
Austin Schuh36a2c3e2021-02-18 22:28:38 -0800114
James Kuszmaule339c852023-02-13 14:54:03 -0800115 if (FLAGS_check_timestamp_channel_frequencies) {
116 // Sanity-check that the timestamp channel can actually support full-rate
117 // messages coming through on the source channel.
118 CHECK_GE(timestamp_channel->frequency(), channel->frequency())
119 << ": Timestamp channel "
120 << configuration::StrippedChannelToString(timestamp_channel)
121 << "'s rate is lower than the source channel.";
122 }
James Kuszmaul839c8aa2023-01-10 15:27:57 -0800123
Austin Schuh61e973f2021-02-21 21:43:56 -0800124 {
125 auto it = timestamp_loggers_.find(timestamp_channel);
126 if (it != timestamp_loggers_.end()) {
127 CHECK(channel_timestamp_loggers_
128 .try_emplace(std::make_pair(channel, connection), it->second)
129 .second);
130 return it->second.get();
Austin Schuh36a2c3e2021-02-18 22:28:38 -0800131 }
Austin Schuh36a2c3e2021-02-18 22:28:38 -0800132 }
Austin Schuh61e973f2021-02-21 21:43:56 -0800133
134 auto result = channel_timestamp_loggers_.try_emplace(
135 std::make_pair(channel, connection),
136 std::make_shared<aos::Sender<RemoteMessage>>(
137 event_loop_->MakeSender<RemoteMessage>(
138 timestamp_channel->name()->string_view())));
139
140 CHECK(timestamp_loggers_.try_emplace(timestamp_channel, result.first->second)
141 .second);
142 return result.first->second.get();
Austin Schuh36a2c3e2021-02-18 22:28:38 -0800143}
144
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800145} // namespace aos::message_bridge