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 33 #include "talk/app/webrtc/peerconnectioninterface.h" 34 #include "talk/app/webrtc/dtmfsender.h" 35 #include "talk/app/webrtc/mediastreamprovider.h" 36 #include "talk/app/webrtc/datachannel.h" 37 #include "talk/app/webrtc/statstypes.h" 38 #include "talk/base/sigslot.h" 39 #include "talk/base/thread.h" 40 #include "talk/media/base/mediachannel.h" 41 #include "talk/p2p/base/session.h" 42 #include "talk/session/media/mediasession.h" 43 44 namespace cricket { 45 class BaseChannel; 46 class ChannelManager; 47 class DataChannel; 48 class StatsReport; 49 class Transport; 50 class VideoCapturer; 51 class VideoChannel; 52 class VoiceChannel; 53 } // namespace cricket 54 55 namespace webrtc { 56 class IceRestartAnswerLatch; 57 class MediaStreamSignaling; 58 class WebRtcSessionDescriptionFactory; 59 60 extern const char kSetLocalSdpFailed[]; 61 extern const char kSetRemoteSdpFailed[]; 62 extern const char kCreateChannelFailed[]; 63 extern const char kBundleWithoutRtcpMux[]; 64 extern const char kInvalidCandidates[]; 65 extern const char kInvalidSdp[]; 66 extern const char kMlineMismatch[]; 67 extern const char kSdpWithoutCrypto[]; 68 extern const char kSdpWithoutSdesAndDtlsDisabled[]; 69 extern const char kSdpWithoutIceUfragPwd[]; 70 extern const char kSessionError[]; 71 extern const char kUpdateStateFailed[]; 72 extern const char kPushDownOfferTDFailed[]; 73 extern const char kPushDownPranswerTDFailed[]; 74 extern const char kPushDownAnswerTDFailed[]; 75 76 // ICE state callback interface. 77 class IceObserver { 78 public: 79 IceObserver() {} 80 // Called any time the IceConnectionState changes 81 virtual void OnIceConnectionChange( 82 PeerConnectionInterface::IceConnectionState new_state) {} 83 // Called any time the IceGatheringState changes 84 virtual void OnIceGatheringChange( 85 PeerConnectionInterface::IceGatheringState new_state) {} 86 // New Ice candidate have been found. 87 virtual void OnIceCandidate(const IceCandidateInterface* candidate) = 0; 88 // All Ice candidates have been found. 89 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange. 90 // (via PeerConnectionObserver) 91 virtual void OnIceComplete() {} 92 93 protected: 94 ~IceObserver() {} 95 96 private: 97 DISALLOW_COPY_AND_ASSIGN(IceObserver); 98 }; 99 100 class WebRtcSession : public cricket::BaseSession, 101 public AudioProviderInterface, 102 public DataChannelFactory, 103 public VideoProviderInterface, 104 public DtmfProviderInterface, 105 public DataChannelProviderInterface { 106 public: 107 WebRtcSession(cricket::ChannelManager* channel_manager, 108 talk_base::Thread* signaling_thread, 109 talk_base::Thread* worker_thread, 110 cricket::PortAllocator* port_allocator, 111 MediaStreamSignaling* mediastream_signaling); 112 virtual ~WebRtcSession(); 113 114 bool Initialize(const PeerConnectionFactoryInterface::Options& options, 115 const MediaConstraintsInterface* constraints, 116 DTLSIdentityServiceInterface* dtls_identity_service); 117 // Deletes the voice, video and data channel and changes the session state 118 // to STATE_RECEIVEDTERMINATE. 119 void Terminate(); 120 121 void RegisterIceObserver(IceObserver* observer) { 122 ice_observer_ = observer; 123 } 124 125 virtual cricket::VoiceChannel* voice_channel() { 126 return voice_channel_.get(); 127 } 128 virtual cricket::VideoChannel* video_channel() { 129 return video_channel_.get(); 130 } 131 virtual cricket::DataChannel* data_channel() { 132 return data_channel_.get(); 133 } 134 135 void SetSecurePolicy(cricket::SecureMediaPolicy secure_policy); 136 cricket::SecureMediaPolicy SecurePolicy() const; 137 138 // Get current ssl role from transport. 139 bool GetSslRole(talk_base::SSLRole* role); 140 141 // Generic error message callback from WebRtcSession. 142 // TODO - It may be necessary to supply error code as well. 143 sigslot::signal0<> SignalError; 144 145 void CreateOffer(CreateSessionDescriptionObserver* observer, 146 const MediaConstraintsInterface* constraints); 147 void CreateAnswer(CreateSessionDescriptionObserver* observer, 148 const MediaConstraintsInterface* constraints); 149 // The ownership of |desc| will be transferred after this call. 150 bool SetLocalDescription(SessionDescriptionInterface* desc, 151 std::string* err_desc); 152 // The ownership of |desc| will be transferred after this call. 153 bool SetRemoteDescription(SessionDescriptionInterface* desc, 154 std::string* err_desc); 155 bool ProcessIceMessage(const IceCandidateInterface* ice_candidate); 156 const SessionDescriptionInterface* local_description() const { 157 return local_desc_.get(); 158 } 159 const SessionDescriptionInterface* remote_description() const { 160 return remote_desc_.get(); 161 } 162 163 // Get the id used as a media stream track's "id" field from ssrc. 164 virtual bool GetTrackIdBySsrc(uint32 ssrc, std::string* id); 165 166 // AudioMediaProviderInterface implementation. 167 virtual void SetAudioPlayout(uint32 ssrc, bool enable, 168 cricket::AudioRenderer* renderer) OVERRIDE; 169 virtual void SetAudioSend(uint32 ssrc, bool enable, 170 const cricket::AudioOptions& options, 171 cricket::AudioRenderer* renderer) OVERRIDE; 172 173 // Implements VideoMediaProviderInterface. 174 virtual bool SetCaptureDevice(uint32 ssrc, 175 cricket::VideoCapturer* camera) OVERRIDE; 176 virtual void SetVideoPlayout(uint32 ssrc, 177 bool enable, 178 cricket::VideoRenderer* renderer) OVERRIDE; 179 virtual void SetVideoSend(uint32 ssrc, bool enable, 180 const cricket::VideoOptions* options) OVERRIDE; 181 182 // Implements DtmfProviderInterface. 183 virtual bool CanInsertDtmf(const std::string& track_id); 184 virtual bool InsertDtmf(const std::string& track_id, 185 int code, int duration); 186 virtual sigslot::signal0<>* GetOnDestroyedSignal(); 187 188 // Implements DataChannelProviderInterface. 189 virtual bool SendData(const cricket::SendDataParams& params, 190 const talk_base::Buffer& payload, 191 cricket::SendDataResult* result) OVERRIDE; 192 virtual bool ConnectDataChannel(DataChannel* webrtc_data_channel) OVERRIDE; 193 virtual void DisconnectDataChannel(DataChannel* webrtc_data_channel) OVERRIDE; 194 virtual void AddSctpDataStream(uint32 sid) OVERRIDE; 195 virtual void RemoveSctpDataStream(uint32 sid) OVERRIDE; 196 virtual bool ReadyToSendData() const OVERRIDE; 197 198 talk_base::scoped_refptr<DataChannel> CreateDataChannel( 199 const std::string& label, 200 const DataChannelInit* config); 201 202 cricket::DataChannelType data_channel_type() const; 203 204 bool IceRestartPending() const; 205 206 void ResetIceRestartLatch(); 207 208 // Called when an SSLIdentity is generated or retrieved by 209 // WebRTCSessionDescriptionFactory. Should happen before setLocalDescription. 210 void OnIdentityReady(talk_base::SSLIdentity* identity); 211 212 // For unit test. 213 bool waiting_for_identity() const; 214 215 private: 216 // Indicates the type of SessionDescription in a call to SetLocalDescription 217 // and SetRemoteDescription. 218 enum Action { 219 kOffer, 220 kPrAnswer, 221 kAnswer, 222 }; 223 224 // Invokes ConnectChannels() on transport proxies, which initiates ice 225 // candidates allocation. 226 bool StartCandidatesAllocation(); 227 bool UpdateSessionState(Action action, cricket::ContentSource source, 228 const cricket::SessionDescription* desc, 229 std::string* err_desc); 230 static Action GetAction(const std::string& type); 231 232 // Transport related callbacks, override from cricket::BaseSession. 233 virtual void OnTransportRequestSignaling(cricket::Transport* transport); 234 virtual void OnTransportConnecting(cricket::Transport* transport); 235 virtual void OnTransportWritable(cricket::Transport* transport); 236 virtual void OnTransportProxyCandidatesReady( 237 cricket::TransportProxy* proxy, 238 const cricket::Candidates& candidates); 239 virtual void OnCandidatesAllocationDone(); 240 241 // Creates local session description with audio and video contents. 242 bool CreateDefaultLocalDescription(); 243 // Enables media channels to allow sending of media. 244 void EnableChannels(); 245 // Creates a JsepIceCandidate and adds it to the local session description 246 // and notify observers. Called when a new local candidate have been found. 247 void ProcessNewLocalCandidate(const std::string& content_name, 248 const cricket::Candidates& candidates); 249 // Returns the media index for a local ice candidate given the content name. 250 // Returns false if the local session description does not have a media 251 // content called |content_name|. 252 bool GetLocalCandidateMediaIndex(const std::string& content_name, 253 int* sdp_mline_index); 254 // Uses all remote candidates in |remote_desc| in this session. 255 bool UseCandidatesInSessionDescription( 256 const SessionDescriptionInterface* remote_desc); 257 // Uses |candidate| in this session. 258 bool UseCandidate(const IceCandidateInterface* candidate); 259 // Deletes the corresponding channel of contents that don't exist in |desc|. 260 // |desc| can be null. This means that all channels are deleted. 261 void RemoveUnusedChannelsAndTransports( 262 const cricket::SessionDescription* desc); 263 264 // Allocates media channels based on the |desc|. If |desc| doesn't have 265 // the BUNDLE option, this method will disable BUNDLE in PortAllocator. 266 // This method will also delete any existing media channels before creating. 267 bool CreateChannels(const cricket::SessionDescription* desc); 268 269 // Helper methods to create media channels. 270 bool CreateVoiceChannel(const cricket::ContentInfo* content); 271 bool CreateVideoChannel(const cricket::ContentInfo* content); 272 bool CreateDataChannel(const cricket::ContentInfo* content); 273 274 // Copy the candidates from |saved_candidates_| to |dest_desc|. 275 // The |saved_candidates_| will be cleared after this function call. 276 void CopySavedCandidates(SessionDescriptionInterface* dest_desc); 277 278 void OnNewDataChannelReceived(const std::string& label, 279 const DataChannelInit& init); 280 281 bool GetLocalTrackId(uint32 ssrc, std::string* track_id); 282 bool GetRemoteTrackId(uint32 ssrc, std::string* track_id); 283 284 std::string BadStateErrMsg(const std::string& type, State state); 285 void SetIceConnectionState(PeerConnectionInterface::IceConnectionState state); 286 287 bool ValidateBundleSettings(const cricket::SessionDescription* desc); 288 bool HasRtcpMuxEnabled(const cricket::ContentInfo* content); 289 // Below methods are helper methods which verifies SDP. 290 bool ValidateSessionDescription(const SessionDescriptionInterface* sdesc, 291 cricket::ContentSource source, 292 std::string* error_desc); 293 294 // Check if a call to SetLocalDescription is acceptable with |action|. 295 bool ExpectSetLocalDescription(Action action); 296 // Check if a call to SetRemoteDescription is acceptable with |action|. 297 bool ExpectSetRemoteDescription(Action action); 298 // Verifies a=setup attribute as per RFC 5763. 299 bool ValidateDtlsSetupAttribute(const cricket::SessionDescription* desc, 300 Action action); 301 302 talk_base::scoped_ptr<cricket::VoiceChannel> voice_channel_; 303 talk_base::scoped_ptr<cricket::VideoChannel> video_channel_; 304 talk_base::scoped_ptr<cricket::DataChannel> data_channel_; 305 cricket::ChannelManager* channel_manager_; 306 MediaStreamSignaling* mediastream_signaling_; 307 IceObserver* ice_observer_; 308 PeerConnectionInterface::IceConnectionState ice_connection_state_; 309 talk_base::scoped_ptr<SessionDescriptionInterface> local_desc_; 310 talk_base::scoped_ptr<SessionDescriptionInterface> remote_desc_; 311 // Candidates that arrived before the remote description was set. 312 std::vector<IceCandidateInterface*> saved_candidates_; 313 // If the remote peer is using a older version of implementation. 314 bool older_version_remote_peer_; 315 bool dtls_enabled_; 316 // Flag will be set based on the constraint value. 317 bool dscp_enabled_; 318 // Specifies which kind of data channel is allowed. This is controlled 319 // by the chrome command-line flag and constraints: 320 // 1. If chrome command-line switch 'enable-sctp-data-channels' is enabled, 321 // constraint kEnableDtlsSrtp is true, and constaint kEnableRtpDataChannels is 322 // not set or false, SCTP is allowed (DCT_SCTP); 323 // 2. If constraint kEnableRtpDataChannels is true, RTP is allowed (DCT_RTP); 324 // 3. If both 1&2 are false, data channel is not allowed (DCT_NONE). 325 cricket::DataChannelType data_channel_type_; 326 talk_base::scoped_ptr<IceRestartAnswerLatch> ice_restart_latch_; 327 328 talk_base::scoped_ptr<WebRtcSessionDescriptionFactory> 329 webrtc_session_desc_factory_; 330 331 sigslot::signal0<> SignalVoiceChannelDestroyed; 332 sigslot::signal0<> SignalVideoChannelDestroyed; 333 sigslot::signal0<> SignalDataChannelDestroyed; 334 335 DISALLOW_COPY_AND_ASSIGN(WebRtcSession); 336 }; 337 } // namespace webrtc 338 339 #endif // TALK_APP_WEBRTC_WEBRTCSESSION_H_ 340