Bug 1339906 - pt 4 - add last sent and received timestamps to RTCIceCandidatePairStats. r=drno, r=qDot
MozReview-Commit-ID: GE23lS7qs9n
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -208,31 +208,35 @@ struct ParamTraits<mozilla::dom::RTCIceC
WriteParam(aMsg, aParam.mPriority);
WriteParam(aMsg, aParam.mNominated);
WriteParam(aMsg, aParam.mReadable);
WriteParam(aMsg, aParam.mRemoteCandidateId);
WriteParam(aMsg, aParam.mSelected);
WriteParam(aMsg, aParam.mState);
WriteParam(aMsg, aParam.mBytesSent);
WriteParam(aMsg, aParam.mBytesReceived);
+ WriteParam(aMsg, aParam.mLastPacketSentTimestamp);
+ WriteParam(aMsg, aParam.mLastPacketReceivedTimestamp);
WriteRTCStats(aMsg, aParam);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mTransportId)) ||
!ReadParam(aMsg, aIter, &(aResult->mLocalCandidateId)) ||
!ReadParam(aMsg, aIter, &(aResult->mPriority)) ||
!ReadParam(aMsg, aIter, &(aResult->mNominated)) ||
!ReadParam(aMsg, aIter, &(aResult->mReadable)) ||
!ReadParam(aMsg, aIter, &(aResult->mRemoteCandidateId)) ||
!ReadParam(aMsg, aIter, &(aResult->mSelected)) ||
!ReadParam(aMsg, aIter, &(aResult->mState)) ||
!ReadParam(aMsg, aIter, &(aResult->mBytesSent)) ||
!ReadParam(aMsg, aIter, &(aResult->mBytesReceived)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mLastPacketSentTimestamp)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mLastPacketReceivedTimestamp)) ||
!ReadRTCStats(aMsg, aIter, aResult)) {
return false;
}
return true;
}
};
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -128,16 +128,18 @@ dictionary RTCIceCandidatePairStats : RT
DOMString localCandidateId;
DOMString remoteCandidateId;
RTCStatsIceCandidatePairState state;
unsigned long long priority;
boolean readable;
boolean nominated;
unsigned long long bytesSent;
unsigned long long bytesReceived;
+ DOMHighResTimeStamp lastPacketSentTimestamp;
+ DOMHighResTimeStamp lastPacketReceivedTimestamp;
boolean selected;
};
enum RTCStatsIceCandidateType {
"host",
"serverreflexive",
"peerreflexive",
"relayed"
--- a/media/mtransport/nricemediastream.cpp
+++ b/media/mtransport/nricemediastream.cpp
@@ -402,16 +402,20 @@ nsresult NrIceMediaStream::GetCandidateP
pair.priority = p1->priority;
pair.nominated = p1->peer_nominated || p1->nominated;
pair.selected = p1->remote->component &&
p1->remote->component->active == p1;
pair.codeword = p1->codeword;
pair.bytes_sent = p1->bytes_sent;
pair.bytes_recvd = p1->bytes_recvd;
+ pair.ms_since_last_send = p1->last_sent.tv_sec*1000
+ + p1->last_sent.tv_usec/1000;
+ pair.ms_since_last_recv = p1->last_recvd.tv_sec*1000
+ + p1->last_recvd.tv_usec/1000;
if (!ToNrIceCandidate(*(p1->local), &pair.local) ||
!ToNrIceCandidate(*(p1->remote), &pair.remote)) {
return NS_ERROR_FAILURE;
}
out_pairs->push_back(pair);
}
--- a/media/mtransport/nricemediastream.h
+++ b/media/mtransport/nricemediastream.h
@@ -121,16 +121,18 @@ struct NrIceCandidatePair {
NrIceCandidate local;
NrIceCandidate remote;
// TODO(bcampen@mozilla.com): Is it important to put the foundation in here?
std::string codeword;
// for RTCIceCandidatePairStats
uint64_t bytes_sent;
uint64_t bytes_recvd;
+ uint64_t ms_since_last_send;
+ uint64_t ms_since_last_recv;
};
class NrIceMediaStream {
public:
static RefPtr<NrIceMediaStream> Create(NrIceCtx *ctx,
const std::string& name,
int components);
enum State { ICE_CONNECTING, ICE_OPEN, ICE_CLOSED};
--- a/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.h
@@ -61,16 +61,18 @@ struct nr_ice_cand_pair_ {
UINT8 priority; /* The priority for this pair */
nr_ice_candidate *local; /* The local candidate */
nr_ice_candidate *remote; /* The remote candidate */
char *foundation; /* The combined foundations */
// for RTCIceCandidatePairStats
UINT8 bytes_sent;
UINT8 bytes_recvd;
+ struct timeval last_sent;
+ struct timeval last_recvd;
nr_stun_client_ctx *stun_client; /* STUN context when acting as a client */
void *stun_client_handle;
void *stun_cb_timer;
void *restart_role_change_cb_timer;
void *restart_nominated_cb_timer;
--- a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c
@@ -824,16 +824,17 @@ int nr_ice_media_stream_send(nr_ice_peer
if ((r==R_IO_ERROR) || (r==R_EOD)) {
nr_ice_component_disconnected(comp);
}
ABORT(r);
}
// accumulate the sent bytes for the active candidate pair
comp->active->bytes_sent += len;
+ gettimeofday(&comp->active->last_sent, 0);
_status=0;
abort:
return(_status);
}
/* Returns R_REJECTED if the component is unpaired or has been disabled. */
int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote)
--- a/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.c
@@ -821,16 +821,17 @@ int nr_ice_peer_ctx_deliver_packet_maybe
}
if(!cand)
ABORT(R_REJECTED);
// accumulate the received bytes for the active candidate pair
if (peer_comp->active) {
peer_comp->active->bytes_recvd += len;
+ gettimeofday(&peer_comp->active->last_recvd, 0);
}
/* OK, there's a match. Call the handler */
if (pctx->handler) {
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): Delivering data", pctx->label);
pctx->handler->vtbl->msg_recvd(pctx->handler->obj,
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -3592,16 +3592,18 @@ static void RecordIceStats_s(
s.mType.Construct(RTCStatsType::Candidate_pair);
s.mLocalCandidateId.Construct(localCodeword);
s.mRemoteCandidateId.Construct(remoteCodeword);
s.mNominated.Construct(candPair.nominated);
s.mPriority.Construct(candPair.priority);
s.mSelected.Construct(candPair.selected);
s.mBytesSent.Construct(candPair.bytes_sent);
s.mBytesReceived.Construct(candPair.bytes_recvd);
+ s.mLastPacketSentTimestamp.Construct(candPair.ms_since_last_send);
+ s.mLastPacketReceivedTimestamp.Construct(candPair.ms_since_last_recv);
s.mState.Construct(RTCStatsIceCandidatePairState(candPair.state));
report->mIceCandidatePairStats.Value().AppendElement(s, fallible);
}
std::vector<NrIceCandidate> candidates;
if (NS_SUCCEEDED(mediaStream.GetLocalCandidates(&candidates))) {
ToRTCIceCandidateStats(candidates,
RTCStatsType::Local_candidate,