media/mtransport/nricectx.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/mtransport/nricectx.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,317 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +// Original author: ekr@rtfm.com
    1.11 +
    1.12 +// Some of this code is cut-and-pasted from nICEr. Copyright is:
    1.13 +
    1.14 +/*
    1.15 +Copyright (c) 2007, Adobe Systems, Incorporated
    1.16 +All rights reserved.
    1.17 +
    1.18 +Redistribution and use in source and binary forms, with or without
    1.19 +modification, are permitted provided that the following conditions are
    1.20 +met:
    1.21 +
    1.22 +* Redistributions of source code must retain the above copyright
    1.23 +  notice, this list of conditions and the following disclaimer.
    1.24 +
    1.25 +* Redistributions in binary form must reproduce the above copyright
    1.26 +  notice, this list of conditions and the following disclaimer in the
    1.27 +  documentation and/or other materials provided with the distribution.
    1.28 +
    1.29 +* Neither the name of Adobe Systems, Network Resonance nor the names of its
    1.30 +  contributors may be used to endorse or promote products derived from
    1.31 +  this software without specific prior written permission.
    1.32 +
    1.33 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.34 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.35 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.36 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.37 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.38 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.39 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.40 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.41 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.42 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.43 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.44 +*/
    1.45 +
    1.46 +/* This Source Code Form is subject to the terms of the Mozilla Public
    1.47 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
    1.48 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
    1.49 +
    1.50 +// Original author: ekr@rtfm.com
    1.51 +
    1.52 +// This is a wrapper around the nICEr ICE stack
    1.53 +#ifndef nricectx_h__
    1.54 +#define nricectx_h__
    1.55 +
    1.56 +#include <vector>
    1.57 +
    1.58 +#include "sigslot.h"
    1.59 +
    1.60 +#include "prnetdb.h"
    1.61 +
    1.62 +#include "mozilla/RefPtr.h"
    1.63 +#include "mozilla/Scoped.h"
    1.64 +#include "nsAutoPtr.h"
    1.65 +#include "nsIEventTarget.h"
    1.66 +#include "nsITimer.h"
    1.67 +
    1.68 +#include "m_cpp_utils.h"
    1.69 +
    1.70 +typedef struct nr_ice_ctx_ nr_ice_ctx;
    1.71 +typedef struct nr_ice_peer_ctx_ nr_ice_peer_ctx;
    1.72 +typedef struct nr_ice_media_stream_ nr_ice_media_stream;
    1.73 +typedef struct nr_ice_handler_ nr_ice_handler;
    1.74 +typedef struct nr_ice_handler_vtbl_ nr_ice_handler_vtbl;
    1.75 +typedef struct nr_ice_candidate_ nr_ice_candidate;
    1.76 +typedef struct nr_ice_cand_pair_ nr_ice_cand_pair;
    1.77 +typedef struct nr_ice_stun_server_ nr_ice_stun_server;
    1.78 +typedef struct nr_ice_turn_server_ nr_ice_turn_server;
    1.79 +typedef struct nr_resolver_ nr_resolver;
    1.80 +
    1.81 +typedef void* NR_SOCKET;
    1.82 +
    1.83 +namespace mozilla {
    1.84 +
    1.85 +class NrIceMediaStream;
    1.86 +
    1.87 +extern const char kNrIceTransportUdp[];
    1.88 +extern const char kNrIceTransportTcp[];
    1.89 +
    1.90 +class NrIceStunServer {
    1.91 + public:
    1.92 +  NrIceStunServer(const PRNetAddr& addr) : has_addr_(true) {
    1.93 +    memcpy(&addr_, &addr, sizeof(addr));
    1.94 +  }
    1.95 +
    1.96 +   // The main function to use. Will take either an address or a hostname.
    1.97 +  static NrIceStunServer* Create(const std::string& addr, uint16_t port) {
    1.98 +    ScopedDeletePtr<NrIceStunServer> server(
    1.99 +        new NrIceStunServer());
   1.100 +
   1.101 +    nsresult rv = server->Init(addr, port);
   1.102 +    if (NS_FAILED(rv))
   1.103 +      return nullptr;
   1.104 +
   1.105 +    return server.forget();
   1.106 +  }
   1.107 +
   1.108 +  nsresult ToNicerStunStruct(nr_ice_stun_server* server,
   1.109 +                             const std::string& transport =
   1.110 +                             kNrIceTransportUdp) const;
   1.111 +
   1.112 + protected:
   1.113 +  NrIceStunServer() : addr_() {}
   1.114 +
   1.115 +  nsresult Init(const std::string& addr, uint16_t port) {
   1.116 +    PRStatus status = PR_StringToNetAddr(addr.c_str(), &addr_);
   1.117 +    if (status == PR_SUCCESS) {
   1.118 +      // Parseable as an address
   1.119 +      addr_.inet.port = PR_htons(port);
   1.120 +      port_ = port;
   1.121 +      has_addr_ = true;
   1.122 +      return NS_OK;
   1.123 +    }
   1.124 +    else if (addr.size() < 256) {
   1.125 +      // Apparently this is a hostname.
   1.126 +      host_ = addr;
   1.127 +      port_ = port;
   1.128 +      has_addr_ = false;
   1.129 +      return NS_OK;
   1.130 +    }
   1.131 +
   1.132 +    return NS_ERROR_FAILURE;
   1.133 +  }
   1.134 +
   1.135 +  bool has_addr_;
   1.136 +  std::string host_;
   1.137 +  uint16_t port_;
   1.138 +  PRNetAddr addr_;
   1.139 +};
   1.140 +
   1.141 +class NrIceTurnServer : public NrIceStunServer {
   1.142 + public:
   1.143 +  static NrIceTurnServer *Create(const std::string& addr, uint16_t port,
   1.144 +                                 const std::string& username,
   1.145 +                                 const std::vector<unsigned char>& password,
   1.146 +                                 const char *transport = kNrIceTransportUdp) {
   1.147 +    ScopedDeletePtr<NrIceTurnServer> server(
   1.148 +        new NrIceTurnServer(username, password, transport));
   1.149 +
   1.150 +    nsresult rv = server->Init(addr, port);
   1.151 +    if (NS_FAILED(rv))
   1.152 +      return nullptr;
   1.153 +
   1.154 +    return server.forget();
   1.155 +  }
   1.156 +
   1.157 +  nsresult ToNicerTurnStruct(nr_ice_turn_server *server) const;
   1.158 +
   1.159 + private:
   1.160 +  NrIceTurnServer(const std::string& username,
   1.161 +                  const std::vector<unsigned char>& password,
   1.162 +                  const char *transport) :
   1.163 +      username_(username), password_(password), transport_(transport) {}
   1.164 +
   1.165 +  std::string username_;
   1.166 +  std::vector<unsigned char> password_;
   1.167 +  std::string transport_;
   1.168 +};
   1.169 +
   1.170 +class NrIceCtx {
   1.171 + public:
   1.172 +  enum ConnectionState { ICE_CTX_INIT,
   1.173 +                         ICE_CTX_CHECKING,
   1.174 +                         ICE_CTX_OPEN,
   1.175 +                         ICE_CTX_FAILED
   1.176 +  };
   1.177 +
   1.178 +  enum GatheringState { ICE_CTX_GATHER_INIT,
   1.179 +                        ICE_CTX_GATHER_STARTED,
   1.180 +                        ICE_CTX_GATHER_COMPLETE
   1.181 +  };
   1.182 +
   1.183 +  enum Controlling { ICE_CONTROLLING,
   1.184 +                     ICE_CONTROLLED
   1.185 +  };
   1.186 +
   1.187 +  static RefPtr<NrIceCtx> Create(const std::string& name,
   1.188 +                                 bool offerer,
   1.189 +                                 bool set_interface_priorities = true);
   1.190 +  virtual ~NrIceCtx();
   1.191 +
   1.192 +  nr_ice_ctx *ctx() { return ctx_; }
   1.193 +  nr_ice_peer_ctx *peer() { return peer_; }
   1.194 +
   1.195 +  // Testing only.
   1.196 +  void destroy_peer_ctx();
   1.197 +
   1.198 +  // Create a media stream
   1.199 +  RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
   1.200 +                                                 int components);
   1.201 +
   1.202 +  // The name of the ctx
   1.203 +  const std::string& name() const { return name_; }
   1.204 +
   1.205 +  // Current state
   1.206 +  ConnectionState connection_state() const {
   1.207 +    return connection_state_;
   1.208 +  }
   1.209 +
   1.210 +  // Current state
   1.211 +  GatheringState gathering_state() const {
   1.212 +    return gathering_state_;
   1.213 +  }
   1.214 +
   1.215 +  // Get the global attributes
   1.216 +  std::vector<std::string> GetGlobalAttributes();
   1.217 +
   1.218 +  // Set the other side's global attributes
   1.219 +  nsresult ParseGlobalAttributes(std::vector<std::string> attrs);
   1.220 +
   1.221 +  // Set whether we are controlling or not.
   1.222 +  nsresult SetControlling(Controlling controlling);
   1.223 +
   1.224 +  // Set the STUN servers. Must be called before StartGathering
   1.225 +  // (if at all).
   1.226 +  nsresult SetStunServers(const std::vector<NrIceStunServer>& stun_servers);
   1.227 +
   1.228 +  // Set the TURN servers. Must be called before StartGathering
   1.229 +  // (if at all).
   1.230 +  nsresult SetTurnServers(const std::vector<NrIceTurnServer>& turn_servers);
   1.231 +
   1.232 +  // Provide the resolution provider. Must be called before
   1.233 +  // StartGathering.
   1.234 +  nsresult SetResolver(nr_resolver *resolver);
   1.235 +
   1.236 +  // Start ICE gathering
   1.237 +  nsresult StartGathering();
   1.238 +
   1.239 +  // Start checking
   1.240 +  nsresult StartChecks();
   1.241 +
   1.242 +  // Finalize the ICE negotiation. I.e., there will be no
   1.243 +  // more forking.
   1.244 +  nsresult Finalize();
   1.245 +
   1.246 +  // Are we trickling?
   1.247 +  bool generating_trickle() const { return trickle_; }
   1.248 +
   1.249 +  // Signals to indicate events. API users can (and should)
   1.250 +  // register for these.
   1.251 +  sigslot::signal2<NrIceCtx*, NrIceCtx::GatheringState>
   1.252 +    SignalGatheringStateChange;
   1.253 +  sigslot::signal2<NrIceCtx*, NrIceCtx::ConnectionState>
   1.254 +    SignalConnectionStateChange;
   1.255 +
   1.256 +  // The thread to direct method calls to
   1.257 +  nsCOMPtr<nsIEventTarget> thread() { return sts_target_; }
   1.258 +
   1.259 +  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceCtx)
   1.260 +
   1.261 + private:
   1.262 +  NrIceCtx(const std::string& name,
   1.263 +           bool offerer)
   1.264 +  : connection_state_(ICE_CTX_INIT),
   1.265 +    gathering_state_(ICE_CTX_GATHER_INIT),
   1.266 +    name_(name),
   1.267 +    offerer_(offerer),
   1.268 +    streams_(),
   1.269 +    ctx_(nullptr),
   1.270 +    peer_(nullptr),
   1.271 +    ice_handler_vtbl_(nullptr),
   1.272 +    ice_handler_(nullptr),
   1.273 +    trickle_(true) {
   1.274 +    // XXX: offerer_ will be used eventually;  placate clang in the meantime.
   1.275 +    (void)offerer_;
   1.276 +  }
   1.277 +
   1.278 +  DISALLOW_COPY_ASSIGN(NrIceCtx);
   1.279 +
   1.280 +  // Callbacks for nICEr
   1.281 +  static void initialized_cb(NR_SOCKET s, int h, void *arg);  // ICE initialized
   1.282 +
   1.283 +  // Handler implementation
   1.284 +  static int select_pair(void *obj,nr_ice_media_stream *stream,
   1.285 +                         int component_id, nr_ice_cand_pair **potentials,
   1.286 +                         int potential_ct);
   1.287 +  static int stream_ready(void *obj, nr_ice_media_stream *stream);
   1.288 +  static int stream_failed(void *obj, nr_ice_media_stream *stream);
   1.289 +  static int ice_completed(void *obj, nr_ice_peer_ctx *pctx);
   1.290 +  static int msg_recvd(void *obj, nr_ice_peer_ctx *pctx,
   1.291 +                       nr_ice_media_stream *stream, int component_id,
   1.292 +                       unsigned char *msg, int len);
   1.293 +  static void trickle_cb(void *arg, nr_ice_ctx *ctx, nr_ice_media_stream *stream,
   1.294 +                         int component_id, nr_ice_candidate *candidate);
   1.295 +
   1.296 +  // Find a media stream by stream ptr. Gross
   1.297 +  RefPtr<NrIceMediaStream> FindStream(nr_ice_media_stream *stream);
   1.298 +
   1.299 +  // Set the state
   1.300 +  void SetConnectionState(ConnectionState state);
   1.301 +
   1.302 +  // Set the state
   1.303 +  void SetGatheringState(GatheringState state);
   1.304 +
   1.305 +  ConnectionState connection_state_;
   1.306 +  GatheringState gathering_state_;
   1.307 +  const std::string name_;
   1.308 +  bool offerer_;
   1.309 +  std::vector<RefPtr<NrIceMediaStream> > streams_;
   1.310 +  nr_ice_ctx *ctx_;
   1.311 +  nr_ice_peer_ctx *peer_;
   1.312 +  nr_ice_handler_vtbl* ice_handler_vtbl_;  // Must be pointer
   1.313 +  nr_ice_handler* ice_handler_;  // Must be pointer
   1.314 +  bool trickle_;
   1.315 +  nsCOMPtr<nsIEventTarget> sts_target_; // The thread to run on
   1.316 +};
   1.317 +
   1.318 +
   1.319 +}  // close namespace
   1.320 +#endif

mercurial