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 83 namespace rtc { 84 class Thread; 85 } 86 87 namespace cricket { 88 class PortAllocator; 89 class WebRtcVideoDecoderFactory; 90 class WebRtcVideoEncoderFactory; 91 } 92 93 namespace webrtc { 94 class AudioDeviceModule; 95 class MediaConstraintsInterface; 96 97 // MediaStream container interface. 98 class 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 114 class 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 133 class 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 143 class 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. 340 class 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. 392 class 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. 430 class 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 439 class 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. 479 class 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. 561 rtc::scoped_refptr<PeerConnectionFactoryInterface> 562 CreatePeerConnectionFactory(); 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. 567 rtc::scoped_refptr<PeerConnectionFactoryInterface> 568 CreatePeerConnectionFactory( 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