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 #ifndef TALK_APP_WEBRTC_WEBRTCSESSION_H_ 29 #define TALK_APP_WEBRTC_WEBRTCSESSION_H_ 30 31 #include <string> 32 #include <vector> 33 34 #include "talk/app/webrtc/datachannel.h" 35 #include "talk/app/webrtc/dtmfsender.h" 36 #include "talk/app/webrtc/mediacontroller.h" 37 #include "talk/app/webrtc/mediastreamprovider.h" 38 #include "talk/app/webrtc/peerconnectioninterface.h" 39 #include "talk/app/webrtc/statstypes.h" 40 #include "talk/media/base/mediachannel.h" 41 #include "talk/session/media/mediasession.h" 42 #include "webrtc/base/sigslot.h" 43 #include "webrtc/base/sslidentity.h" 44 #include "webrtc/base/thread.h" 45 #include "webrtc/p2p/base/transportcontroller.h" 46 47 namespace cricket { 48 49 class ChannelManager; 50 class DataChannel; 51 class StatsReport; 52 class VideoCapturer; 53 class VideoChannel; 54 class VoiceChannel; 55 56 } // namespace cricket 57 58 namespace webrtc { 59 60 class IceRestartAnswerLatch; 61 class JsepIceCandidate; 62 class MediaStreamSignaling; 63 class WebRtcSessionDescriptionFactory; 64 65 extern const char kBundleWithoutRtcpMux[]; 66 extern const char kCreateChannelFailed[]; 67 extern const char kInvalidCandidates[]; 68 extern const char kInvalidSdp[]; 69 extern const char kMlineMismatch[]; 70 extern const char kPushDownTDFailed[]; 71 extern const char kSdpWithoutDtlsFingerprint[]; 72 extern const char kSdpWithoutSdesCrypto[]; 73 extern const char kSdpWithoutIceUfragPwd[]; 74 extern const char kSdpWithoutSdesAndDtlsDisabled[]; 75 extern const char kSessionError[]; 76 extern const char kSessionErrorDesc[]; 77 extern const char kDtlsSetupFailureRtp[]; 78 extern const char kDtlsSetupFailureRtcp[]; 79 extern const char kEnableBundleFailed[]; 80 81 // Maximum number of received video streams that will be processed by webrtc 82 // even if they are not signalled beforehand. 83 extern const int kMaxUnsignalledRecvStreams; 84 85 // ICE state callback interface. 86 class IceObserver { 87 public: 88 IceObserver() {} 89 // Called any time the IceConnectionState changes 90 // TODO(honghaiz): Change the name to OnIceConnectionStateChange so as to 91 // conform to the w3c standard. 92 virtual void OnIceConnectionChange( 93 PeerConnectionInterface::IceConnectionState new_state) {} 94 // Called any time the IceGatheringState changes 95 virtual void OnIceGatheringChange( 96 PeerConnectionInterface::IceGatheringState new_state) {} 97 // New Ice candidate have been found. 98 virtual void OnIceCandidate(const IceCandidateInterface* candidate) = 0; 99 // All Ice candidates have been found. 100 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange. 101 // (via PeerConnectionObserver) 102 virtual void OnIceComplete() {} 103 104 // Called whenever the state changes between receiving and not receiving. 105 virtual void OnIceConnectionReceivingChange(bool receiving) {} 106 107 protected: 108 ~IceObserver() {} 109 110 private: 111 RTC_DISALLOW_COPY_AND_ASSIGN(IceObserver); 112 }; 113 114 // Statistics for all the transports of the session. 115 typedef std::map<std::string, cricket::TransportStats> TransportStatsMap; 116 typedef std::map<std::string, std::string> ProxyTransportMap; 117 118 // TODO(pthatcher): Think of a better name for this. We already have 119 // a TransportStats in transport.h. Perhaps TransportsStats? 120 struct SessionStats { 121 ProxyTransportMap proxy_to_transport; 122 TransportStatsMap transport_stats; 123 }; 124 125 // A WebRtcSession manages general session state. This includes negotiation 126 // of both the application-level and network-level protocols: the former 127 // defines what will be sent and the latter defines how it will be sent. Each 128 // network-level protocol is represented by a Transport object. Each Transport 129 // participates in the network-level negotiation. The individual streams of 130 // packets are represented by TransportChannels. The application-level protocol 131 // is represented by SessionDecription objects. 132 class WebRtcSession : public AudioProviderInterface, 133 public VideoProviderInterface, 134 public DtmfProviderInterface, 135 public DataChannelProviderInterface, 136 public sigslot::has_slots<> { 137 public: 138 enum State { 139 STATE_INIT = 0, 140 STATE_SENTOFFER, // Sent offer, waiting for answer. 141 STATE_RECEIVEDOFFER, // Received an offer. Need to send answer. 142 STATE_SENTPRANSWER, // Sent provisional answer. Need to send answer. 143 STATE_RECEIVEDPRANSWER, // Received provisional answer, waiting for answer. 144 STATE_INPROGRESS, // Offer/answer exchange completed. 145 STATE_CLOSED, // Close() was called. 146 }; 147 148 enum Error { 149 ERROR_NONE = 0, // no error 150 ERROR_CONTENT = 1, // channel errors in SetLocalContent/SetRemoteContent 151 ERROR_TRANSPORT = 2, // transport error of some kind 152 }; 153 154 WebRtcSession(webrtc::MediaControllerInterface* media_controller, 155 rtc::Thread* signaling_thread, 156 rtc::Thread* worker_thread, 157 cricket::PortAllocator* port_allocator); 158 virtual ~WebRtcSession(); 159 160 // These are const to allow them to be called from const methods. 161 rtc::Thread* signaling_thread() const { return signaling_thread_; } 162 rtc::Thread* worker_thread() const { return worker_thread_; } 163 cricket::PortAllocator* port_allocator() const { return port_allocator_; } 164 165 // The ID of this session. 166 const std::string& id() const { return sid_; } 167 168 bool Initialize( 169 const PeerConnectionFactoryInterface::Options& options, 170 const MediaConstraintsInterface* constraints, 171 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, 172 const PeerConnectionInterface::RTCConfiguration& rtc_configuration); 173 // Deletes the voice, video and data channel and changes the session state 174 // to STATE_CLOSED. 175 void Close(); 176 177 // Returns true if we were the initial offerer. 178 bool initial_offerer() const { return initial_offerer_; } 179 180 // Returns the current state of the session. See the enum above for details. 181 // Each time the state changes, we will fire this signal. 182 State state() const { return state_; } 183 sigslot::signal2<WebRtcSession*, State> SignalState; 184 185 // Returns the last error in the session. See the enum above for details. 186 Error error() const { return error_; } 187 const std::string& error_desc() const { return error_desc_; } 188 189 void RegisterIceObserver(IceObserver* observer) { 190 ice_observer_ = observer; 191 } 192 193 virtual cricket::VoiceChannel* voice_channel() { 194 return voice_channel_.get(); 195 } 196 virtual cricket::VideoChannel* video_channel() { 197 return video_channel_.get(); 198 } 199 virtual cricket::DataChannel* data_channel() { 200 return data_channel_.get(); 201 } 202 203 void SetSdesPolicy(cricket::SecurePolicy secure_policy); 204 cricket::SecurePolicy SdesPolicy() const; 205 206 // Get current ssl role from transport. 207 bool GetSslRole(const std::string& transport_name, rtc::SSLRole* role); 208 209 // Get current SSL role for this channel's transport. 210 // If |transport| is null, returns false. 211 bool GetSslRole(const cricket::BaseChannel* channel, rtc::SSLRole* role); 212 213 void CreateOffer( 214 CreateSessionDescriptionObserver* observer, 215 const PeerConnectionInterface::RTCOfferAnswerOptions& options, 216 const cricket::MediaSessionOptions& session_options); 217 void CreateAnswer(CreateSessionDescriptionObserver* observer, 218 const MediaConstraintsInterface* constraints, 219 const cricket::MediaSessionOptions& session_options); 220 // The ownership of |desc| will be transferred after this call. 221 bool SetLocalDescription(SessionDescriptionInterface* desc, 222 std::string* err_desc); 223 // The ownership of |desc| will be transferred after this call. 224 bool SetRemoteDescription(SessionDescriptionInterface* desc, 225 std::string* err_desc); 226 bool ProcessIceMessage(const IceCandidateInterface* ice_candidate); 227 228 bool SetIceTransports(PeerConnectionInterface::IceTransportsType type); 229 230 cricket::IceConfig ParseIceConfig( 231 const PeerConnectionInterface::RTCConfiguration& config) const; 232 233 void SetIceConfig(const cricket::IceConfig& ice_config); 234 235 // Start gathering candidates for any new transports, or transports doing an 236 // ICE restart. 237 void MaybeStartGathering(); 238 239 const SessionDescriptionInterface* local_description() const { 240 return local_desc_.get(); 241 } 242 const SessionDescriptionInterface* remote_description() const { 243 return remote_desc_.get(); 244 } 245 246 // Get the id used as a media stream track's "id" field from ssrc. 247 virtual bool GetLocalTrackIdBySsrc(uint32_t ssrc, std::string* track_id); 248 virtual bool GetRemoteTrackIdBySsrc(uint32_t ssrc, std::string* track_id); 249 250 // AudioMediaProviderInterface implementation. 251 void SetAudioPlayout(uint32_t ssrc, bool enable) override; 252 void SetAudioSend(uint32_t ssrc, 253 bool enable, 254 const cricket::AudioOptions& options, 255 cricket::AudioRenderer* renderer) override; 256 void SetAudioPlayoutVolume(uint32_t ssrc, double volume) override; 257 void SetRawAudioSink(uint32_t ssrc, 258 rtc::scoped_ptr<AudioSinkInterface> sink) override; 259 260 // Implements VideoMediaProviderInterface. 261 bool SetCaptureDevice(uint32_t ssrc, cricket::VideoCapturer* camera) override; 262 void SetVideoPlayout(uint32_t ssrc, 263 bool enable, 264 cricket::VideoRenderer* renderer) override; 265 void SetVideoSend(uint32_t ssrc, 266 bool enable, 267 const cricket::VideoOptions* options) override; 268 269 // Implements DtmfProviderInterface. 270 virtual bool CanInsertDtmf(const std::string& track_id); 271 virtual bool InsertDtmf(const std::string& track_id, 272 int code, int duration); 273 virtual sigslot::signal0<>* GetOnDestroyedSignal(); 274 275 // Implements DataChannelProviderInterface. 276 bool SendData(const cricket::SendDataParams& params, 277 const rtc::Buffer& payload, 278 cricket::SendDataResult* result) override; 279 bool ConnectDataChannel(DataChannel* webrtc_data_channel) override; 280 void DisconnectDataChannel(DataChannel* webrtc_data_channel) override; 281 void AddSctpDataStream(int sid) override; 282 void RemoveSctpDataStream(int sid) override; 283 bool ReadyToSendData() const override; 284 285 // Returns stats for all channels of all transports. 286 // This avoids exposing the internal structures used to track them. 287 virtual bool GetTransportStats(SessionStats* stats); 288 289 // Get stats for a specific channel 290 bool GetChannelTransportStats(cricket::BaseChannel* ch, SessionStats* stats); 291 292 // virtual so it can be mocked in unit tests 293 virtual bool GetLocalCertificate( 294 const std::string& transport_name, 295 rtc::scoped_refptr<rtc::RTCCertificate>* certificate); 296 297 // Caller owns returned certificate 298 virtual bool GetRemoteSSLCertificate(const std::string& transport_name, 299 rtc::SSLCertificate** cert); 300 301 cricket::DataChannelType data_channel_type() const; 302 303 bool IceRestartPending() const; 304 305 void ResetIceRestartLatch(); 306 307 // Called when an RTCCertificate is generated or retrieved by 308 // WebRTCSessionDescriptionFactory. Should happen before setLocalDescription. 309 void OnCertificateReady( 310 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); 311 void OnDtlsSetupFailure(cricket::BaseChannel*, bool rtcp); 312 313 // For unit test. 314 bool waiting_for_certificate_for_testing() const; 315 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate_for_testing(); 316 317 void set_metrics_observer( 318 webrtc::MetricsObserverInterface* metrics_observer) { 319 metrics_observer_ = metrics_observer; 320 } 321 322 // Called when voice_channel_, video_channel_ and data_channel_ are created 323 // and destroyed. As a result of, for example, setting a new description. 324 sigslot::signal0<> SignalVoiceChannelCreated; 325 sigslot::signal0<> SignalVoiceChannelDestroyed; 326 sigslot::signal0<> SignalVideoChannelCreated; 327 sigslot::signal0<> SignalVideoChannelDestroyed; 328 sigslot::signal0<> SignalDataChannelCreated; 329 sigslot::signal0<> SignalDataChannelDestroyed; 330 331 // Called when a valid data channel OPEN message is received. 332 // std::string represents the data channel label. 333 sigslot::signal2<const std::string&, const InternalDataChannelInit&> 334 SignalDataChannelOpenMessage; 335 336 private: 337 // Indicates the type of SessionDescription in a call to SetLocalDescription 338 // and SetRemoteDescription. 339 enum Action { 340 kOffer, 341 kPrAnswer, 342 kAnswer, 343 }; 344 345 // Log session state. 346 void LogState(State old_state, State new_state); 347 348 // Updates the state, signaling if necessary. 349 virtual void SetState(State state); 350 351 // Updates the error state, signaling if necessary. 352 // TODO(ronghuawu): remove the SetError method that doesn't take |error_desc|. 353 virtual void SetError(Error error, const std::string& error_desc); 354 355 bool UpdateSessionState(Action action, cricket::ContentSource source, 356 std::string* err_desc); 357 static Action GetAction(const std::string& type); 358 // Push the media parts of the local or remote session description 359 // down to all of the channels. 360 bool PushdownMediaDescription(cricket::ContentAction action, 361 cricket::ContentSource source, 362 std::string* error_desc); 363 364 bool PushdownTransportDescription(cricket::ContentSource source, 365 cricket::ContentAction action, 366 std::string* error_desc); 367 368 // Helper methods to push local and remote transport descriptions. 369 bool PushdownLocalTransportDescription( 370 const cricket::SessionDescription* sdesc, 371 cricket::ContentAction action, 372 std::string* error_desc); 373 bool PushdownRemoteTransportDescription( 374 const cricket::SessionDescription* sdesc, 375 cricket::ContentAction action, 376 std::string* error_desc); 377 378 // Returns true and the TransportInfo of the given |content_name| 379 // from |description|. Returns false if it's not available. 380 static bool GetTransportDescription( 381 const cricket::SessionDescription* description, 382 const std::string& content_name, 383 cricket::TransportDescription* info); 384 385 cricket::BaseChannel* GetChannel(const std::string& content_name); 386 // Cause all the BaseChannels in the bundle group to have the same 387 // transport channel. 388 bool EnableBundle(const cricket::ContentGroup& bundle); 389 390 // Enables media channels to allow sending of media. 391 void EnableChannels(); 392 // Returns the media index for a local ice candidate given the content name. 393 // Returns false if the local session description does not have a media 394 // content called |content_name|. 395 bool GetLocalCandidateMediaIndex(const std::string& content_name, 396 int* sdp_mline_index); 397 // Uses all remote candidates in |remote_desc| in this session. 398 bool UseCandidatesInSessionDescription( 399 const SessionDescriptionInterface* remote_desc); 400 // Uses |candidate| in this session. 401 bool UseCandidate(const IceCandidateInterface* candidate); 402 // Deletes the corresponding channel of contents that don't exist in |desc|. 403 // |desc| can be null. This means that all channels are deleted. 404 void RemoveUnusedChannels(const cricket::SessionDescription* desc); 405 406 // Allocates media channels based on the |desc|. If |desc| doesn't have 407 // the BUNDLE option, this method will disable BUNDLE in PortAllocator. 408 // This method will also delete any existing media channels before creating. 409 bool CreateChannels(const cricket::SessionDescription* desc); 410 411 // Helper methods to create media channels. 412 bool CreateVoiceChannel(const cricket::ContentInfo* content); 413 bool CreateVideoChannel(const cricket::ContentInfo* content); 414 bool CreateDataChannel(const cricket::ContentInfo* content); 415 416 // Listens to SCTP CONTROL messages on unused SIDs and process them as OPEN 417 // messages. 418 void OnDataChannelMessageReceived(cricket::DataChannel* channel, 419 const cricket::ReceiveDataParams& params, 420 const rtc::Buffer& payload); 421 422 std::string BadStateErrMsg(State state); 423 void SetIceConnectionState(PeerConnectionInterface::IceConnectionState state); 424 void SetIceConnectionReceiving(bool receiving); 425 426 bool ValidateBundleSettings(const cricket::SessionDescription* desc); 427 bool HasRtcpMuxEnabled(const cricket::ContentInfo* content); 428 // Below methods are helper methods which verifies SDP. 429 bool ValidateSessionDescription(const SessionDescriptionInterface* sdesc, 430 cricket::ContentSource source, 431 std::string* err_desc); 432 433 // Check if a call to SetLocalDescription is acceptable with |action|. 434 bool ExpectSetLocalDescription(Action action); 435 // Check if a call to SetRemoteDescription is acceptable with |action|. 436 bool ExpectSetRemoteDescription(Action action); 437 // Verifies a=setup attribute as per RFC 5763. 438 bool ValidateDtlsSetupAttribute(const cricket::SessionDescription* desc, 439 Action action); 440 441 // Returns true if we are ready to push down the remote candidate. 442 // |remote_desc| is the new remote description, or NULL if the current remote 443 // description should be used. Output |valid| is true if the candidate media 444 // index is valid. 445 bool ReadyToUseRemoteCandidate(const IceCandidateInterface* candidate, 446 const SessionDescriptionInterface* remote_desc, 447 bool* valid); 448 449 void OnTransportControllerConnectionState(cricket::IceConnectionState state); 450 void OnTransportControllerReceiving(bool receiving); 451 void OnTransportControllerGatheringState(cricket::IceGatheringState state); 452 void OnTransportControllerCandidatesGathered( 453 const std::string& transport_name, 454 const cricket::Candidates& candidates); 455 456 std::string GetSessionErrorMsg(); 457 458 // Invoked when TransportController connection completion is signaled. 459 // Reports stats for all transports in use. 460 void ReportTransportStats(); 461 462 // Gather the usage of IPv4/IPv6 as best connection. 463 void ReportBestConnectionState(const cricket::TransportStats& stats); 464 465 void ReportNegotiatedCiphers(const cricket::TransportStats& stats); 466 467 void OnSentPacket_w(cricket::TransportChannel* channel, 468 const rtc::SentPacket& sent_packet); 469 470 rtc::Thread* const signaling_thread_; 471 rtc::Thread* const worker_thread_; 472 cricket::PortAllocator* const port_allocator_; 473 474 State state_ = STATE_INIT; 475 Error error_ = ERROR_NONE; 476 std::string error_desc_; 477 478 const std::string sid_; 479 bool initial_offerer_ = false; 480 481 rtc::scoped_ptr<cricket::TransportController> transport_controller_; 482 MediaControllerInterface* media_controller_; 483 rtc::scoped_ptr<cricket::VoiceChannel> voice_channel_; 484 rtc::scoped_ptr<cricket::VideoChannel> video_channel_; 485 rtc::scoped_ptr<cricket::DataChannel> data_channel_; 486 cricket::ChannelManager* channel_manager_; 487 IceObserver* ice_observer_; 488 PeerConnectionInterface::IceConnectionState ice_connection_state_; 489 bool ice_connection_receiving_; 490 rtc::scoped_ptr<SessionDescriptionInterface> local_desc_; 491 rtc::scoped_ptr<SessionDescriptionInterface> remote_desc_; 492 // If the remote peer is using a older version of implementation. 493 bool older_version_remote_peer_; 494 bool dtls_enabled_; 495 // Specifies which kind of data channel is allowed. This is controlled 496 // by the chrome command-line flag and constraints: 497 // 1. If chrome command-line switch 'enable-sctp-data-channels' is enabled, 498 // constraint kEnableDtlsSrtp is true, and constaint kEnableRtpDataChannels is 499 // not set or false, SCTP is allowed (DCT_SCTP); 500 // 2. If constraint kEnableRtpDataChannels is true, RTP is allowed (DCT_RTP); 501 // 3. If both 1&2 are false, data channel is not allowed (DCT_NONE). 502 cricket::DataChannelType data_channel_type_; 503 rtc::scoped_ptr<IceRestartAnswerLatch> ice_restart_latch_; 504 505 rtc::scoped_ptr<WebRtcSessionDescriptionFactory> 506 webrtc_session_desc_factory_; 507 508 // Member variables for caching global options. 509 cricket::AudioOptions audio_options_; 510 cricket::VideoOptions video_options_; 511 MetricsObserverInterface* metrics_observer_; 512 513 // Declares the bundle policy for the WebRTCSession. 514 PeerConnectionInterface::BundlePolicy bundle_policy_; 515 516 // Declares the RTCP mux policy for the WebRTCSession. 517 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy_; 518 519 RTC_DISALLOW_COPY_AND_ASSIGN(WebRtcSession); 520 }; 521 } // namespace webrtc 522 523 #endif // TALK_APP_WEBRTC_WEBRTCSESSION_H_ 524