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