• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
IceObserver()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.
OnIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)92   virtual void OnIceConnectionChange(
93       PeerConnectionInterface::IceConnectionState new_state) {}
94   // Called any time the IceGatheringState changes
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)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)
OnIceComplete()102   virtual void OnIceComplete() {}
103 
104   // Called whenever the state changes between receiving and not receiving.
OnIceConnectionReceivingChange(bool receiving)105   virtual void OnIceConnectionReceivingChange(bool receiving) {}
106 
107  protected:
~IceObserver()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.
signaling_thread()161   rtc::Thread* signaling_thread() const { return signaling_thread_; }
worker_thread()162   rtc::Thread* worker_thread() const { return worker_thread_; }
port_allocator()163   cricket::PortAllocator* port_allocator() const { return port_allocator_; }
164 
165   // The ID of this session.
id()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.
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.
state()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.
error()186   Error error() const { return error_; }
error_desc()187   const std::string& error_desc() const { return error_desc_; }
188 
RegisterIceObserver(IceObserver * observer)189   void RegisterIceObserver(IceObserver* observer) {
190     ice_observer_ = observer;
191   }
192 
voice_channel()193   virtual cricket::VoiceChannel* voice_channel() {
194     return voice_channel_.get();
195   }
video_channel()196   virtual cricket::VideoChannel* video_channel() {
197     return video_channel_.get();
198   }
data_channel()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 
local_description()239   const SessionDescriptionInterface* local_description() const {
240     return local_desc_.get();
241   }
remote_description()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 
set_metrics_observer(webrtc::MetricsObserverInterface * metrics_observer)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