Bug 906990 - Adding a bulk getter for the current state of all ICE candidate pairs(plus a little testing). r=ekr

This commit is contained in:
Byron Campen [:bwc] 2013-09-09 10:19:01 -07:00
Родитель 61ea412a96
Коммит 5e217066fa
5 изменённых файлов: 139 добавлений и 12 удалений

Просмотреть файл

@ -73,12 +73,9 @@ namespace mozilla {
MOZ_MTLOG_MODULE("mtransport")
// Make an NrIceCandidate from the candidate |cand|.
// This is not a member fxn because we want to hide the
// defn of nr_ice_candidate but we pass by reference.
static NrIceCandidate* MakeNrIceCandidate(const nr_ice_candidate& candc) {
ScopedDeletePtr<NrIceCandidate> out(new NrIceCandidate());
static bool ToNrIceCandidate(const nr_ice_candidate& candc,
NrIceCandidate* out) {
MOZ_ASSERT(out);
int r;
// Const-cast because the internal nICEr code isn't const-correct.
nr_ice_candidate *cand = const_cast<nr_ice_candidate *>(&candc);
@ -86,16 +83,16 @@ static NrIceCandidate* MakeNrIceCandidate(const nr_ice_candidate& candc) {
r = nr_transport_addr_get_addrstring(&cand->addr, addr, sizeof(addr));
if (r)
return nullptr;
return false;
int port;
r=nr_transport_addr_get_port(&cand->addr, &port);
r = nr_transport_addr_get_port(&cand->addr, &port);
if (r)
return nullptr;
return false;
NrIceCandidate::Type type;
switch(cand->type) {
switch (cand->type) {
case HOST:
type = NrIceCandidate::ICE_HOST;
break;
@ -109,13 +106,23 @@ static NrIceCandidate* MakeNrIceCandidate(const nr_ice_candidate& candc) {
type = NrIceCandidate::ICE_RELAYED;
break;
default:
return nullptr;
return false;
}
out->host = addr;
out->port = port;
out->type = type;
return true;
}
// Make an NrIceCandidate from the candidate |cand|.
// This is not a member fxn because we want to hide the
// defn of nr_ice_candidate but we pass by reference.
static NrIceCandidate* MakeNrIceCandidate(const nr_ice_candidate& candc) {
ScopedDeletePtr<NrIceCandidate> out(new NrIceCandidate());
if (!ToNrIceCandidate(candc, out)) {
return nullptr;
}
return out.forget();
}
@ -255,6 +262,66 @@ void NrIceMediaStream::EmitAllCandidates() {
RFREE(attrs);
}
nsresult NrIceMediaStream::GetCandidatePairs(std::vector<NrIceCandidatePair>*
outPairs) const {
MOZ_ASSERT(outPairs);
// Get the check_list on the peer stream (this is where the check_list
// actually lives, not in stream_)
nr_ice_media_stream* peerStream = nullptr;
int r = nr_ice_peer_ctx_find_pstream(ctx_->peer(), stream_, &peerStream);
if (r != 0) {
return NS_ERROR_FAILURE;
}
nr_ice_cand_pair *p1;
outPairs->clear();
TAILQ_FOREACH(p1, &peerStream->check_list, entry) {
MOZ_ASSERT(p1);
MOZ_ASSERT(p1->local);
MOZ_ASSERT(p1->remote);
NrIceCandidatePair pair;
switch (p1->state) {
case NR_ICE_PAIR_STATE_FROZEN:
pair.state = NrIceCandidatePair::State::STATE_FROZEN;
break;
case NR_ICE_PAIR_STATE_WAITING:
pair.state = NrIceCandidatePair::State::STATE_WAITING;
break;
case NR_ICE_PAIR_STATE_IN_PROGRESS:
pair.state = NrIceCandidatePair::State::STATE_IN_PROGRESS;
break;
case NR_ICE_PAIR_STATE_FAILED:
pair.state = NrIceCandidatePair::State::STATE_FAILED;
break;
case NR_ICE_PAIR_STATE_SUCCEEDED:
pair.state = NrIceCandidatePair::State::STATE_SUCCEEDED;
break;
case NR_ICE_PAIR_STATE_CANCELLED:
pair.state = NrIceCandidatePair::State::STATE_CANCELLED;
break;
default:
return NS_ERROR_FAILURE;
}
pair.priority = p1->priority;
pair.nominated = p1->peer_nominated != 0 || p1->nominated != 0;
pair.selected = p1->local->component != nullptr &&
p1->local->component->active == p1;
if (!ToNrIceCandidate(*(p1->local), &pair.local) ||
!ToNrIceCandidate(*(p1->remote), &pair.remote)) {
return NS_ERROR_FAILURE;
}
outPairs->push_back(pair);
}
return NS_OK;
}
nsresult NrIceMediaStream::GetDefaultCandidate(int component,
std::string *addrp,
int *portp) {

Просмотреть файл

@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef nricemediastream_h__
#define nricemediastream_h__
#include <string>
#include <vector>
#include "sigslot.h"
@ -78,6 +79,33 @@ struct NrIceCandidate {
Type type;
};
struct NrIceCandidatePair {
enum State {
STATE_FROZEN,
STATE_WAITING,
STATE_IN_PROGRESS,
STATE_FAILED,
STATE_SUCCEEDED,
STATE_CANCELLED
};
State state;
uint64_t priority;
// Set regardless of who nominated it. Does not necessarily mean that it is
// ready to be selected (ie; nominated by peer, but our check has not
// succeeded yet.) Note: since this implementation uses aggressive nomination,
// when we are the controlling agent, this will always be set if the pair is
// in STATE_SUCCEEDED.
bool nominated;
// Set if this candidate pair has been selected. Note: Since we are using
// aggressive nomination, this could change frequently as ICE runs.
bool selected;
NrIceCandidate local;
NrIceCandidate remote;
// TODO(bcampen@mozilla.com): Is it important to put the foundation in here?
};
class NrIceMediaStream {
public:
static RefPtr<NrIceMediaStream> Create(NrIceCtx *ctx,
@ -95,6 +123,10 @@ class NrIceMediaStream {
// Get all the candidates
std::vector<std::string> GetCandidates() const;
// Get all candidate pairs, whether in the check list or triggered check
// queue, in priority order. outPairs is cleared before being filled.
nsresult GetCandidatePairs(std::vector<NrIceCandidatePair>* outPairs) const;
// Get the default candidate as host and port
nsresult GetDefaultCandidate(int component, std::string *host, int *port);

Просмотреть файл

@ -107,6 +107,7 @@ class IceTestPeer : public sigslot::has_slots<> {
streams_.push_back(stream);
stream->SignalCandidate.connect(this, &IceTestPeer::GotCandidate);
stream->SignalReady.connect(this, &IceTestPeer::StreamReady);
stream->SignalFailed.connect(this, &IceTestPeer::StreamFailed);
stream->SignalPacketReceived.connect(this, &IceTestPeer::PacketReceived);
}
@ -353,9 +354,35 @@ class IceTestPeer : public sigslot::has_slots<> {
candidates_[stream->name()].push_back(candidate);
}
void DumpCandidatePairs(NrIceMediaStream *stream) {
std::vector<NrIceCandidatePair> pairs;
nsresult r = stream->GetCandidatePairs(&pairs);
ASSERT_TRUE(NS_SUCCEEDED(r));
std::cerr << "Begin list of candidate pairs [" << std::endl;
for (std::vector<NrIceCandidatePair>::iterator p = pairs.begin();
p != pairs.end(); ++p) {
std::cerr << std::endl;
DumpCandidate("Local", p->local);
DumpCandidate("Remote", p->remote);
std::cerr << "state = " << p->state
<< " priority = " << p->priority
<< " nominated = " << p->nominated
<< " selected = " << p->selected << std::endl;
}
std::cerr << "]" << std::endl;
}
void StreamReady(NrIceMediaStream *stream) {
++ready_ct_;
std::cerr << "Stream ready " << stream->name() << " ct=" << ready_ct_ << std::endl;
DumpCandidatePairs(stream);
}
void StreamFailed(NrIceMediaStream *stream) {
std::cerr << "Stream failed " << stream->name() << " ct=" << ready_ct_ << std::endl;
DumpCandidatePairs(stream);
}
void IceCompleted(NrIceCtx *ctx) {

Просмотреть файл

@ -229,7 +229,7 @@ static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream
return(_status);
}
static int nr_ice_peer_ctx_find_pstream(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, nr_ice_media_stream **pstreamp)
int nr_ice_peer_ctx_find_pstream(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, nr_ice_media_stream **pstreamp)
{
int _status;
nr_ice_media_stream *pstream;

Просмотреть файл

@ -67,6 +67,7 @@ typedef STAILQ_HEAD(nr_ice_peer_ctx_head_, nr_ice_peer_ctx_) nr_ice_peer_ctx_hea
int nr_ice_peer_ctx_create(nr_ice_ctx *ctx, nr_ice_handler *handler,char *label, nr_ice_peer_ctx **pctxp);
int nr_ice_peer_ctx_destroy(nr_ice_peer_ctx **pctxp);
int nr_ice_peer_ctx_parse_stream_attributes(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char **attrs, int attr_ct);
int nr_ice_peer_ctx_find_pstream(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, nr_ice_media_stream **pstreamp);
int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *cand);
int nr_ice_peer_ctx_pair_candidates(nr_ice_peer_ctx *pctx);