stats: implement transport iceState

https://w3c.github.io/webrtc-stats/#dom-rtctransportstats-selectedcandidatepairid

BUG=webrtc:14022

Change-Id: I206bff7048d2df3e3aff0af55072097f49d54e8f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261720
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Philipp Hancke <philipp.hancke@googlemail.com>
Cr-Commit-Position: refs/heads/main@{#36840}
This commit is contained in:
Philipp Hancke
2022-05-09 17:43:31 +02:00
committed by WebRTC LUCI CQ
parent cf4ed1516e
commit 1f49157b41
7 changed files with 61 additions and 3 deletions

View File

@ -104,6 +104,17 @@ struct RTCIceRole {
static const char* const kControlling;
};
// https://www.w3.org/TR/webrtc/#dom-rtcicetransportstate
struct RTCIceTransportState {
static const char* const kNew;
static const char* const kChecking;
static const char* const kConnected;
static const char* const kCompleted;
static const char* const kDisconnected;
static const char* const kFailed;
static const char* const kClosed;
};
// https://w3c.github.io/webrtc-stats/#certificatestats-dict*
class RTC_EXPORT RTCCertificateStats final : public RTCStats {
public:
@ -710,6 +721,7 @@ class RTC_EXPORT RTCTransportStats final : public RTCStats {
RTCStatsMember<uint32_t> selected_candidate_pair_changes;
RTCStatsMember<std::string> ice_role;
RTCStatsMember<std::string> ice_local_username_fragment;
RTCStatsMember<std::string> ice_state;
};
} // namespace webrtc

View File

@ -50,6 +50,7 @@ struct IceTransportStats {
IceRole ice_role = ICEROLE_UNKNOWN;
std::string ice_local_username_fragment;
webrtc::IceTransportState ice_state = webrtc::IceTransportState::kNew;
};
typedef std::vector<Candidate> Candidates;

View File

@ -1666,6 +1666,7 @@ bool P2PTransportChannel::GetStats(IceTransportStats* ice_transport_stats) {
ice_transport_stats->ice_role = GetIceRole();
ice_transport_stats->ice_local_username_fragment = ice_parameters_.ufrag;
ice_transport_stats->ice_state = ComputeIceTransportState();
return true;
}

View File

@ -243,6 +243,28 @@ const char* DtlsTransportStateToRTCDtlsTransportState(
}
}
const char* IceTransportStateToRTCIceTransportState(IceTransportState state) {
switch (state) {
case IceTransportState::kNew:
return RTCIceTransportState::kNew;
case IceTransportState::kChecking:
return RTCIceTransportState::kChecking;
case IceTransportState::kConnected:
return RTCIceTransportState::kConnected;
case IceTransportState::kCompleted:
return RTCIceTransportState::kCompleted;
case IceTransportState::kFailed:
return RTCIceTransportState::kFailed;
case IceTransportState::kDisconnected:
return RTCIceTransportState::kDisconnected;
case IceTransportState::kClosed:
return RTCIceTransportState::kClosed;
default:
RTC_CHECK_NOTREACHED();
return nullptr;
}
}
const char* NetworkTypeToStatsType(rtc::AdapterType type) {
switch (type) {
case rtc::ADAPTER_TYPE_CELLULAR:
@ -2118,6 +2140,8 @@ void RTCStatsCollector::ProduceTransportStats_n(
IceRoleToRTCIceRole(channel_stats.ice_transport_stats.ice_role);
transport_stats->ice_local_username_fragment =
channel_stats.ice_transport_stats.ice_local_username_fragment;
transport_stats->ice_state = IceTransportStateToRTCIceTransportState(
channel_stats.ice_transport_stats.ice_state);
for (const cricket::ConnectionInfo& info :
channel_stats.ice_transport_stats.connection_infos) {
if (info.best_connection) {

View File

@ -2469,6 +2469,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
expected_rtp_transport.selected_candidate_pair_changes = 1;
expected_rtp_transport.ice_role = RTCIceRole::kUnknown;
expected_rtp_transport.ice_local_username_fragment = "thelocalufrag";
expected_rtp_transport.ice_state = RTCIceTransportState::kNew;
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
EXPECT_EQ(
@ -2496,6 +2497,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
rtcp_transport_channel_stats.ice_transport_stats.packets_received = 4;
rtcp_transport_channel_stats.ice_transport_stats.ice_local_username_fragment =
"thelocalufrag";
rtcp_transport_channel_stats.ice_transport_stats.ice_state =
IceTransportState::kChecking;
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
rtcp_transport_channel_stats});
@ -2515,6 +2518,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
expected_rtcp_transport.selected_candidate_pair_changes = 0;
expected_rtcp_transport.ice_role = RTCIceRole::kUnknown;
expected_rtcp_transport.ice_local_username_fragment = "thelocalufrag";
expected_rtcp_transport.ice_state = RTCIceTransportState::kChecking;
expected_rtp_transport.rtcp_transport_stats_id = expected_rtcp_transport.id();
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
@ -2618,6 +2622,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStatsWithCrypto) {
cricket::ICEROLE_CONTROLLING;
rtp_transport_channel_stats.ice_transport_stats.ice_local_username_fragment =
"thelocalufrag";
rtp_transport_channel_stats.ice_transport_stats.ice_state =
IceTransportState::kConnected;
// 0x2F is TLS_RSA_WITH_AES_128_CBC_SHA according to IANA
rtp_transport_channel_stats.ssl_cipher_suite = 0x2F;
rtp_transport_channel_stats.srtp_crypto_suite = rtc::kSrtpAes128CmSha1_80;
@ -2639,6 +2645,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStatsWithCrypto) {
expected_rtp_transport.packets_received = 0;
expected_rtp_transport.ice_role = RTCIceRole::kControlling;
expected_rtp_transport.ice_local_username_fragment = "thelocalufrag";
expected_rtp_transport.ice_state = "connected";
// Crypto parameters
expected_rtp_transport.tls_version = "0203";
expected_rtp_transport.dtls_role = RTCDtlsRole::kClient;

View File

@ -1145,6 +1145,7 @@ class RTCStatsReportVerifier {
transport.selected_candidate_pair_changes);
verifier.TestMemberIsDefined(transport.ice_role);
verifier.TestMemberIsDefined(transport.ice_local_username_fragment);
verifier.TestMemberIsDefined(transport.ice_state);
return verifier.ExpectAllMembersSuccessfullyTested();
}

View File

@ -72,6 +72,15 @@ const char* const RTCIceRole::kUnknown = "unknown";
const char* const RTCIceRole::kControlled = "controlled";
const char* const RTCIceRole::kControlling = "controlling";
// https://www.w3.org/TR/webrtc/#dom-rtcicetransportstate
const char* const RTCIceTransportState::kNew = "new";
const char* const RTCIceTransportState::kChecking = "checking";
const char* const RTCIceTransportState::kConnected = "connected";
const char* const RTCIceTransportState::kCompleted = "completed";
const char* const RTCIceTransportState::kDisconnected = "disconnected";
const char* const RTCIceTransportState::kFailed = "failed";
const char* const RTCIceTransportState::kClosed = "closed";
// clang-format off
WEBRTC_RTCSTATS_IMPL(RTCCertificateStats, RTCStats, "certificate",
&fingerprint,
@ -1099,7 +1108,8 @@ WEBRTC_RTCSTATS_IMPL(RTCTransportStats, RTCStats, "transport",
&srtp_cipher,
&selected_candidate_pair_changes,
&ice_role,
&ice_local_username_fragment)
&ice_local_username_fragment,
&ice_state)
// clang-format on
RTCTransportStats::RTCTransportStats(const std::string& id,
@ -1123,7 +1133,8 @@ RTCTransportStats::RTCTransportStats(std::string&& id, int64_t timestamp_us)
srtp_cipher("srtpCipher"),
selected_candidate_pair_changes("selectedCandidatePairChanges"),
ice_role("iceRole"),
ice_local_username_fragment("iceLocalUsernameFragment") {}
ice_local_username_fragment("iceLocalUsernameFragment"),
ice_state("iceState") {}
RTCTransportStats::RTCTransportStats(const RTCTransportStats& other)
: RTCStats(other.id(), other.timestamp_us()),
@ -1142,7 +1153,8 @@ RTCTransportStats::RTCTransportStats(const RTCTransportStats& other)
srtp_cipher(other.srtp_cipher),
selected_candidate_pair_changes(other.selected_candidate_pair_changes),
ice_role(other.ice_role),
ice_local_username_fragment(other.ice_local_username_fragment) {}
ice_local_username_fragment(other.ice_local_username_fragment),
ice_state(other.ice_state) {}
RTCTransportStats::~RTCTransportStats() {}