RTCIceCandidatePairStats.[state/priority] added, ConnectionInfo updated.
State and priority added to ConnectionInfo. The Connection::State enum is replaced by IceCandidatePairState enum class. At P2PTransportChannel::GetStats, Connection::stats is called, producing ConnectionInfo for the connection that is then filled in with additional values from the Connection. This is refactored so that all values are set by Connection::stats. RTCStatsCollector is updated to surface the ConnectionInfo stats. BUG=webrtc:6755, chromium:633550, chromium:627816 Review-Url: https://codereview.webrtc.org/2597423003 Cr-Commit-Position: refs/heads/master@{#15870}
This commit is contained in:
parent
7eb0e23bcf
commit
06495bcbb7
@ -359,8 +359,8 @@ class RTCStatsReportVerifier {
|
||||
candidate_pair.local_candidate_id, RTCLocalIceCandidateStats::kType);
|
||||
verifier.TestMemberIsIDReference(
|
||||
candidate_pair.remote_candidate_id, RTCRemoteIceCandidateStats::kType);
|
||||
verifier.TestMemberIsUndefined(candidate_pair.state);
|
||||
verifier.TestMemberIsUndefined(candidate_pair.priority);
|
||||
verifier.TestMemberIsDefined(candidate_pair.state);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(candidate_pair.priority);
|
||||
verifier.TestMemberIsUndefined(candidate_pair.nominated);
|
||||
verifier.TestMemberIsDefined(candidate_pair.writable);
|
||||
verifier.TestMemberIsUndefined(candidate_pair.readable);
|
||||
|
||||
@ -114,6 +114,23 @@ const char* DataStateToRTCDataChannelState(
|
||||
}
|
||||
}
|
||||
|
||||
const char* IceCandidatePairStateToRTCStatsIceCandidatePairState(
|
||||
cricket::IceCandidatePairState state) {
|
||||
switch (state) {
|
||||
case cricket::IceCandidatePairState::WAITING:
|
||||
return RTCStatsIceCandidatePairState::kWaiting;
|
||||
case cricket::IceCandidatePairState::IN_PROGRESS:
|
||||
return RTCStatsIceCandidatePairState::kInProgress;
|
||||
case cricket::IceCandidatePairState::SUCCEEDED:
|
||||
return RTCStatsIceCandidatePairState::kSucceeded;
|
||||
case cricket::IceCandidatePairState::FAILED:
|
||||
return RTCStatsIceCandidatePairState::kFailed;
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<RTCCodecStats> CodecStatsFromRtpCodecParameters(
|
||||
uint64_t timestamp_us, bool inbound, bool audio,
|
||||
const RtpCodecParameters& codec_params) {
|
||||
@ -646,6 +663,9 @@ void RTCStatsCollector::ProduceIceCandidateAndPairStats_n(
|
||||
timestamp_us, info.local_candidate, true, report);
|
||||
candidate_pair_stats->remote_candidate_id = ProduceIceCandidateStats(
|
||||
timestamp_us, info.remote_candidate, false, report);
|
||||
candidate_pair_stats->state =
|
||||
IceCandidatePairStateToRTCStatsIceCandidatePairState(info.state);
|
||||
candidate_pair_stats->priority = info.priority;
|
||||
// TODO(hbos): This writable is different than the spec. It goes to
|
||||
// false after a certain amount of time without a response passes.
|
||||
// crbug.com/633550
|
||||
|
||||
@ -1066,6 +1066,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
|
||||
connection_info.sent_ping_requests_before_first_response = 2000;
|
||||
connection_info.recv_ping_responses = 4321;
|
||||
connection_info.sent_ping_responses = 1000;
|
||||
connection_info.state = cricket::IceCandidatePairState::IN_PROGRESS;
|
||||
connection_info.priority = 5555;
|
||||
|
||||
cricket::TransportChannelStats transport_channel_stats;
|
||||
transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
||||
@ -1092,6 +1094,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
|
||||
expected_pair.local_candidate_id = "RTCIceCandidate_" + local_candidate->id();
|
||||
expected_pair.remote_candidate_id =
|
||||
"RTCIceCandidate_" + remote_candidate->id();
|
||||
expected_pair.state = RTCStatsIceCandidatePairState::kInProgress;
|
||||
expected_pair.priority = 5555;
|
||||
expected_pair.writable = true;
|
||||
expected_pair.bytes_sent = 42;
|
||||
expected_pair.bytes_received = 1234;
|
||||
|
||||
@ -32,7 +32,6 @@ struct RTCStatsIceCandidatePairState {
|
||||
static const char* kInProgress;
|
||||
static const char* kFailed;
|
||||
static const char* kSucceeded;
|
||||
static const char* kCancelled;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webrtc-pc/#rtcicecandidatetype-enum
|
||||
@ -120,9 +119,7 @@ class RTCIceCandidatePairStats final : public RTCStats {
|
||||
RTCStatsMember<std::string> remote_candidate_id;
|
||||
// TODO(hbos): Support enum types?
|
||||
// "RTCStatsMember<RTCStatsIceCandidatePairState>"?
|
||||
// TODO(hbos): Not collected by |RTCStatsCollector|. crbug.com/633550
|
||||
RTCStatsMember<std::string> state;
|
||||
// TODO(hbos): Not collected by |RTCStatsCollector|. crbug.com/633550
|
||||
RTCStatsMember<uint64_t> priority;
|
||||
// TODO(hbos): Not collected by |RTCStatsCollector|. crbug.com/633550
|
||||
RTCStatsMember<bool> nominated;
|
||||
|
||||
@ -41,6 +41,28 @@ static bool VerifyIceParams(const TransportDescription& desc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ConnectionInfo::ConnectionInfo()
|
||||
: best_connection(false),
|
||||
writable(false),
|
||||
receiving(false),
|
||||
timeout(false),
|
||||
new_connection(false),
|
||||
rtt(0),
|
||||
sent_total_bytes(0),
|
||||
sent_bytes_second(0),
|
||||
sent_discarded_packets(0),
|
||||
sent_total_packets(0),
|
||||
sent_ping_requests_total(0),
|
||||
sent_ping_requests_before_first_response(0),
|
||||
sent_ping_responses(0),
|
||||
recv_total_bytes(0),
|
||||
recv_bytes_second(0),
|
||||
recv_ping_requests(0),
|
||||
recv_ping_responses(0),
|
||||
key(nullptr),
|
||||
state(IceCandidatePairState::WAITING),
|
||||
priority(0) {}
|
||||
|
||||
bool BadTransportDescription(const std::string& desc, std::string* err_desc) {
|
||||
if (err_desc) {
|
||||
*err_desc = desc;
|
||||
|
||||
@ -31,6 +31,7 @@ namespace cricket {
|
||||
|
||||
class TransportChannelImpl;
|
||||
class TransportChannelImpl;
|
||||
enum class IceCandidatePairState;
|
||||
|
||||
typedef std::vector<Candidate> Candidates;
|
||||
|
||||
@ -83,25 +84,7 @@ enum ContinualGatheringPolicy {
|
||||
// Stats that we can return about the connections for a transport channel.
|
||||
// TODO(hta): Rename to ConnectionStats
|
||||
struct ConnectionInfo {
|
||||
ConnectionInfo()
|
||||
: best_connection(false),
|
||||
writable(false),
|
||||
receiving(false),
|
||||
timeout(false),
|
||||
new_connection(false),
|
||||
rtt(0),
|
||||
sent_total_bytes(0),
|
||||
sent_bytes_second(0),
|
||||
sent_discarded_packets(0),
|
||||
sent_total_packets(0),
|
||||
sent_ping_requests_total(0),
|
||||
sent_ping_requests_before_first_response(0),
|
||||
sent_ping_responses(0),
|
||||
recv_total_bytes(0),
|
||||
recv_bytes_second(0),
|
||||
recv_ping_requests(0),
|
||||
recv_ping_responses(0),
|
||||
key(NULL) {}
|
||||
ConnectionInfo();
|
||||
|
||||
bool best_connection; // Is this the best connection we have?
|
||||
bool writable; // Has this connection received a STUN response?
|
||||
@ -127,6 +110,10 @@ struct ConnectionInfo {
|
||||
Candidate local_candidate; // The local candidate for this connection.
|
||||
Candidate remote_candidate; // The remote candidate for this connection.
|
||||
void* key; // A static value that identifies this conn.
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-state
|
||||
IceCandidatePairState state;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-priority
|
||||
uint64_t priority;
|
||||
};
|
||||
|
||||
// Information about all the connections of a channel.
|
||||
|
||||
@ -1012,17 +1012,8 @@ bool P2PTransportChannel::GetStats(ConnectionInfos *infos) {
|
||||
for (Connection* connection : connections_) {
|
||||
ConnectionInfo info = connection->stats();
|
||||
info.best_connection = (selected_connection_ == connection);
|
||||
info.receiving = connection->receiving();
|
||||
info.writable = (connection->write_state() == Connection::STATE_WRITABLE);
|
||||
info.timeout =
|
||||
(connection->write_state() == Connection::STATE_WRITE_TIMEOUT);
|
||||
info.new_connection = !connection->reported();
|
||||
infos->push_back(std::move(info));
|
||||
connection->set_reported(true);
|
||||
info.rtt = connection->rtt();
|
||||
info.local_candidate = connection->local_candidate();
|
||||
info.remote_candidate = connection->remote_candidate();
|
||||
info.key = connection;
|
||||
infos->push_back(info);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1559,7 +1550,7 @@ bool P2PTransportChannel::IsPingable(const Connection* conn,
|
||||
}
|
||||
|
||||
// A failed connection will not be pinged.
|
||||
if (conn->state() == Connection::STATE_FAILED) {
|
||||
if (conn->state() == IceCandidatePairState::FAILED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -4017,14 +4017,14 @@ TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
|
||||
ASSERT_TRUE(conn2 != nullptr);
|
||||
EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
|
||||
// |conn2| should not send a ping yet.
|
||||
EXPECT_EQ(Connection::STATE_WAITING, conn2->state());
|
||||
EXPECT_EQ(IceCandidatePairState::WAITING, conn2->state());
|
||||
EXPECT_EQ(TransportChannelState::STATE_COMPLETED, ch.GetState());
|
||||
// Wait for |conn1| becoming not receiving.
|
||||
EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), kMediumTimeout, clock);
|
||||
// Make sure conn2 is not deleted.
|
||||
conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
|
||||
ASSERT_TRUE(conn2 != nullptr);
|
||||
EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_INPROGRESS, conn2->state(),
|
||||
EXPECT_EQ_SIMULATED_WAIT(IceCandidatePairState::IN_PROGRESS, conn2->state(),
|
||||
kDefaultTimeout, clock);
|
||||
conn2->ReceivedPingResponse(LOW_RTT, "id");
|
||||
EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
|
||||
|
||||
@ -868,7 +868,7 @@ Connection::Connection(Port* port,
|
||||
last_data_received_(0),
|
||||
last_ping_response_received_(0),
|
||||
reported_(false),
|
||||
state_(STATE_WAITING),
|
||||
state_(IceCandidatePairState::WAITING),
|
||||
receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT),
|
||||
time_created_ms_(rtc::TimeMillis()) {
|
||||
// All of our connections start in WAITING state.
|
||||
@ -937,8 +937,8 @@ void Connection::UpdateReceiving(int64_t now) {
|
||||
SignalStateChange(this);
|
||||
}
|
||||
|
||||
void Connection::set_state(State state) {
|
||||
State old_state = state_;
|
||||
void Connection::set_state(IceCandidatePairState state) {
|
||||
IceCandidatePairState old_state = state_;
|
||||
state_ = state;
|
||||
if (state != old_state) {
|
||||
LOG_J(LS_VERBOSE, this) << "set_state";
|
||||
@ -1126,12 +1126,12 @@ void Connection::Destroy() {
|
||||
}
|
||||
|
||||
void Connection::FailAndDestroy() {
|
||||
set_state(Connection::STATE_FAILED);
|
||||
set_state(IceCandidatePairState::FAILED);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void Connection::FailAndPrune() {
|
||||
set_state(Connection::STATE_FAILED);
|
||||
set_state(IceCandidatePairState::FAILED);
|
||||
Prune();
|
||||
}
|
||||
|
||||
@ -1223,7 +1223,7 @@ void Connection::Ping(int64_t now) {
|
||||
<< ", id=" << rtc::hex_encode(req->id())
|
||||
<< ", nomination=" << nomination_;
|
||||
requests_.Send(req);
|
||||
state_ = STATE_INPROGRESS;
|
||||
state_ = IceCandidatePairState::IN_PROGRESS;
|
||||
num_pings_sent_++;
|
||||
}
|
||||
|
||||
@ -1250,7 +1250,7 @@ void Connection::ReceivedPingResponse(int rtt, const std::string& request_id) {
|
||||
last_ping_response_received_ = rtc::TimeMillis();
|
||||
UpdateReceiving(last_ping_response_received_);
|
||||
set_write_state(STATE_WRITABLE);
|
||||
set_state(STATE_SUCCEEDED);
|
||||
set_state(IceCandidatePairState::SUCCEEDED);
|
||||
rtt_samples_++;
|
||||
rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1);
|
||||
}
|
||||
@ -1331,8 +1331,8 @@ std::string Connection::ToString() const {
|
||||
<< ":" << remote.protocol() << ":" << remote.address().ToSensitiveString()
|
||||
<< "|" << CONNECT_STATE_ABBREV[connected()]
|
||||
<< RECEIVE_STATE_ABBREV[receiving()] << WRITE_STATE_ABBREV[write_state()]
|
||||
<< ICESTATE[state()] << "|" << remote_nomination() << "|" << nomination()
|
||||
<< "|" << priority() << "|";
|
||||
<< ICESTATE[static_cast<int>(state())] << "|" << remote_nomination() << "|"
|
||||
<< nomination() << "|" << priority() << "|";
|
||||
if (rtt_ < DEFAULT_RTT) {
|
||||
ss << rtt_ << "]";
|
||||
} else {
|
||||
@ -1471,6 +1471,16 @@ ConnectionInfo Connection::stats() {
|
||||
stats_.recv_total_bytes = recv_rate_tracker_.TotalSampleCount();
|
||||
stats_.sent_bytes_second = round(send_rate_tracker_.ComputeRate());
|
||||
stats_.sent_total_bytes = send_rate_tracker_.TotalSampleCount();
|
||||
stats_.receiving = receiving_;
|
||||
stats_.writable = write_state_ == STATE_WRITABLE;
|
||||
stats_.timeout = write_state_ == STATE_WRITE_TIMEOUT;
|
||||
stats_.new_connection = !reported_;
|
||||
stats_.rtt = rtt_;
|
||||
stats_.local_candidate = local_candidate();
|
||||
stats_.remote_candidate = remote_candidate();
|
||||
stats_.key = this;
|
||||
stats_.state = state_;
|
||||
stats_.priority = priority();
|
||||
return stats_;
|
||||
}
|
||||
|
||||
|
||||
@ -92,6 +92,16 @@ enum IcePriorityValue {
|
||||
ICE_TYPE_PREFERENCE_HOST = 126
|
||||
};
|
||||
|
||||
// States are from RFC 5245. http://tools.ietf.org/html/rfc5245#section-5.7.4
|
||||
enum class IceCandidatePairState {
|
||||
WAITING = 0, // Check has not been performed, Waiting pair on CL.
|
||||
IN_PROGRESS, // Check has been sent, transaction is in progress.
|
||||
SUCCEEDED, // Check already done, produced a successful result.
|
||||
FAILED, // Check for this connection failed.
|
||||
// According to spec there should also be a frozen state, but nothing is ever
|
||||
// frozen because we have not implemented ICE freezing logic.
|
||||
};
|
||||
|
||||
const char* ProtoToString(ProtocolType proto);
|
||||
bool StringToProto(const char* value, ProtocolType* proto);
|
||||
|
||||
@ -419,14 +429,6 @@ class Connection : public CandidatePairInterface,
|
||||
uint32_t nomination;
|
||||
};
|
||||
|
||||
// States are from RFC 5245. http://tools.ietf.org/html/rfc5245#section-5.7.4
|
||||
enum State {
|
||||
STATE_WAITING = 0, // Check has not been performed, Waiting pair on CL.
|
||||
STATE_INPROGRESS, // Check has been sent, transaction is in progress.
|
||||
STATE_SUCCEEDED, // Check already done, produced a successful result.
|
||||
STATE_FAILED // Check for this connection failed.
|
||||
};
|
||||
|
||||
virtual ~Connection();
|
||||
|
||||
// The local port where this connection sends and receives packets.
|
||||
@ -467,6 +469,8 @@ class Connection : public CandidatePairInterface,
|
||||
// Estimate of the round-trip time over this connection.
|
||||
int rtt() const { return rtt_; }
|
||||
|
||||
// Gets the |ConnectionInfo| stats, where |best_connection| has not been
|
||||
// populated (default value false).
|
||||
ConnectionInfo stats();
|
||||
|
||||
sigslot::signal1<Connection*> SignalStateChange;
|
||||
@ -575,7 +579,7 @@ class Connection : public CandidatePairInterface,
|
||||
// Invoked when Connection receives STUN error response with 487 code.
|
||||
void HandleRoleConflictFromPeer();
|
||||
|
||||
State state() const { return state_; }
|
||||
IceCandidatePairState state() const { return state_; }
|
||||
|
||||
int num_pings_sent() const { return num_pings_sent_; }
|
||||
|
||||
@ -630,7 +634,7 @@ class Connection : public CandidatePairInterface,
|
||||
// Changes the state and signals if necessary.
|
||||
void set_write_state(WriteState value);
|
||||
void UpdateReceiving(int64_t now);
|
||||
void set_state(State state);
|
||||
void set_state(IceCandidatePairState state);
|
||||
void set_connected(bool value);
|
||||
|
||||
uint32_t nomination() const { return nomination_; }
|
||||
@ -686,7 +690,7 @@ class Connection : public CandidatePairInterface,
|
||||
std::vector<SentPing> pings_since_last_response_;
|
||||
|
||||
bool reported_;
|
||||
State state_;
|
||||
IceCandidatePairState state_;
|
||||
// Time duration to switch from receiving to not receiving.
|
||||
int receiving_timeout_;
|
||||
int64_t time_created_ms_;
|
||||
|
||||
@ -334,7 +334,8 @@ class TurnPortTest : public testing::Test,
|
||||
}
|
||||
|
||||
bool CheckConnectionFailedAndPruned(Connection* conn) {
|
||||
return conn && !conn->active() && conn->state() == Connection::STATE_FAILED;
|
||||
return conn && !conn->active() &&
|
||||
conn->state() == IceCandidatePairState::FAILED;
|
||||
}
|
||||
|
||||
// Checks that |turn_port_| has a nonempty set of connections and they are all
|
||||
|
||||
@ -19,10 +19,9 @@ const char* RTCDataChannelState::kClosed = "closed";
|
||||
|
||||
const char* RTCStatsIceCandidatePairState::kFrozen = "frozen";
|
||||
const char* RTCStatsIceCandidatePairState::kWaiting = "waiting";
|
||||
const char* RTCStatsIceCandidatePairState::kInProgress = "inprogress";
|
||||
const char* RTCStatsIceCandidatePairState::kInProgress = "in-progress";
|
||||
const char* RTCStatsIceCandidatePairState::kFailed = "failed";
|
||||
const char* RTCStatsIceCandidatePairState::kSucceeded = "succeeded";
|
||||
const char* RTCStatsIceCandidatePairState::kCancelled = "cancelled";
|
||||
|
||||
// Strings defined in https://tools.ietf.org/html/rfc5245.
|
||||
const char* RTCIceCandidateType::kHost = "host";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user