Add jmi field for packets discarded due to network error

Also included the total packets attempted to send.

BUG=427555

Copied from https://webrtc-codereview.appspot.com/25959004/

R=harryjin@google.com, juberti@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/32039004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7693 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/app/webrtc/statscollector.cc b/talk/app/webrtc/statscollector.cc
index fefb0ad..4c19967 100644
--- a/talk/app/webrtc/statscollector.cc
+++ b/talk/app/webrtc/statscollector.cc
@@ -164,6 +164,8 @@
     "googRetransmitBitrate";
 const char StatsReport::kStatsValueNameRtt[] = "googRtt";
 const char StatsReport::kStatsValueNameSsrc[] = "ssrc";
+const char StatsReport::kStatsValueNameSendPacketsDiscarded[] =
+    "packetsDiscardedOnSend";
 const char StatsReport::kStatsValueNameTargetEncBitrate[] =
     "googTargetEncBitrate";
 const char StatsReport::kStatsValueNameTransmitBitrate[] =
@@ -886,6 +888,10 @@
               channel_iter->connection_infos[i];
           report->AddValue(StatsReport::kStatsValueNameBytesSent,
                            info.sent_total_bytes);
+          report->AddValue(StatsReport::kStatsValueNameSendPacketsDiscarded,
+                           info.sent_discarded_packets);
+          report->AddValue(StatsReport::kStatsValueNamePacketsSent,
+                           info.sent_total_packets);
           report->AddValue(StatsReport::kStatsValueNameBytesReceived,
                            info.recv_total_bytes);
           report->AddBoolean(StatsReport::kStatsValueNameWritable,
diff --git a/talk/app/webrtc/statstypes.h b/talk/app/webrtc/statstypes.h
index 8a1530a..0dbced6 100644
--- a/talk/app/webrtc/statstypes.h
+++ b/talk/app/webrtc/statstypes.h
@@ -255,6 +255,7 @@
   static const char kStatsValueNameChannelId[];
   static const char kStatsValueNameTrackId[];
   static const char kStatsValueNameSsrc[];
+  static const char kStatsValueNameSendPacketsDiscarded[];
   static const char kStatsValueNameTypingNoiseState[];
   static const char kStatsValueNameDer[];
   static const char kStatsValueNameFingerprint[];
diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc
index 84a2420..94e3cb3 100644
--- a/webrtc/p2p/base/p2ptransportchannel.cc
+++ b/webrtc/p2p/base/p2ptransportchannel.cc
@@ -842,6 +842,8 @@
     info.rtt = connection->rtt();
     info.sent_total_bytes = connection->sent_total_bytes();
     info.sent_bytes_second = connection->sent_bytes_second();
+    info.sent_discarded_packets = connection->sent_discarded_packets();
+    info.sent_total_packets = connection->sent_total_packets();
     info.recv_total_bytes = connection->recv_total_bytes();
     info.recv_bytes_second = connection->recv_bytes_second();
     info.local_candidate = connection->local_candidate();
diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc
index 4f32719..2e87aec 100644
--- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc
+++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc
@@ -1225,6 +1225,8 @@
   EXPECT_TRUE(infos[0].readable);
   EXPECT_TRUE(infos[0].writable);
   EXPECT_FALSE(infos[0].timeout);
+  EXPECT_EQ(10U, infos[0].sent_total_packets);
+  EXPECT_EQ(0U, infos[0].sent_discarded_packets);
   EXPECT_EQ(10 * 36U, infos[0].sent_total_bytes);
   EXPECT_EQ(10 * 36U, infos[0].recv_total_bytes);
   EXPECT_GT(infos[0].rtt, 0U);
diff --git a/webrtc/p2p/base/port.cc b/webrtc/p2p/base/port.cc
index d71d6fa..1cda7c1 100644
--- a/webrtc/p2p/base/port.cc
+++ b/webrtc/p2p/base/port.cc
@@ -851,15 +851,28 @@
 // Connection
 //
 
-Connection::Connection(Port* port, size_t index,
+Connection::Connection(Port* port,
+                       size_t index,
                        const Candidate& remote_candidate)
-  : port_(port), local_candidate_index_(index),
-    remote_candidate_(remote_candidate), read_state_(STATE_READ_INIT),
-    write_state_(STATE_WRITE_INIT), connected_(true), pruned_(false),
-    use_candidate_attr_(false), remote_ice_mode_(ICEMODE_FULL),
-    requests_(port->thread()), rtt_(DEFAULT_RTT), last_ping_sent_(0),
-    last_ping_received_(0), last_data_received_(0),
-    last_ping_response_received_(0), reported_(false), state_(STATE_WAITING) {
+    : port_(port),
+      local_candidate_index_(index),
+      remote_candidate_(remote_candidate),
+      read_state_(STATE_READ_INIT),
+      write_state_(STATE_WRITE_INIT),
+      connected_(true),
+      pruned_(false),
+      use_candidate_attr_(false),
+      remote_ice_mode_(ICEMODE_FULL),
+      requests_(port->thread()),
+      rtt_(DEFAULT_RTT),
+      last_ping_sent_(0),
+      last_ping_received_(0),
+      last_data_received_(0),
+      last_ping_response_received_(0),
+      sent_packets_discarded_(0),
+      sent_packets_total_(0),
+      reported_(false),
+      state_(STATE_WAITING) {
   // All of our connections start in WAITING state.
   // TODO(mallinath) - Start connections from STATE_FROZEN.
   // Wire up to send stun packets
@@ -1348,6 +1361,14 @@
   return send_rate_tracker_.total_units();
 }
 
+size_t Connection::sent_discarded_packets() {
+  return sent_packets_discarded_;
+}
+
+size_t Connection::sent_total_packets() {
+  return sent_packets_total_;
+}
+
 void Connection::MaybeAddPrflxCandidate(ConnectionRequest* request,
                                         StunMessage* response) {
   // RFC 5245
@@ -1423,11 +1444,13 @@
     error_ = EWOULDBLOCK;
     return SOCKET_ERROR;
   }
+  sent_packets_total_++;
   int sent = port_->SendTo(data, size, remote_candidate_.address(),
                            options, true);
   if (sent <= 0) {
     ASSERT(sent < 0);
     error_ = port_->GetError();
+    sent_packets_discarded_++;
   } else {
     send_rate_tracker_.Update(sent);
   }
diff --git a/webrtc/p2p/base/port.h b/webrtc/p2p/base/port.h
index 87072e6..0026437 100644
--- a/webrtc/p2p/base/port.h
+++ b/webrtc/p2p/base/port.h
@@ -453,6 +453,10 @@
 
   size_t sent_total_bytes();
   size_t sent_bytes_second();
+  // Used to track how many packets are discarded in the application socket due
+  // to errors.
+  size_t sent_discarded_packets();
+  size_t sent_total_packets();
   size_t recv_total_bytes();
   size_t recv_bytes_second();
   sigslot::signal1<Connection*> SignalStateChange;
@@ -579,6 +583,8 @@
 
   rtc::RateTracker recv_rate_tracker_;
   rtc::RateTracker send_rate_tracker_;
+  uint32 sent_packets_discarded_;
+  uint32 sent_packets_total_;
 
  private:
   void MaybeAddPrflxCandidate(ConnectionRequest* request,
diff --git a/webrtc/p2p/base/tcpport.cc b/webrtc/p2p/base/tcpport.cc
index c5891f2..89265d7 100644
--- a/webrtc/p2p/base/tcpport.cc
+++ b/webrtc/p2p/base/tcpport.cc
@@ -272,8 +272,10 @@
     error_ = EWOULDBLOCK;
     return SOCKET_ERROR;
   }
+  sent_packets_total_++;
   int sent = socket_->Send(data, size, options);
   if (sent < 0) {
+    sent_packets_discarded_++;
     error_ = socket_->GetError();
   } else {
     send_rate_tracker_.Update(sent);
diff --git a/webrtc/p2p/base/transport.h b/webrtc/p2p/base/transport.h
index ab772fe..1091cb0 100644
--- a/webrtc/p2p/base/transport.h
+++ b/webrtc/p2p/base/transport.h
@@ -132,6 +132,8 @@
         rtt(0),
         sent_total_bytes(0),
         sent_bytes_second(0),
+        sent_discarded_packets(0),
+        sent_total_packets(0),
         recv_total_bytes(0),
         recv_bytes_second(0),
         key(NULL) {}
@@ -144,6 +146,11 @@
   size_t rtt;                  // The STUN RTT for this connection.
   size_t sent_total_bytes;     // Total bytes sent on this connection.
   size_t sent_bytes_second;    // Bps over the last measurement interval.
+  size_t sent_discarded_packets;  // Number of outgoing packets discarded due to
+                                  // socket errors.
+  size_t sent_total_packets;  // Number of total outgoing packets attempted for
+                              // sending.
+
   size_t recv_total_bytes;     // Total bytes received on this connection.
   size_t recv_bytes_second;    // Bps over the last measurement interval.
   Candidate local_candidate;   // The local candidate for this connection.