1/*
2 * libjingle
3 * Copyright 2012, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 *  1. Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 *  2. Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 *  3. The name of the author may not be used to endorse or promote products
14 *     derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28// This file contains the PeerConnection interface as defined in
29// http://dev.w3.org/2011/webrtc/editor/webrtc.html#peer-to-peer-connections.
30// Applications must use this interface to implement peerconnection.
31// PeerConnectionFactory class provides factory methods to create
32// peerconnection, mediastream and media tracks objects.
33//
34// The Following steps are needed to setup a typical call using Jsep.
35// 1. Create a PeerConnectionFactoryInterface. Check constructors for more
36// information about input parameters.
37// 2. Create a PeerConnection object. Provide a configuration string which
38// points either to stun or turn server to generate ICE candidates and provide
39// an object that implements the PeerConnectionObserver interface.
40// 3. Create local MediaStream and MediaTracks using the PeerConnectionFactory
41// and add it to PeerConnection by calling AddStream.
42// 4. Create an offer and serialize it and send it to the remote peer.
43// 5. Once an ice candidate have been found PeerConnection will call the
44// observer function OnIceCandidate. The candidates must also be serialized and
45// sent to the remote peer.
46// 6. Once an answer is received from the remote peer, call
47// SetLocalSessionDescription with the offer and SetRemoteSessionDescription
48// with the remote answer.
49// 7. Once a remote candidate is received from the remote peer, provide it to
50// the peerconnection by calling AddIceCandidate.
51
52
53// The Receiver of a call can decide to accept or reject the call.
54// This decision will be taken by the application not peerconnection.
55// If application decides to accept the call
56// 1. Create PeerConnectionFactoryInterface if it doesn't exist.
57// 2. Create a new PeerConnection.
58// 3. Provide the remote offer to the new PeerConnection object by calling
59// SetRemoteSessionDescription.
60// 4. Generate an answer to the remote offer by calling CreateAnswer and send it
61// back to the remote peer.
62// 5. Provide the local answer to the new PeerConnection by calling
63// SetLocalSessionDescription with the answer.
64// 6. Provide the remote ice candidates by calling AddIceCandidate.
65// 7. Once a candidate have been found PeerConnection will call the observer
66// function OnIceCandidate. Send these candidates to the remote peer.
67
68#ifndef TALK_APP_WEBRTC_PEERCONNECTIONINTERFACE_H_
69#define TALK_APP_WEBRTC_PEERCONNECTIONINTERFACE_H_
70
71#include <string>
72#include <vector>
73
74#include "talk/app/webrtc/datachannelinterface.h"
75#include "talk/app/webrtc/dtmfsenderinterface.h"
76#include "talk/app/webrtc/jsep.h"
77#include "talk/app/webrtc/mediastreaminterface.h"
78#include "talk/app/webrtc/statstypes.h"
79#include "talk/app/webrtc/umametrics.h"
80#include "webrtc/base/fileutils.h"
81#include "webrtc/base/socketaddress.h"
82
83namespace rtc {
84class Thread;
85}
86
87namespace cricket {
88class PortAllocator;
89class WebRtcVideoDecoderFactory;
90class WebRtcVideoEncoderFactory;
91}
92
93namespace webrtc {
94class AudioDeviceModule;
95class MediaConstraintsInterface;
96
97// MediaStream container interface.
98class StreamCollectionInterface : public rtc::RefCountInterface {
99 public:
100  // TODO(ronghuawu): Update the function names to c++ style, e.g. find -> Find.
101  virtual size_t count() = 0;
102  virtual MediaStreamInterface* at(size_t index) = 0;
103  virtual MediaStreamInterface* find(const std::string& label) = 0;
104  virtual MediaStreamTrackInterface* FindAudioTrack(
105      const std::string& id) = 0;
106  virtual MediaStreamTrackInterface* FindVideoTrack(
107      const std::string& id) = 0;
108
109 protected:
110  // Dtor protected as objects shouldn't be deleted via this interface.
111  ~StreamCollectionInterface() {}
112};
113
114class StatsObserver : public rtc::RefCountInterface {
115 public:
116  // TODO(tommi): Remove.
117  virtual void OnComplete(const std::vector<StatsReport>& reports) {}
118
119  // TODO(tommi): Make pure virtual and remove implementation.
120  virtual void OnComplete(const StatsReports& reports) {
121    std::vector<StatsReportCopyable> report_copies;
122    for (size_t i = 0; i < reports.size(); ++i)
123      report_copies.push_back(StatsReportCopyable(*reports[i]));
124    std::vector<StatsReport>* r =
125        reinterpret_cast<std::vector<StatsReport>*>(&report_copies);
126     OnComplete(*r);
127   }
128
129 protected:
130  virtual ~StatsObserver() {}
131};
132
133class UMAObserver : public rtc::RefCountInterface {
134 public:
135  virtual void IncrementCounter(PeerConnectionUMAMetricsCounter type) = 0;
136  virtual void AddHistogramSample(PeerConnectionUMAMetricsName type,
137                                  int value) = 0;
138
139 protected:
140  virtual ~UMAObserver() {}
141};
142
143class PeerConnectionInterface : public rtc::RefCountInterface {
144 public:
145  // See http://dev.w3.org/2011/webrtc/editor/webrtc.html#state-definitions .
146  enum SignalingState {
147    kStable,
148    kHaveLocalOffer,
149    kHaveLocalPrAnswer,
150    kHaveRemoteOffer,
151    kHaveRemotePrAnswer,
152    kClosed,
153  };
154
155  // TODO(bemasc): Remove IceState when callers are changed to
156  // IceConnection/GatheringState.
157  enum IceState {
158    kIceNew,
159    kIceGathering,
160    kIceWaiting,
161    kIceChecking,
162    kIceConnected,
163    kIceCompleted,
164    kIceFailed,
165    kIceClosed,
166  };
167
168  enum IceGatheringState {
169    kIceGatheringNew,
170    kIceGatheringGathering,
171    kIceGatheringComplete
172  };
173
174  enum IceConnectionState {
175    kIceConnectionNew,
176    kIceConnectionChecking,
177    kIceConnectionConnected,
178    kIceConnectionCompleted,
179    kIceConnectionFailed,
180    kIceConnectionDisconnected,
181    kIceConnectionClosed,
182  };
183
184  struct IceServer {
185    std::string uri;
186    std::string username;
187    std::string password;
188  };
189  typedef std::vector<IceServer> IceServers;
190
191  enum IceTransportsType {
192    kNone,
193    kRelay,
194    kNoHost,
195    kAll
196  };
197
198  struct RTCConfiguration {
199    IceTransportsType type;
200    IceServers servers;
201
202    RTCConfiguration() : type(kAll) {}
203    explicit RTCConfiguration(IceTransportsType type) : type(type) {}
204  };
205
206  struct RTCOfferAnswerOptions {
207    static const int kUndefined = -1;
208    static const int kMaxOfferToReceiveMedia = 1;
209
210    // The default value for constraint offerToReceiveX:true.
211    static const int kOfferToReceiveMediaTrue = 1;
212
213    int offer_to_receive_video;
214    int offer_to_receive_audio;
215    bool voice_activity_detection;
216    bool ice_restart;
217    bool use_rtp_mux;
218
219    RTCOfferAnswerOptions()
220        : offer_to_receive_video(kUndefined),
221          offer_to_receive_audio(kUndefined),
222          voice_activity_detection(true),
223          ice_restart(false),
224          use_rtp_mux(true) {}
225
226    RTCOfferAnswerOptions(int offer_to_receive_video,
227                          int offer_to_receive_audio,
228                          bool voice_activity_detection,
229                          bool ice_restart,
230                          bool use_rtp_mux)
231        : offer_to_receive_video(offer_to_receive_video),
232          offer_to_receive_audio(offer_to_receive_audio),
233          voice_activity_detection(voice_activity_detection),
234          ice_restart(ice_restart),
235          use_rtp_mux(use_rtp_mux) {}
236  };
237
238  // Used by GetStats to decide which stats to include in the stats reports.
239  // |kStatsOutputLevelStandard| includes the standard stats for Javascript API;
240  // |kStatsOutputLevelDebug| includes both the standard stats and additional
241  // stats for debugging purposes.
242  enum StatsOutputLevel {
243    kStatsOutputLevelStandard,
244    kStatsOutputLevelDebug,
245  };
246
247  // Accessor methods to active local streams.
248  virtual rtc::scoped_refptr<StreamCollectionInterface>
249      local_streams() = 0;
250
251  // Accessor methods to remote streams.
252  virtual rtc::scoped_refptr<StreamCollectionInterface>
253      remote_streams() = 0;
254
255  // Add a new MediaStream to be sent on this PeerConnection.
256  // Note that a SessionDescription negotiation is needed before the
257  // remote peer can receive the stream.
258  virtual bool AddStream(MediaStreamInterface* stream,
259                         const MediaConstraintsInterface* constraints) = 0;
260
261  // Remove a MediaStream from this PeerConnection.
262  // Note that a SessionDescription negotiation is need before the
263  // remote peer is notified.
264  virtual void RemoveStream(MediaStreamInterface* stream) = 0;
265
266  // Returns pointer to the created DtmfSender on success.
267  // Otherwise returns NULL.
268  virtual rtc::scoped_refptr<DtmfSenderInterface> CreateDtmfSender(
269      AudioTrackInterface* track) = 0;
270
271  virtual bool GetStats(StatsObserver* observer,
272                        MediaStreamTrackInterface* track,
273                        StatsOutputLevel level) = 0;
274
275  virtual rtc::scoped_refptr<DataChannelInterface> CreateDataChannel(
276      const std::string& label,
277      const DataChannelInit* config) = 0;
278
279  virtual const SessionDescriptionInterface* local_description() const = 0;
280  virtual const SessionDescriptionInterface* remote_description() const = 0;
281
282  // Create a new offer.
283  // The CreateSessionDescriptionObserver callback will be called when done.
284  virtual void CreateOffer(CreateSessionDescriptionObserver* observer,
285                           const MediaConstraintsInterface* constraints) {}
286
287  // TODO(jiayl): remove the default impl and the old interface when chromium
288  // code is updated.
289  virtual void CreateOffer(CreateSessionDescriptionObserver* observer,
290                           const RTCOfferAnswerOptions& options) {}
291
292  // Create an answer to an offer.
293  // The CreateSessionDescriptionObserver callback will be called when done.
294  virtual void CreateAnswer(CreateSessionDescriptionObserver* observer,
295                            const MediaConstraintsInterface* constraints) = 0;
296  // Sets the local session description.
297  // JsepInterface takes the ownership of |desc| even if it fails.
298  // The |observer| callback will be called when done.
299  virtual void SetLocalDescription(SetSessionDescriptionObserver* observer,
300                                   SessionDescriptionInterface* desc) = 0;
301  // Sets the remote session description.
302  // JsepInterface takes the ownership of |desc| even if it fails.
303  // The |observer| callback will be called when done.
304  virtual void SetRemoteDescription(SetSessionDescriptionObserver* observer,
305                                    SessionDescriptionInterface* desc) = 0;
306  // Restarts or updates the ICE Agent process of gathering local candidates
307  // and pinging remote candidates.
308  virtual bool UpdateIce(const IceServers& configuration,
309                         const MediaConstraintsInterface* constraints) = 0;
310  // Provides a remote candidate to the ICE Agent.
311  // A copy of the |candidate| will be created and added to the remote
312  // description. So the caller of this method still has the ownership of the
313  // |candidate|.
314  // TODO(ronghuawu): Consider to change this so that the AddIceCandidate will
315  // take the ownership of the |candidate|.
316  virtual bool AddIceCandidate(const IceCandidateInterface* candidate) = 0;
317
318  virtual void RegisterUMAObserver(UMAObserver* observer) = 0;
319
320  // Returns the current SignalingState.
321  virtual SignalingState signaling_state() = 0;
322
323  // TODO(bemasc): Remove ice_state when callers are changed to
324  // IceConnection/GatheringState.
325  // Returns the current IceState.
326  virtual IceState ice_state() = 0;
327  virtual IceConnectionState ice_connection_state() = 0;
328  virtual IceGatheringState ice_gathering_state() = 0;
329
330  // Terminates all media and closes the transport.
331  virtual void Close() = 0;
332
333 protected:
334  // Dtor protected as objects shouldn't be deleted via this interface.
335  ~PeerConnectionInterface() {}
336};
337
338// PeerConnection callback interface. Application should implement these
339// methods.
340class PeerConnectionObserver {
341 public:
342  enum StateType {
343    kSignalingState,
344    kIceState,
345  };
346
347  virtual void OnError() = 0;
348
349  // Triggered when the SignalingState changed.
350  virtual void OnSignalingChange(
351     PeerConnectionInterface::SignalingState new_state) {}
352
353  // Triggered when SignalingState or IceState have changed.
354  // TODO(bemasc): Remove once callers transition to OnSignalingChange.
355  virtual void OnStateChange(StateType state_changed) {}
356
357  // Triggered when media is received on a new stream from remote peer.
358  virtual void OnAddStream(MediaStreamInterface* stream) = 0;
359
360  // Triggered when a remote peer close a stream.
361  virtual void OnRemoveStream(MediaStreamInterface* stream) = 0;
362
363  // Triggered when a remote peer open a data channel.
364  // TODO(perkj): Make pure virtual.
365  virtual void OnDataChannel(DataChannelInterface* data_channel) {}
366
367  // Triggered when renegotiation is needed, for example the ICE has restarted.
368  virtual void OnRenegotiationNeeded() = 0;
369
370  // Called any time the IceConnectionState changes
371  virtual void OnIceConnectionChange(
372      PeerConnectionInterface::IceConnectionState new_state) {}
373
374  // Called any time the IceGatheringState changes
375  virtual void OnIceGatheringChange(
376      PeerConnectionInterface::IceGatheringState new_state) {}
377
378  // New Ice candidate have been found.
379  virtual void OnIceCandidate(const IceCandidateInterface* candidate) = 0;
380
381  // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
382  // All Ice candidates have been found.
383  virtual void OnIceComplete() {}
384
385 protected:
386  // Dtor protected as objects shouldn't be deleted via this interface.
387  ~PeerConnectionObserver() {}
388};
389
390// Factory class used for creating cricket::PortAllocator that is used
391// for ICE negotiation.
392class PortAllocatorFactoryInterface : public rtc::RefCountInterface {
393 public:
394  struct StunConfiguration {
395    StunConfiguration(const std::string& address, int port)
396        : server(address, port) {}
397    // STUN server address and port.
398    rtc::SocketAddress server;
399  };
400
401  struct TurnConfiguration {
402    TurnConfiguration(const std::string& address,
403                      int port,
404                      const std::string& username,
405                      const std::string& password,
406                      const std::string& transport_type,
407                      bool secure)
408        : server(address, port),
409          username(username),
410          password(password),
411          transport_type(transport_type),
412          secure(secure) {}
413    rtc::SocketAddress server;
414    std::string username;
415    std::string password;
416    std::string transport_type;
417    bool secure;
418  };
419
420  virtual cricket::PortAllocator* CreatePortAllocator(
421      const std::vector<StunConfiguration>& stun_servers,
422      const std::vector<TurnConfiguration>& turn_configurations) = 0;
423
424 protected:
425  PortAllocatorFactoryInterface() {}
426  ~PortAllocatorFactoryInterface() {}
427};
428
429// Used to receive callbacks of DTLS identity requests.
430class DTLSIdentityRequestObserver : public rtc::RefCountInterface {
431 public:
432  virtual void OnFailure(int error) = 0;
433  virtual void OnSuccess(const std::string& der_cert,
434                         const std::string& der_private_key) = 0;
435 protected:
436  virtual ~DTLSIdentityRequestObserver() {}
437};
438
439class DTLSIdentityServiceInterface {
440 public:
441  // Asynchronously request a DTLS identity, including a self-signed certificate
442  // and the private key used to sign the certificate, from the identity store
443  // for the given identity name.
444  // DTLSIdentityRequestObserver::OnSuccess will be called with the identity if
445  // the request succeeded; DTLSIdentityRequestObserver::OnFailure will be
446  // called with an error code if the request failed.
447  //
448  // Only one request can be made at a time. If a second request is called
449  // before the first one completes, RequestIdentity will abort and return
450  // false.
451  //
452  // |identity_name| is an internal name selected by the client to identify an
453  // identity within an origin. E.g. an web site may cache the certificates used
454  // to communicate with differnent peers under different identity names.
455  //
456  // |common_name| is the common name used to generate the certificate. If the
457  // certificate already exists in the store, |common_name| is ignored.
458  //
459  // |observer| is the object to receive success or failure callbacks.
460  //
461  // Returns true if either OnFailure or OnSuccess will be called.
462  virtual bool RequestIdentity(
463      const std::string& identity_name,
464      const std::string& common_name,
465      DTLSIdentityRequestObserver* observer) = 0;
466
467  virtual ~DTLSIdentityServiceInterface() {}
468};
469
470// PeerConnectionFactoryInterface is the factory interface use for creating
471// PeerConnection, MediaStream and media tracks.
472// PeerConnectionFactoryInterface will create required libjingle threads,
473// socket and network manager factory classes for networking.
474// If an application decides to provide its own threads and network
475// implementation of these classes it should use the alternate
476// CreatePeerConnectionFactory method which accepts threads as input and use the
477// CreatePeerConnection version that takes a PortAllocatorFactoryInterface as
478// argument.
479class PeerConnectionFactoryInterface : public rtc::RefCountInterface {
480 public:
481  class Options {
482   public:
483    Options() :
484      disable_encryption(false),
485      disable_sctp_data_channels(false) {
486    }
487    bool disable_encryption;
488    bool disable_sctp_data_channels;
489  };
490
491  virtual void SetOptions(const Options& options) = 0;
492
493  virtual rtc::scoped_refptr<PeerConnectionInterface>
494      CreatePeerConnection(
495          const PeerConnectionInterface::RTCConfiguration& configuration,
496          const MediaConstraintsInterface* constraints,
497          PortAllocatorFactoryInterface* allocator_factory,
498          DTLSIdentityServiceInterface* dtls_identity_service,
499          PeerConnectionObserver* observer) = 0;
500
501  // TODO(mallinath) : Remove below versions after clients are updated
502  // to above method.
503  // In latest W3C WebRTC draft, PC constructor will take RTCConfiguration,
504  // and not IceServers. RTCConfiguration is made up of ice servers and
505  // ice transport type.
506  // http://dev.w3.org/2011/webrtc/editor/webrtc.html
507  inline rtc::scoped_refptr<PeerConnectionInterface>
508      CreatePeerConnection(
509          const PeerConnectionInterface::IceServers& configuration,
510          const MediaConstraintsInterface* constraints,
511          PortAllocatorFactoryInterface* allocator_factory,
512          DTLSIdentityServiceInterface* dtls_identity_service,
513          PeerConnectionObserver* observer) {
514      PeerConnectionInterface::RTCConfiguration rtc_config;
515      rtc_config.servers = configuration;
516      return CreatePeerConnection(rtc_config, constraints, allocator_factory,
517                                  dtls_identity_service, observer);
518  }
519
520  virtual rtc::scoped_refptr<MediaStreamInterface>
521      CreateLocalMediaStream(const std::string& label) = 0;
522
523  // Creates a AudioSourceInterface.
524  // |constraints| decides audio processing settings but can be NULL.
525  virtual rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
526      const MediaConstraintsInterface* constraints) = 0;
527
528  // Creates a VideoSourceInterface. The new source take ownership of
529  // |capturer|. |constraints| decides video resolution and frame rate but can
530  // be NULL.
531  virtual rtc::scoped_refptr<VideoSourceInterface> CreateVideoSource(
532      cricket::VideoCapturer* capturer,
533      const MediaConstraintsInterface* constraints) = 0;
534
535  // Creates a new local VideoTrack. The same |source| can be used in several
536  // tracks.
537  virtual rtc::scoped_refptr<VideoTrackInterface>
538      CreateVideoTrack(const std::string& label,
539                       VideoSourceInterface* source) = 0;
540
541  // Creates an new AudioTrack. At the moment |source| can be NULL.
542  virtual rtc::scoped_refptr<AudioTrackInterface>
543      CreateAudioTrack(const std::string& label,
544                       AudioSourceInterface* source) = 0;
545
546  // Starts AEC dump using existing file. Takes ownership of |file| and passes
547  // it on to VoiceEngine (via other objects) immediately, which will take
548  // the ownerhip. If the operation fails, the file will be closed.
549  // TODO(grunell): Remove when Chromium has started to use AEC in each source.
550  // http://crbug.com/264611.
551  virtual bool StartAecDump(rtc::PlatformFile file) = 0;
552
553 protected:
554  // Dtor and ctor protected as objects shouldn't be created or deleted via
555  // this interface.
556  PeerConnectionFactoryInterface() {}
557  ~PeerConnectionFactoryInterface() {} // NOLINT
558};
559
560// Create a new instance of PeerConnectionFactoryInterface.
561rtc::scoped_refptr<PeerConnectionFactoryInterface>
562CreatePeerConnectionFactory();
563
564// Create a new instance of PeerConnectionFactoryInterface.
565// Ownership of |factory|, |default_adm|, and optionally |encoder_factory| and
566// |decoder_factory| transferred to the returned factory.
567rtc::scoped_refptr<PeerConnectionFactoryInterface>
568CreatePeerConnectionFactory(
569    rtc::Thread* worker_thread,
570    rtc::Thread* signaling_thread,
571    AudioDeviceModule* default_adm,
572    cricket::WebRtcVideoEncoderFactory* encoder_factory,
573    cricket::WebRtcVideoDecoderFactory* decoder_factory);
574
575}  // namespace webrtc
576
577#endif  // TALK_APP_WEBRTC_PEERCONNECTIONINTERFACE_H_
578