Add ChannelIsForwardedFromNode to aos/configuration.h

Change-Id: I52a42fbc1b2137da8bc2585a5d6ee803f793bdd4
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/configuration.cc b/aos/configuration.cc
index aa69d99..d100321 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -1353,6 +1353,15 @@
   return false;
 }
 
+bool ChannelIsForwardedFromNode(const Channel *channel, const Node *node) {
+  if (node == nullptr) {
+    return false;
+  }
+  return ChannelIsSendableOnNode(channel, node) &&
+         channel->has_destination_nodes() &&
+         channel->destination_nodes()->size() > 0u;
+}
+
 bool ChannelMessageIsLoggedOnNode(const Channel *channel, const Node *node) {
   if (node == nullptr) {
     // Single node world.  If there is a local logger, then we want to use
diff --git a/aos/configuration.h b/aos/configuration.h
index 0e5ef74..06f4db4 100644
--- a/aos/configuration.h
+++ b/aos/configuration.h
@@ -157,6 +157,10 @@
 // provided node.
 bool ChannelIsReadableOnNode(const Channel *channel, const Node *node);
 
+// Returns true if the provided channel is sent on the provided node and gets
+// forwarded to any other nodes.
+bool ChannelIsForwardedFromNode(const Channel *channel, const Node *node);
+
 // Returns true if the message is supposed to be logged on this node.
 bool ChannelMessageIsLoggedOnNode(const Channel *channel, const Node *node);
 bool ChannelMessageIsLoggedOnNode(const Channel *channel,
diff --git a/aos/configuration_test.cc b/aos/configuration_test.cc
index c4df812..560e5eb 100644
--- a/aos/configuration_test.cc
+++ b/aos/configuration_test.cc
@@ -438,6 +438,63 @@
       ChannelIsReadableOnNode(&bad_channel2.message(), &node.message()));
 }
 
+// Tests that our channel is forwarded helpers work as intended.
+TEST_F(ConfigurationTest, ChannelIsForwardedFromNode) {
+  FlatbufferDetachedBuffer<Channel> forwarded_channel(JsonToFlatbuffer(
+      R"channel({
+  "name": "/test",
+  "type": "aos.examples.Ping",
+  "source_node": "bar",
+  "destination_nodes": [
+    {
+      "name": "baz"
+    },
+    {
+      "name": "foo"
+    }
+  ]
+})channel",
+      Channel::MiniReflectTypeTable()));
+
+  FlatbufferDetachedBuffer<Channel> single_node_channel(JsonToFlatbuffer(
+      R"channel({
+  "name": "/test",
+  "type": "aos.examples.Ping"
+})channel",
+      Channel::MiniReflectTypeTable()));
+
+  FlatbufferDetachedBuffer<Channel> zero_length_vector_channel(JsonToFlatbuffer(
+      R"channel({
+  "name": "/test",
+  "type": "aos.examples.Ping",
+  "source_node": "bar",
+  "destination_nodes": [
+  ]
+})channel",
+      Channel::MiniReflectTypeTable()));
+
+  FlatbufferDetachedBuffer<Node> node(JsonToFlatbuffer(
+      R"node({
+  "name": "bar"
+})node",
+      Node::MiniReflectTypeTable()));
+
+  FlatbufferDetachedBuffer<Node> readable_node(JsonToFlatbuffer(
+      R"node({
+  "name": "foo"
+})node",
+      Node::MiniReflectTypeTable()));
+
+  EXPECT_TRUE(ChannelIsForwardedFromNode(&forwarded_channel.message(),
+                                         &node.message()));
+  EXPECT_FALSE(ChannelIsForwardedFromNode(&forwarded_channel.message(),
+                                          &readable_node.message()));
+  EXPECT_FALSE(
+      ChannelIsForwardedFromNode(&single_node_channel.message(), nullptr));
+  EXPECT_FALSE(ChannelIsForwardedFromNode(&zero_length_vector_channel.message(),
+                                          &node.message()));
+}
+
 // Tests that our node message is logged helpers work as intended.
 TEST_F(ConfigurationTest, ChannelMessageIsLoggedOnNode) {
   FlatbufferDetachedBuffer<Channel> logged_on_self_channel(JsonToFlatbuffer(
diff --git a/aos/network/message_bridge_server_lib.cc b/aos/network/message_bridge_server_lib.cc
index 0947794..e9f6e0d 100644
--- a/aos/network/message_bridge_server_lib.cc
+++ b/aos/network/message_bridge_server_lib.cc
@@ -335,8 +335,8 @@
   for (const Channel *channel : *event_loop_->configuration()->channels()) {
     CHECK(channel->has_source_node());
 
-    if (configuration::ChannelIsSendableOnNode(channel, event_loop_->node()) &&
-        channel->has_destination_nodes()) {
+    if (configuration::ChannelIsForwardedFromNode(channel,
+                                                  event_loop_->node())) {
       bool any_reliable = false;
       for (const Connection *connection : *channel->destination_nodes()) {
         if (connection->time_to_live() == 0) {