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