Home | History | Annotate | Download | only in webrtc
      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_DATACHANNEL_H_
     29 #define TALK_APP_WEBRTC_DATACHANNEL_H_
     30 
     31 #include <string>
     32 #include <queue>
     33 
     34 #include "talk/app/webrtc/datachannelinterface.h"
     35 #include "talk/app/webrtc/proxy.h"
     36 #include "talk/base/scoped_ref_ptr.h"
     37 #include "talk/base/sigslot.h"
     38 #include "talk/session/media/channel.h"
     39 
     40 namespace webrtc {
     41 
     42 class WebRtcSession;
     43 
     44 // DataChannel is a an implementation of the DataChannelInterface based on
     45 // libjingle's data engine. It provides an implementation of unreliable data
     46 // channels. Currently this class is specifically designed to use RtpDataEngine,
     47 // and will changed to use SCTP in the future.
     48 
     49 // DataChannel states:
     50 // kConnecting: The channel has been created but SSRC for sending and receiving
     51 //              has not yet been set and the transport might not yet be ready.
     52 // kOpen: The channel have a local SSRC set by a call to UpdateSendSsrc
     53 //        and a remote SSRC set by call to UpdateReceiveSsrc and the transport
     54 //        has been writable once.
     55 // kClosing: DataChannelInterface::Close has been called or UpdateReceiveSsrc
     56 //           has been called with SSRC==0
     57 // kClosed: Both UpdateReceiveSsrc and UpdateSendSsrc has been called with
     58 //          SSRC==0.
     59 class DataChannel : public DataChannelInterface,
     60                     public sigslot::has_slots<> {
     61  public:
     62   static talk_base::scoped_refptr<DataChannel> Create(
     63       WebRtcSession* session,
     64       const std::string& label,
     65       const DataChannelInit* config);
     66 
     67   virtual void RegisterObserver(DataChannelObserver* observer);
     68   virtual void UnregisterObserver();
     69 
     70   virtual std::string label() const  { return label_; }
     71   virtual bool reliable() const;
     72   virtual int id() const { return config_.id; }
     73   virtual uint64 buffered_amount() const;
     74   virtual void Close();
     75   virtual DataState state() const { return state_; }
     76   virtual bool Send(const DataBuffer& buffer);
     77   // Send a control message right now, or queue for later.
     78   virtual bool SendControl(const talk_base::Buffer* buffer);
     79   void ConnectToDataSession();
     80 
     81   // Set the SSRC this channel should use to receive data from the
     82   // underlying data engine.
     83   void SetReceiveSsrc(uint32 receive_ssrc);
     84   // The remote peer request that this channel should be closed.
     85   void RemotePeerRequestClose();
     86 
     87   // Set the SSRC this channel should use to send data on the
     88   // underlying data engine. |send_ssrc| == 0 means that the channel is no
     89   // longer part of the session negotiation.
     90   void SetSendSsrc(uint32 send_ssrc);
     91 
     92   // Called if the underlying data engine is closing.
     93   void OnDataEngineClose();
     94 
     95   // Called when the channel's ready to use.  That can happen when the
     96   // underlying DataMediaChannel becomes ready, or when this channel is a new
     97   // stream on an existing DataMediaChannel, and we've finished negotiation.
     98   void OnChannelReady(bool writable);
     99  protected:
    100   DataChannel(WebRtcSession* session, const std::string& label);
    101   virtual ~DataChannel();
    102 
    103   bool Init(const DataChannelInit* config);
    104   bool HasNegotiationCompleted();
    105 
    106   // Sigslots from cricket::DataChannel
    107   void OnDataReceived(cricket::DataChannel* channel,
    108                       const cricket::ReceiveDataParams& params,
    109                       const talk_base::Buffer& payload);
    110 
    111  private:
    112   void DoClose();
    113   void UpdateState();
    114   void SetState(DataState state);
    115   void DisconnectFromDataSession();
    116   bool IsConnectedToDataSession() { return data_session_ != NULL; }
    117   void DeliverQueuedControlData();
    118   void QueueControl(const talk_base::Buffer* buffer);
    119   void DeliverQueuedReceivedData();
    120   void ClearQueuedReceivedData();
    121   void SendQueuedSendData();
    122   void ClearQueuedSendData();
    123   bool InternalSendWithoutQueueing(const DataBuffer& buffer,
    124                                    cricket::SendDataResult* send_result);
    125   bool QueueSendData(const DataBuffer& buffer);
    126 
    127   std::string label_;
    128   DataChannelInit config_;
    129   DataChannelObserver* observer_;
    130   DataState state_;
    131   bool was_ever_writable_;
    132   WebRtcSession* session_;
    133   cricket::DataChannel* data_session_;
    134   bool send_ssrc_set_;
    135   uint32 send_ssrc_;
    136   bool receive_ssrc_set_;
    137   uint32 receive_ssrc_;
    138   // Control messages that always have to get sent out before any queued
    139   // data.
    140   std::queue<const talk_base::Buffer*> queued_control_data_;
    141   std::queue<DataBuffer*> queued_received_data_;
    142   std::deque<DataBuffer*> queued_send_data_;
    143 };
    144 
    145 class DataChannelFactory {
    146  public:
    147   virtual talk_base::scoped_refptr<DataChannel> CreateDataChannel(
    148       const std::string& label,
    149       const DataChannelInit* config) = 0;
    150 
    151  protected:
    152   virtual ~DataChannelFactory() {}
    153 };
    154 
    155 // Define proxy for DataChannelInterface.
    156 BEGIN_PROXY_MAP(DataChannel)
    157   PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*)
    158   PROXY_METHOD0(void, UnregisterObserver)
    159   PROXY_CONSTMETHOD0(std::string, label)
    160   PROXY_CONSTMETHOD0(bool, reliable)
    161   PROXY_CONSTMETHOD0(int, id)
    162   PROXY_CONSTMETHOD0(DataState, state)
    163   PROXY_CONSTMETHOD0(uint64, buffered_amount)
    164   PROXY_METHOD0(void, Close)
    165   PROXY_METHOD1(bool, Send, const DataBuffer&)
    166 END_PROXY()
    167 
    168 }  // namespace webrtc
    169 
    170 #endif  // TALK_APP_WEBRTC_DATACHANNEL_H_
    171