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 
13 #include "absl/types/optional.h"
14 #include "pc/sctp_utils.h"
15 
16 namespace webrtc {
17 
SctpDataChannelTransport(cricket::SctpTransportInternal * sctp_transport)18 SctpDataChannelTransport::SctpDataChannelTransport(
19     cricket::SctpTransportInternal* sctp_transport)
20     : sctp_transport_(sctp_transport) {
21   sctp_transport_->SignalReadyToSendData.connect(
22       this, &SctpDataChannelTransport::OnReadyToSendData);
23   sctp_transport_->SignalDataReceived.connect(
24       this, &SctpDataChannelTransport::OnDataReceived);
25   sctp_transport_->SignalClosingProcedureStartedRemotely.connect(
26       this, &SctpDataChannelTransport::OnClosingProcedureStartedRemotely);
27   sctp_transport_->SignalClosingProcedureComplete.connect(
28       this, &SctpDataChannelTransport::OnClosingProcedureComplete);
29   sctp_transport_->SignalClosedAbruptly.connect(
30       this, &SctpDataChannelTransport::OnClosedAbruptly);
31 }
32 
OpenChannel(int channel_id)33 RTCError SctpDataChannelTransport::OpenChannel(int channel_id) {
34   sctp_transport_->OpenStream(channel_id);
35   return RTCError::OK();
36 }
37 
SendData(int channel_id,const SendDataParams & params,const rtc::CopyOnWriteBuffer & buffer)38 RTCError SctpDataChannelTransport::SendData(
39     int channel_id,
40     const SendDataParams& params,
41     const rtc::CopyOnWriteBuffer& buffer) {
42   // Map webrtc::SendDataParams to cricket::SendDataParams.
43   // TODO(mellem):  See about unifying these structs.
44   cricket::SendDataParams sd_params;
45   sd_params.sid = channel_id;
46   sd_params.type = ToCricketDataMessageType(params.type);
47   sd_params.ordered = params.ordered;
48   sd_params.reliable = !(params.max_rtx_count || params.max_rtx_ms);
49   sd_params.max_rtx_count = params.max_rtx_count.value_or(-1);
50   sd_params.max_rtx_ms = params.max_rtx_ms.value_or(-1);
51 
52   cricket::SendDataResult result;
53   sctp_transport_->SendData(sd_params, buffer, &result);
54 
55   // TODO(mellem):  See about changing the interfaces to not require mapping
56   // SendDataResult to RTCError and back again.
57   switch (result) {
58     case cricket::SendDataResult::SDR_SUCCESS:
59       return RTCError::OK();
60     case cricket::SendDataResult::SDR_BLOCK: {
61       // Send buffer is full.
62       ready_to_send_ = false;
63       return RTCError(RTCErrorType::RESOURCE_EXHAUSTED);
64     }
65     case cricket::SendDataResult::SDR_ERROR:
66       return RTCError(RTCErrorType::NETWORK_ERROR);
67   }
68   return RTCError(RTCErrorType::NETWORK_ERROR);
69 }
70 
CloseChannel(int channel_id)71 RTCError SctpDataChannelTransport::CloseChannel(int channel_id) {
72   sctp_transport_->ResetStream(channel_id);
73   return RTCError::OK();
74 }
75 
SetDataSink(DataChannelSink * sink)76 void SctpDataChannelTransport::SetDataSink(DataChannelSink* sink) {
77   sink_ = sink;
78   if (sink_ && ready_to_send_) {
79     sink_->OnReadyToSend();
80   }
81 }
82 
IsReadyToSend() const83 bool SctpDataChannelTransport::IsReadyToSend() const {
84   return ready_to_send_;
85 }
86 
OnReadyToSendData()87 void SctpDataChannelTransport::OnReadyToSendData() {
88   ready_to_send_ = true;
89   if (sink_) {
90     sink_->OnReadyToSend();
91   }
92 }
93 
OnDataReceived(const cricket::ReceiveDataParams & params,const rtc::CopyOnWriteBuffer & buffer)94 void SctpDataChannelTransport::OnDataReceived(
95     const cricket::ReceiveDataParams& params,
96     const rtc::CopyOnWriteBuffer& buffer) {
97   if (sink_) {
98     sink_->OnDataReceived(params.sid, ToWebrtcDataMessageType(params.type),
99                           buffer);
100   }
101 }
102 
OnClosingProcedureStartedRemotely(int channel_id)103 void SctpDataChannelTransport::OnClosingProcedureStartedRemotely(
104     int channel_id) {
105   if (sink_) {
106     sink_->OnChannelClosing(channel_id);
107   }
108 }
109 
OnClosingProcedureComplete(int channel_id)110 void SctpDataChannelTransport::OnClosingProcedureComplete(int channel_id) {
111   if (sink_) {
112     sink_->OnChannelClosed(channel_id);
113   }
114 }
115 
OnClosedAbruptly()116 void SctpDataChannelTransport::OnClosedAbruptly() {
117   if (sink_) {
118     sink_->OnTransportClosed();
119   }
120 }
121 
122 }  // namespace webrtc
123