LCOV - code coverage report
Current view: top level - media/mtransport - nricemediastream.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 287 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : // Original author: ekr@rtfm.com
       8             : 
       9             : // Some of this code is cut-and-pasted from nICEr. Copyright is:
      10             : 
      11             : /*
      12             : Copyright (c) 2007, Adobe Systems, Incorporated
      13             : All rights reserved.
      14             : 
      15             : Redistribution and use in source and binary forms, with or without
      16             : modification, are permitted provided that the following conditions are
      17             : met:
      18             : 
      19             : * Redistributions of source code must retain the above copyright
      20             :   notice, this list of conditions and the following disclaimer.
      21             : 
      22             : * Redistributions in binary form must reproduce the above copyright
      23             :   notice, this list of conditions and the following disclaimer in the
      24             :   documentation and/or other materials provided with the distribution.
      25             : 
      26             : * Neither the name of Adobe Systems, Network Resonance nor the names of its
      27             :   contributors may be used to endorse or promote products derived from
      28             :   this software without specific prior written permission.
      29             : 
      30             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      31             : "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      32             : LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      33             : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      34             : OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      35             : SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      36             : LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      37             : DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      38             : THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      39             : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      40             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      41             : */
      42             : 
      43             : 
      44             : #include <string>
      45             : #include <vector>
      46             : 
      47             : #include "logging.h"
      48             : #include "nsError.h"
      49             : 
      50             : // nICEr includes
      51             : extern "C" {
      52             : #include "nr_api.h"
      53             : #include "registry.h"
      54             : #include "async_timer.h"
      55             : #include "ice_util.h"
      56             : #include "transport_addr.h"
      57             : #include "nr_crypto.h"
      58             : #include "nr_socket.h"
      59             : #include "nr_socket_local.h"
      60             : #include "stun_client_ctx.h"
      61             : #include "stun_server_ctx.h"
      62             : #include "ice_ctx.h"
      63             : #include "ice_candidate.h"
      64             : #include "ice_handler.h"
      65             : }
      66             : 
      67             : // Local includes
      68             : #include "nricectx.h"
      69             : #include "nricemediastream.h"
      70             : 
      71             : namespace mozilla {
      72             : 
      73           0 : MOZ_MTLOG_MODULE("mtransport")
      74             : 
      75           0 : static bool ToNrIceAddr(nr_transport_addr &addr,
      76             :                         NrIceAddr *out) {
      77             :   int r;
      78             :   char addrstring[INET6_ADDRSTRLEN + 1];
      79             : 
      80           0 :   r = nr_transport_addr_get_addrstring(&addr, addrstring, sizeof(addrstring));
      81           0 :   if (r)
      82           0 :     return false;
      83           0 :   out->host = addrstring;
      84             : 
      85             :   int port;
      86           0 :   r = nr_transport_addr_get_port(&addr, &port);
      87           0 :   if (r)
      88           0 :     return false;
      89             : 
      90           0 :   out->port = port;
      91             : 
      92           0 :   switch (addr.protocol) {
      93             :     case IPPROTO_TCP:
      94           0 :       if (addr.tls_host[0] != '\0') {
      95           0 :         out->transport = kNrIceTransportTls;
      96             :       } else {
      97           0 :         out->transport = kNrIceTransportTcp;
      98             :       }
      99           0 :       break;
     100             :     case IPPROTO_UDP:
     101           0 :       out->transport = kNrIceTransportUdp;
     102           0 :       break;
     103             :     default:
     104           0 :       MOZ_CRASH();
     105             :       return false;
     106             :   }
     107             : 
     108           0 :   return true;
     109             : }
     110             : 
     111           0 : static bool ToNrIceCandidate(const nr_ice_candidate& candc,
     112             :                              NrIceCandidate* out) {
     113           0 :   MOZ_ASSERT(out);
     114             :   int r;
     115             :   // Const-cast because the internal nICEr code isn't const-correct.
     116           0 :   nr_ice_candidate *cand = const_cast<nr_ice_candidate *>(&candc);
     117             : 
     118           0 :   if (!ToNrIceAddr(cand->addr, &out->cand_addr))
     119           0 :     return false;
     120             : 
     121           0 :   if (cand->isock) {
     122             :     nr_transport_addr addr;
     123           0 :     r = nr_socket_getaddr(cand->isock->sock, &addr);
     124           0 :     if (r)
     125           0 :       return false;
     126             : 
     127           0 :     if (!ToNrIceAddr(addr, &out->local_addr))
     128           0 :       return false;
     129             :   }
     130             : 
     131             :   NrIceCandidate::Type type;
     132             : 
     133           0 :   switch (cand->type) {
     134             :     case HOST:
     135           0 :       type = NrIceCandidate::ICE_HOST;
     136           0 :       break;
     137             :     case SERVER_REFLEXIVE:
     138           0 :       type = NrIceCandidate::ICE_SERVER_REFLEXIVE;
     139           0 :       break;
     140             :     case PEER_REFLEXIVE:
     141           0 :       type = NrIceCandidate::ICE_PEER_REFLEXIVE;
     142           0 :       break;
     143             :     case RELAYED:
     144           0 :       type = NrIceCandidate::ICE_RELAYED;
     145           0 :       break;
     146             :     default:
     147           0 :       return false;
     148             :   }
     149             : 
     150             :   NrIceCandidate::TcpType tcp_type;
     151           0 :   switch (cand->tcp_type) {
     152             :     case TCP_TYPE_ACTIVE:
     153           0 :       tcp_type = NrIceCandidate::ICE_ACTIVE;
     154           0 :       break;
     155             :     case TCP_TYPE_PASSIVE:
     156           0 :       tcp_type = NrIceCandidate::ICE_PASSIVE;
     157           0 :       break;
     158             :     case TCP_TYPE_SO:
     159           0 :       tcp_type = NrIceCandidate::ICE_SO;
     160           0 :       break;
     161             :     default:
     162           0 :       tcp_type = NrIceCandidate::ICE_NONE;
     163           0 :       break;
     164             :   }
     165             : 
     166           0 :   out->type = type;
     167           0 :   out->tcp_type = tcp_type;
     168           0 :   out->codeword = candc.codeword;
     169           0 :   return true;
     170             : }
     171             : 
     172             : // Make an NrIceCandidate from the candidate |cand|.
     173             : // This is not a member fxn because we want to hide the
     174             : // defn of nr_ice_candidate but we pass by reference.
     175           0 : static UniquePtr<NrIceCandidate> MakeNrIceCandidate(const nr_ice_candidate& candc) {
     176           0 :   UniquePtr<NrIceCandidate> out(new NrIceCandidate());
     177             : 
     178           0 :   if (!ToNrIceCandidate(candc, out.get())) {
     179           0 :     return nullptr;
     180             :   }
     181           0 :   return out;
     182             : }
     183             : 
     184             : // NrIceMediaStream
     185             : RefPtr<NrIceMediaStream>
     186           0 : NrIceMediaStream::Create(NrIceCtx *ctx,
     187             :                          const std::string& name,
     188             :                          int components) {
     189             :   RefPtr<NrIceMediaStream> stream =
     190           0 :     new NrIceMediaStream(ctx, name, components);
     191           0 :   MOZ_ASSERT(stream->ctx_ == ctx->ctx());
     192             : 
     193           0 :   int r = nr_ice_add_media_stream(ctx->ctx(),
     194           0 :                                   const_cast<char *>(name.c_str()),
     195           0 :                                   components, &stream->stream_);
     196           0 :   if (r) {
     197           0 :     MOZ_MTLOG(ML_ERROR, "Couldn't create ICE media stream for '"
     198             :               << name << "'");
     199           0 :     return nullptr;
     200             :   }
     201             : 
     202           0 :   return stream;
     203             : }
     204             : 
     205           0 : NrIceMediaStream::NrIceMediaStream(NrIceCtx *ctx,
     206             :                                    const std::string& name,
     207           0 :                                    size_t components) :
     208             :       state_(ICE_CONNECTING),
     209           0 :       ctx_(ctx->ctx()),
     210           0 :       ctx_peer_(ctx->peer()),
     211             :       name_(name),
     212             :       components_(components),
     213             :       stream_(nullptr),
     214             :       level_(0),
     215           0 :       has_parsed_attrs_(false)
     216             : {
     217           0 : }
     218             : 
     219           0 : NrIceMediaStream::~NrIceMediaStream() {
     220             :   // We do not need to destroy anything. All major resources
     221             :   // are attached to the ice ctx.
     222           0 : }
     223             : 
     224           0 : nsresult NrIceMediaStream::ParseAttributes(std::vector<std::string>&
     225             :                                            attributes) {
     226           0 :   if (!stream_)
     227           0 :     return NS_ERROR_FAILURE;
     228             : 
     229           0 :   std::vector<char *> attributes_in;
     230             : 
     231           0 :   for (auto& attribute : attributes) {
     232           0 :     attributes_in.push_back(const_cast<char *>(attribute.c_str()));
     233             :   }
     234             : 
     235             :   // Still need to call nr_ice_ctx_parse_stream_attributes.
     236           0 :   int r = nr_ice_peer_ctx_parse_stream_attributes(ctx_peer_,
     237             :                                                   stream_,
     238           0 :                                                   attributes_in.size() ?
     239             :                                                   &attributes_in[0] : nullptr,
     240           0 :                                                   attributes_in.size());
     241           0 :   if (r) {
     242           0 :     MOZ_MTLOG(ML_ERROR, "Couldn't parse attributes for stream "
     243             :               << name_ << "'");
     244           0 :     return NS_ERROR_FAILURE;
     245             :   }
     246             : 
     247           0 :   has_parsed_attrs_ = true;
     248           0 :   return NS_OK;
     249             : }
     250             : 
     251             : // Parse trickle ICE candidate
     252           0 : nsresult NrIceMediaStream::ParseTrickleCandidate(const std::string& candidate) {
     253             :   int r;
     254             : 
     255           0 :   MOZ_MTLOG(ML_DEBUG, "NrIceCtx(" << ctx_->label << ")/STREAM(" <<
     256             :             name() << ") : parsing trickle candidate " << candidate);
     257             : 
     258           0 :   r = nr_ice_peer_ctx_parse_trickle_candidate(ctx_peer_,
     259             :                                               stream_,
     260             :                                               const_cast<char *>(
     261           0 :                                                 candidate.c_str())
     262           0 :                                               );
     263           0 :   if (r) {
     264           0 :     if (r == R_ALREADY) {
     265           0 :       MOZ_MTLOG(ML_ERROR, "Trickle candidates are redundant for stream '"
     266             :                 << name_ << "' because it is completed");
     267             : 
     268             :     } else {
     269           0 :       MOZ_MTLOG(ML_ERROR, "Couldn't parse trickle candidate for stream '"
     270             :                 << name_ << "'");
     271           0 :       return NS_ERROR_FAILURE;
     272             :     }
     273             :   }
     274             : 
     275           0 :   return NS_OK;
     276             : }
     277             : 
     278             : // Returns NS_ERROR_NOT_AVAILABLE if component is unpaired or disabled.
     279           0 : nsresult NrIceMediaStream::GetActivePair(int component,
     280             :                                          UniquePtr<NrIceCandidate>* localp,
     281             :                                          UniquePtr<NrIceCandidate>* remotep) {
     282             :   int r;
     283             :   nr_ice_candidate *local_int;
     284             :   nr_ice_candidate *remote_int;
     285             : 
     286           0 :   if (!stream_) {
     287           0 :     return NS_ERROR_NOT_AVAILABLE;
     288             :   }
     289             : 
     290           0 :   r = nr_ice_media_stream_get_active(ctx_peer_,
     291             :                                      stream_,
     292             :                                      component,
     293           0 :                                      &local_int, &remote_int);
     294             :   // If result is R_REJECTED then component is unpaired or disabled.
     295           0 :   if (r == R_REJECTED)
     296           0 :     return NS_ERROR_NOT_AVAILABLE;
     297             : 
     298           0 :   if (r)
     299           0 :     return NS_ERROR_FAILURE;
     300             : 
     301             :   UniquePtr<NrIceCandidate> local(
     302           0 :       MakeNrIceCandidate(*local_int));
     303           0 :   if (!local)
     304           0 :     return NS_ERROR_FAILURE;
     305             : 
     306             :   UniquePtr<NrIceCandidate> remote(
     307           0 :       MakeNrIceCandidate(*remote_int));
     308           0 :   if (!remote)
     309           0 :     return NS_ERROR_FAILURE;
     310             : 
     311           0 :   if (localp)
     312           0 :     *localp = Move(local);
     313           0 :   if (remotep)
     314           0 :     *remotep = Move(remote);
     315             : 
     316           0 :   return NS_OK;
     317             : }
     318             : 
     319             : 
     320           0 : nsresult NrIceMediaStream::GetCandidatePairs(std::vector<NrIceCandidatePair>*
     321             :                                              out_pairs) const {
     322           0 :   MOZ_ASSERT(out_pairs);
     323           0 :   if (!stream_) {
     324           0 :     return NS_ERROR_NOT_AVAILABLE;
     325             :   }
     326             : 
     327             :   // If we haven't at least started checking then there is nothing to report
     328           0 :   if (ctx_peer_->state != NR_ICE_PEER_STATE_PAIRED) {
     329           0 :     return NS_OK;
     330             :   }
     331             : 
     332             :   // Get the check_list on the peer stream (this is where the check_list
     333             :   // actually lives, not in stream_)
     334             :   nr_ice_media_stream* peer_stream;
     335           0 :   int r = nr_ice_peer_ctx_find_pstream(ctx_peer_, stream_, &peer_stream);
     336           0 :   if (r != 0) {
     337           0 :     return NS_ERROR_FAILURE;
     338             :   }
     339             : 
     340             :   nr_ice_cand_pair *p1, *p2;
     341           0 :   out_pairs->clear();
     342             : 
     343           0 :   TAILQ_FOREACH(p1, &peer_stream->check_list, check_queue_entry) {
     344           0 :     MOZ_ASSERT(p1);
     345           0 :     MOZ_ASSERT(p1->local);
     346           0 :     MOZ_ASSERT(p1->remote);
     347           0 :     NrIceCandidatePair pair;
     348             : 
     349           0 :     p2 = TAILQ_FIRST(&peer_stream->check_list);
     350           0 :     while (p2) {
     351           0 :       if (p1 == p2) {
     352             :         /* Don't compare with our self. */
     353           0 :         p2=TAILQ_NEXT(p2, check_queue_entry);
     354           0 :         continue;
     355             :       }
     356           0 :       if (strncmp(p1->codeword,p2->codeword,sizeof(p1->codeword))==0) {
     357             :         /* In case of duplicate pairs we only report the one winning pair */
     358           0 :         if (
     359           0 :             ((p2->remote->component && (p2->remote->component->active == p2)) &&
     360           0 :              !(p1->remote->component && (p1->remote->component->active == p1))) ||
     361           0 :             ((p2->peer_nominated || p2->nominated) &&
     362           0 :              !(p1->peer_nominated || p1->nominated)) ||
     363           0 :             (p2->priority > p1->priority) ||
     364           0 :             ((p2->state == NR_ICE_PAIR_STATE_SUCCEEDED) &&
     365           0 :              (p1->state != NR_ICE_PAIR_STATE_SUCCEEDED)) ||
     366           0 :             ((p2->state != NR_ICE_PAIR_STATE_CANCELLED) &&
     367           0 :              (p1->state == NR_ICE_PAIR_STATE_CANCELLED))
     368             :             ) {
     369             :           /* p2 is a better pair. */
     370             :           break;
     371             :         }
     372             :       }
     373           0 :       p2=TAILQ_NEXT(p2, check_queue_entry);
     374             :     }
     375           0 :     if (p2) {
     376             :       /* p2 points to a duplicate but better pair so skip this one */
     377           0 :       continue;
     378             :     }
     379             : 
     380           0 :     switch (p1->state) {
     381             :       case NR_ICE_PAIR_STATE_FROZEN:
     382           0 :         pair.state = NrIceCandidatePair::State::STATE_FROZEN;
     383           0 :         break;
     384             :       case NR_ICE_PAIR_STATE_WAITING:
     385           0 :         pair.state = NrIceCandidatePair::State::STATE_WAITING;
     386           0 :         break;
     387             :       case NR_ICE_PAIR_STATE_IN_PROGRESS:
     388           0 :         pair.state = NrIceCandidatePair::State::STATE_IN_PROGRESS;
     389           0 :         break;
     390             :       case NR_ICE_PAIR_STATE_FAILED:
     391           0 :         pair.state = NrIceCandidatePair::State::STATE_FAILED;
     392           0 :         break;
     393             :       case NR_ICE_PAIR_STATE_SUCCEEDED:
     394           0 :         pair.state = NrIceCandidatePair::State::STATE_SUCCEEDED;
     395           0 :         break;
     396             :       case NR_ICE_PAIR_STATE_CANCELLED:
     397           0 :         pair.state = NrIceCandidatePair::State::STATE_CANCELLED;
     398           0 :         break;
     399             :       default:
     400           0 :         MOZ_ASSERT(0);
     401             :     }
     402             : 
     403           0 :     pair.priority = p1->priority;
     404           0 :     pair.nominated = p1->peer_nominated || p1->nominated;
     405             :     // As discussed with drno: a component's can_send field (set to true
     406             :     // by ICE consent) is a very close approximation for writable and
     407             :     // readable. Note: the component for the local candidate never has
     408             :     // the can_send member set to true, remote for both readable and
     409             :     // writable. (mjf)
     410           0 :     pair.writable = p1->remote->component->can_send;
     411           0 :     pair.readable = p1->remote->component->can_send;
     412           0 :     pair.selected = p1->remote->component &&
     413           0 :                     p1->remote->component->active == p1;
     414           0 :     pair.codeword = p1->codeword;
     415           0 :     pair.bytes_sent = p1->bytes_sent;
     416           0 :     pair.bytes_recvd = p1->bytes_recvd;
     417           0 :     pair.ms_since_last_send = p1->last_sent.tv_sec*1000
     418           0 :                               + p1->last_sent.tv_usec/1000;
     419           0 :     pair.ms_since_last_recv = p1->last_recvd.tv_sec*1000
     420           0 :                               + p1->last_recvd.tv_usec/1000;
     421             : 
     422           0 :     if (!ToNrIceCandidate(*(p1->local), &pair.local) ||
     423           0 :         !ToNrIceCandidate(*(p1->remote), &pair.remote)) {
     424           0 :       return NS_ERROR_FAILURE;
     425             :     }
     426             : 
     427           0 :     out_pairs->push_back(pair);
     428             :   }
     429             : 
     430           0 :   return NS_OK;
     431             : }
     432             : 
     433           0 : nsresult NrIceMediaStream::GetDefaultCandidate(
     434             :     int component,
     435             :     NrIceCandidate* candidate) const {
     436             : 
     437             :   nr_ice_candidate *cand;
     438             : 
     439           0 :   int r = nr_ice_media_stream_get_default_candidate(stream_, component, &cand);
     440           0 :   if (r) {
     441           0 :     MOZ_MTLOG(ML_ERROR, "Couldn't get default ICE candidate for '"
     442             :               << name_ << "'");
     443           0 :     return NS_ERROR_FAILURE;
     444             :   }
     445             : 
     446           0 :   if (!ToNrIceCandidate(*cand, candidate)) {
     447           0 :     MOZ_MTLOG(ML_ERROR, "Failed to convert default ICE candidate for '"
     448             :               << name_ << "'");
     449           0 :     return NS_ERROR_FAILURE;
     450             :   }
     451             : 
     452           0 :   return NS_OK;
     453             : }
     454             : 
     455           0 : std::vector<std::string> NrIceMediaStream::GetCandidates() const {
     456           0 :   char **attrs = nullptr;
     457             :   int attrct;
     458             :   int r;
     459           0 :   std::vector<std::string> ret;
     460             : 
     461           0 :   if (!stream_) {
     462           0 :     return ret;
     463             :   }
     464             : 
     465           0 :   r = nr_ice_media_stream_get_attributes(stream_,
     466           0 :                                          &attrs, &attrct);
     467           0 :   if (r) {
     468           0 :     MOZ_MTLOG(ML_ERROR, "Couldn't get ICE candidates for '"
     469             :               << name_ << "'");
     470           0 :     return ret;
     471             :   }
     472             : 
     473           0 :   for (int i=0; i<attrct; i++) {
     474           0 :     ret.push_back(attrs[i]);
     475           0 :     RFREE(attrs[i]);
     476             :   }
     477             : 
     478           0 :   RFREE(attrs);
     479             : 
     480           0 :   return ret;
     481             : }
     482             : 
     483           0 : static nsresult GetCandidatesFromStream(
     484             :     nr_ice_media_stream *stream,
     485             :     std::vector<NrIceCandidate> *candidates) {
     486           0 :   MOZ_ASSERT(candidates);
     487           0 :   nr_ice_component* comp=STAILQ_FIRST(&stream->components);
     488           0 :   while(comp){
     489           0 :     if (comp->state != NR_ICE_COMPONENT_DISABLED) {
     490           0 :       nr_ice_candidate *cand = TAILQ_FIRST(&comp->candidates);
     491           0 :       while(cand){
     492           0 :         NrIceCandidate new_cand;
     493             :         // This can fail if the candidate is server reflexive or relayed, and
     494             :         // has not yet received a response (ie; it doesn't know its address
     495             :         // yet). For the purposes of this code, this isn't a candidate we're
     496             :         // interested in, since it is not fully baked yet.
     497           0 :         if (ToNrIceCandidate(*cand, &new_cand)) {
     498           0 :           candidates->push_back(new_cand);
     499             :         }
     500           0 :         cand=TAILQ_NEXT(cand,entry_comp);
     501             :       }
     502             :     }
     503           0 :     comp=STAILQ_NEXT(comp,entry);
     504             :   }
     505             : 
     506           0 :   return NS_OK;
     507             : }
     508             : 
     509           0 : nsresult NrIceMediaStream::GetLocalCandidates(
     510             :     std::vector<NrIceCandidate>* candidates) const {
     511           0 :   if (!stream_) {
     512           0 :     return NS_ERROR_NOT_AVAILABLE;
     513             :   }
     514             : 
     515           0 :   return GetCandidatesFromStream(stream_, candidates);
     516             : }
     517             : 
     518           0 : nsresult NrIceMediaStream::GetRemoteCandidates(
     519             :     std::vector<NrIceCandidate>* candidates) const {
     520           0 :   if (!stream_) {
     521           0 :     return NS_ERROR_NOT_AVAILABLE;
     522             :   }
     523             : 
     524             :   // If we haven't at least started checking then there is nothing to report
     525           0 :   if (ctx_peer_->state != NR_ICE_PEER_STATE_PAIRED) {
     526           0 :     return NS_OK;
     527             :   }
     528             : 
     529             :   nr_ice_media_stream* peer_stream;
     530           0 :   int r = nr_ice_peer_ctx_find_pstream(ctx_peer_, stream_, &peer_stream);
     531           0 :   if (r != 0) {
     532           0 :     return NS_ERROR_FAILURE;
     533             :   }
     534             : 
     535           0 :   return GetCandidatesFromStream(peer_stream, candidates);
     536             : }
     537             : 
     538             : 
     539           0 : nsresult NrIceMediaStream::DisableComponent(int component_id) {
     540           0 :   if (!stream_)
     541           0 :     return NS_ERROR_FAILURE;
     542             : 
     543           0 :   int r = nr_ice_media_stream_disable_component(stream_,
     544           0 :                                                 component_id);
     545           0 :   if (r) {
     546           0 :     MOZ_MTLOG(ML_ERROR, "Couldn't disable '" << name_ << "':" <<
     547             :               component_id);
     548           0 :     return NS_ERROR_FAILURE;
     549             :   }
     550             : 
     551           0 :   return NS_OK;
     552             : }
     553             : 
     554           0 : nsresult NrIceMediaStream::GetConsentStatus(int component_id, bool *can_send, struct timeval *ts) {
     555           0 :   if (!stream_)
     556           0 :     return NS_ERROR_FAILURE;
     557             : 
     558             :   nr_ice_media_stream* peer_stream;
     559           0 :   int r = nr_ice_peer_ctx_find_pstream(ctx_peer_, stream_, &peer_stream);
     560           0 :   if (r) {
     561           0 :     MOZ_MTLOG(ML_ERROR, "Failed to find peer stream for '" << name_ << "':" <<
     562             :               component_id);
     563           0 :     return NS_ERROR_FAILURE;
     564             :   }
     565             : 
     566           0 :   int send = 0;
     567           0 :   r = nr_ice_media_stream_get_consent_status(peer_stream, component_id,
     568           0 :                                              &send, ts);
     569           0 :   if (r) {
     570           0 :     MOZ_MTLOG(ML_ERROR, "Failed to get consent status for '" << name_ << "':" <<
     571             :               component_id);
     572           0 :     return NS_ERROR_FAILURE;
     573             :   }
     574           0 :   *can_send = !!send;
     575             : 
     576           0 :   return NS_OK;
     577             : }
     578             : 
     579           0 : nsresult NrIceMediaStream::SendPacket(int component_id,
     580             :                                       const unsigned char *data,
     581             :                                       size_t len) {
     582           0 :   if (!stream_)
     583           0 :     return NS_ERROR_FAILURE;
     584             : 
     585           0 :   int r = nr_ice_media_stream_send(ctx_peer_, stream_,
     586             :                                    component_id,
     587           0 :                                    const_cast<unsigned char *>(data), len);
     588           0 :   if (r) {
     589           0 :     MOZ_MTLOG(ML_ERROR, "Couldn't send media on '" << name_ << "'");
     590           0 :     if (r == R_WOULDBLOCK) {
     591           0 :       return NS_BASE_STREAM_WOULD_BLOCK;
     592             :     }
     593             : 
     594           0 :     return NS_BASE_STREAM_OSERROR;
     595             :   }
     596             : 
     597           0 :   return NS_OK;
     598             : }
     599             : 
     600             : 
     601           0 : void NrIceMediaStream::Ready() {
     602             :   // This function is called whenever a stream becomes ready, but it
     603             :   // gets fired multiple times when a stream gets nominated repeatedly.
     604           0 :   if (state_ != ICE_OPEN) {
     605           0 :     MOZ_MTLOG(ML_DEBUG, "Marking stream ready '" << name_ << "'");
     606           0 :     state_ = ICE_OPEN;
     607           0 :     SignalReady(this);
     608             :   }
     609             :   else {
     610           0 :     MOZ_MTLOG(ML_DEBUG, "Stream ready callback fired again for '" << name_ << "'");
     611             :   }
     612           0 : }
     613             : 
     614           0 : void NrIceMediaStream::Close() {
     615           0 :   MOZ_MTLOG(ML_DEBUG, "Marking stream closed '" << name_ << "'");
     616           0 :   state_ = ICE_CLOSED;
     617             : 
     618           0 :   if (stream_) {
     619           0 :     int r = nr_ice_remove_media_stream(ctx_, &stream_);
     620           0 :     if (r) {
     621           0 :       MOZ_ASSERT(false, "Failed to remove stream");
     622             :       MOZ_MTLOG(ML_ERROR, "Failed to remove stream, error=" << r);
     623             :     }
     624             :   }
     625           0 : }
     626             : 
     627             : }  // close namespace

Generated by: LCOV version 1.13