| /* |
| * Copyright 2019 The WebRTC Project Authors. All rights reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "pc/sctp_data_channel_transport.h" |
| #include "pc/sctp_utils.h" |
| |
| namespace webrtc { |
| |
| SctpDataChannelTransport::SctpDataChannelTransport( |
| cricket::SctpTransportInternal* sctp_transport) |
| : sctp_transport_(sctp_transport) { |
| sctp_transport_->SignalReadyToSendData.connect( |
| this, &SctpDataChannelTransport::OnReadyToSendData); |
| sctp_transport_->SignalDataReceived.connect( |
| this, &SctpDataChannelTransport::OnDataReceived); |
| sctp_transport_->SignalClosingProcedureStartedRemotely.connect( |
| this, &SctpDataChannelTransport::OnClosingProcedureStartedRemotely); |
| sctp_transport_->SignalClosingProcedureComplete.connect( |
| this, &SctpDataChannelTransport::OnClosingProcedureComplete); |
| } |
| |
| RTCError SctpDataChannelTransport::OpenChannel(int channel_id) { |
| sctp_transport_->OpenStream(channel_id); |
| return RTCError::OK(); |
| } |
| |
| RTCError SctpDataChannelTransport::SendData( |
| int channel_id, |
| const SendDataParams& params, |
| const rtc::CopyOnWriteBuffer& buffer) { |
| // Map webrtc::SendDataParams to cricket::SendDataParams. |
| // TODO(mellem): See about unifying these structs. |
| cricket::SendDataParams sd_params; |
| sd_params.sid = channel_id; |
| sd_params.type = ToCricketDataMessageType(params.type); |
| sd_params.ordered = params.ordered; |
| sd_params.reliable = !(params.max_rtx_count || params.max_rtx_ms); |
| sd_params.max_rtx_count = params.max_rtx_count.value_or(-1); |
| sd_params.max_rtx_ms = params.max_rtx_ms.value_or(-1); |
| |
| cricket::SendDataResult result; |
| sctp_transport_->SendData(sd_params, buffer, &result); |
| |
| // TODO(mellem): See about changing the interfaces to not require mapping |
| // SendDataResult to RTCError and back again. |
| switch (result) { |
| case cricket::SendDataResult::SDR_SUCCESS: |
| return RTCError::OK(); |
| case cricket::SendDataResult::SDR_BLOCK: { |
| // Send buffer is full. |
| ready_to_send_ = false; |
| return RTCError(RTCErrorType::RESOURCE_EXHAUSTED); |
| } |
| case cricket::SendDataResult::SDR_ERROR: |
| return RTCError(RTCErrorType::NETWORK_ERROR); |
| } |
| return RTCError(RTCErrorType::NETWORK_ERROR); |
| } |
| |
| RTCError SctpDataChannelTransport::CloseChannel(int channel_id) { |
| sctp_transport_->ResetStream(channel_id); |
| return RTCError::OK(); |
| } |
| |
| void SctpDataChannelTransport::SetDataSink(DataChannelSink* sink) { |
| sink_ = sink; |
| if (sink_ && ready_to_send_) { |
| sink_->OnReadyToSend(); |
| } |
| } |
| |
| bool SctpDataChannelTransport::IsReadyToSend() const { |
| return ready_to_send_; |
| } |
| |
| void SctpDataChannelTransport::OnReadyToSendData() { |
| ready_to_send_ = true; |
| if (sink_) { |
| sink_->OnReadyToSend(); |
| } |
| } |
| |
| void SctpDataChannelTransport::OnDataReceived( |
| const cricket::ReceiveDataParams& params, |
| const rtc::CopyOnWriteBuffer& buffer) { |
| if (sink_) { |
| sink_->OnDataReceived(params.sid, ToWebrtcDataMessageType(params.type), |
| buffer); |
| } |
| } |
| |
| void SctpDataChannelTransport::OnClosingProcedureStartedRemotely( |
| int channel_id) { |
| if (sink_) { |
| sink_->OnChannelClosing(channel_id); |
| } |
| } |
| |
| void SctpDataChannelTransport::OnClosingProcedureComplete(int channel_id) { |
| if (sink_) { |
| sink_->OnChannelClosed(channel_id); |
| } |
| } |
| |
| } // namespace webrtc |