зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
61ea412a96
Коммит
5e217066fa
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче