| /* | 
 |  *  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); | 
 |   sctp_transport_->SignalClosedAbruptly.connect( | 
 |       this, &SctpDataChannelTransport::OnClosedAbruptly); | 
 | } | 
 |  | 
 | 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); | 
 |   } | 
 | } | 
 |  | 
 | void SctpDataChannelTransport::OnClosedAbruptly() { | 
 |   if (sink_) { | 
 |     sink_->OnTransportClosed(); | 
 |   } | 
 | } | 
 |  | 
 | }  // namespace webrtc |