1 /*
2  *  Copyright 2019 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "pc/sctp_data_channel_transport.h"
12 #include "pc/sctp_utils.h"
13 
14 namespace webrtc {
15 
SctpDataChannelTransport(cricket::SctpTransportInternal * sctp_transport)16 SctpDataChannelTransport::SctpDataChannelTransport(
17     cricket::SctpTransportInternal* sctp_transport)
18     : sctp_transport_(sctp_transport) {
19   sctp_transport_->SignalReadyToSendData.connect(
20       this, &SctpDataChannelTransport::OnReadyToSendData);
21   sctp_transport_->SignalDataReceived.connect(
22       this, &SctpDataChannelTransport::OnDataReceived);
23   sctp_transport_->SignalClosingProcedureStartedRemotely.connect(
24       this, &SctpDataChannelTransport::OnClosingProcedureStartedRemotely);
25   sctp_transport_->SignalClosingProcedureComplete.connect(
26       this, &SctpDataChannelTransport::OnClosingProcedureComplete);
27   sctp_transport_->SignalClosedAbruptly.connect(
28       this, &SctpDataChannelTransport::OnClosedAbruptly);
29 }
30 
OpenChannel(int channel_id)31 RTCError SctpDataChannelTransport::OpenChannel(int channel_id) {
32   sctp_transport_->OpenStream(channel_id);
33   return RTCError::OK();
34 }
35 
SendData(int channel_id,const SendDataParams & params,const rtc::CopyOnWriteBuffer & buffer)36 RTCError SctpDataChannelTransport::SendData(
37     int channel_id,
38     const SendDataParams& params,
39     const rtc::CopyOnWriteBuffer& buffer) {
40   // Map webrtc::SendDataParams to cricket::SendDataParams.
41   // TODO(mellem):  See about unifying these structs.
42   cricket::SendDataParams sd_params;
43   sd_params.sid = channel_id;
44   sd_params.type = ToCricketDataMessageType(params.type);
45   sd_params.ordered = params.ordered;
46   sd_params.reliable = !(params.max_rtx_count || params.max_rtx_ms);
47   sd_params.max_rtx_count = params.max_rtx_count.value_or(-1);
48   sd_params.max_rtx_ms = params.max_rtx_ms.value_or(-1);
49 
50   cricket::SendDataResult result;
51   sctp_transport_->SendData(sd_params, buffer, &result);
52 
53   // TODO(mellem):  See about changing the interfaces to not require mapping
54   // SendDataResult to RTCError and back again.
55   switch (result) {
56     case cricket::SendDataResult::SDR_SUCCESS:
57       return RTCError::OK();
58     case cricket::SendDataResult::SDR_BLOCK: {
59       // Send buffer is full.
60       ready_to_send_ = false;
61       return RTCError(RTCErrorType::RESOURCE_EXHAUSTED);
62     }
63     case cricket::SendDataResult::SDR_ERROR:
64       return RTCError(RTCErrorType::NETWORK_ERROR);
65   }
66   return RTCError(RTCErrorType::NETWORK_ERROR);
67 }
68 
CloseChannel(int channel_id)69 RTCError SctpDataChannelTransport::CloseChannel(int channel_id) {
70   sctp_transport_->ResetStream(channel_id);
71   return RTCError::OK();
72 }
73 
SetDataSink(DataChannelSink * sink)74 void SctpDataChannelTransport::SetDataSink(DataChannelSink* sink) {
75   sink_ = sink;
76   if (sink_ && ready_to_send_) {
77     sink_->OnReadyToSend();
78   }
79 }
80 
IsReadyToSend() const81 bool SctpDataChannelTransport::IsReadyToSend() const {
82   return ready_to_send_;
83 }
84 
OnReadyToSendData()85 void SctpDataChannelTransport::OnReadyToSendData() {
86   ready_to_send_ = true;
87   if (sink_) {
88     sink_->OnReadyToSend();
89   }
90 }
91 
OnDataReceived(const cricket::ReceiveDataParams & params,const rtc::CopyOnWriteBuffer & buffer)92 void SctpDataChannelTransport::OnDataReceived(
93     const cricket::ReceiveDataParams& params,
94     const rtc::CopyOnWriteBuffer& buffer) {
95   if (sink_) {
96     sink_->OnDataReceived(params.sid, ToWebrtcDataMessageType(params.type),
97                           buffer);
98   }
99 }
100 
OnClosingProcedureStartedRemotely(int channel_id)101 void SctpDataChannelTransport::OnClosingProcedureStartedRemotely(
102     int channel_id) {
103   if (sink_) {
104     sink_->OnChannelClosing(channel_id);
105   }
106 }
107 
OnClosingProcedureComplete(int channel_id)108 void SctpDataChannelTransport::OnClosingProcedureComplete(int channel_id) {
109   if (sink_) {
110     sink_->OnChannelClosed(channel_id);
111   }
112 }
113 
OnClosedAbruptly()114 void SctpDataChannelTransport::OnClosedAbruptly() {
115   if (sink_) {
116     sink_->OnTransportClosed();
117   }
118 }
119 
120 }  // namespace webrtc
121