Bumping manifests a=b2g-bump
[gecko.git] / media / mtransport / nricectx.h
blobf17bbf91df0af1db721c97e21e3ae5b6aa78a3ba
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/. */
7 // Original author: ekr@rtfm.com
9 // Some of this code is cut-and-pasted from nICEr. Copyright is:
12 Copyright (c) 2007, Adobe Systems, Incorporated
13 All rights reserved.
15 Redistribution and use in source and binary forms, with or without
16 modification, are permitted provided that the following conditions are
17 met:
19 * Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
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.
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.
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.
43 /* This Source Code Form is subject to the terms of the Mozilla Public
44 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
45 * You can obtain one at http://mozilla.org/MPL/2.0/. */
47 // Original author: ekr@rtfm.com
49 // This is a wrapper around the nICEr ICE stack
50 #ifndef nricectx_h__
51 #define nricectx_h__
53 #include <string>
54 #include <vector>
56 #include "sigslot.h"
58 #include "prnetdb.h"
60 #include "mozilla/RefPtr.h"
61 #include "mozilla/Scoped.h"
62 #include "mozilla/TimeStamp.h"
63 #include "nsAutoPtr.h"
64 #include "nsIEventTarget.h"
65 #include "nsITimer.h"
67 #include "m_cpp_utils.h"
69 typedef struct nr_ice_ctx_ nr_ice_ctx;
70 typedef struct nr_ice_peer_ctx_ nr_ice_peer_ctx;
71 typedef struct nr_ice_media_stream_ nr_ice_media_stream;
72 typedef struct nr_ice_handler_ nr_ice_handler;
73 typedef struct nr_ice_handler_vtbl_ nr_ice_handler_vtbl;
74 typedef struct nr_ice_candidate_ nr_ice_candidate;
75 typedef struct nr_ice_cand_pair_ nr_ice_cand_pair;
76 typedef struct nr_ice_stun_server_ nr_ice_stun_server;
77 typedef struct nr_ice_turn_server_ nr_ice_turn_server;
78 typedef struct nr_resolver_ nr_resolver;
80 typedef void* NR_SOCKET;
82 namespace mozilla {
84 // Timestamps set whenever a packet is dropped due to global rate limiting
85 // (see nr_socket_prsock.cpp)
86 TimeStamp nr_socket_short_term_violation_time();
87 TimeStamp nr_socket_long_term_violation_time();
89 class NrIceMediaStream;
91 extern const char kNrIceTransportUdp[];
92 extern const char kNrIceTransportTcp[];
94 class NrIceStunServer {
95 public:
96 explicit NrIceStunServer(const PRNetAddr& addr) : has_addr_(true) {
97 memcpy(&addr_, &addr, sizeof(addr));
100 // The main function to use. Will take either an address or a hostname.
101 static NrIceStunServer* Create(const std::string& addr, uint16_t port) {
102 ScopedDeletePtr<NrIceStunServer> server(
103 new NrIceStunServer());
105 nsresult rv = server->Init(addr, port);
106 if (NS_FAILED(rv))
107 return nullptr;
109 return server.forget();
112 nsresult ToNicerStunStruct(nr_ice_stun_server* server,
113 const std::string& transport =
114 kNrIceTransportUdp) const;
116 protected:
117 NrIceStunServer() : addr_() {}
119 nsresult Init(const std::string& addr, uint16_t port) {
120 PRStatus status = PR_StringToNetAddr(addr.c_str(), &addr_);
121 if (status == PR_SUCCESS) {
122 // Parseable as an address
123 addr_.inet.port = PR_htons(port);
124 port_ = port;
125 has_addr_ = true;
126 return NS_OK;
128 else if (addr.size() < 256) {
129 // Apparently this is a hostname.
130 host_ = addr;
131 port_ = port;
132 has_addr_ = false;
133 return NS_OK;
136 return NS_ERROR_FAILURE;
139 bool has_addr_;
140 std::string host_;
141 uint16_t port_;
142 PRNetAddr addr_;
145 class NrIceTurnServer : public NrIceStunServer {
146 public:
147 static NrIceTurnServer *Create(const std::string& addr, uint16_t port,
148 const std::string& username,
149 const std::vector<unsigned char>& password,
150 const char *transport = kNrIceTransportUdp) {
151 ScopedDeletePtr<NrIceTurnServer> server(
152 new NrIceTurnServer(username, password, transport));
154 nsresult rv = server->Init(addr, port);
155 if (NS_FAILED(rv))
156 return nullptr;
158 return server.forget();
161 nsresult ToNicerTurnStruct(nr_ice_turn_server *server) const;
163 private:
164 NrIceTurnServer(const std::string& username,
165 const std::vector<unsigned char>& password,
166 const char *transport) :
167 username_(username), password_(password), transport_(transport) {}
169 std::string username_;
170 std::vector<unsigned char> password_;
171 std::string transport_;
174 class NrIceCtx {
175 public:
176 enum ConnectionState { ICE_CTX_INIT,
177 ICE_CTX_CHECKING,
178 ICE_CTX_OPEN,
179 ICE_CTX_FAILED
182 enum GatheringState { ICE_CTX_GATHER_INIT,
183 ICE_CTX_GATHER_STARTED,
184 ICE_CTX_GATHER_COMPLETE
187 enum Controlling { ICE_CONTROLLING,
188 ICE_CONTROLLED
191 static RefPtr<NrIceCtx> Create(const std::string& name,
192 bool offerer,
193 bool set_interface_priorities = true,
194 bool allow_loopback = false);
196 // Deinitialize all ICE global state. Used only for testing.
197 static void internal_DeinitializeGlobal();
200 nr_ice_ctx *ctx() { return ctx_; }
201 nr_ice_peer_ctx *peer() { return peer_; }
203 // Testing only.
204 void destroy_peer_ctx();
206 // Create a media stream
207 RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
208 int components);
210 RefPtr<NrIceMediaStream> GetStream(size_t index) {
211 if (index < streams_.size()) {
212 return streams_[index];
214 return nullptr;
217 // Some might be null
218 size_t GetStreamCount() const
220 return streams_.size();
223 // The name of the ctx
224 const std::string& name() const { return name_; }
226 // Get ufrag and password.
227 std::string ufrag() const;
228 std::string pwd() const;
230 // Current state
231 ConnectionState connection_state() const {
232 return connection_state_;
235 // Current state
236 GatheringState gathering_state() const {
237 return gathering_state_;
240 // Get the global attributes
241 std::vector<std::string> GetGlobalAttributes();
243 // Set the other side's global attributes
244 nsresult ParseGlobalAttributes(std::vector<std::string> attrs);
246 // Set whether we are controlling or not.
247 nsresult SetControlling(Controlling controlling);
249 Controlling GetControlling();
251 // Set the STUN servers. Must be called before StartGathering
252 // (if at all).
253 nsresult SetStunServers(const std::vector<NrIceStunServer>& stun_servers);
255 // Set the TURN servers. Must be called before StartGathering
256 // (if at all).
257 nsresult SetTurnServers(const std::vector<NrIceTurnServer>& turn_servers);
259 // Provide the resolution provider. Must be called before
260 // StartGathering.
261 nsresult SetResolver(nr_resolver *resolver);
263 // Start ICE gathering
264 nsresult StartGathering();
266 // Start checking
267 nsresult StartChecks();
269 // Finalize the ICE negotiation. I.e., there will be no
270 // more forking.
271 nsresult Finalize();
273 // Are we trickling?
274 bool generating_trickle() const { return trickle_; }
276 // Signals to indicate events. API users can (and should)
277 // register for these.
278 sigslot::signal2<NrIceCtx*, NrIceCtx::GatheringState>
279 SignalGatheringStateChange;
280 sigslot::signal2<NrIceCtx*, NrIceCtx::ConnectionState>
281 SignalConnectionStateChange;
283 // The thread to direct method calls to
284 nsCOMPtr<nsIEventTarget> thread() { return sts_target_; }
286 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceCtx)
288 private:
289 NrIceCtx(const std::string& name,
290 bool offerer)
291 : connection_state_(ICE_CTX_INIT),
292 gathering_state_(ICE_CTX_GATHER_INIT),
293 name_(name),
294 offerer_(offerer),
295 streams_(),
296 ctx_(nullptr),
297 peer_(nullptr),
298 ice_handler_vtbl_(nullptr),
299 ice_handler_(nullptr),
300 trickle_(true) {
301 // XXX: offerer_ will be used eventually; placate clang in the meantime.
302 (void)offerer_;
305 virtual ~NrIceCtx();
307 DISALLOW_COPY_ASSIGN(NrIceCtx);
309 // Callbacks for nICEr
310 static void initialized_cb(NR_SOCKET s, int h, void *arg); // ICE initialized
312 // Handler implementation
313 static int select_pair(void *obj,nr_ice_media_stream *stream,
314 int component_id, nr_ice_cand_pair **potentials,
315 int potential_ct);
316 static int stream_ready(void *obj, nr_ice_media_stream *stream);
317 static int stream_failed(void *obj, nr_ice_media_stream *stream);
318 static int ice_checking(void *obj, nr_ice_peer_ctx *pctx);
319 static int ice_completed(void *obj, nr_ice_peer_ctx *pctx);
320 static int msg_recvd(void *obj, nr_ice_peer_ctx *pctx,
321 nr_ice_media_stream *stream, int component_id,
322 unsigned char *msg, int len);
323 static void trickle_cb(void *arg, nr_ice_ctx *ctx, nr_ice_media_stream *stream,
324 int component_id, nr_ice_candidate *candidate);
326 // Find a media stream by stream ptr. Gross
327 RefPtr<NrIceMediaStream> FindStream(nr_ice_media_stream *stream);
329 // Set the state
330 void SetConnectionState(ConnectionState state);
332 // Set the state
333 void SetGatheringState(GatheringState state);
335 ConnectionState connection_state_;
336 GatheringState gathering_state_;
337 const std::string name_;
338 bool offerer_;
339 std::vector<RefPtr<NrIceMediaStream> > streams_;
340 nr_ice_ctx *ctx_;
341 nr_ice_peer_ctx *peer_;
342 nr_ice_handler_vtbl* ice_handler_vtbl_; // Must be pointer
343 nr_ice_handler* ice_handler_; // Must be pointer
344 bool trickle_;
345 nsCOMPtr<nsIEventTarget> sts_target_; // The thread to run on
349 } // close namespace
350 #endif