Merge "Ignore pitch from camera readings"
diff --git a/aos/configuration.cc b/aos/configuration.cc
index 25d59ff..b388bd3 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -272,55 +272,6 @@
return a->name()->string_view() == name;
}
-// Maps name for the provided maps. Modifies name.
-void HandleMaps(const flatbuffers::Vector<flatbuffers::Offset<aos::Map>> *maps,
- std::string *name, std::string_view type, const Node *node) {
- // For the same reason we merge configs in reverse order, we want to process
- // maps in reverse order. That lets the outer config overwrite channels from
- // the inner configs.
- for (auto i = maps->rbegin(); i != maps->rend(); ++i) {
- if (!i->has_match() || !i->match()->has_name()) {
- continue;
- }
- if (!i->has_rename() || !i->rename()->has_name()) {
- continue;
- }
-
- // Handle normal maps (now that we know that match and rename are filled
- // out).
- const std::string_view match_name = i->match()->name()->string_view();
- if (match_name != *name) {
- if (match_name.back() == '*' &&
- std::string_view(*name).substr(
- 0, std::min(name->size(), match_name.size() - 1)) ==
- match_name.substr(0, match_name.size() - 1)) {
- CHECK_EQ(match_name.find('*'), match_name.size() - 1);
- } else {
- continue;
- }
- }
-
- // Handle type specific maps.
- if (i->match()->has_type() && i->match()->type()->string_view() != type) {
- continue;
- }
-
- // Now handle node specific maps.
- if (node != nullptr && i->match()->has_source_node() &&
- i->match()->source_node()->string_view() !=
- node->name()->string_view()) {
- continue;
- }
-
- std::string new_name(i->rename()->name()->string_view());
- if (match_name.back() == '*') {
- new_name += std::string(name->substr(match_name.size() - 1));
- }
- VLOG(1) << "Renamed \"" << *name << "\" to \"" << new_name << "\"";
- *name = std::move(new_name);
- }
-}
-
void ValidateConfiguration(const Flatbuffer<Configuration> &config) {
// No imports should be left.
CHECK(!config.message().has_imports());
@@ -419,6 +370,55 @@
} // namespace
+// Maps name for the provided maps. Modifies name.
+void HandleMaps(const flatbuffers::Vector<flatbuffers::Offset<aos::Map>> *maps,
+ std::string *name, std::string_view type, const Node *node) {
+ // For the same reason we merge configs in reverse order, we want to process
+ // maps in reverse order. That lets the outer config overwrite channels from
+ // the inner configs.
+ for (auto i = maps->rbegin(); i != maps->rend(); ++i) {
+ if (!i->has_match() || !i->match()->has_name()) {
+ continue;
+ }
+ if (!i->has_rename() || !i->rename()->has_name()) {
+ continue;
+ }
+
+ // Handle normal maps (now that we know that match and rename are filled
+ // out).
+ const std::string_view match_name = i->match()->name()->string_view();
+ if (match_name != *name) {
+ if (match_name.back() == '*' &&
+ std::string_view(*name).substr(
+ 0, std::min(name->size(), match_name.size() - 1)) ==
+ match_name.substr(0, match_name.size() - 1)) {
+ CHECK_EQ(match_name.find('*'), match_name.size() - 1);
+ } else {
+ continue;
+ }
+ }
+
+ // Handle type specific maps.
+ if (i->match()->has_type() && i->match()->type()->string_view() != type) {
+ continue;
+ }
+
+ // Now handle node specific maps.
+ if (node != nullptr && i->match()->has_source_node() &&
+ i->match()->source_node()->string_view() !=
+ node->name()->string_view()) {
+ continue;
+ }
+
+ std::string new_name(i->rename()->name()->string_view());
+ if (match_name.back() == '*') {
+ new_name += std::string(name->substr(match_name.size() - 1));
+ }
+ VLOG(1) << "Renamed \"" << *name << "\" to \"" << new_name << "\"";
+ *name = std::move(new_name);
+ }
+}
+
FlatbufferDetachedBuffer<Configuration> MergeConfiguration(
const Flatbuffer<Configuration> &config) {
// auto_merge_config will contain all the fields of the Configuration that are
diff --git a/aos/events/logging/log_reader.cc b/aos/events/logging/log_reader.cc
index 2eb3094..05555c6 100644
--- a/aos/events/logging/log_reader.cc
+++ b/aos/events/logging/log_reader.cc
@@ -39,6 +39,12 @@
"The time to buffer ahead in the log file to accurately reconstruct time.");
namespace aos {
+namespace configuration {
+// We don't really want to expose this publicly, but log reader doesn't really
+// want to re-implement it.
+void HandleMaps(const flatbuffers::Vector<flatbuffers::Offset<aos::Map>> *maps,
+ std::string *name, std::string_view type, const Node *node);
+}
namespace logger {
namespace {
@@ -892,6 +898,65 @@
nullptr));
channel_offsets.emplace_back(
CopyChannel(c, pair.second.remapped_name, "", &fbb));
+
+ if (c->has_destination_nodes()) {
+ for (const Connection *connection : *c->destination_nodes()) {
+ switch (connection->timestamp_logger()) {
+ case LoggerConfig::LOCAL_LOGGER:
+ case LoggerConfig::NOT_LOGGED:
+ // There is no timestamp channel associated with this, so ignore it.
+ break;
+
+ case LoggerConfig::REMOTE_LOGGER:
+ case LoggerConfig::LOCAL_AND_REMOTE_LOGGER:
+ // We want to make a split timestamp channel regardless of what type
+ // of log this used to be. No sense propagating the single
+ // timestamp channel.
+
+ CHECK(connection->has_timestamp_logger_nodes());
+ for (const flatbuffers::String *timestamp_logger_node :
+ *connection->timestamp_logger_nodes()) {
+ const Node *node = configuration::GetNode(
+ logged_configuration(), timestamp_logger_node->string_view());
+ message_bridge::ChannelTimestampFinder finder(
+ logged_configuration(), "log_reader", node);
+
+ // We are assuming here that all the maps are setup correctly to
+ // handle arbitrary timestamps. Apply the maps for this node to
+ // see what name this ends up with.
+ std::string name = finder.SplitChannelName(
+ pair.second.remapped_name, c->type()->str(), connection);
+ std::string unmapped_name = name;
+ configuration::HandleMaps(logged_configuration()->maps(), &name,
+ "aos.message_bridge.RemoteMessage",
+ node);
+ CHECK_NE(name, unmapped_name)
+ << ": Remote timestamp channel was not remapped, this is "
+ "very fishy";
+ flatbuffers::Offset<flatbuffers::String> channel_name_offset =
+ fbb.CreateString(name);
+ flatbuffers::Offset<flatbuffers::String> channel_type_offset =
+ fbb.CreateString("aos.message_bridge.RemoteMessage");
+ flatbuffers::Offset<flatbuffers::String> source_node_offset =
+ fbb.CreateString(timestamp_logger_node->string_view());
+
+ // Now, build a channel. Don't log it, 2 senders, and match the
+ // source frequency.
+ Channel::Builder channel_builder(fbb);
+ channel_builder.add_name(channel_name_offset);
+ channel_builder.add_type(channel_type_offset);
+ channel_builder.add_source_node(source_node_offset);
+ channel_builder.add_logger(LoggerConfig::NOT_LOGGED);
+ channel_builder.add_num_senders(2);
+ if (c->has_frequency()) {
+ channel_builder.add_frequency(c->frequency());
+ }
+ channel_offsets.emplace_back(channel_builder.Finish());
+ }
+ break;
+ }
+ }
+ }
}
// Now reconstruct the original channels, translating types as needed
diff --git a/aos/events/logging/logger_test.cc b/aos/events/logging/logger_test.cc
index 13b2312..2b504f3 100644
--- a/aos/events/logging/logger_test.cc
+++ b/aos/events/logging/logger_test.cc
@@ -1767,6 +1767,83 @@
reader.Deregister();
}
+// Tests that we can remap a forwarded channel as well.
+TEST_P(MultinodeLoggerTest, RemapForwardedLoggedChannel) {
+ time_converter_.StartEqual();
+ {
+ LoggerState pi1_logger = MakeLogger(pi1_);
+ LoggerState pi2_logger = MakeLogger(pi2_);
+
+ event_loop_factory_.RunFor(chrono::milliseconds(95));
+
+ StartLogger(&pi1_logger);
+ StartLogger(&pi2_logger);
+
+ event_loop_factory_.RunFor(chrono::milliseconds(20000));
+ }
+
+ LogReader reader(SortParts(logfiles_));
+
+ reader.RemapLoggedChannel<examples::Ping>("/test");
+
+ SimulatedEventLoopFactory log_reader_factory(reader.configuration());
+ log_reader_factory.set_send_delay(chrono::microseconds(0));
+
+ reader.Register(&log_reader_factory);
+
+ const Node *pi1 =
+ configuration::GetNode(log_reader_factory.configuration(), "pi1");
+ const Node *pi2 =
+ configuration::GetNode(log_reader_factory.configuration(), "pi2");
+
+ // Confirm we can read the data on the remapped channel, just for pi1. Nothing
+ // else should have moved.
+ std::unique_ptr<EventLoop> pi1_event_loop =
+ log_reader_factory.MakeEventLoop("test", pi1);
+ pi1_event_loop->SkipTimingReport();
+ std::unique_ptr<EventLoop> full_pi1_event_loop =
+ log_reader_factory.MakeEventLoop("test", pi1);
+ full_pi1_event_loop->SkipTimingReport();
+ std::unique_ptr<EventLoop> pi2_event_loop =
+ log_reader_factory.MakeEventLoop("test", pi2);
+ pi2_event_loop->SkipTimingReport();
+
+ MessageCounter<examples::Ping> pi1_ping(pi1_event_loop.get(), "/test");
+ MessageCounter<examples::Ping> pi2_ping(pi2_event_loop.get(), "/test");
+ MessageCounter<examples::Ping> pi1_original_ping(pi1_event_loop.get(),
+ "/original/test");
+ MessageCounter<examples::Ping> pi2_original_ping(pi2_event_loop.get(),
+ "/original/test");
+
+ std::unique_ptr<MessageCounter<message_bridge::RemoteMessage>>
+ pi1_original_ping_timestamp;
+ std::unique_ptr<MessageCounter<message_bridge::RemoteMessage>>
+ pi1_ping_timestamp;
+ if (!shared()) {
+ pi1_original_ping_timestamp =
+ std::make_unique<MessageCounter<message_bridge::RemoteMessage>>(
+ pi1_event_loop.get(),
+ "/pi1/aos/remote_timestamps/pi2/original/test/aos-examples-Ping");
+ pi1_ping_timestamp =
+ std::make_unique<MessageCounter<message_bridge::RemoteMessage>>(
+ pi1_event_loop.get(),
+ "/pi1/aos/remote_timestamps/pi2/test/aos-examples-Ping");
+ }
+
+ log_reader_factory.Run();
+
+ EXPECT_EQ(pi1_ping.count(), 0u);
+ EXPECT_EQ(pi2_ping.count(), 0u);
+ EXPECT_NE(pi1_original_ping.count(), 0u);
+ EXPECT_NE(pi2_original_ping.count(), 0u);
+ if (!shared()) {
+ EXPECT_NE(pi1_original_ping_timestamp->count(), 0u);
+ EXPECT_EQ(pi1_ping_timestamp->count(), 0u);
+ }
+
+ reader.Deregister();
+}
+
// Tests that we properly recreate forwarded timestamps when replaying a log.
// This should be enough that we can then re-run the logger and get a valid log
// back.
diff --git a/aos/network/timestamp_channel.cc b/aos/network/timestamp_channel.cc
index bc8c1d9..bbd62c4 100644
--- a/aos/network/timestamp_channel.cc
+++ b/aos/network/timestamp_channel.cc
@@ -12,11 +12,14 @@
std::string ChannelTimestampFinder::SplitChannelName(
const Channel *channel, const Connection *connection) {
- std::string type(channel->type()->string_view());
+ return SplitChannelName(channel->name()->string_view(), channel->type()->str(), connection);
+}
+
+std::string ChannelTimestampFinder::SplitChannelName(
+ std::string_view name, std::string type, const Connection *connection) {
std::replace(type.begin(), type.end(), '.', '-');
return absl::StrCat("/aos/remote_timestamps/",
- connection->name()->string_view(),
- channel->name()->string_view(), "/", type);
+ connection->name()->string_view(), name, "/", type);
}
std::string ChannelTimestampFinder::CombinedChannelName(
diff --git a/aos/network/timestamp_channel.h b/aos/network/timestamp_channel.h
index 1702632..738ca10 100644
--- a/aos/network/timestamp_channel.h
+++ b/aos/network/timestamp_channel.h
@@ -29,6 +29,8 @@
const Connection *connection);
std::string SplitChannelName(const Channel *channel,
const Connection *connection);
+ std::string SplitChannelName(std::string_view name, std::string type,
+ const Connection *connection);
std::string CombinedChannelName(std::string_view remote_node);
private:
diff --git a/aos/starter/starter_cmd.cc b/aos/starter/starter_cmd.cc
index 8f9e125..e9b6ed5 100644
--- a/aos/starter/starter_cmd.cc
+++ b/aos/starter/starter_cmd.cc
@@ -2,6 +2,7 @@
#include <functional>
#include <iostream>
#include <optional>
+#include <string_view>
#include <unordered_map>
#include "absl/strings/str_format.h"
@@ -23,13 +24,14 @@
{"restart", aos::starter::Command::RESTART}};
void PrintKey() {
- absl::PrintF("%-30s %-30s %s\n\n", "Name", "Time since last started", "State");
+ absl::PrintF("%-30s %-30s %s\n\n", "Name", "Time since last started",
+ "State");
}
void PrintApplicationStatus(const aos::starter::ApplicationStatus *app_status,
- const aos::monotonic_clock::time_point &time) {
- const auto last_start_time =
- aos::monotonic_clock::time_point(chrono::nanoseconds(app_status->last_start_time()));
+ const aos::monotonic_clock::time_point &time) {
+ const auto last_start_time = aos::monotonic_clock::time_point(
+ chrono::nanoseconds(app_status->last_start_time()));
const auto time_running =
chrono::duration_cast<chrono::seconds>(time - last_start_time);
absl::PrintF("%-30s %-30s %s\n", app_status->name()->string_view(),
@@ -54,7 +56,8 @@
}
} else if (argc == 2) {
// Print status for the specified process.
- const char *application_name = argv[1];
+ const auto application_name =
+ aos::starter::FindApplication(argv[1], config);
auto status = aos::starter::GetStatus(application_name, config);
PrintKey();
PrintApplicationStatus(&status.message(), aos::monotonic_clock::now());
@@ -68,7 +71,6 @@
bool InteractWithProgram(int argc, char **argv,
const aos::Configuration *config) {
const char *command_string = argv[0];
-
if (argc != 2) {
LOG(ERROR) << "The \"" << command_string
<< "\" command requires an application name as an argument.";
@@ -81,8 +83,7 @@
<< "\" is not in kCommandConversions.";
const aos::starter::Command command = command_search->second;
- const char *application_name = argv[1];
-
+ const auto application_name = aos::starter::FindApplication(argv[1], config);
if (aos::starter::SendCommandBlocking(command, application_name, config,
chrono::seconds(3))) {
switch (command) {
@@ -143,7 +144,7 @@
if (parsing_failed) {
LOG(ERROR) << "Parsing failed. Valid commands are:";
- for (auto entry: kCommands) {
+ for (auto entry : kCommands) {
LOG(ERROR) << " - " << entry.first;
}
return 1;
diff --git a/aos/starter/starter_rpc_lib.cc b/aos/starter/starter_rpc_lib.cc
index 20f6f5a..67b3fb2 100644
--- a/aos/starter/starter_rpc_lib.cc
+++ b/aos/starter/starter_rpc_lib.cc
@@ -26,6 +26,19 @@
return *search;
}
+std::string_view FindApplication(const std::string_view &name,
+ const aos::Configuration *config) {
+ std::string_view app_name = name;
+ for (const auto app : *config->applications()) {
+ if (app->executable_name() != nullptr &&
+ app->executable_name()->string_view() == name) {
+ app_name = app->name()->string_view();
+ break;
+ }
+ }
+ return app_name;
+}
+
bool SendCommandBlocking(aos::starter::Command command, std::string_view name,
const aos::Configuration *config,
std::chrono::milliseconds timeout) {
@@ -127,15 +140,15 @@
aos::starter::ApplicationStatus>::Empty();
}
-std::optional<const aos::FlatbufferVector<aos::starter::Status>> GetStarterStatus(
- const aos::Configuration *config) {
+std::optional<const aos::FlatbufferVector<aos::starter::Status>>
+GetStarterStatus(const aos::Configuration *config) {
ShmEventLoop event_loop(config);
event_loop.SkipAosLog();
auto status_fetcher = event_loop.MakeFetcher<aos::starter::Status>("/aos");
status_fetcher.Fetch();
- return (status_fetcher ? std::make_optional(status_fetcher.CopyFlatBuffer()) :
- std::nullopt);
+ return (status_fetcher ? std::make_optional(status_fetcher.CopyFlatBuffer())
+ : std::nullopt);
}
} // namespace starter
diff --git a/aos/starter/starter_rpc_lib.h b/aos/starter/starter_rpc_lib.h
index 24c757e..7d6de873 100644
--- a/aos/starter/starter_rpc_lib.h
+++ b/aos/starter/starter_rpc_lib.h
@@ -16,6 +16,11 @@
const aos::starter::ApplicationStatus *FindApplicationStatus(
const aos::starter::Status &status, std::string_view name);
+// Checks if the name is an executable name and if it is, it returns that
+// application's name, otherwise returns name as given
+std::string_view FindApplication(const std::string_view &name,
+ const aos::Configuration *config);
+
// Sends the given command to the application with the name name. Creates a
// temporary event loop from the provided config for sending the command and
// receiving back status messages. Returns true if the command executed
@@ -33,8 +38,8 @@
// Fetches the entire status message of starter. Creates a temporary event loop
// from the provided config for fetching.
-std::optional<const aos::FlatbufferVector<aos::starter::Status>> GetStarterStatus(
- const aos::Configuration *config);
+std::optional<const aos::FlatbufferVector<aos::starter::Status>>
+GetStarterStatus(const aos::Configuration *config);
} // namespace starter
} // namespace aos
diff --git a/third_party/rawrtc/rawrtc-data-channel/BUILD b/third_party/rawrtc/rawrtc-data-channel/BUILD
index 096024a..500ad8b 100644
--- a/third_party/rawrtc/rawrtc-data-channel/BUILD
+++ b/third_party/rawrtc/rawrtc-data-channel/BUILD
@@ -25,6 +25,10 @@
"-Wno-cast-qual",
"-Wno-cast-align",
"-Wno-missing-braces",
+ "-DUSE_OPENSSL",
+ "-DHAVE_INET6",
+ "-DHAVE_STDBOOL_H",
+ "-DHAVE_INTTYPES_H",
],
defines = [
"RAWRTCDC_HAVE_SCTP_REDIRECT_TRANSPORT=0",
@@ -34,6 +38,6 @@
visibility = ["//visibility:public"],
deps = [
"@com_github_rawrtc_rawrtc_common//:rawrtcc",
- "@com_github_rawrtc_usrsctp//:usrsctp_crc32",
+ "@com_github_rawrtc_usrsctp//:usrsctp",
],
)
diff --git a/third_party/rawrtc/rawrtc/BUILD b/third_party/rawrtc/rawrtc/BUILD
index df14384..77416d8 100644
--- a/third_party/rawrtc/rawrtc/BUILD
+++ b/third_party/rawrtc/rawrtc/BUILD
@@ -21,6 +21,11 @@
"-Wno-cast-qual",
"-Wno-missing-braces",
"-Iexternal/com_github_rawrtc_rawrtc/",
+ "-DUSE_OPENSSL",
+ #"-DUSE_ZLIB",
+ "-DHAVE_INET6",
+ "-DHAVE_STDBOOL_H",
+ "-DHAVE_INTTYPES_H",
],
includes = ["include/"],
local_defines = [
@@ -32,3 +37,29 @@
"@com_github_rawrtc_rawrtc_data_channel//:rawrtcdc",
],
)
+
+cc_binary(
+ name = "peer-connection",
+ srcs = [
+ "tools/helper/common.c",
+ "tools/helper/common.h",
+ "tools/helper/handler.c",
+ "tools/helper/handler.h",
+ "tools/helper/parameters.c",
+ "tools/helper/parameters.h",
+ "tools/helper/utils.c",
+ "tools/helper/utils.h",
+ "tools/peer-connection.c",
+ ],
+ copts = [
+ "-Wno-missing-braces",
+ "-Wno-incompatible-pointer-types-discards-qualifiers",
+ ] + compiler_select({
+ "clang": [],
+ "gcc": [
+ "-Wno-discarded-qualifiers",
+ ],
+ }),
+ includes = ["tools"],
+ deps = [":rawrtc"],
+)
diff --git a/third_party/rawrtc/re/BUILD b/third_party/rawrtc/re/BUILD
index af720c5..63efff7 100644
--- a/third_party/rawrtc/re/BUILD
+++ b/third_party/rawrtc/re/BUILD
@@ -13,7 +13,9 @@
"src/hmac/apple/**",
"src/hmac/hmac.c",
"src/mqueue/win32/**",
- "src/tls/openssl/**",
+ "src/sha/**",
+ "src/md5/**",
+ "src/ice/ice.c",
"src/dns/win32/**",
"src/mod/win32/**",
"src/lock/lock.c",
@@ -27,6 +29,7 @@
copts = compiler_select({
"clang": [
"-Wno-incompatible-pointer-types-discards-qualifiers",
+ "-Wno-macro-redefined",
],
"gcc": [
"-Wno-discarded-qualifiers",
@@ -40,6 +43,38 @@
"-Wno-cast-qual",
"-Wno-cast-align",
"-Wno-implicit-function-declaration",
+ "-DUSE_OPENSSL",
+ "-DUSE_TLS",
+ "-DUSE_OPENSSL_DTLS",
+ "-DUSE_DTLS",
+ "-DUSE_OPENSSL_SRTP",
+ "-DUSE_DTLS_SRTP",
+ #"-DUSE_ZLIB",
+ "-DHAVE_INET6",
+ "-DHAVE_SELECT",
+ "-DHAVE_STDBOOL_H",
+ "-DHAVE_INTTYPES_H",
+ "-DHAVE_NET_ROUTE_H",
+ "-DHAVE_SYS_SYSCTL_H",
+ "-DHAVE_FORK",
+ "-DHAVE_INET_NTOP",
+ "-DHAVE_PWD_H",
+ "-DHAVE_SELECT_H",
+ "-DHAVE_SETRLIMIT",
+ "-DHAVE_SIGNAL",
+ "-DHAVE_STRERROR_R",
+ "-DHAVE_STRINGS_H",
+ "-DHAVE_SYS_TIME_H",
+ "-DHAVE_UNAME",
+ "-DHAVE_UNISTD_H",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_GETIFADDRS",
+ "-DHAVE_DLFCN",
+ "-DHAVE_EPOLL",
+ "-DHAVE_RESOLV",
+ "-DHAVE_POLL",
+ "-DHAVE_INET_PTON",
+ "-DHAVE_ROUTE_LIST",
],
defines = ["HAVE_INTTYPES_H"],
includes = ["include/"],
diff --git a/third_party/rawrtc/re/include/meson.build b/third_party/rawrtc/re/include/meson.build
new file mode 100644
index 0000000..c9e1b30
--- /dev/null
+++ b/third_party/rawrtc/re/include/meson.build
@@ -0,0 +1,52 @@
+includes = files([
+ 're.h',
+ 're_aes.h',
+ 're_base64.h',
+ 're_bfcp.h',
+ 're_bitv.h',
+ 're_conf.h',
+ 're_crc32.h',
+ 're_dbg.h',
+ 're_dns.h',
+ 're_fmt.h',
+ 're_hash.h',
+ 're_hmac.h',
+ 're_httpauth.h',
+ 're_http.h',
+ 're_ice.h',
+ 're_jbuf.h',
+ 're_json.h',
+ 're_list.h',
+ 're_lock.h',
+ 're_main.h',
+ 're_mbuf.h',
+ 're_md5.h',
+ 're_mem.h',
+ 're_mod.h',
+ 're_mqueue.h',
+ 're_msg.h',
+ 're_natbd.h',
+ 're_net.h',
+ 're_odict.h',
+ 're_rtmp.h',
+ 're_rtp.h',
+ 're_sa.h',
+ 're_sdp.h',
+ 're_sha.h',
+ 're_sipevent.h',
+ 're_sip.h',
+ 're_sipreg.h',
+ 're_sipsess.h',
+ 're_srtp.h',
+ 're_stun.h',
+ 're_sys.h',
+ 're_tcp.h',
+ 're_telev.h',
+ 're_tls.h',
+ 're_tmr.h',
+ 're_turn.h',
+ 're_types.h',
+ 're_udp.h',
+ 're_uri.h',
+ 're_websock.h',
+])
diff --git a/third_party/rawrtc/re/include/re_sdp.h b/third_party/rawrtc/re/include/re_sdp.h
index f34bab5..457cb4d 100644
--- a/third_party/rawrtc/re/include/re_sdp.h
+++ b/third_party/rawrtc/re/include/re_sdp.h
@@ -99,6 +99,7 @@
void sdp_media_set_lport_rtcp(struct sdp_media *m, uint16_t port);
void sdp_media_set_laddr_rtcp(struct sdp_media *m, const struct sa *laddr);
void sdp_media_set_ldir(struct sdp_media *m, enum sdp_dir dir);
+void sdp_media_ldir_exclude(struct sdp_media *m, bool exclude);
int sdp_media_set_lattr(struct sdp_media *m, bool replace,
const char *name, const char *value, ...);
void sdp_media_del_lattr(struct sdp_media *m, const char *name);
diff --git a/third_party/rawrtc/re/include/re_tls.h b/third_party/rawrtc/re/include/re_tls.h
index 05b3c93..09ad028 100644
--- a/third_party/rawrtc/re/include/re_tls.h
+++ b/third_party/rawrtc/re/include/re_tls.h
@@ -54,6 +54,8 @@
uint8_t *srv_key, size_t srv_key_size);
const char *tls_cipher_name(const struct tls_conn *tc);
int tls_set_ciphers(struct tls *tls, const char *cipherv[], size_t count);
+int tls_set_dh_params_pem(struct tls *tls, const char *pem, size_t len);
+int tls_set_dh_params_der(struct tls *tls, const uint8_t *der, size_t len);
int tls_set_servername(struct tls_conn *tc, const char *servername);
@@ -66,6 +68,9 @@
/* UDP (DTLS) */
typedef void (dtls_conn_h)(const struct sa *peer, void *arg);
+typedef int (dtls_send_h)(struct tls_conn *tc, const struct sa *dst,
+ struct mbuf *mb, void *arg);
+typedef size_t (dtls_mtu_h)(struct tls_conn *tc, void *arg);
typedef void (dtls_estab_h)(void *arg);
typedef void (dtls_recv_h)(struct mbuf *mb, void *arg);
typedef void (dtls_close_h)(int err, void *arg);
@@ -75,8 +80,13 @@
int dtls_listen(struct dtls_sock **sockp, const struct sa *laddr,
struct udp_sock *us, uint32_t htsize, int layer,
dtls_conn_h *connh, void *arg);
+int dtls_socketless(struct dtls_sock **sockp, uint32_t htsize,
+ dtls_conn_h *connh, dtls_send_h *sendh, dtls_mtu_h *mtuh,
+ void *arg);
struct udp_sock *dtls_udp_sock(struct dtls_sock *sock);
void dtls_set_mtu(struct dtls_sock *sock, size_t mtu);
+size_t dtls_headroom(struct dtls_sock *sock);
+void dtls_set_headroom(struct dtls_sock *sock, size_t headroom);
int dtls_connect(struct tls_conn **ptc, struct tls *tls,
struct dtls_sock *sock, const struct sa *peer,
dtls_estab_h *estabh, dtls_recv_h *recvh,
@@ -86,6 +96,7 @@
dtls_estab_h *estabh, dtls_recv_h *recvh,
dtls_close_h *closeh, void *arg);
int dtls_send(struct tls_conn *tc, struct mbuf *mb);
+bool dtls_receive(struct dtls_sock *sock, struct sa *src, struct mbuf *mb);
void dtls_set_handlers(struct tls_conn *tc, dtls_estab_h *estabh,
dtls_recv_h *recvh, dtls_close_h *closeh, void *arg);
const struct sa *dtls_peer(const struct tls_conn *tc);
diff --git a/third_party/rawrtc/re/meson.build b/third_party/rawrtc/re/meson.build
new file mode 100644
index 0000000..2757cff
--- /dev/null
+++ b/third_party/rawrtc/re/meson.build
@@ -0,0 +1,373 @@
+# Project definition
+project('rawrre', 'c',
+ version: '0.6.0',
+ default_options: ['c_std=c99'],
+ meson_version: '>=0.46.0')
+
+# Set compiler warning flags
+compiler = meson.get_compiler('c')
+compiler_args = compiler.get_supported_arguments([
+ '-Wall',
+ '-Wmissing-declarations',
+ '-Wmissing-prototypes',
+ '-Wstrict-prototypes',
+ '-Wbad-function-cast',
+ '-Wsign-compare',
+ '-Wnested-externs',
+ '-Wshadow',
+ '-Waggregate-return',
+ '-Wcast-align',
+ '-Wextra',
+ '-Wold-style-definition',
+ '-Wdeclaration-after-statement',
+ '-Wuninitialized', # TODO: Only when optimising? But why?
+ '-Wshorten-64-to-32', # Apple-specific
+ '-pedantic',
+])
+add_project_arguments(compiler_args, language: 'c')
+
+# TODO: Include -g flag for extra debug stuff?
+# TODO: Optimise for speed or size?
+
+# Configuration
+# TODO: Generate a configuration file instead of defining? Would simplify the
+# configuration.
+# This would allow projects depending on this able to import those
+# defines, too.
+compile_args = []
+configuration = configuration_data()
+
+# OS
+system = host_machine.system()
+add_project_arguments('-DOS="@0@"'.format(system), language: 'c')
+configuration.set_quoted('OS', system)
+if system == 'darwin'
+ add_project_arguments('-DDARWIN', language: 'c')
+ configuration.set('DARWIN', 1)
+elif system == 'dragonfly'
+ add_project_arguments('-DDRAGONFLY', language: 'c')
+ configuration.set('DRAGONFLY', 1)
+elif system == 'freebsd'
+ add_project_arguments('-DFREEBSD', language: 'c')
+ configuration.set('FREEBSD', 1)
+elif system == 'gnu'
+ add_project_arguments('-DGNU', language: 'c')
+ configuration.set('GNU', 1)
+elif system == 'gnu/kfreebsd'
+ add_project_arguments(
+ '-DKFREEBSD',
+ '-D_GNU_SOURCE',
+ language: 'c')
+ configuration.set('GNU', 1)
+ configuration.set('_GNU_SOURCE', 1)
+elif system == 'linux'
+ add_project_arguments('-DLINUX', language: 'c')
+ configuration.set('LINUX', 1)
+elif system == 'netbsd'
+ add_project_arguments('-DDNETBSD', language: 'c')
+ configuration.set('NETBSD', 1)
+elif system == 'sunos'
+ add_project_arguments('-DSOLARIS', language: 'c')
+ configuration.set('SOLARIS', 1)
+ compile_args += '-DSOLARIS'
+elif system == 'windows'
+ add_project_arguments('-DWIN32', language: 'c')
+ configuration.set('WIN32', 1)
+ compile_args += '-DWIN32'
+else
+ warning('Unhandled OS: @0@'.format(system))
+endif
+
+# Architecture
+cpu = host_machine.cpu()
+add_project_arguments('-DARCH="@0@"'.format(cpu), language: 'c')
+configuration.set_quoted('ARCH', cpu)
+
+# Dependency: Threads
+# TODO: Make this overridable
+thread_dep = dependency('threads', required: false)
+
+# Dependency: OpenSSL
+openssl_dep = dependency('openssl', version: '>=0.9.8', required: false)
+# TODO: Make this overridable
+if openssl_dep.found()
+ add_project_arguments(
+ '-DUSE_OPENSSL',
+ '-DUSE_TLS',
+ language: 'c')
+ configuration.set('USE_OPENSSL', 1)
+ configuration.set('USE_TLS', 1)
+ compile_args += '-DUSE_OPENSSL'
+
+ # Check for DTLS
+ if compiler.has_header('openssl/dtls1.h')
+ add_project_arguments(
+ '-DUSE_OPENSSL_DTLS',
+ '-DUSE_DTLS',
+ language: 'c')
+ configuration.set('USE_OPENSSL_DTLS', 1)
+ configuration.set('USE_DTLS', 1)
+ endif
+
+ # Check for SRTP
+ if compiler.has_header('openssl/srtp.h')
+ add_project_arguments(
+ '-DUSE_OPENSSL_SRTP',
+ '-DUSE_DTLS_SRTP',
+ language: 'c')
+ configuration.set('USE_OPENSSL_SRTP', 1)
+ configuration.set('USE_DTLS_SRTP', 1)
+ endif
+endif
+
+# Dependency: zlib
+# TODO: Make this overridable
+# TODO: Arbitrary version, ask maintainers
+zlib_dep = dependency('zlib', version: '>=1.2.8', required: false)
+if zlib_dep.found()
+ add_project_arguments('-DUSE_ZLIB', language: 'c')
+ configuration.set('USE_ZLIB', 1)
+ compile_args += '-DUSE_ZLIB'
+endif
+
+# Dependencies list
+dependencies = [
+ thread_dep,
+ openssl_dep,
+ zlib_dep,
+]
+
+# Features: Common
+add_project_arguments(
+ '-DHAVE_INET6',
+ '-DHAVE_SELECT',
+ '-DHAVE_STDBOOL_H',
+ language: 'c')
+configuration.set('HAVE_INET6', 1)
+configuration.set('HAVE_SELECT', 1)
+configuration.set('HAVE_STDBOOL_H', 1)
+compile_args += [
+ '-DHAVE_INET6',
+ '-DHAVE_STDBOOL_H',
+]
+
+# Features: Check for fixed size integer types
+if compiler.has_header('inttypes.h')
+ add_project_arguments('-DHAVE_INTTYPES_H', language: 'c')
+ configuration.set('HAVE_INTTYPES_H', 1)
+ compile_args += '-DHAVE_INTTYPES_H'
+endif
+
+# Features: Check for route
+have_net_route = compiler.has_header('net/route.h')
+if have_net_route
+ add_project_arguments('-DHAVE_NET_ROUTE_H', language: 'c')
+ configuration.set('HAVE_NET_ROUTE_H', 1)
+endif
+
+# Features: Check for sysctl
+have_sysctl = compiler.has_header('sys/sysctl.h')
+if have_sysctl
+ add_project_arguments('-DHAVE_SYS_SYSCTL_H', language: 'c')
+ configuration.set('HAVE_SYS_SYSCTL_H', 1)
+endif
+
+# Features: OS-specific
+if system == 'windows'
+ # Windows
+ add_project_arguments(
+ '-DHAVE_IO_H',
+ '-D_WIN32_WINNT=0x0501',
+ '-D__ssize_t_defined',
+ language: 'c')
+ configuration.set('HAVE_IO_H', 1)
+ configuration.set('_WIN32_WINNT', 0x0501)
+ configuration.set('__ssize_t_defined', 1)
+ compile_args += '-D__ssize_t_defined'
+
+ # Additional linking
+ dependencies += compiler.find_library('wsock32', required: true)
+ dependencies += compiler.find_library('ws2_32', required: true)
+ dependencies += compiler.find_library('iphlpapi', required: true)
+
+ # TODO: APP_LFLAGS += -Wl,--export-all-symbols
+else
+ # UNIX
+ add_project_arguments(
+ '-DHAVE_FORK',
+ '-DHAVE_INET_NTOP',
+ '-DHAVE_PWD_H',
+ '-DHAVE_SELECT_H',
+ '-DHAVE_SETRLIMIT',
+ '-DHAVE_SIGNAL',
+ '-DHAVE_STRERROR_R',
+ '-DHAVE_STRINGS_H',
+ '-DHAVE_SYS_TIME_H',
+ '-DHAVE_UNAME',
+ '-DHAVE_UNISTD_H',
+ language: 'c')
+ configuration.set('HAVE_FORK', 1)
+ configuration.set('HAVE_INET_NTOP', 1)
+ configuration.set('HAVE_PWD_H', 1)
+ configuration.set('HAVE_SELECT_H', 1)
+ configuration.set('HAVE_SETRLIMIT', 1)
+ configuration.set('HAVE_SIGNAL', 1)
+ configuration.set('HAVE_STRERROR_R', 1)
+ configuration.set('HAVE_STRINGS_H', 1)
+ configuration.set('HAVE_SYS_TIME_H', 1)
+ configuration.set('HAVE_UNAME', 1)
+ configuration.set('HAVE_UNISTD_H', 1)
+
+ # Solaris requires some additional linking
+ if system == 'sunos'
+ dependencies += compiler.find_library('socket', required: true)
+ dependencies += compiler.find_library('nsl', required: true)
+ endif
+
+ # Check for pthread
+ if compiler.has_header('pthread.h')
+ add_project_arguments('-DHAVE_PTHREAD', language: 'c')
+ configuration.set('HAVE_PTHREAD', 1)
+ endif
+
+ # Check for ifaddrs
+ ifaddrs_prefix = '''
+ #include <sys/socket.h>
+ #define __USE_MISC 1 /**< Use MISC code */
+ #include <net/if.h>
+ #include <ifaddrs.h>
+ '''
+ if compiler.has_function('getifaddrs', prefix: ifaddrs_prefix)
+ add_project_arguments('-DHAVE_GETIFADDRS', language: 'c')
+ configuration.set('HAVE_GETIFADDRS', 1)
+ endif
+
+ # Check for dlfcn
+ if compiler.has_header('dlfcn.h')
+ # Linux, GNU and Solaris require linking
+ if system == 'linux' or system == 'gnu' or system == 'sunos'
+ dependencies += compiler.find_library('dl', required: true)
+ endif
+ add_project_link_arguments('-rdynamic', language: 'c')
+ add_project_arguments('-DHAVE_DLFCN', language: 'c')
+ configuration.set('HAVE_DLFCN', 1)
+ endif
+
+ # Check for epoll
+ if compiler.has_header('sys/epoll.h')
+ add_project_arguments('-DHAVE_EPOLL', language: 'c')
+ configuration.set('HAVE_EPOLL', 1)
+ endif
+
+ # Check for resolv
+ resolv_prefix = '''
+ #define _BSD_SOURCE 1
+ #define _DEFAULT_SOURCE 1
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <arpa/nameser.h>
+ #include <resolv.h>
+ '''
+ if compiler.has_type('struct __res_state', prefix: resolv_prefix)
+ # OSX/iOS and Solaris require linking
+ if system == 'darwin' or system == 'sunos'
+ dependencies += compiler.find_library('resolv', required: true)
+ endif
+ add_project_arguments('-DHAVE_RESOLV', language: 'c')
+ configuration.set('HAVE_RESOLV', 1)
+ endif
+
+ # Check for kqueue
+ kqueue_prefix = '''
+ #include <sys/types.h>
+ #include <sys/event.h>
+ #include <sys/time.h>
+ '''
+ if compiler.has_function('kqueue', prefix: kqueue_prefix)
+ add_project_arguments('-DHAVE_KQUEUE', language: 'c')
+ configuration.set('HAVE_KQUEUE', 1)
+ endif
+
+ # Check for arc4random
+ if compiler.has_function('arc4random', prefix: '#include <stdlib.h>')
+ add_project_arguments('-DHAVE_ARC4RANDOM', language: 'c')
+ configuration.set('HAVE_ARC4RANDOM', 1)
+ endif
+
+ # Features OSX/iOS is lacking
+ if not (system == 'darwin')
+ # OSX/iOS's poll() does not support devices
+ add_project_arguments(
+ '-DHAVE_POLL',
+ '-DHAVE_INET_PTON',
+ language: 'c')
+ configuration.set('HAVE_POLL', 1)
+ configuration.set('HAVE_INET_PTON', 1)
+ endif
+endif
+
+# Features: Routing for Linux and *BSD
+if system == 'linux' or (have_sysctl and have_net_route)
+ add_project_arguments('-DHAVE_ROUTE_LIST', language: 'c')
+ configuration.set('HAVE_ROUTE_LIST', 1)
+endif
+
+# Version
+version = meson.project_version()
+version_array = version.split('.')
+add_project_arguments(
+ '-DVERSION="@0@"'.format(version),
+ '-DVER_MAJOR=@0@'.format(version_array[0]),
+ '-DVER_MINOR=@0@'.format(version_array[1]),
+ '-DVER_PATCH=@0@'.format(version_array[2]),
+ language: 'c')
+configuration.set_quoted('VERSION', version)
+configuration.set('VER_MAJOR', version_array[0])
+configuration.set('VER_MINOR', version_array[1])
+configuration.set('VER_PATCH', version_array[2])
+
+# TODO: Define 'RELEASE' when using build type 'release'
+# Also, compile_args += '-DMBUF_DEBUG=1' in that case
+# TODO: Check if we need to do anything for gcov
+# TODO: Check if we need to do anything for GNU profiling
+# TODO: Port packaging section
+# TODO: Port clang section
+# TODO: Port documentation section
+
+# Includes
+include_dir = include_directories('include')
+subdir('include')
+
+# Sources & Modules
+# TODO: Make which to build configurable
+subdir('src')
+
+# Build library
+re = library(meson.project_name(), sources,
+ dependencies: dependencies,
+ include_directories: include_dir,
+ install: true,
+ version: version)
+
+# Install headers
+install_headers(includes, subdir: 're')
+
+# Declare dependency
+re_dep = declare_dependency(
+ compile_args: compile_args,
+ include_directories: include_dir,
+ link_with: re)
+
+# Generate pkg-config file
+pkg = import('pkgconfig')
+description = '''Generic library for real-time communications with
+ async IO support'''
+description = ' '.join(description.split())
+pkg.generate(re,
+ name: 'libre',
+ description: description,
+ url: 'http://www.creytiv.com/re.html',
+ extra_cflags: compile_args, # https://github.com/creytiv/re/issues/167
+ subdirs: 're')
+
+# TODO: Ensure 'install' has the same result as when invoking 'make'
diff --git a/third_party/rawrtc/re/src/aes/meson.build b/third_party/rawrtc/re/src/aes/meson.build
new file mode 100644
index 0000000..6f869ca
--- /dev/null
+++ b/third_party/rawrtc/re/src/aes/meson.build
@@ -0,0 +1,6 @@
+# TODO: What about apple/aes.c?
+if openssl_dep.found()
+ sources += files('openssl/aes.c')
+else
+ sources += files('stub.c')
+endif
diff --git a/third_party/rawrtc/re/src/base64/meson.build b/third_party/rawrtc/re/src/base64/meson.build
new file mode 100644
index 0000000..5b6f4ff
--- /dev/null
+++ b/third_party/rawrtc/re/src/base64/meson.build
@@ -0,0 +1 @@
+sources += files('b64.c')
diff --git a/third_party/rawrtc/re/src/bfcp/meson.build b/third_party/rawrtc/re/src/bfcp/meson.build
new file mode 100644
index 0000000..8e333b0
--- /dev/null
+++ b/third_party/rawrtc/re/src/bfcp/meson.build
@@ -0,0 +1,7 @@
+sources += files([
+ 'attr.c',
+ 'conn.c',
+ 'msg.c',
+ 'reply.c',
+ 'request.c',
+])
diff --git a/third_party/rawrtc/re/src/conf/meson.build b/third_party/rawrtc/re/src/conf/meson.build
new file mode 100644
index 0000000..ea1c1cfc
--- /dev/null
+++ b/third_party/rawrtc/re/src/conf/meson.build
@@ -0,0 +1 @@
+sources += files('conf.c')
diff --git a/third_party/rawrtc/re/src/crc32/meson.build b/third_party/rawrtc/re/src/crc32/meson.build
new file mode 100644
index 0000000..f073ff7
--- /dev/null
+++ b/third_party/rawrtc/re/src/crc32/meson.build
@@ -0,0 +1,3 @@
+if not zlib_dep.found()
+ sources += files('crc32.c')
+endif
diff --git a/third_party/rawrtc/re/src/dbg/meson.build b/third_party/rawrtc/re/src/dbg/meson.build
new file mode 100644
index 0000000..7c71321
--- /dev/null
+++ b/third_party/rawrtc/re/src/dbg/meson.build
@@ -0,0 +1 @@
+sources += files('dbg.c')
diff --git a/third_party/rawrtc/re/src/dns/meson.build b/third_party/rawrtc/re/src/dns/meson.build
new file mode 100644
index 0000000..cfd6aa0
--- /dev/null
+++ b/third_party/rawrtc/re/src/dns/meson.build
@@ -0,0 +1,23 @@
+sources += files([
+ 'client.c',
+ 'cstr.c',
+ 'dname.c',
+ 'hdr.c',
+ 'ns.c',
+ 'rr.c',
+ 'rrlist.c',
+])
+
+if configuration.has('HAVE_RESOLV')
+ sources += files('res.c')
+endif
+
+if system == 'windows'
+ sources += files('win32/srv.c')
+elif system == 'darwin'
+ sources += files('darwin/srv.c')
+ dependencies += dependency(
+ 'appleframeworks',
+ modules: ['SystemConfiguration', 'CoreFoundation'],
+ required: true)
+endif
diff --git a/third_party/rawrtc/re/src/fmt/meson.build b/third_party/rawrtc/re/src/fmt/meson.build
new file mode 100644
index 0000000..bcc4750
--- /dev/null
+++ b/third_party/rawrtc/re/src/fmt/meson.build
@@ -0,0 +1,12 @@
+sources += files([
+ 'ch.c',
+ 'hexdump.c',
+ 'pl.c',
+ 'print.c',
+ 'prm.c',
+ 'regex.c',
+ 'str.c',
+ 'str_error.c',
+ 'time.c',
+ 'unicode.c',
+])
diff --git a/third_party/rawrtc/re/src/fmt/print.c b/third_party/rawrtc/re/src/fmt/print.c
index 85e9ebf..c0247b4 100644
--- a/third_party/rawrtc/re/src/fmt/print.c
+++ b/third_party/rawrtc/re/src/fmt/print.c
@@ -303,6 +303,11 @@
}
break;
+ case 'h':
+ lenmod = LENMOD_NONE;
+ fm = true;
+ break;
+
case 'H':
ph = va_arg(ap, re_printf_h *);
ph_arg = va_arg(ap, void *);
diff --git a/third_party/rawrtc/re/src/hash/func.c b/third_party/rawrtc/re/src/hash/func.c
index 3943c94..f379904 100644
--- a/third_party/rawrtc/re/src/hash/func.c
+++ b/third_party/rawrtc/re/src/hash/func.c
@@ -312,20 +312,19 @@
k += 12;
}
- /* all the case statements fall through */
switch (length) {
- case 12: c+=((uint32_t)k[11])<<24;
- case 11: c+=((uint32_t)k[10])<<16;
- case 10: c+=((uint32_t)k[9])<<8;
- case 9 : c+=k[8];
- case 8 : b+=((uint32_t)k[7])<<24;
- case 7 : b+=((uint32_t)k[6])<<16;
- case 6 : b+=((uint32_t)k[5])<<8;
- case 5 : b+=k[4];
- case 4 : a+=((uint32_t)k[3])<<24;
- case 3 : a+=((uint32_t)k[2])<<16;
- case 2 : a+=((uint32_t)k[1])<<8;
+ case 12: c+=((uint32_t)k[11])<<24; /* fall through */
+ case 11: c+=((uint32_t)k[10])<<16; /* fall through */
+ case 10: c+=((uint32_t)k[9])<<8; /* fall through */
+ case 9 : c+=k[8]; /* fall through */
+ case 8 : b+=((uint32_t)k[7])<<24; /* fall through */
+ case 7 : b+=((uint32_t)k[6])<<16; /* fall through */
+ case 6 : b+=((uint32_t)k[5])<<8; /* fall through */
+ case 5 : b+=k[4]; /* fall through */
+ case 4 : a+=((uint32_t)k[3])<<24; /* fall through */
+ case 3 : a+=((uint32_t)k[2])<<16; /* fall through */
+ case 2 : a+=((uint32_t)k[1])<<8; /* fall through */
case 1 : a+=k[0];
break;
case 0 : return c;
diff --git a/third_party/rawrtc/re/src/hash/meson.build b/third_party/rawrtc/re/src/hash/meson.build
new file mode 100644
index 0000000..57d8c12
--- /dev/null
+++ b/third_party/rawrtc/re/src/hash/meson.build
@@ -0,0 +1,4 @@
+sources += files([
+ 'hash.c',
+ 'func.c',
+])
diff --git a/third_party/rawrtc/re/src/hmac/meson.build b/third_party/rawrtc/re/src/hmac/meson.build
new file mode 100644
index 0000000..7a7293a
--- /dev/null
+++ b/third_party/rawrtc/re/src/hmac/meson.build
@@ -0,0 +1,8 @@
+sources += files('hmac_sha1.c')
+
+# TODO: What about apple/hmac.c?
+if openssl_dep.found()
+ sources += files('openssl/hmac.c')
+else
+ sources += files('hmac.c')
+endif
diff --git a/third_party/rawrtc/re/src/http/meson.build b/third_party/rawrtc/re/src/http/meson.build
new file mode 100644
index 0000000..3ee5939
--- /dev/null
+++ b/third_party/rawrtc/re/src/http/meson.build
@@ -0,0 +1,7 @@
+sources += files([
+ 'auth.c',
+ 'chunk.c',
+ 'client.c',
+ 'msg.c',
+ 'server.c',
+])
diff --git a/third_party/rawrtc/re/src/httpauth/meson.build b/third_party/rawrtc/re/src/httpauth/meson.build
new file mode 100644
index 0000000..2ad5862
--- /dev/null
+++ b/third_party/rawrtc/re/src/httpauth/meson.build
@@ -0,0 +1,4 @@
+sources += files([
+ 'basic.c',
+ 'digest.c',
+])
diff --git a/third_party/rawrtc/re/src/ice/meson.build b/third_party/rawrtc/re/src/ice/meson.build
new file mode 100644
index 0000000..be63f72
--- /dev/null
+++ b/third_party/rawrtc/re/src/ice/meson.build
@@ -0,0 +1,12 @@
+sources += files([
+ 'cand.c',
+ 'candpair.c',
+ 'chklist.c',
+ 'comp.c',
+ 'connchk.c',
+ 'icem.c',
+ 'icesdp.c',
+ 'icestr.c',
+ 'stunsrv.c',
+ 'util.c',
+])
diff --git a/third_party/rawrtc/re/src/jbuf/meson.build b/third_party/rawrtc/re/src/jbuf/meson.build
new file mode 100644
index 0000000..1b11bc8
--- /dev/null
+++ b/third_party/rawrtc/re/src/jbuf/meson.build
@@ -0,0 +1 @@
+sources += files('jbuf.c')
diff --git a/third_party/rawrtc/re/src/json/meson.build b/third_party/rawrtc/re/src/json/meson.build
new file mode 100644
index 0000000..f5461df
--- /dev/null
+++ b/third_party/rawrtc/re/src/json/meson.build
@@ -0,0 +1,5 @@
+sources += files([
+ 'decode.c',
+ 'decode_odict.c',
+ 'encode.c',
+])
diff --git a/third_party/rawrtc/re/src/list/meson.build b/third_party/rawrtc/re/src/list/meson.build
new file mode 100644
index 0000000..2027364
--- /dev/null
+++ b/third_party/rawrtc/re/src/list/meson.build
@@ -0,0 +1 @@
+sources += files('list.c')
diff --git a/third_party/rawrtc/re/src/lock/meson.build b/third_party/rawrtc/re/src/lock/meson.build
new file mode 100644
index 0000000..bd400bd
--- /dev/null
+++ b/third_party/rawrtc/re/src/lock/meson.build
@@ -0,0 +1,8 @@
+# TODO: What about lock.c?
+if configuration.has('HAVE_PTHREAD')
+ sources += files('rwlock.c')
+endif
+
+if system == 'windows'
+ sources += files('win32/lock.c')
+endif
diff --git a/third_party/rawrtc/re/src/main/main.c b/third_party/rawrtc/re/src/main/main.c
index b90c139..0243b4b 100644
--- a/third_party/rawrtc/re/src/main/main.c
+++ b/third_party/rawrtc/re/src/main/main.c
@@ -786,6 +786,8 @@
flags |= FD_WRITE;
if (re->events[i].events & (EPOLLERR|EPOLLHUP))
flags |= FD_EXCEPT;
+ if (re->events[i].events & EPOLLHUP)
+ flags |= FD_EXCEPT;
if (!flags) {
DEBUG_WARNING("epoll: no flags fd=%d\n", fd);
diff --git a/third_party/rawrtc/re/src/main/meson.build b/third_party/rawrtc/re/src/main/meson.build
new file mode 100644
index 0000000..f0a5b98
--- /dev/null
+++ b/third_party/rawrtc/re/src/main/meson.build
@@ -0,0 +1,13 @@
+sources += files([
+ 'init.c',
+ 'main.c',
+ 'method.c',
+])
+
+if configuration.has('HAVE_EPOLL')
+ sources += files('epoll.c')
+endif
+
+if openssl_dep.found()
+ sources += files('openssl.c')
+endif
diff --git a/third_party/rawrtc/re/src/mbuf/meson.build b/third_party/rawrtc/re/src/mbuf/meson.build
new file mode 100644
index 0000000..eaec9d1
--- /dev/null
+++ b/third_party/rawrtc/re/src/mbuf/meson.build
@@ -0,0 +1 @@
+sources += files('mbuf.c')
diff --git a/third_party/rawrtc/re/src/md5/meson.build b/third_party/rawrtc/re/src/md5/meson.build
new file mode 100644
index 0000000..547a2fc
--- /dev/null
+++ b/third_party/rawrtc/re/src/md5/meson.build
@@ -0,0 +1,5 @@
+if not openssl_dep.found()
+ sources += files('md5.c')
+endif
+
+sources += files('wrap.c')
diff --git a/third_party/rawrtc/re/src/mem/meson.build b/third_party/rawrtc/re/src/mem/meson.build
new file mode 100644
index 0000000..3e15795
--- /dev/null
+++ b/third_party/rawrtc/re/src/mem/meson.build
@@ -0,0 +1,4 @@
+sources += files([
+ 'mem.c',
+ 'secure.c',
+])
diff --git a/third_party/rawrtc/re/src/meson.build b/third_party/rawrtc/re/src/meson.build
new file mode 100644
index 0000000..aa5ff49
--- /dev/null
+++ b/third_party/rawrtc/re/src/meson.build
@@ -0,0 +1,50 @@
+sources = []
+
+# Modules
+subdir('aes')
+subdir('base64')
+subdir('bfcp')
+subdir('conf')
+subdir('crc32')
+subdir('dbg')
+subdir('dns')
+subdir('fmt')
+subdir('hash')
+subdir('hmac')
+subdir('http')
+subdir('httpauth')
+subdir('ice')
+subdir('jbuf')
+subdir('json')
+subdir('list')
+subdir('lock')
+subdir('main')
+subdir('mbuf')
+subdir('md5')
+subdir('mem')
+subdir('mod')
+subdir('mqueue')
+subdir('msg')
+subdir('natbd')
+subdir('net')
+subdir('odict')
+subdir('rtmp')
+subdir('rtp')
+subdir('sa')
+subdir('sdp')
+subdir('sha')
+subdir('sip')
+subdir('sipevent')
+subdir('sipreg')
+subdir('sipsess')
+subdir('srtp')
+subdir('stun')
+subdir('sys')
+subdir('tcp')
+subdir('telev')
+subdir('tls')
+subdir('tmr')
+subdir('turn')
+subdir('udp')
+subdir('uri')
+subdir('websock')
diff --git a/third_party/rawrtc/re/src/mod/meson.build b/third_party/rawrtc/re/src/mod/meson.build
new file mode 100644
index 0000000..eb9a306
--- /dev/null
+++ b/third_party/rawrtc/re/src/mod/meson.build
@@ -0,0 +1,9 @@
+sources += files('mod.c')
+
+if configuration.has('HAVE_DLFCN')
+ sources += files('dl.c')
+endif
+
+if system == 'windows'
+ sources += files('win32/dll.c')
+endif
diff --git a/third_party/rawrtc/re/src/mqueue/meson.build b/third_party/rawrtc/re/src/mqueue/meson.build
new file mode 100644
index 0000000..65d6d5b
--- /dev/null
+++ b/third_party/rawrtc/re/src/mqueue/meson.build
@@ -0,0 +1,5 @@
+sources += files('mqueue.c')
+
+if system == 'windows'
+ sources += files('win32/pipe.c')
+endif
diff --git a/third_party/rawrtc/re/src/msg/meson.build b/third_party/rawrtc/re/src/msg/meson.build
new file mode 100644
index 0000000..a70396e
--- /dev/null
+++ b/third_party/rawrtc/re/src/msg/meson.build
@@ -0,0 +1,4 @@
+sources += files([
+ 'ctype.c',
+ 'param.c',
+])
diff --git a/third_party/rawrtc/re/src/natbd/meson.build b/third_party/rawrtc/re/src/natbd/meson.build
new file mode 100644
index 0000000..523d452
--- /dev/null
+++ b/third_party/rawrtc/re/src/natbd/meson.build
@@ -0,0 +1,8 @@
+sources += files([
+ 'filtering.c',
+ 'genalg.c',
+ 'hairpinning.c',
+ 'lifetime.c',
+ 'mapping.c',
+ 'natstr.c',
+])
diff --git a/third_party/rawrtc/re/src/net/meson.build b/third_party/rawrtc/re/src/net/meson.build
new file mode 100644
index 0000000..1408fed
--- /dev/null
+++ b/third_party/rawrtc/re/src/net/meson.build
@@ -0,0 +1,26 @@
+sources += files([
+ 'if.c',
+ 'net.c',
+ 'netstr.c',
+ 'rt.c',
+ 'sock.c',
+ 'sockopt.c',
+])
+
+if system == 'windows'
+ sources += files('win32/wif.c')
+else
+ sources += files('posix/pif.c')
+endif
+
+if configuration.has('HAVE_ROUTE_LIST')
+ if system == 'linux'
+ sources += files('linux/rt.c')
+ else
+ sources += files('bsd/brt.c')
+ endif
+endif
+
+if configuration.has('HAVE_GETIFADDRS')
+ sources += files('ifaddrs.c')
+endif
diff --git a/third_party/rawrtc/re/src/odict/meson.build b/third_party/rawrtc/re/src/odict/meson.build
new file mode 100644
index 0000000..8ac0cde
--- /dev/null
+++ b/third_party/rawrtc/re/src/odict/meson.build
@@ -0,0 +1,6 @@
+sources += files([
+ 'entry.c',
+ 'odict.c',
+ 'type.c',
+ 'get.c',
+])
diff --git a/third_party/rawrtc/re/src/rtmp/meson.build b/third_party/rawrtc/re/src/rtmp/meson.build
new file mode 100644
index 0000000..78a6214
--- /dev/null
+++ b/third_party/rawrtc/re/src/rtmp/meson.build
@@ -0,0 +1,12 @@
+sources += files([
+ 'amf.c',
+ 'amf_dec.c',
+ 'amf_enc.c',
+ 'chunk.c',
+ 'conn.c',
+ 'control.c',
+ 'ctrans.c',
+ 'dechunk.c',
+ 'hdr.c',
+ 'stream.c',
+])
diff --git a/third_party/rawrtc/re/src/rtp/meson.build b/third_party/rawrtc/re/src/rtp/meson.build
new file mode 100644
index 0000000..0fc1506
--- /dev/null
+++ b/third_party/rawrtc/re/src/rtp/meson.build
@@ -0,0 +1,12 @@
+sources += files([
+ 'fb.c',
+ 'member.c',
+ 'ntp.c',
+ 'pkt.c',
+ 'rr.c',
+ 'rtcp.c',
+ 'rtp.c',
+ 'sdes.c',
+ 'sess.c',
+ 'source.c',
+])
diff --git a/third_party/rawrtc/re/src/sa/meson.build b/third_party/rawrtc/re/src/sa/meson.build
new file mode 100644
index 0000000..92e8cbe
--- /dev/null
+++ b/third_party/rawrtc/re/src/sa/meson.build
@@ -0,0 +1,6 @@
+sources += files([
+ 'ntop.c',
+ 'printaddr.c',
+ 'pton.c',
+ 'sa.c',
+])
diff --git a/third_party/rawrtc/re/src/sdp/media.c b/third_party/rawrtc/re/src/sdp/media.c
index 07ce3a2..05e769c 100644
--- a/third_party/rawrtc/re/src/sdp/media.c
+++ b/third_party/rawrtc/re/src/sdp/media.c
@@ -446,6 +446,7 @@
if (!m || !laddr)
return;
+ m->flags |= MEDIA_LADDR_SET;
m->laddr = *laddr;
}
@@ -513,6 +514,25 @@
/**
+ * Set whether the local direction flag of an SDP media line should be excluded
+ * when encoding. Defaults to false.
+ *
+ * @param m SDP Media line
+ * @param exclude Exclude direction flag
+ */
+void sdp_media_ldir_exclude(struct sdp_media *m, bool exclude)
+{
+ if (!m)
+ return;
+
+ if (exclude)
+ m->flags |= MEDIA_LDIR_EXCLUDE;
+ else
+ m->flags &= ~MEDIA_LDIR_EXCLUDE;
+}
+
+
+/**
* Set a local attribute of an SDP Media line
*
* @param m SDP Media line
diff --git a/third_party/rawrtc/re/src/sdp/meson.build b/third_party/rawrtc/re/src/sdp/meson.build
new file mode 100644
index 0000000..03b62dd
--- /dev/null
+++ b/third_party/rawrtc/re/src/sdp/meson.build
@@ -0,0 +1,9 @@
+sources += files([
+ 'attr.c',
+ 'format.c',
+ 'media.c',
+ 'msg.c',
+ 'session.c',
+ 'str.c',
+ 'util.c',
+])
diff --git a/third_party/rawrtc/re/src/sdp/msg.c b/third_party/rawrtc/re/src/sdp/msg.c
index c1a8bbc..82b8905 100644
--- a/third_party/rawrtc/re/src/sdp/msg.c
+++ b/third_party/rawrtc/re/src/sdp/msg.c
@@ -398,7 +398,7 @@
err |= mbuf_write_str(mb, "\r\n");
- if (sa_isset(&m->laddr, SA_ADDR)) {
+ if (m->flags & MEDIA_LADDR_SET) {
const int ipver = sa_af(&m->laddr) == AF_INET ? 4 : 6;
err |= mbuf_printf(mb, "c=IN IP%d %j\r\n", ipver, &m->laddr);
}
@@ -443,8 +443,10 @@
err |= mbuf_printf(mb, "a=rtcp:%u\r\n",
sa_port(&m->laddr_rtcp));
- err |= mbuf_printf(mb, "a=%s\r\n",
- sdp_dir_name(offer ? m->ldir : m->ldir & m->rdir));
+ if (!(m->flags & MEDIA_LDIR_EXCLUDE))
+ err |= mbuf_printf(mb, "a=%s\r\n",
+ sdp_dir_name(offer ? m->ldir :
+ m->ldir & m->rdir));
for (le = m->lattrl.head; le; le = le->next)
err |= mbuf_printf(mb, "%H", sdp_attr_print, le->data);
diff --git a/third_party/rawrtc/re/src/sdp/sdp.h b/third_party/rawrtc/re/src/sdp/sdp.h
index f0588d1..604082a 100644
--- a/third_party/rawrtc/re/src/sdp/sdp.h
+++ b/third_party/rawrtc/re/src/sdp/sdp.h
@@ -10,6 +10,11 @@
RTP_DYNPT_END = 127,
};
+enum {
+ MEDIA_LADDR_SET = 1<<0,
+ MEDIA_LDIR_EXCLUDE = 1<<1,
+};
+
struct sdp_session {
struct list lmedial;
@@ -27,6 +32,7 @@
struct sdp_media {
struct le le;
+ uint8_t flags;
struct list lfmtl;
struct list rfmtl;
struct list lattrl;
diff --git a/third_party/rawrtc/re/src/sha/meson.build b/third_party/rawrtc/re/src/sha/meson.build
new file mode 100644
index 0000000..387b6b5
--- /dev/null
+++ b/third_party/rawrtc/re/src/sha/meson.build
@@ -0,0 +1,3 @@
+if not openssl_dep.found()
+ sources += files('sha1.c')
+endif
diff --git a/third_party/rawrtc/re/src/sip/meson.build b/third_party/rawrtc/re/src/sip/meson.build
new file mode 100644
index 0000000..f80c6e9
--- /dev/null
+++ b/third_party/rawrtc/re/src/sip/meson.build
@@ -0,0 +1,17 @@
+sources += files([
+ 'addr.c',
+ 'auth.c',
+ 'contact.c',
+ 'cseq.c',
+ 'ctrans.c',
+ 'dialog.c',
+ 'keepalive.c',
+ 'keepalive_udp.c',
+ 'msg.c',
+ 'reply.c',
+ 'request.c',
+ 'sip.c',
+ 'strans.c',
+ 'transp.c',
+ 'via.c',
+])
diff --git a/third_party/rawrtc/re/src/sipevent/meson.build b/third_party/rawrtc/re/src/sipevent/meson.build
new file mode 100644
index 0000000..543aa84
--- /dev/null
+++ b/third_party/rawrtc/re/src/sipevent/meson.build
@@ -0,0 +1,6 @@
+sources += files([
+ 'listen.c',
+ 'msg.c',
+ 'notify.c',
+ 'subscribe.c',
+])
diff --git a/third_party/rawrtc/re/src/sipreg/meson.build b/third_party/rawrtc/re/src/sipreg/meson.build
new file mode 100644
index 0000000..0e7bb02
--- /dev/null
+++ b/third_party/rawrtc/re/src/sipreg/meson.build
@@ -0,0 +1 @@
+sources += files('reg.c')
diff --git a/third_party/rawrtc/re/src/sipsess/meson.build b/third_party/rawrtc/re/src/sipsess/meson.build
new file mode 100644
index 0000000..4731317
--- /dev/null
+++ b/third_party/rawrtc/re/src/sipsess/meson.build
@@ -0,0 +1,12 @@
+sources += files([
+ 'sess.c',
+ 'accept.c',
+ 'ack.c',
+ 'close.c',
+ 'connect.c',
+ 'info.c',
+ 'listen.c',
+ 'modify.c',
+ 'reply.c',
+ 'request.c',
+])
diff --git a/third_party/rawrtc/re/src/srtp/meson.build b/third_party/rawrtc/re/src/srtp/meson.build
new file mode 100644
index 0000000..eb56909
--- /dev/null
+++ b/third_party/rawrtc/re/src/srtp/meson.build
@@ -0,0 +1,7 @@
+sources += files([
+ 'misc.c',
+ 'replay.c',
+ 'srtcp.c',
+ 'srtp.c',
+ 'stream.c',
+])
diff --git a/third_party/rawrtc/re/src/stun/meson.build b/third_party/rawrtc/re/src/stun/meson.build
new file mode 100644
index 0000000..5f0a018
--- /dev/null
+++ b/third_party/rawrtc/re/src/stun/meson.build
@@ -0,0 +1,14 @@
+sources += files([
+ 'addr.c',
+ 'attr.c',
+ 'ctrans.c',
+ 'dnsdisc.c',
+ 'hdr.c',
+ 'ind.c',
+ 'keepalive.c',
+ 'msg.c',
+ 'rep.c',
+ 'req.c',
+ 'stun.c',
+ 'stunstr.c',
+])
diff --git a/third_party/rawrtc/re/src/sys/meson.build b/third_party/rawrtc/re/src/sys/meson.build
new file mode 100644
index 0000000..7ffb335
--- /dev/null
+++ b/third_party/rawrtc/re/src/sys/meson.build
@@ -0,0 +1,8 @@
+sources += files([
+ 'daemon.c',
+ 'endian.c',
+ 'fs.c',
+ 'rand.c',
+ 'sleep.c',
+ 'sys.c',
+])
diff --git a/third_party/rawrtc/re/src/tcp/meson.build b/third_party/rawrtc/re/src/tcp/meson.build
new file mode 100644
index 0000000..344d6ee
--- /dev/null
+++ b/third_party/rawrtc/re/src/tcp/meson.build
@@ -0,0 +1,4 @@
+sources += files([
+ 'tcp.c',
+ 'tcp_high.c',
+])
diff --git a/third_party/rawrtc/re/src/telev/meson.build b/third_party/rawrtc/re/src/telev/meson.build
new file mode 100644
index 0000000..e785374
--- /dev/null
+++ b/third_party/rawrtc/re/src/telev/meson.build
@@ -0,0 +1 @@
+sources += files('telev.c')
diff --git a/third_party/rawrtc/re/src/tls/meson.build b/third_party/rawrtc/re/src/tls/meson.build
new file mode 100644
index 0000000..2fc61e8
--- /dev/null
+++ b/third_party/rawrtc/re/src/tls/meson.build
@@ -0,0 +1,7 @@
+if openssl_dep.found()
+ sources += files([
+ 'openssl/tls.c',
+ 'openssl/tls_tcp.c',
+ 'openssl/tls_udp.c',
+ ])
+endif
diff --git a/third_party/rawrtc/re/src/tls/openssl/tls.c b/third_party/rawrtc/re/src/tls/openssl/tls.c
index d84e65f..bc855b1 100644
--- a/third_party/rawrtc/re/src/tls/openssl/tls.c
+++ b/third_party/rawrtc/re/src/tls/openssl/tls.c
@@ -10,6 +10,8 @@
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#include <openssl/dh.h>
+#include <openssl/ec.h>
#include <re_types.h>
#include <re_fmt.h>
#include <re_mem.h>
@@ -853,6 +855,158 @@
}
+static int set_dh_params(struct tls *tls, DH *dh)
+{
+ int codes;
+ long r;
+#if OPENSSL_VERSION_NUMBER < 0x1000200fL
+ EC_KEY *ec_key;
+#endif
+
+ if (!DH_check(dh, &codes))
+ return ENOMEM;
+ if (codes) {
+#if defined(DH_CHECK_P_NOT_PRIME)
+ if (codes & DH_CHECK_P_NOT_PRIME)
+ DEBUG_WARNING("set_dh_params: p is not prime\n");
+#endif
+#if defined(DH_CHECK_P_NOT_SAFE_PRIME)
+ if (codes & DH_CHECK_P_NOT_SAFE_PRIME)
+ DEBUG_WARNING("set_dh_params: p is not safe prime\n");
+#endif
+#if defined(DH_UNABLE_TO_CHECK_GENERATOR)
+ if (codes & DH_UNABLE_TO_CHECK_GENERATOR)
+ DEBUG_WARNING("set_dh_params: generator g "
+ "cannot be checked\n");
+#endif
+#if defined(DH_NOT_SUITABLE_GENERATOR)
+ if (codes & DH_NOT_SUITABLE_GENERATOR)
+ DEBUG_WARNING("set_dh_params: generator g "
+ "is not suitable\n");
+#endif
+#if defined(DH_CHECK_Q_NOT_PRIME)
+ if (codes & DH_CHECK_Q_NOT_PRIME)
+ DEBUG_WARNING("set_dh_params: q is not prime\n");
+#endif
+#if defined(DH_CHECK_INVALID_Q_VALUE)
+ if (codes & DH_CHECK_INVALID_Q_VALUE)
+ DEBUG_WARNING("set_dh_params: q is invalid\n");
+#endif
+#if defined(DH_CHECK_INVALID_J_VALUE)
+ if (codes & DH_CHECK_INVALID_J_VALUE)
+ DEBUG_WARNING("set_dh_params: j is invalid\n");
+#endif
+ return EINVAL;
+ }
+
+ if (!SSL_CTX_set_tmp_dh(tls->ctx, dh)) {
+ DEBUG_WARNING("set_dh_params: set_tmp_dh failed\n");
+ return ENOMEM;
+ }
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
+ r = SSL_CTX_set_ecdh_auto(tls->ctx, (long) 1);
+ if (!r) {
+ DEBUG_WARNING("set_dh_params: set_ecdh_auto failed\n");
+ return ENOMEM;
+ }
+#else
+ ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ if (!ec_key)
+ return ENOMEM;
+ r = SSL_CTX_set_tmp_ecdh(tls->ctx, ec_key);
+ EC_KEY_free(ec_key);
+ if (!r) {
+ DEBUG_WARNING("set_dh_params: set_tmp_ecdh failed\n");
+ return ENOMEM;
+ }
+#endif
+
+ return 0;
+}
+
+
+/**
+ * Set Diffie-Hellman parameters on a TLS context
+ *
+ * @param tls TLS Context
+ * @param pem Diffie-Hellman parameters in PEM format
+ * @param len Length of PEM string
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int tls_set_dh_params_pem(struct tls *tls, const char *pem, size_t len)
+{
+ BIO *bio = NULL;
+ DH *dh = NULL;
+ int err = ENOMEM;
+
+ if (!tls || !pem || !len)
+ return EINVAL;
+
+ bio = BIO_new_mem_buf((char *)pem, (int)len);
+ if (!bio)
+ goto out;
+
+ dh = PEM_read_bio_DHparams(bio, NULL, 0, NULL);
+ if (!dh)
+ goto out;
+
+ err = set_dh_params(tls, dh);
+ if (err)
+ goto out;
+
+ err = 0;
+
+ out:
+ if (dh)
+ DH_free(dh);
+ if (bio)
+ BIO_free(bio);
+ if (err)
+ ERR_clear_error();
+
+ return err;
+}
+
+
+/**
+ * Set Diffie-Hellman parameters on a TLS context
+ *
+ * @param tls TLS Context
+ * @param der Diffie-Hellman parameters in DER format
+ * @param len Length of DER bytes
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int tls_set_dh_params_der(struct tls *tls, const uint8_t *der, size_t len)
+{
+ DH *dh = NULL;
+ int err = ENOMEM;
+
+ if (!tls || !der || !len)
+ return EINVAL;
+
+ dh = d2i_DHparams(NULL, &der, len);
+ if (!dh)
+ goto out;
+
+ err = set_dh_params(tls, dh);
+ if (err)
+ goto out;
+
+ err = 0;
+
+ out:
+ if (dh)
+ DH_free(dh);
+ if (err)
+ ERR_clear_error();
+
+ return err;
+}
+
+
/**
* Set the server name on a TLS Connection, using TLS SNI extension.
*
diff --git a/third_party/rawrtc/re/src/tls/openssl/tls.h b/third_party/rawrtc/re/src/tls/openssl/tls.h
index 2c621d5..c0c4d51 100644
--- a/third_party/rawrtc/re/src/tls/openssl/tls.h
+++ b/third_party/rawrtc/re/src/tls/openssl/tls.h
@@ -20,9 +20,11 @@
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(LIBRESSL_VERSION_NUMBER)
+#ifndef OPENSSL_IS_BORINGSSL
#define SSL_state SSL_get_state
#define SSL_ST_OK TLS_ST_OK
#endif
+#endif
struct tls {
diff --git a/third_party/rawrtc/re/src/tls/openssl/tls_udp.c b/third_party/rawrtc/re/src/tls/openssl/tls_udp.c
index 4ec81a3..669c6cf 100644
--- a/third_party/rawrtc/re/src/tls/openssl/tls_udp.c
+++ b/third_party/rawrtc/re/src/tls/openssl/tls_udp.c
@@ -27,8 +27,9 @@
enum {
- MTU_DEFAULT = 1400,
- MTU_FALLBACK = 548,
+ MTU_DEFAULT = 1400,
+ MTU_FALLBACK = 548,
+ HEADROOM_DEFAULT = 4,
};
@@ -39,8 +40,11 @@
struct hash *ht;
struct mbuf *mb;
dtls_conn_h *connh;
+ dtls_send_h *sendh;
+ dtls_mtu_h *mtuh;
void *arg;
size_t mtu;
+ size_t headroom;
};
@@ -109,18 +113,17 @@
struct tls_conn *tc = b->ptr;
#endif
struct mbuf *mb;
- enum {SPACE = 4};
int err;
- mb = mbuf_alloc(SPACE + len);
+ mb = mbuf_alloc(tc->sock->headroom + len);
if (!mb)
return -1;
- mb->pos = SPACE;
+ mb->pos = tc->sock->headroom;
(void)mbuf_write_mem(mb, (void *)buf, len);
- mb->pos = SPACE;
+ mb->pos = tc->sock->headroom;
- err = udp_send_helper(tc->sock->us, &tc->peer, mb, tc->sock->uh);
+ err = tc->sock->sendh(tc, &tc->peer, mb, tc->arg);
mem_deref(mb);
@@ -146,7 +149,17 @@
#if defined (BIO_CTRL_DGRAM_QUERY_MTU)
case BIO_CTRL_DGRAM_QUERY_MTU:
- return tc ? tc->sock->mtu : MTU_DEFAULT;
+ if (tc) {
+ if (tc->sock->mtuh) {
+ return tc->sock->mtuh(tc, tc->arg);
+ }
+ else {
+ return tc->sock->mtu;
+ }
+ }
+ else {
+ return MTU_DEFAULT;
+ }
#endif
#if defined (BIO_CTRL_DGRAM_GET_FALLBACK_MTU)
@@ -750,6 +763,13 @@
}
+static int send_handler(struct tls_conn *tc, const struct sa *dst,
+ struct mbuf *mb, void *arg) {
+ (void)arg;
+ return udp_send_helper(tc->sock->us, dst, mb, tc->sock->uh);
+}
+
+
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
struct dtls_sock *sock = arg;
@@ -783,6 +803,20 @@
/**
+ * Feed data to a DTLS socket
+ *
+ * @param sock DTLS socket
+ * @param src Source address
+ * @param mb Buffer to receive
+ *
+ * @return whether the packet has been handled.
+ */
+bool dtls_receive(struct dtls_sock *sock, struct sa *src, struct mbuf *mb) {
+ return recv_handler(src, mb, sock);
+}
+
+
+/**
* Create DTLS Socket
*
* @param sockp Pointer to returned DTLS Socket
@@ -827,8 +861,57 @@
if (err)
goto out;
+ sock->mtu = MTU_DEFAULT;
+ sock->headroom = HEADROOM_DEFAULT;
+ sock->connh = connh;
+ sock->sendh = send_handler;
+ sock->arg = arg;
+
+ out:
+ if (err)
+ mem_deref(sock);
+ else
+ *sockp = sock;
+
+ return err;
+}
+
+
+/**
+ * Create a DTLS Socket without using an UDP socket underneath
+ *
+ * @param sockp Pointer to returned DTLS Socket
+ * @param htsize Connection hash table size. Set to 0 if one DTLS session shall
+ * be used for all peers.
+ * @param connh Connect handler
+ * @param sendh Send handler
+ * @param mtuh MTU handler
+ * @param arg Handler argument
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int dtls_socketless(struct dtls_sock **sockp, uint32_t htsize,
+ dtls_conn_h *connh, dtls_send_h *sendh, dtls_mtu_h *mtuh,
+ void *arg)
+{
+ struct dtls_sock *sock;
+ int err;
+
+ if (!sockp || !sendh)
+ return EINVAL;
+
+ sock = mem_zalloc(sizeof(*sock), sock_destructor);
+ if (!sock)
+ return ENOMEM;
+
+ err = hash_alloc(&sock->ht, hash_valid_size(htsize));
+ if (err)
+ goto out;
+
sock->mtu = MTU_DEFAULT;
sock->connh = connh;
+ sock->sendh = sendh;
+ sock->mtuh = mtuh;
sock->arg = arg;
out:
@@ -869,6 +952,34 @@
}
+/*
+ * Get headroom of a DTLS Socket
+ *
+ * @param sock DTLS Socket
+ *
+ * @return Headroom value.
+ */
+size_t dtls_headroom(struct dtls_sock *sock)
+{
+ return sock ? sock->headroom : 0;
+}
+
+
+/**
+ * Set headroom on a DTLS Socket
+ *
+ * @param sock DTLS Socket
+ * @param headroom Headroom value
+ */
+void dtls_set_headroom(struct dtls_sock *sock, size_t headroom)
+{
+ if (!sock)
+ return;
+
+ sock->headroom = headroom;
+}
+
+
void dtls_recv_packet(struct dtls_sock *sock, const struct sa *src,
struct mbuf *mb)
{
diff --git a/third_party/rawrtc/re/src/tmr/meson.build b/third_party/rawrtc/re/src/tmr/meson.build
new file mode 100644
index 0000000..9e9fb4a
--- /dev/null
+++ b/third_party/rawrtc/re/src/tmr/meson.build
@@ -0,0 +1 @@
+sources += files('tmr.c')
diff --git a/third_party/rawrtc/re/src/turn/meson.build b/third_party/rawrtc/re/src/turn/meson.build
new file mode 100644
index 0000000..4d0b6c5
--- /dev/null
+++ b/third_party/rawrtc/re/src/turn/meson.build
@@ -0,0 +1,5 @@
+sources += files([
+ 'chan.c',
+ 'perm.c',
+ 'turnc.c',
+])
diff --git a/third_party/rawrtc/re/src/udp/meson.build b/third_party/rawrtc/re/src/udp/meson.build
new file mode 100644
index 0000000..7dabb52
--- /dev/null
+++ b/third_party/rawrtc/re/src/udp/meson.build
@@ -0,0 +1,4 @@
+sources += files([
+ 'udp.c',
+ 'mcast.c',
+])
diff --git a/third_party/rawrtc/re/src/uri/meson.build b/third_party/rawrtc/re/src/uri/meson.build
new file mode 100644
index 0000000..b0b67fe
--- /dev/null
+++ b/third_party/rawrtc/re/src/uri/meson.build
@@ -0,0 +1,5 @@
+sources += files([
+ 'uri.c',
+ 'ucmp.c',
+ 'uric.c',
+])
diff --git a/third_party/rawrtc/re/src/websock/meson.build b/third_party/rawrtc/re/src/websock/meson.build
new file mode 100644
index 0000000..ca078d3
--- /dev/null
+++ b/third_party/rawrtc/re/src/websock/meson.build
@@ -0,0 +1 @@
+sources += files('websock.c')
diff --git a/third_party/rawrtc/usrsctp/BUILD b/third_party/rawrtc/usrsctp/BUILD
index 7704bb9..654d29b 100644
--- a/third_party/rawrtc/usrsctp/BUILD
+++ b/third_party/rawrtc/usrsctp/BUILD
@@ -1,21 +1,63 @@
-# usrsctp is only actually being used for the CRC function, and getting
-# the entire library building was being obnoxious.
+load("@//tools/build_rules:select.bzl", "compiler_select")
+
cc_library(
- name = "usrsctp_crc32",
- srcs = ["usrsctplib/netinet/sctp_crc32.c"],
+ name = "usrsctp",
+ srcs = [
+ "usrsctplib/netinet/sctp_asconf.c",
+ "usrsctplib/netinet/sctp_auth.c",
+ "usrsctplib/netinet/sctp_bsd_addr.c",
+ "usrsctplib/netinet/sctp_callout.c",
+ "usrsctplib/netinet/sctp_cc_functions.c",
+ "usrsctplib/netinet/sctp_crc32.c",
+ "usrsctplib/netinet/sctp_indata.c",
+ "usrsctplib/netinet/sctp_input.c",
+ "usrsctplib/netinet/sctp_output.c",
+ "usrsctplib/netinet/sctp_pcb.c",
+ "usrsctplib/netinet/sctp_peeloff.c",
+ "usrsctplib/netinet/sctp_sha1.c",
+ "usrsctplib/netinet/sctp_ss_functions.c",
+ "usrsctplib/netinet/sctp_sysctl.c",
+ "usrsctplib/netinet/sctp_timer.c",
+ "usrsctplib/netinet/sctp_userspace.c",
+ "usrsctplib/netinet/sctp_usrreq.c",
+ "usrsctplib/netinet/sctputil.c",
+ "usrsctplib/netinet6/sctp6_usrreq.c",
+ "usrsctplib/user_environment.c",
+ "usrsctplib/user_mbuf.c",
+ "usrsctplib/user_recv_thread.c",
+ "usrsctplib/user_socket.c",
+ ],
hdrs = glob(["usrsctplib/**/*.h"]),
copts = [
"-Wno-cast-qual",
"-Wno-cast-align",
"-Wno-unused-parameter",
"-Wno-incompatible-pointer-types-discards-qualifiers",
+ "-D__Userspace_os_Linux",
+ "-D__Userspace__",
+ "-D_GNU_SOURCE",
+ "-DSCTP_DEBUG",
+ "-DSCTP_SIMPLE_ALLOCATOR",
+ "-DINET",
+ "-DINET6",
+ "-DSCTP_PROCESS_LEVEL_LOCKS",
+ "-DHAVE_SYS_QUEUE_H",
+ "-DHAVE_STDATOMIC_H",
+ "-DHAVE_NETINET_IP_ICMP_H",
+ "-DHAVE_LINUX_RTNETLINK_H",
+ "-DHAVE_LINUX_IF_ADDR_H",
+ "-Wno-address-of-packed-member",
+ ] + compiler_select({
+ "clang": [],
+ "gcc": [
+ "-Wno-discarded-qualifiers",
+ ],
+ }),
+ includes = [
+ "usrsctplib/",
+ "usrsctplib/netinet",
+ "usrsctplib/netinet6",
],
- defines = [
- "__Userspace_os_Linux",
- "__Userspace__",
- "SCTP_SIMPLE_ALLOCATOR",
- ],
- includes = ["usrsctplib/"],
target_compatible_with = ["@platforms//os:linux"],
visibility = ["//visibility:public"],
)
diff --git a/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctp_constants.h b/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctp_constants.h
index e275dd9..57240cd 100755
--- a/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctp_constants.h
+++ b/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctp_constants.h
@@ -778,7 +778,7 @@
#define SCTP_DEFAULT_SPLIT_POINT_MIN 2904
/* Maximum length of diagnostic information in error causes */
-#define SCTP_DIAG_INFO_LEN 64
+#define SCTP_DIAG_INFO_LEN 128
/* ABORT CODES and other tell-tale location
* codes are generated by adding the below
diff --git a/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctp_pcb.c b/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctp_pcb.c
index ec3ff6d..ca84395 100755
--- a/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctp_pcb.c
+++ b/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctp_pcb.c
@@ -6845,7 +6845,7 @@
TAILQ_INIT(&SCTP_BASE_INFO(callqueue));
#endif
#if defined(__Userspace__)
- mbuf_init(NULL);
+ usrsctpmbuf_init(NULL);
atomic_init();
#if defined(THREAD_SUPPORT) && (defined(INET) || defined(INET6))
recv_thread_init();
diff --git a/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctputil.c b/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctputil.c
index 87e7774..5ac93d5 100755
--- a/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctputil.c
+++ b/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctputil.c
@@ -5013,7 +5013,7 @@
*/
struct mbuf *
-sctp_generate_cause(uint16_t code, char *info)
+sctp_generate_cause(uint16_t code, const char *info)
{
struct mbuf *m;
struct sctp_gen_error_cause *cause;
diff --git a/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctputil.h b/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctputil.h
index 7746d54..1babe19 100755
--- a/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctputil.h
+++ b/third_party/rawrtc/usrsctp/usrsctplib/netinet/sctputil.h
@@ -281,7 +281,7 @@
#endif
);
-struct mbuf *sctp_generate_cause(uint16_t, char *);
+struct mbuf *sctp_generate_cause(uint16_t, const char *);
struct mbuf *sctp_generate_no_user_data_cause(uint32_t);
void sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
diff --git a/third_party/rawrtc/usrsctp/usrsctplib/user_mbuf.c b/third_party/rawrtc/usrsctp/usrsctplib/user_mbuf.c
index 9a82746..232d74e 100755
--- a/third_party/rawrtc/usrsctp/usrsctplib/user_mbuf.c
+++ b/third_party/rawrtc/usrsctp/usrsctplib/user_mbuf.c
@@ -121,7 +121,7 @@
mbuf_mb_args.type = type;
#endif
/* Mbuf master zone, zone_mbuf, has already been
- * created in mbuf_init() */
+ * created in usrsctpmbuf_init() */
mret = SCTP_ZONE_GET(zone_mbuf, struct mbuf);
#if defined(SCTP_SIMPLE_ALLOCATOR)
mb_ctor_mbuf(mret, &mbuf_mb_args, 0);
@@ -328,11 +328,11 @@
/************ End functions to substitute umem_cache_alloc and umem_cache_free **************/
/* __Userspace__
- * TODO: mbuf_init must be called in the initialization routines
+ * TODO: usrsctpmbuf_init must be called in the initialization routines
* of userspace stack.
*/
void
-mbuf_init(void *dummy)
+usrsctpmbuf_init(void *dummy)
{
/*
diff --git a/third_party/rawrtc/usrsctp/usrsctplib/user_mbuf.h b/third_party/rawrtc/usrsctp/usrsctplib/user_mbuf.h
index 7893ea9..64a0ac3 100755
--- a/third_party/rawrtc/usrsctp/usrsctplib/user_mbuf.h
+++ b/third_party/rawrtc/usrsctp/usrsctplib/user_mbuf.h
@@ -58,7 +58,7 @@
/* mbuf initialization function */
-void mbuf_init(void *);
+void usrsctpmbuf_init(void *);
#define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from))
#define MGET(m, how, type) ((m) = m_get((how), (type)))
diff --git a/y2020/actors/autonomous_actor.cc b/y2020/actors/autonomous_actor.cc
index c78a33f..da64408 100644
--- a/y2020/actors/autonomous_actor.cc
+++ b/y2020/actors/autonomous_actor.cc
@@ -12,12 +12,12 @@
#include "y2020/control_loops/drivetrain/drivetrain_base.h"
DEFINE_bool(spline_auto, false, "If true, define a spline autonomous mode");
-DEFINE_bool(ignore_vision, true, "If true, ignore vision");
-DEFINE_bool(galactic_search, true,
+DEFINE_bool(ignore_vision, false, "If true, ignore vision");
+DEFINE_bool(galactic_search, false,
"If true, do the galactic search autonomous");
DEFINE_bool(bounce, false, "If true, run the AutoNav Bounce autonomous");
DEFINE_bool(barrel, false, "If true, run the AutoNav Barrel autonomous");
-DEFINE_bool(slalom, false, "If true, run the AutoNav Slalom autonomous");
+DEFINE_bool(slalom, true, "If true, run the AutoNav Slalom autonomous");
namespace y2020 {
namespace actors {
diff --git a/y2020/actors/splines/autonav_barrel.json b/y2020/actors/splines/autonav_barrel.json
index 2649661..467420b 100644
--- a/y2020/actors/splines/autonav_barrel.json
+++ b/y2020/actors/splines/autonav_barrel.json
@@ -1 +1 @@
-{"spline_count": 4, "spline_x": [-3.439527264404297, -1.4521381072998047, -1.9621627899169916, 2.3140273590087896, -0.15155005187988285, -1.2099180084228516, -2.2682859649658202, -1.9194444671630853, 2.2364890686035164, 3.0541333465576175, 2.1377636993408204, 1.2213940521240234, -1.428989520263672, 1.0701125885009766, 3.340432150268555, 3.8391586853027344, 4.337885220336914, 3.065018728637696, 2.9864502685546874, 0.33045889892578123, -3.72018571472168], "spline_y": [0.0026085617065429684, -0.004877609252929687, -0.094301220703125, 0.4880167236328125, -1.993748071289062, -1.4883794998168944, -0.9830109283447268, 2.509491009521483, -2.4357923103332517, 0.09796495056152343, 1.1720165428161622, 2.246068135070801, 1.8604140586853029, -2.8892405044555662, -2.3678153549194336, -1.3137169052124023, -0.2596184555053709, 1.3271532943725592, -0.6553675552368162, -0.01534266815185547, -0.04329328765869141], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 7.499999999999998}, {"constraint_type": "LATERAL_ACCELERATION", "value": 8.499999999999995}, {"constraint_type": "VOLTAGE", "value": 11.999999999999993}]}
\ No newline at end of file
+{"spline_count": 4, "spline_x": [-3.439527264404297, -1.4521381072998047, -1.9621627899169916, 2.661975888061524, 0.06282058410644531, -1.1731946685791015, -2.4092099212646483, -2.2820851226806633, 2.9662840576171883, 4.035525769042969, 2.715648193359375, 1.3957706176757811, -2.313226245117187, 1.953077297973632, 4.110928143310546, 4.481738067626953, 4.85254799194336, 3.436316995239258, 1.6429130905151372, -1.0130782791137694, -4.985386976623535], "spline_y": [0.0026085617065429684, -0.004877609252929687, -0.094301220703125, 1.5597702003479004, -2.059494058227539, -1.5799808853149415, -1.1004677124023439, 3.477822891998291, -3.3979725334167483, 0.032006476593017474, 1.223588104248047, 2.4151697319030765, 1.3683539772033693, -3.5761337516784657, -2.7649265808105468, -1.4880899826049805, -0.2112533843994142, 1.531212641143799, -0.560890182495117, 0.07913470458984374, -0.04733257598876953], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 7.499999999999998}, {"constraint_type": "LATERAL_ACCELERATION", "value": 8.499999999999995}, {"constraint_type": "VOLTAGE", "value": 11.999999999999993}]}
\ No newline at end of file
diff --git a/y2020/actors/splines/autonav_bounce_1.json b/y2020/actors/splines/autonav_bounce_1.json
index 233040c..53989c5 100644
--- a/y2020/actors/splines/autonav_bounce_1.json
+++ b/y2020/actors/splines/autonav_bounce_1.json
@@ -1 +1 @@
-{"spline_count": 1, "spline_x": [-3.854933303833008, -3.1908587219238282, -2.8742285649343122, -2.3949857243581434, -2.3116481497990145, -2.304892561983471], "spline_y": [0.04259449310302734, 0.04866970367431641, 0.12185038589540864, 0.3335849649896266, 0.9762657982284103, 1.5617851239669422], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 6.0}, {"constraint_type": "LATERAL_ACCELERATION", "value": 6.0}, {"constraint_type": "VOLTAGE", "value": 9.999999999999993}]}
\ No newline at end of file
+{"spline_count": 1, "spline_x": [-3.6514654907226562, -2.933625585937499, -2.8310597534179687, -2.3949857243581434, -2.3116481497990145, -2.304892561983471], "spline_y": [-0.0021888198852539065, -0.012177745056152347, 0.24826333465576164, 0.3335849649896266, 0.9762657982284103, 1.5617851239669422], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 6.0}, {"constraint_type": "LATERAL_ACCELERATION", "value": 6.0}, {"constraint_type": "VOLTAGE", "value": 12.0}]}
\ No newline at end of file
diff --git a/y2020/actors/splines/autonav_bounce_2.json b/y2020/actors/splines/autonav_bounce_2.json
index 365f721..de04a24 100644
--- a/y2020/actors/splines/autonav_bounce_2.json
+++ b/y2020/actors/splines/autonav_bounce_2.json
@@ -1 +1 @@
-{"spline_count": 2, "spline_x": [-2.300972622575431, -2.276803448275862, -2.2197493927001952, -2.0912932800292934, -1.8907473815917966, -1.6507643554687499, -1.4107813293457032, -1.1313611755371065, -0.17296153564453126, -0.002871917724609375, -0.0033345198006461863], "spline_y": [1.52789615352236, 0.9051463547279094, 0.5131617004394531, 0.6903293746948247, 0.10570575714111341, -0.4938134628295899, -1.0933326828002932, -1.7077475051879882, -2.25593497467041, -1.0112510650634765, 1.5787289769665949], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 6.0}, {"constraint_type": "LATERAL_ACCELERATION", "value": 5.0}, {"constraint_type": "VOLTAGE", "value": 9.999999999999993}]}
\ No newline at end of file
+{"spline_count": 2, "spline_x": [-2.300972622575431, -2.2976492889404296, -2.2449048339843745, -2.0912932800292934, -1.8907473815917966, -1.6507643554687499, -1.4107813293457032, -1.1313611755371067, 0.10809223937988281, -0.002871917724609375, -0.0033345198006461863], "spline_y": [1.52789615352236, 0.8841274291992188, 0.5057435485839843, 0.6903293746948247, 0.10570575714111341, -0.4938134628295899, -1.0933326828002932, -1.7077475051879885, -2.2848872772216797, -1.0112510650634765, 1.5787289769665949], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 6.0}, {"constraint_type": "LATERAL_ACCELERATION", "value": 6.0}, {"constraint_type": "VOLTAGE", "value": 12.0}]}
\ No newline at end of file
diff --git a/y2020/actors/splines/autonav_bounce_3.json b/y2020/actors/splines/autonav_bounce_3.json
index 96a3e83..9ef5ae2 100644
--- a/y2020/actors/splines/autonav_bounce_3.json
+++ b/y2020/actors/splines/autonav_bounce_3.json
@@ -1 +1 @@
-{"spline_count": 1, "spline_x": [0.012595041322314211, 0.035615267944335935, -1.0700335235595704, 3.6841669830322266, 2.4339549224853516, 2.4026312530517577], "spline_y": [1.5869752066115703, -0.6927920150756836, -2.8280890045166016, -2.13918454284668, -0.8389284439086915, 1.5275657707214354], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 5.5}, {"constraint_type": "LATERAL_ACCELERATION", "value": 5.5}, {"constraint_type": "VOLTAGE", "value": 9.999999999999993}]}
\ No newline at end of file
+{"spline_count": 1, "spline_x": [0.012595041322314211, 0.035615267944335935, -1.0700335235595704, 3.6841669830322266, 2.4339549224853516, 2.4026312530517577], "spline_y": [1.5869752066115703, -0.6927920150756836, -2.8280890045166016, -2.13918454284668, -0.8389284439086915, 1.5275657707214354], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 5.5}, {"constraint_type": "LATERAL_ACCELERATION", "value": 5.5}, {"constraint_type": "VOLTAGE", "value": 12.0}]}
\ No newline at end of file
diff --git a/y2020/actors/splines/autonav_bounce_4.json b/y2020/actors/splines/autonav_bounce_4.json
index 042b800..ee65a95 100644
--- a/y2020/actors/splines/autonav_bounce_4.json
+++ b/y2020/actors/splines/autonav_bounce_4.json
@@ -1 +1 @@
-{"spline_count": 1, "spline_x": [2.420588296508789, 2.4232765045166014, 2.5394848846055655, 2.5435332334653036, 2.696887710571289, 3.661613708496094], "spline_y": [1.5176544570922852, 0.9584327774047853, 0.7181724172979964, 0.2998157461902411, 0.1163405731201172, 0.12068274993896484], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 5.5}, {"constraint_type": "LATERAL_ACCELERATION", "value": 5.5}, {"constraint_type": "VOLTAGE", "value": 9.999999999999993}]}
\ No newline at end of file
+{"spline_count": 1, "spline_x": [2.420588296508789, 2.4232765045166014, 2.411430715942383, 3.181959380926238, 3.284892517089844, 3.989023956298828], "spline_y": [1.5176544570922852, 0.9584327774047853, 0.49865735321044924, 0.1483674322864324, -0.07779583282470703, -0.5024309600830078], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 5.5}, {"constraint_type": "LATERAL_ACCELERATION", "value": 5.5}, {"constraint_type": "VOLTAGE", "value": 12.0}]}
\ No newline at end of file
diff --git a/y2020/actors/splines/autonav_slalom.json b/y2020/actors/splines/autonav_slalom.json
index 6936d80..664b929 100644
--- a/y2020/actors/splines/autonav_slalom.json
+++ b/y2020/actors/splines/autonav_slalom.json
@@ -1 +1 @@
-{"spline_count": 8, "spline_x": [-3.4749518463134765, -3.1365934295654294, -2.9590075597612686, -2.760017578125, -2.5225692810058593, -2.273429890106328, -2.0242904992067965, -1.7634600145268742, -1.4530334014892579, -1.1285066986083985, -0.68847890625, -0.24845111389160157, 0.30707776794433594, 1.871516759595437, 2.184855541688278, 2.417896609990923, 2.650937678293568, 2.8036810328060167, 3.5928316545035397, 3.8742948612577215, 3.853217129516602, 3.832139397775482, 3.5085207275390626, 2.5905665683350616, 2.4835600727761933, 2.3169760114107887, 2.150391950045384, 1.9242303228734432, 1.4789411224365234, 1.0076788024902341, 0.21033948669433594, -0.5869998291015622, -1.7104161407470695, -1.6109939147949213, -2.028241729609699, -2.2553543746758296, -2.4824670197419603, -2.519444495059444, -3.4609283874195165, -3.690070111083984, -4.450609153747559], "spline_y": [-1.6666796630859375, -1.5026007247924806, -1.3657751963192004, -1.3422337692260742, -1.0754058700561524, -0.758464560101141, -0.4415232501461297, -0.07446852940602877, 0.20931454925537119, 0.2820978973388672, 0.3545516143798828, 0.4270053314208984, 0.49912941741943356, 0.32144404823651485, -0.1969548795707987, -0.7699543538073782, -1.3429538280439577, -1.970553848709803, -1.7554159149993005, -1.2416998867240683, -0.7131605392456054, -0.18462119176714253, 0.3587414749145508, 0.459862695717713, -0.20117116182572614, -0.7732763550311204, -1.3453815482365146, -1.8285580771038639, -1.8799707138061523, -2.1832105377197277, -2.2168379425048825, -2.2504653472900373, -2.0144803329467713, -1.7455779479980467, -1.3180884153753891, -0.7902526419865145, -0.2624168685976398, 0.365765145557452, 1.047112901958292, 1.014591268157959, 1.6061016746520995], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 6.999999999999993}, {"constraint_type": "LATERAL_ACCELERATION", "value": 6.999999999999993}, {"constraint_type": "VOLTAGE", "value": 12.0}]}
\ No newline at end of file
+{"spline_count": 8, "spline_x": [-3.635843479156494, -3.2806723095703125, -3.1868360023498545, -2.858219025878906, -2.5751525830078124, -2.3197756127929687, -2.064398642578125, -1.8367111450195317, -1.7695840795898432, -0.7814239306640623, -0.18952982666015625, 0.40236427734374985, 0.5979923364257812, 1.9385774853515625, 2.5234608544921873, 2.8941172998046873, 3.2647737451171874, 3.4212032666015624, 4.386921788780882, 4.586409534109282, 4.4665292285156255, 4.346648922921969, 3.907400566406256, 2.758564643554687, 2.5834497895730655, 2.3319990527343752, 2.080548315895685, 1.7527616961999257, 1.7609669311523446, 0.8905572692871097, 0.13155197021484377, -0.6274533288574221, -1.2750542651367192, -1.6109939147949213, -2.028241729609699, -2.2553543746758296, -2.4824670197419603, -2.519444495059444, -3.4609283874195165, -3.690070111083984, -4.450609153747559], "spline_y": [-1.7265489738464355, -1.5607546752929686, -1.4611474120330816, -1.326837150878906, -1.023809600830078, -0.7159144409179687, -0.4080192810058594, -0.09525651123046863, -0.04151700073242237, 0.44292831298828117, 0.5805910729980469, 0.7182538330078126, 0.5091340393066406, 1.3885468725585939, 0.09532766967773454, -0.7626050793457031, -1.6205378283691407, -2.0431841235351564, -1.6678404465544734, -1.0808934231010208, -0.5693647814941407, -0.05783613988726066, 0.3782741198730468, 0.4133138415527349, -0.31849562837846057, -0.8944612170410157, -1.4704268057035708, -1.8905485130974853, -1.8685408300781232, -2.0658371594238267, -2.0819412927246095, -2.0980454260253922, -1.932957363281254, -1.7455779479980467, -1.3180884153753891, -0.7902526419865145, -0.2624168685976398, 0.365765145557452, 1.047112901958292, 1.014591268157959, 1.6061016746520995], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 6.999999999999993}, {"constraint_type": "LATERAL_ACCELERATION", "value": 6.999999999999993}, {"constraint_type": "VOLTAGE", "value": 12.0}]}
\ No newline at end of file
diff --git a/y2020/vision/tools/python_code/README.md b/y2020/vision/tools/python_code/README.md
new file mode 100644
index 0000000..09e0b01
--- /dev/null
+++ b/y2020/vision/tools/python_code/README.md
@@ -0,0 +1,42 @@
+# Notes on running the SIFT matching code
+
+Here are some of the key modules:
+
+## Camera Definition
+ * Class defined in camera_definition.py
+ * Includes:
+ * Camera Intrinsic
+ * Camera Extrinsic
+ * Team number & node name
+ * We create a separate camera definition for each camera (on each robot)
+ * For now, they're all identical, but we need a mechanism for having each be unique, esp. for the extrinsics
+
+## Target Definition
+ * Class defined in target_definition.py
+ * For each target (e.g., Power Port Red, Power Port Blue, Loading Station Red, etc), we define both an ideal target (e.g., the CAD / graphic version, with known 3D point locations) and a training target (an image from our cameras in the environment we're expecting).
+ * KEY IDEA: We use the ideal target info (including 3D locations of points) to determine the 3D locations of the keypoints in the training target
+
+ * The following are parts of the TargetData class:
+ * image
+ * List of polygons which define flat surfaces on the ideal target
+ * List of corresponding 3D points for the polygons, so we can automatically extract 3D locations of the keypoints (via interpolation)
+ * Keypoint List of extracted keypoints from the target image (ideal & training)
+ * Descriptor list (which is used to match features)
+ * (Ideal) Target point position and rotation
+ * (Ideal) Target point 2D-- location of a special point in the target used to help visualize accuracy of matches
+ * Target point radius (used to help size things to check on distance)
+ * Keypoint List 3d of the 3D locations of each of the keypoints
+ * These are computed based on the 3D polygon definition
+ * These are 3D with respect to our global origin
+ * This is used to determine our pose as we do th ematching
+
+## Header definition of target data
+
+ * Creating the config file
+ * The output of all this is a sift_training_data.h file that gets used in other parts of the code (e.g., //y2020/vision:camera_reader)
+ * By building "run_load_training_data", you should get this file generated
+
+## Testing / debugging
+ * There's a couple tests that can be run through bazel
+ * image_match_test.py is a good way to see what's being matched
+ * You have to specify and select the correct query_image to test on
diff --git a/y2020/vision/tools/python_code/image_match_test.py b/y2020/vision/tools/python_code/image_match_test.py
index 8d16104..b085166 100644
--- a/y2020/vision/tools/python_code/image_match_test.py
+++ b/y2020/vision/tools/python_code/image_match_test.py
@@ -32,7 +32,7 @@
'test_images/train_loading_bay_blue.png', #9
'test_images/train_loading_bay_red.png', #10
'test_images/pi-7971-3_test_image.png', #11
- 'sample_images/capture-2020-02-13-16-40-07.png',
+ 'test_images/test_taped_dusk-2021-04-03-19-30-00.png', #12
]
training_image_index = 0
@@ -126,6 +126,7 @@
# If we're querying static images, show full results
if (query_image_index is not -1):
print("Showing results for static query image")
+ cv2.imshow('test', query_images[0]), cv2.waitKey(0)
homography_list, matches_mask_list = tam.show_results(
training_images, train_keypoint_lists, query_images,
query_keypoint_lists, target_pt_list, good_matches_list)
@@ -162,18 +163,24 @@
# -- This causes a lot of mapping around of points, but overall OK
src_pts_3d = []
+ query_image_matches = query_images[0].copy()
for m in good_matches:
src_pts_3d.append(target_list[i].keypoint_list_3d[m.trainIdx])
pt = query_keypoint_lists[0][m.queryIdx].pt
- query_images[0] = cv2.circle(
- query_images[0], (int(pt[0]), int(pt[1])), 5, (0, 255, 0), 3)
+ query_image_matches = cv2.circle(query_image_matches,
+ (int(pt[0]), int(pt[1])), 5,
+ (0, 255, 0), 3)
- cv2.imshow('DEBUG', query_images[0]), cv2.waitKey(0)
+ cv2.imshow('DEBUG matches', query_image_matches), cv2.waitKey(0)
# Reshape 3d point list to work with computations to follow
src_pts_3d_array = np.asarray(np.float32(src_pts_3d)).reshape(-1, 3, 1)
# Load from camera parameters
cam_mat = camera_params.camera_int.camera_matrix
+ cam_mat[0][0] = 390
+ cam_mat[1][1] = 390
+ # TODO<Jim>: Would be good to read this from a config file
+ print("FIXING CAM MAT to pi camera: ", cam_mat)
dist_coeffs = camera_params.camera_int.dist_coeffs
# Create list of matching query point locations
@@ -227,9 +234,17 @@
img_ret = field_display.plot_line_on_field(img_ret, (255, 255, 0),
T_w_ci_estj, T_w_target_pt)
# THESE ARE OUR ESTIMATES OF HEADING, DISTANCE, AND SKEW TO TARGET
- log_file.write('%lf, %lf, %lf\n' %
- (heading_est, distance_to_target_ground,
- angle_to_target_robot))
+ log_file.write(
+ '%lf, %lf, %lf\n' %
+ (heading_est, distance_to_target_ground, angle_to_target_robot))
+ print("Estimates: \n Heading on field: ",
+ "{:.2f}".format(heading_est), " radians; ",
+ "{:.2f}".format(heading_est / math.pi * 180.0),
+ " degrees\n Distance to target: ",
+ "{:.2f}".format(distance_to_target_ground),
+ "m\n Angle to target: ", "{:.2f}".format(angle_to_target_robot),
+ " radians; ", "{:.2f}".format(angle_to_target_robot / math.pi *
+ 180.0), " degrees\n")
# A bunch of code to visualize things...
#
@@ -241,9 +256,9 @@
target_pt_list[i].reshape(-1, 1, 2),
homography_list[i]).astype(int)
# Ballpark the size of the circle so it looks right on image
- radius = int(
- 32 * abs(homography_list[i][0][0] + homography_list[i][1][1]) /
- 2) # Average of scale factors
+ radius = int(12 *
+ abs(homography_list[i][0][0] + homography_list[i][1][1]) /
+ 2) # Average of scale factors
query_image_copy = cv2.circle(query_image_copy,
(target_point_2d_trans.flatten()[0],
target_point_2d_trans.flatten()[1]),
diff --git a/y2020/vision/tools/python_code/image_stream.py b/y2020/vision/tools/python_code/image_stream.py
deleted file mode 100644
index 2cd5ac7..0000000
--- a/y2020/vision/tools/python_code/image_stream.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import cv2
-import datetime
-# Open the device at the ID X for /dev/videoX
-CAMERA_INDEX = 0
-cap = cv2.VideoCapture(CAMERA_INDEX)
-
-#Check whether user selected camera is opened successfully.
-if not (cap.isOpened()):
- print("Could not open video device /dev/video%d" % CAMERA_INDEX)
- quit()
-
-while True:
- # Capture frame-by-frame
- ret, frame = cap.read()
-
- exp = cap.get(cv2.CAP_PROP_EXPOSURE)
- #print("Exposure:", exp)
- # Display the resulting frame
- cv2.imshow('preview', frame)
-
- #Waits for a user input to capture image or quit the application
- keystroke = cv2.waitKey(1)
-
- if keystroke & 0xFF == ord('q'):
- break
- elif keystroke & 0xFF == ord('c'):
- image_name = datetime.datetime.today().strftime(
- "capture-%b-%d-%Y-%H-%M-%S.png")
- print("Capturing image as %s" % image_name)
- cv2.imwrite(image_name, frame)
-
-# When everything's done, release the capture
-cap.release()
-cv2.destroyAllWindows()
diff --git a/y2020/vision/tools/python_code/target_definition.py b/y2020/vision/tools/python_code/target_definition.py
index 6080ac2..be7e223 100644
--- a/y2020/vision/tools/python_code/target_definition.py
+++ b/y2020/vision/tools/python_code/target_definition.py
@@ -14,8 +14,8 @@
global VISUALIZE_KEYPOINTS
VISUALIZE_KEYPOINTS = False
-# For now, just have a 32 pixel radius, based on original training image
-target_radius_default = 32.
+# For now, just have a 12 pixel radius, based on captured (taped) training image
+target_radius_default = 12.
class TargetData:
@@ -55,8 +55,8 @@
def project_keypoint_to_3d_by_polygon(self, keypoint_list):
# Create dummy array of correct size that we can put values in
- point_list_3d = np.asarray(
- [(0., 0., 0.) for kp in keypoint_list]).reshape(-1, 3)
+ point_list_3d = np.asarray([(0., 0., 0.)
+ for kp in keypoint_list]).reshape(-1, 3)
# Iterate through our polygons
for poly_ind in range(len(self.polygon_list)):
# Filter and project points for each polygon in the list
@@ -64,9 +64,10 @@
keypoint_list, None, [self.polygon_list[poly_ind]])
glog.info("Filtering kept %d of %d features" %
(len(keep_list), len(keypoint_list)))
- filtered_point_array = np.asarray(
- [(keypoint.pt[0], keypoint.pt[1])
- for keypoint in filtered_keypoints]).reshape(-1, 2)
+ filtered_point_array = np.asarray([
+ (keypoint.pt[0], keypoint.pt[1])
+ for keypoint in filtered_keypoints
+ ]).reshape(-1, 2)
filtered_point_list_3d = dtd.compute_3d_points(
filtered_point_array, self.reprojection_map_list[poly_ind])
for i in range(len(keep_list)):
@@ -100,13 +101,16 @@
loading_bay_edge_y = 0.784
loading_bay_width = 1.524
loading_bay_height = 0.933
- wing_angle = 20. * math.pi / 180.
+ # Wing angle on actual field target
+ # wing_angle = 20. * math.pi / 180.
+ ### NOTE: Setting wing angle to zero to match current FRC971 target
+ wing_angle = 0
# Pick the target center location at halfway between top and bottom of the top panel
- power_port_target_height = (
- power_port_total_height + power_port_bottom_wing_height) / 2.
+ power_port_target_height = (power_port_total_height +
+ power_port_bottom_wing_height) / 2.
- ### Cafeteria target definition
+ ### Taped up FRC target definition
inch_to_meter = 0.0254
c_power_port_total_height = (79.5 + 39.5) * inch_to_meter
c_power_port_edge_y = 1.089
@@ -116,65 +120,81 @@
c_power_port_white_marker_z = (79.5 - 19.5) * inch_to_meter
# Pick the target center location at halfway between top and bottom of the top panel
- c_power_port_target_height = (
- power_port_total_height + power_port_bottom_wing_height) / 2.
+ c_power_port_target_height = (power_port_total_height +
+ power_port_bottom_wing_height) / 2.
###
- ### Cafe power port
+ ### Taped power port
###
- # Create the reference "ideal" image
- ideal_power_port_cafe = TargetData(
- 'test_images/train_cafeteria-2020-02-13-16-27-25.png')
+ # Create the reference "ideal" image.
+ # NOTE: Since we don't have an "ideal" (e.g., graphic) version, we're
+ # just using the same image as the training image.
+ ideal_power_port_taped = TargetData(
+ 'test_images/train_power_port_taped-2020-08-20-13-27-50.png')
# Start at lower left corner, and work around clockwise
# These are taken by manually finding the points in gimp for this image
- power_port_cafe_main_panel_polygon_points_2d = [(271, 456), (278, 394),
- (135, 382), (286, 294),
- (389, 311), (397,
- 403), (401,
- 458)]
+ power_port_taped_main_panel_polygon_points_2d = [(181, 423), (186, 192),
+ (45, 191), (188, 93),
+ (310, 99), (314, 196),
+ (321, 414)]
# These are "virtual" 3D points based on the expected geometry
- power_port_cafe_main_panel_polygon_points_3d = [
+ power_port_taped_main_panel_polygon_points_3d = [
+ (field_length / 2., -c_power_port_edge_y, 0.),
(field_length / 2., -c_power_port_edge_y,
- c_power_port_white_marker_z), (field_length / 2.,
- -c_power_port_edge_y,
- c_power_port_bottom_wing_height),
+ c_power_port_bottom_wing_height),
(field_length / 2., -c_power_port_edge_y + c_power_port_wing_width,
- c_power_port_bottom_wing_height), (field_length / 2.,
- -c_power_port_edge_y,
- c_power_port_total_height),
+ c_power_port_bottom_wing_height),
+ (field_length / 2., -c_power_port_edge_y, c_power_port_total_height),
(field_length / 2., -c_power_port_edge_y - c_power_port_width,
c_power_port_total_height),
(field_length / 2., -c_power_port_edge_y - c_power_port_width,
c_power_port_bottom_wing_height),
- (field_length / 2., -c_power_port_edge_y - c_power_port_width,
- c_power_port_white_marker_z)
+ (field_length / 2., -c_power_port_edge_y - c_power_port_width, 0.)
]
- # Populate the cafe power port
- ideal_power_port_cafe.polygon_list.append(
- power_port_cafe_main_panel_polygon_points_2d)
- ideal_power_port_cafe.polygon_list_3d.append(
- power_port_cafe_main_panel_polygon_points_3d)
+ power_port_taped_wing_panel_polygon_points_2d = [(312, 99), (438, 191),
+ (315, 195)]
+
+ # These are "virtual" 3D points based on the expected geometry
+ power_port_taped_wing_panel_polygon_points_3d = [
+ (field_length / 2., -power_port_edge_y - power_port_width,
+ power_port_total_height),
+ (field_length / 2. - power_port_wing_width * math.sin(wing_angle),
+ -power_port_edge_y - power_port_width -
+ power_port_wing_width * math.cos(wing_angle),
+ power_port_bottom_wing_height),
+ (field_length / 2., -power_port_edge_y - power_port_width,
+ power_port_bottom_wing_height)
+ ]
+
+ # Populate the taped power port
+ ideal_power_port_taped.polygon_list.append(
+ power_port_taped_main_panel_polygon_points_2d)
+ ideal_power_port_taped.polygon_list_3d.append(
+ power_port_taped_main_panel_polygon_points_3d)
+ # Including the wing panel
+ ideal_power_port_taped.polygon_list.append(
+ power_port_taped_wing_panel_polygon_points_2d)
+ ideal_power_port_taped.polygon_list_3d.append(
+ power_port_taped_wing_panel_polygon_points_3d)
# Location of target. Rotation is pointing in -x direction
- ideal_power_port_cafe.target_rotation = np.identity(3, np.double)
- ideal_power_port_cafe.target_position = np.array([
+ ideal_power_port_taped.target_rotation = np.identity(3, np.double)
+ ideal_power_port_taped.target_position = np.array([
field_length / 2., -c_power_port_edge_y - c_power_port_width / 2.,
c_power_port_target_height
])
- ideal_power_port_cafe.target_point_2d = np.float32([[340, 350]]).reshape(
- -1, 1, 2) # train_cafeteria-2020-02-13-16-27-25.png
+ ideal_power_port_taped.target_point_2d = np.float32([[250, 146]]).reshape(
+ -1, 1, 2) # train_power_port_taped-2020-08-20-13-27-50.png
- ideal_target_list.append(ideal_power_port_cafe)
- training_target_power_port_cafe = TargetData(
- 'test_images/train_cafeteria-2020-02-13-16-27-25.png')
- training_target_power_port_cafe.target_rotation = ideal_power_port_cafe.target_rotation
- training_target_power_port_cafe.target_position = ideal_power_port_cafe.target_position
- training_target_power_port_cafe.target_radius = target_radius_default
- training_target_list.append(training_target_power_port_cafe)
+ training_target_power_port_taped = TargetData(
+ 'test_images/train_power_port_taped-2020-08-20-13-27-50.png')
+ training_target_power_port_taped.target_rotation = ideal_power_port_taped.target_rotation
+ training_target_power_port_taped.target_position = ideal_power_port_taped.target_position
+ training_target_power_port_taped.target_radius = target_radius_default
###
### Red Power Port
@@ -186,23 +206,21 @@
# Start at lower left corner, and work around clockwise
# These are taken by manually finding the points in gimp for this image
power_port_red_main_panel_polygon_points_2d = [(451, 679), (451, 304),
- (100, 302), (451, 74), (689,
- 74),
- (689, 302), (689, 679)]
+ (100, 302), (451, 74),
+ (689, 74), (689, 302),
+ (689, 679)]
# These are "virtual" 3D points based on the expected geometry
power_port_red_main_panel_polygon_points_3d = [
- (-field_length / 2., power_port_edge_y,
- 0.), (-field_length / 2., power_port_edge_y,
- power_port_bottom_wing_height),
+ (-field_length / 2., power_port_edge_y, 0.),
+ (-field_length / 2., power_port_edge_y, power_port_bottom_wing_height),
(-field_length / 2., power_port_edge_y - power_port_wing_width,
- power_port_bottom_wing_height), (-field_length / 2.,
- power_port_edge_y,
- power_port_total_height),
+ power_port_bottom_wing_height),
+ (-field_length / 2., power_port_edge_y, power_port_total_height),
(-field_length / 2., power_port_edge_y + power_port_width,
- power_port_total_height), (-field_length / 2.,
- power_port_edge_y + power_port_width,
- power_port_bottom_wing_height),
+ power_port_total_height),
+ (-field_length / 2., power_port_edge_y + power_port_width,
+ power_port_bottom_wing_height),
(-field_length / 2., power_port_edge_y + power_port_width, 0.)
]
@@ -215,9 +233,9 @@
(-field_length / 2. + power_port_wing_width * math.sin(wing_angle),
power_port_edge_y + power_port_width +
power_port_wing_width * math.cos(wing_angle),
- power_port_bottom_wing_height), (-field_length / 2.,
- power_port_edge_y + power_port_width,
- power_port_bottom_wing_height)
+ power_port_bottom_wing_height),
+ (-field_length / 2., power_port_edge_y + power_port_width,
+ power_port_bottom_wing_height)
]
# Populate the red power port
@@ -246,8 +264,6 @@
-1, 1, 2) # ideal_power_port_red.png
# np.float32([[305, 97]]).reshape(-1, 1, 2), #train_power_port_red_webcam.png
- # Add the ideal 3D target to our list
- ideal_target_list.append(ideal_power_port_red)
# And add the training image we'll actually use to the training list
training_target_power_port_red = TargetData(
'test_images/train_power_port_red_webcam.png')
@@ -256,8 +272,6 @@
training_target_power_port_red.target_position = ideal_power_port_red.target_position
training_target_power_port_red.target_radius = target_radius_default
- training_target_list.append(training_target_power_port_red)
-
###
### Red Loading Bay
###
@@ -266,16 +280,16 @@
# Start at lower left corner, and work around clockwise
# These are taken by manually finding the points in gimp for this image
- loading_bay_red_polygon_points_2d = [(42, 406), (42, 35), (651, 34), (651,
- 406)]
+ loading_bay_red_polygon_points_2d = [(42, 406), (42, 35), (651, 34),
+ (651, 406)]
# These are "virtual" 3D points based on the expected geometry
loading_bay_red_polygon_points_3d = [
(field_length / 2., loading_bay_edge_y + loading_bay_width, 0.),
(field_length / 2., loading_bay_edge_y + loading_bay_width,
- loading_bay_height), (field_length / 2., loading_bay_edge_y,
- loading_bay_height), (field_length / 2.,
- loading_bay_edge_y, 0.)
+ loading_bay_height),
+ (field_length / 2., loading_bay_edge_y, loading_bay_height),
+ (field_length / 2., loading_bay_edge_y, 0.)
]
ideal_loading_bay_red.polygon_list.append(
@@ -291,13 +305,11 @@
ideal_loading_bay_red.target_point_2d = np.float32([[366, 236]]).reshape(
-1, 1, 2) # ideal_loading_bay_red.png
- ideal_target_list.append(ideal_loading_bay_red)
training_target_loading_bay_red = TargetData(
'test_images/train_loading_bay_red.png')
training_target_loading_bay_red.target_rotation = ideal_loading_bay_red.target_rotation
training_target_loading_bay_red.target_position = ideal_loading_bay_red.target_position
training_target_loading_bay_red.target_radius = target_radius_default
- training_target_list.append(training_target_loading_bay_red)
###
### Blue Power Port
@@ -308,23 +320,21 @@
# Start at lower left corner, and work around clockwise
# These are taken by manually finding the points in gimp for this image
power_port_blue_main_panel_polygon_points_2d = [(438, 693), (438, 285),
- (93, 285), (440, 50), (692,
- 50),
- (692, 285), (692, 693)]
+ (93, 285), (440, 50),
+ (692, 50), (692, 285),
+ (692, 693)]
# These are "virtual" 3D points based on the expected geometry
power_port_blue_main_panel_polygon_points_3d = [
- (field_length / 2., -power_port_edge_y,
- 0.), (field_length / 2., -power_port_edge_y,
- power_port_bottom_wing_height),
+ (field_length / 2., -power_port_edge_y, 0.),
+ (field_length / 2., -power_port_edge_y, power_port_bottom_wing_height),
(field_length / 2., -power_port_edge_y + power_port_wing_width,
- power_port_bottom_wing_height), (field_length / 2.,
- -power_port_edge_y,
- power_port_total_height),
+ power_port_bottom_wing_height),
+ (field_length / 2., -power_port_edge_y, power_port_total_height),
(field_length / 2., -power_port_edge_y - power_port_width,
- power_port_total_height), (field_length / 2.,
- -power_port_edge_y - power_port_width,
- power_port_bottom_wing_height),
+ power_port_total_height),
+ (field_length / 2., -power_port_edge_y - power_port_width,
+ power_port_bottom_wing_height),
(field_length / 2., -power_port_edge_y - power_port_width, 0.)
]
@@ -343,10 +353,15 @@
]
# Populate the blue power port
+ # ideal_power_port_blue.polygon_list.append(
+ # power_port_blue_main_panel_polygon_points_2d)
+ # ideal_power_port_blue.polygon_list_3d.append(
+ # power_port_blue_main_panel_polygon_points_3d)
+ # Including the wing panel
ideal_power_port_blue.polygon_list.append(
- power_port_blue_main_panel_polygon_points_2d)
+ power_port_blue_wing_panel_polygon_points_2d)
ideal_power_port_blue.polygon_list_3d.append(
- power_port_blue_main_panel_polygon_points_3d)
+ power_port_blue_wing_panel_polygon_points_3d)
# Location of target. Rotation is pointing in -x direction
ideal_power_port_blue.target_rotation = np.identity(3, np.double)
@@ -357,15 +372,12 @@
ideal_power_port_blue.target_point_2d = np.float32([[567, 180]]).reshape(
-1, 1, 2) # ideal_power_port_blue.png
- #### TEMPORARILY DISABLING the BLUE POWER PORT target
- #ideal_target_list.append(ideal_power_port_blue)
training_target_power_port_blue = TargetData(
'test_images/train_power_port_blue.png')
+ # 'test_images/image_from_ios-scaled.jpg')
training_target_power_port_blue.target_rotation = ideal_power_port_blue.target_rotation
training_target_power_port_blue.target_position = ideal_power_port_blue.target_position
training_target_power_port_blue.target_radius = target_radius_default
- #### TEMPORARILY DISABLING the BLUE POWER PORT target
- #training_target_list.append(training_target_power_port_blue)
###
### Blue Loading Bay
@@ -376,16 +388,16 @@
# Start at lower left corner, and work around clockwise
# These are taken by manually finding the points in gimp for this image
- loading_bay_blue_polygon_points_2d = [(7, 434), (7, 1), (729, 1), (729,
- 434)]
+ loading_bay_blue_polygon_points_2d = [(7, 434), (7, 1), (729, 1),
+ (729, 434)]
# These are "virtual" 3D points based on the expected geometry
loading_bay_blue_polygon_points_3d = [
(-field_length / 2., -loading_bay_edge_y - loading_bay_width, 0.),
(-field_length / 2., -loading_bay_edge_y - loading_bay_width,
- loading_bay_height), (-field_length / 2., -loading_bay_edge_y,
- loading_bay_height), (-field_length / 2.,
- -loading_bay_edge_y, 0.)
+ loading_bay_height),
+ (-field_length / 2., -loading_bay_edge_y, loading_bay_height),
+ (-field_length / 2., -loading_bay_edge_y, 0.)
]
ideal_loading_bay_blue.polygon_list.append(
@@ -403,12 +415,36 @@
ideal_loading_bay_blue.target_point_2d = np.float32([[366, 236]]).reshape(
-1, 1, 2) # ideal_loading_bay_blue.png
- ideal_target_list.append(ideal_loading_bay_blue)
training_target_loading_bay_blue = TargetData(
'test_images/train_loading_bay_blue.png')
training_target_loading_bay_blue.target_rotation = ideal_loading_bay_blue.target_rotation
training_target_loading_bay_blue.target_position = ideal_loading_bay_blue.target_position
training_target_loading_bay_blue.target_radius = target_radius_default
+
+ ######################################################################
+ # Generate lists of ideal and training targets based on all the
+ # definitions above
+ ######################################################################
+
+ ### Taped power port
+ ideal_target_list.append(ideal_power_port_taped)
+ training_target_list.append(training_target_power_port_taped)
+
+ ### Red Power Port
+ ### NOTE: Temporarily taking this out of the list
+ #ideal_target_list.append(ideal_power_port_red)
+ #training_target_list.append(training_target_power_port_red)
+
+ ### Red Loading Bay
+ ideal_target_list.append(ideal_loading_bay_red)
+ training_target_list.append(training_target_loading_bay_red)
+
+ ### Blue Power Port
+ #ideal_target_list.append(ideal_power_port_blue)
+ #training_target_list.append(training_target_power_port_blue)
+
+ ### Blue Loading Bay
+ ideal_target_list.append(ideal_loading_bay_blue)
training_target_list.append(training_target_loading_bay_blue)
return ideal_target_list, training_target_list
@@ -424,8 +460,8 @@
camera_params = camera_definition.load_camera_definitions()[0]
for ideal_target in ideal_target_list:
- glog.info(
- "\nPreparing target for image %s" % ideal_target.image_filename)
+ glog.info("\nPreparing target for image %s" %
+ ideal_target.image_filename)
ideal_target.extract_features(feature_extractor)
ideal_target.filter_keypoints_by_polygons()
ideal_target.compute_reprojection_maps()
@@ -463,8 +499,8 @@
dtd.visualize_reprojections(
img_copy,
np.asarray(kp_in_poly2d).reshape(-1, 2),
- np.asarray(kp_in_poly3d).reshape(
- -1, 3), camera_params.camera_int.camera_matrix,
+ np.asarray(kp_in_poly3d).reshape(-1, 3),
+ camera_params.camera_int.camera_matrix,
camera_params.camera_int.dist_coeffs)
###############
@@ -521,14 +557,14 @@
training_target.target_point_2d = training_target_point_2d.reshape(
-1, 1, 2)
- glog.info("Started with %d keypoints" % len(
- training_target.keypoint_list))
+ glog.info("Started with %d keypoints" %
+ len(training_target.keypoint_list))
training_target.keypoint_list, training_target.descriptor_list, rejected_keypoint_list, rejected_descriptor_list, _ = dtd.filter_keypoints_by_polygons(
training_target.keypoint_list, training_target.descriptor_list,
training_target.polygon_list)
- glog.info("After filtering by polygons, had %d keypoints" % len(
- training_target.keypoint_list))
+ glog.info("After filtering by polygons, had %d keypoints" %
+ len(training_target.keypoint_list))
if VISUALIZE_KEYPOINTS:
tam.show_keypoints(training_target.image,
training_target.keypoint_list)
@@ -568,9 +604,9 @@
pts = polygon.astype(int).reshape(-1, 2)
img_copy = dtd.draw_polygon(img_copy, pts, (255, 0, 0),
True)
- kp_tmp = np.asarray(
- [(kp.pt[0], kp.pt[1])
- for kp in training_target.keypoint_list]).reshape(-1, 2)
+ kp_tmp = np.asarray([(kp.pt[0], kp.pt[1])
+ for kp in training_target.keypoint_list
+ ]).reshape(-1, 2)
dtd.visualize_reprojections(
img_copy, kp_tmp, training_target.keypoint_list_3d,
camera_params.camera_int.camera_matrix,
@@ -582,11 +618,10 @@
if __name__ == '__main__':
ap = argparse.ArgumentParser()
- ap.add_argument(
- "--visualize",
- help="Whether to visualize the results",
- default=False,
- action='store_true')
+ ap.add_argument("--visualize",
+ help="Whether to visualize the results",
+ default=False,
+ action='store_true')
args = vars(ap.parse_args())
VISUALIZE_KEYPOINTS = args["visualize"]
diff --git a/y2020/vision/tools/python_code/test_images/test_taped_dusk-2021-04-03-19-30-00.png b/y2020/vision/tools/python_code/test_images/test_taped_dusk-2021-04-03-19-30-00.png
new file mode 100644
index 0000000..fb4952e
--- /dev/null
+++ b/y2020/vision/tools/python_code/test_images/test_taped_dusk-2021-04-03-19-30-00.png
Binary files differ
diff --git a/y2020/vision/tools/python_code/test_images/train_power_port_taped-2020-08-20-13-27-50.png b/y2020/vision/tools/python_code/test_images/train_power_port_taped-2020-08-20-13-27-50.png
new file mode 100644
index 0000000..b635a12
--- /dev/null
+++ b/y2020/vision/tools/python_code/test_images/train_power_port_taped-2020-08-20-13-27-50.png
Binary files differ
diff --git a/y2020/vision/tools/python_code/train_and_match.py b/y2020/vision/tools/python_code/train_and_match.py
index 7a9d9bf..ad1bbde 100644
--- a/y2020/vision/tools/python_code/train_and_match.py
+++ b/y2020/vision/tools/python_code/train_and_match.py
@@ -240,8 +240,8 @@
transformed_target = cv2.perspectiveTransform(
target_point_list[i].reshape(-1, 1, 2), H)
# Ballpark the size of the circle so it looks right on image
- radius = int(
- 32 * abs(H[0][0] + H[1][1]) / 2) # Average of scale factors
+ radius = int(12 * abs(H[0][0] + H[1][1]) /
+ 2) # Average of scale factors
# We're only using one query image at this point
query_image = query_images[QUERY_INDEX].copy()