Logger: Define contract to record transmit time for reliable messages

The sent time for reliable messages are not very useful to estimate
network latency across reboots. Add a new field which provides
information about the transmit time, i.e time at which the message
was handed to the kernel to be sent over the network.

This can then be used as a valid timestamp point for the timestamp
solver particularly for reliable messages. It also gives us higher
visibility into the path of the message through the network.

Change-Id: I7f2ea6b0300894d542a42de9caddc57efa965253
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/logging/log_namer.cc b/aos/events/logging/log_namer.cc
index 3bbca3b..4f8da91 100644
--- a/aos/events/logging/log_namer.cc
+++ b/aos/events/logging/log_namer.cc
@@ -395,7 +395,12 @@
   const UUID &source_node_boot_uuid = state[node_index].boot_uuid;
   const Node *const source_node =
       configuration::GetNode(configuration_, node_index);
-  CHECK_EQ(LogFileHeader::MiniReflectTypeTable()->num_elems, 35u);
+  CHECK_EQ(LogFileHeader::MiniReflectTypeTable()->num_elems, 37u)
+      << ": If you added new fields to the LogFileHeader table, don't forget "
+         "to add it below!";
+  ;
+  // TODO(Mithun): Add  oldest_remote_reliable_monotonic_transmit_timestamps,
+  // and oldest_local_reliable_monotonic_transmit_timestamps to logfile header.
   flatbuffers::FlatBufferBuilder fbb;
   fbb.ForceDefaults(true);
 
diff --git a/aos/events/logging/logfile_sorting.cc b/aos/events/logging/logfile_sorting.cc
index 2eaf00b..8fba5c1 100644
--- a/aos/events/logging/logfile_sorting.cc
+++ b/aos/events/logging/logfile_sorting.cc
@@ -48,7 +48,7 @@
 }
 
 bool ConfigOnly(const LogFileHeader *header) {
-  CHECK_EQ(LogFileHeader::MiniReflectTypeTable()->num_elems, 35u);
+  CHECK_EQ(LogFileHeader::MiniReflectTypeTable()->num_elems, 37u);
   if (header->has_monotonic_start_time()) return false;
   if (header->has_realtime_start_time()) return false;
   if (header->has_max_out_of_order_duration()) return false;
@@ -74,6 +74,10 @@
   if (header->has_oldest_local_unreliable_monotonic_timestamps()) return false;
   if (header->has_oldest_remote_reliable_monotonic_timestamps()) return false;
   if (header->has_oldest_local_reliable_monotonic_timestamps()) return false;
+  if (header->has_oldest_remote_reliable_monotonic_transmit_timestamps())
+    return false;
+  if (header->has_oldest_local_reliable_monotonic_transmit_timestamps())
+    return false;
   if (header->has_oldest_logger_remote_unreliable_monotonic_timestamps())
     return false;
   if (header->has_oldest_logger_local_unreliable_monotonic_timestamps())
diff --git a/aos/events/logging/logger.fbs b/aos/events/logging/logger.fbs
index 5733fa0..f24922a 100644
--- a/aos/events/logging/logger.fbs
+++ b/aos/events/logging/logger.fbs
@@ -206,6 +206,12 @@
   oldest_remote_reliable_monotonic_timestamps:[int64] (id: 28);
   oldest_local_reliable_monotonic_timestamps:[int64] (id: 29);
 
+  // For all channels *excluding* the unreliable channels (ttl != 0), record the
+  // oldest time a reliable message was sent to the kernel to be transmitted over
+  // the network.
+  oldest_remote_reliable_monotonic_transmit_timestamps:[int64] (id: 35);
+  oldest_local_reliable_monotonic_transmit_timestamps:[int64] (id: 36);
+
   // For all the remote timestamps which come back to the logger.  The "local"
   // time here is the logger node boot, and "remote" is the node which sent the
   // timestamps.
@@ -257,6 +263,30 @@
   // Time this timestamp was received on the monotonic clock of the logger node
   // in nanoseconds.
   monotonic_timestamp_time:int64 = -9223372036854775808 (id: 8);
+
+  // Time that this message was handed to the kernel to be published over the
+  // network on the remote node.
+  //
+  // monotonic_sent_time captures the time the message was pushed into queue.
+  // For reliable messages (ttl != 0) this may not be equal to the time it was
+  // published.
+  //
+  // For example:
+  // 1. Node A sends a reliable message RM1 to the queue at 10 seconds.
+  // 2. Node B reboots at 80 seconds and requests for all reliable messages.
+  // 3. The reliable message RM1 is sent to node B with a sent time of 10 seconds
+  //    even though time is past 80 seconds.
+  // 4. Using this as a valid timestamp point confuses the timestamp solver.
+  //
+  // i.e. monotonic_sent_time for reliable messages is not very useful to
+  // estimate network latency.
+  //
+  // Having more timestamp information such as transmit time can improve reliablity
+  // of the log reader (timestamp solver) especially when reliable messages are involved.
+  //
+  // This data also provides higher visibility into the path of a message across the
+  // network.
+  monotonic_remote_transmit_time:int64 = -9223372036854775808 (id: 9);
 }
 
 root_type MessageHeader;