| Index: webrtc/pc/channel.cc
|
| diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc
|
| index 56335e24d085c74c37050233eb6ca6b73b75adaa..1f29261ed2532bdf7422792b5e9878b7a06e3efc 100644
|
| --- a/webrtc/pc/channel.cc
|
| +++ b/webrtc/pc/channel.cc
|
| @@ -69,6 +69,7 @@ enum {
|
| MSG_READYTOSENDDATA,
|
| MSG_DATARECEIVED,
|
| MSG_FIRSTPACKETRECEIVED,
|
| + MSG_STREAMCLOSEDREMOTELY,
|
| };
|
|
|
| // Value specified in RFC 5764.
|
| @@ -930,16 +931,16 @@ void BaseChannel::ChannelWritable_n() {
|
| UpdateMediaSendRecvState();
|
| }
|
|
|
| -void BaseChannel::SignalDtlsSrtpSetupFailure_n(bool rtcp) {
|
| +void BaseChannel::SignalDtlsSetupFailure_n(bool rtcp) {
|
| RTC_DCHECK(network_thread_->IsCurrent());
|
| invoker_.AsyncInvoke<void>(
|
| RTC_FROM_HERE, signaling_thread(),
|
| - Bind(&BaseChannel::SignalDtlsSrtpSetupFailure_s, this, rtcp));
|
| + Bind(&BaseChannel::SignalDtlsSetupFailure_s, this, rtcp));
|
| }
|
|
|
| -void BaseChannel::SignalDtlsSrtpSetupFailure_s(bool rtcp) {
|
| +void BaseChannel::SignalDtlsSetupFailure_s(bool rtcp) {
|
| RTC_DCHECK(signaling_thread() == rtc::Thread::Current());
|
| - SignalDtlsSrtpSetupFailure(this, rtcp);
|
| + SignalDtlsSetupFailure(this, rtcp);
|
| }
|
|
|
| bool BaseChannel::SetDtlsSrtpCryptoSuites_n(TransportChannel* tc, bool rtcp) {
|
| @@ -1060,13 +1061,13 @@ void BaseChannel::MaybeSetupDtlsSrtp_n() {
|
| }
|
|
|
| if (!SetupDtlsSrtp_n(false)) {
|
| - SignalDtlsSrtpSetupFailure_n(false);
|
| + SignalDtlsSetupFailure_n(false);
|
| return;
|
| }
|
|
|
| if (rtcp_transport_channel_) {
|
| if (!SetupDtlsSrtp_n(true)) {
|
| - SignalDtlsSrtpSetupFailure_n(true);
|
| + SignalDtlsSetupFailure_n(true);
|
| return;
|
| }
|
| }
|
| @@ -2146,23 +2147,25 @@ void VideoChannel::GetSrtpCryptoSuites_n(
|
| GetSupportedVideoCryptoSuites(crypto_options(), crypto_suites);
|
| }
|
|
|
| -RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
|
| - rtc::Thread* network_thread,
|
| - DataMediaChannel* media_channel,
|
| - TransportController* transport_controller,
|
| - const std::string& content_name,
|
| - bool rtcp,
|
| - bool srtp_required)
|
| +DataChannel::DataChannel(rtc::Thread* worker_thread,
|
| + rtc::Thread* network_thread,
|
| + DataMediaChannel* media_channel,
|
| + TransportController* transport_controller,
|
| + const std::string& content_name,
|
| + bool rtcp,
|
| + bool srtp_required)
|
| : BaseChannel(worker_thread,
|
| network_thread,
|
| media_channel,
|
| transport_controller,
|
| content_name,
|
| rtcp,
|
| - srtp_required) {}
|
| + srtp_required),
|
| + data_channel_type_(cricket::DCT_NONE),
|
| + ready_to_send_data_(false) {}
|
|
|
| -RtpDataChannel::~RtpDataChannel() {
|
| - TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
|
| +DataChannel::~DataChannel() {
|
| + TRACE_EVENT0("webrtc", "DataChannel::~DataChannel");
|
| StopMediaMonitor();
|
| // this can't be done in the base class, since it calls a virtual
|
| DisableMedia_w();
|
| @@ -2170,48 +2173,78 @@ RtpDataChannel::~RtpDataChannel() {
|
| Deinit();
|
| }
|
|
|
| -bool RtpDataChannel::Init_w(const std::string* bundle_transport_name) {
|
| +bool DataChannel::Init_w(const std::string* bundle_transport_name) {
|
| if (!BaseChannel::Init_w(bundle_transport_name)) {
|
| return false;
|
| }
|
| - media_channel()->SignalDataReceived.connect(this,
|
| - &RtpDataChannel::OnDataReceived);
|
| + media_channel()->SignalDataReceived.connect(
|
| + this, &DataChannel::OnDataReceived);
|
| media_channel()->SignalReadyToSend.connect(
|
| - this, &RtpDataChannel::OnDataChannelReadyToSend);
|
| + this, &DataChannel::OnDataChannelReadyToSend);
|
| + media_channel()->SignalStreamClosedRemotely.connect(
|
| + this, &DataChannel::OnStreamClosedRemotely);
|
| return true;
|
| }
|
|
|
| -bool RtpDataChannel::SendData(const SendDataParams& params,
|
| - const rtc::CopyOnWriteBuffer& payload,
|
| - SendDataResult* result) {
|
| +bool DataChannel::SendData(const SendDataParams& params,
|
| + const rtc::CopyOnWriteBuffer& payload,
|
| + SendDataResult* result) {
|
| return InvokeOnWorker(
|
| RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
|
| payload, result));
|
| }
|
|
|
| -const ContentInfo* RtpDataChannel::GetFirstContent(
|
| +const ContentInfo* DataChannel::GetFirstContent(
|
| const SessionDescription* sdesc) {
|
| return GetFirstDataContent(sdesc);
|
| }
|
|
|
| -bool RtpDataChannel::CheckDataChannelTypeFromContent(
|
| - const DataContentDescription* content,
|
| - std::string* error_desc) {
|
| - bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
|
| - (content->protocol() == kMediaProtocolDtlsSctp));
|
| +bool DataChannel::WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) {
|
| + if (data_channel_type_ == DCT_SCTP) {
|
| + // TODO(pthatcher): Do this in a more robust way by checking for
|
| + // SCTP or DTLS.
|
| + return !IsRtpPacket(packet->data(), packet->size());
|
| + } else if (data_channel_type_ == DCT_RTP) {
|
| + return BaseChannel::WantsPacket(rtcp, packet);
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool DataChannel::SetDataChannelType(DataChannelType new_data_channel_type,
|
| + std::string* error_desc) {
|
| + // It hasn't been set before, so set it now.
|
| + if (data_channel_type_ == DCT_NONE) {
|
| + data_channel_type_ = new_data_channel_type;
|
| + return true;
|
| + }
|
| +
|
| // It's been set before, but doesn't match. That's bad.
|
| - if (is_sctp) {
|
| - SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
|
| - error_desc);
|
| + if (data_channel_type_ != new_data_channel_type) {
|
| + std::ostringstream desc;
|
| + desc << "Data channel type mismatch."
|
| + << " Expected " << data_channel_type_
|
| + << " Got " << new_data_channel_type;
|
| + SafeSetError(desc.str(), error_desc);
|
| return false;
|
| }
|
| +
|
| + // It's hasn't changed. Nothing to do.
|
| return true;
|
| }
|
|
|
| -bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
|
| - ContentAction action,
|
| - std::string* error_desc) {
|
| - TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
|
| +bool DataChannel::SetDataChannelTypeFromContent(
|
| + const DataContentDescription* content,
|
| + std::string* error_desc) {
|
| + bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
|
| + (content->protocol() == kMediaProtocolDtlsSctp));
|
| + DataChannelType data_channel_type = is_sctp ? DCT_SCTP : DCT_RTP;
|
| + return SetDataChannelType(data_channel_type, error_desc);
|
| +}
|
| +
|
| +bool DataChannel::SetLocalContent_w(const MediaContentDescription* content,
|
| + ContentAction action,
|
| + std::string* error_desc) {
|
| + TRACE_EVENT0("webrtc", "DataChannel::SetLocalContent_w");
|
| RTC_DCHECK(worker_thread() == rtc::Thread::Current());
|
| LOG(LS_INFO) << "Setting local data description";
|
|
|
| @@ -2223,14 +2256,19 @@ bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
|
| return false;
|
| }
|
|
|
| - if (!CheckDataChannelTypeFromContent(data, error_desc)) {
|
| + if (!SetDataChannelTypeFromContent(data, error_desc)) {
|
| return false;
|
| }
|
|
|
| - if (!SetRtpTransportParameters(content, action, CS_LOCAL, error_desc)) {
|
| - return false;
|
| + if (data_channel_type_ == DCT_RTP) {
|
| + if (!SetRtpTransportParameters(content, action, CS_LOCAL, error_desc)) {
|
| + return false;
|
| + }
|
| }
|
|
|
| + // FYI: We send the SCTP port number (not to be confused with the
|
| + // underlying UDP port number) as a codec parameter. So even SCTP
|
| + // data channels need codecs.
|
| DataRecvParameters recv_params = last_recv_params_;
|
| RtpParametersFromMediaDescription(data, &recv_params);
|
| if (!media_channel()->SetRecvParameters(recv_params)) {
|
| @@ -2238,8 +2276,10 @@ bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
|
| error_desc);
|
| return false;
|
| }
|
| - for (const DataCodec& codec : data->codecs()) {
|
| - bundle_filter()->AddPayloadType(codec.id);
|
| + if (data_channel_type_ == DCT_RTP) {
|
| + for (const DataCodec& codec : data->codecs()) {
|
| + bundle_filter()->AddPayloadType(codec.id);
|
| + }
|
| }
|
| last_recv_params_ = recv_params;
|
|
|
| @@ -2257,10 +2297,10 @@ bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
|
| return true;
|
| }
|
|
|
| -bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| - ContentAction action,
|
| - std::string* error_desc) {
|
| - TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
|
| +bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| + ContentAction action,
|
| + std::string* error_desc) {
|
| + TRACE_EVENT0("webrtc", "DataChannel::SetRemoteContent_w");
|
| RTC_DCHECK(worker_thread() == rtc::Thread::Current());
|
|
|
| const DataContentDescription* data =
|
| @@ -2277,15 +2317,17 @@ bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| return true;
|
| }
|
|
|
| - if (!CheckDataChannelTypeFromContent(data, error_desc)) {
|
| + if (!SetDataChannelTypeFromContent(data, error_desc)) {
|
| return false;
|
| }
|
|
|
| LOG(LS_INFO) << "Setting remote data description";
|
| - if (!SetRtpTransportParameters(content, action, CS_REMOTE, error_desc)) {
|
| + if (data_channel_type_ == DCT_RTP &&
|
| + !SetRtpTransportParameters(content, action, CS_REMOTE, error_desc)) {
|
| return false;
|
| }
|
|
|
| +
|
| DataSendParameters send_params = last_send_params_;
|
| RtpSendParametersFromMediaDescription<DataCodec>(data, &send_params);
|
| if (!media_channel()->SetSendParameters(send_params)) {
|
| @@ -2310,7 +2352,7 @@ bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| return true;
|
| }
|
|
|
| -void RtpDataChannel::UpdateMediaSendRecvState_w() {
|
| +void DataChannel::UpdateMediaSendRecvState_w() {
|
| // Render incoming data if we're the active call, and we have the local
|
| // content. We receive data on the default channel and multiplexed streams.
|
| bool recv = IsReadyToReceiveMedia_w();
|
| @@ -2331,7 +2373,7 @@ void RtpDataChannel::UpdateMediaSendRecvState_w() {
|
| LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
|
| }
|
|
|
| -void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
|
| +void DataChannel::OnMessage(rtc::Message *pmsg) {
|
| switch (pmsg->message_id) {
|
| case MSG_READYTOSENDDATA: {
|
| DataChannelReadyToSendMessageData* data =
|
| @@ -2344,7 +2386,7 @@ void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
|
| case MSG_DATARECEIVED: {
|
| DataReceivedMessageData* data =
|
| static_cast<DataReceivedMessageData*>(pmsg->pdata);
|
| - SignalDataReceived(data->params, data->payload);
|
| + SignalDataReceived(this, data->params, data->payload);
|
| delete data;
|
| break;
|
| }
|
| @@ -2354,27 +2396,33 @@ void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
|
| delete data;
|
| break;
|
| }
|
| + case MSG_STREAMCLOSEDREMOTELY: {
|
| + rtc::TypedMessageData<uint32_t>* data =
|
| + static_cast<rtc::TypedMessageData<uint32_t>*>(pmsg->pdata);
|
| + SignalStreamClosedRemotely(data->data());
|
| + delete data;
|
| + break;
|
| + }
|
| default:
|
| BaseChannel::OnMessage(pmsg);
|
| break;
|
| }
|
| }
|
|
|
| -void RtpDataChannel::OnConnectionMonitorUpdate(
|
| - ConnectionMonitor* monitor,
|
| - const std::vector<ConnectionInfo>& infos) {
|
| +void DataChannel::OnConnectionMonitorUpdate(
|
| + ConnectionMonitor* monitor, const std::vector<ConnectionInfo>& infos) {
|
| SignalConnectionMonitor(this, infos);
|
| }
|
|
|
| -void RtpDataChannel::StartMediaMonitor(int cms) {
|
| +void DataChannel::StartMediaMonitor(int cms) {
|
| media_monitor_.reset(new DataMediaMonitor(media_channel(), worker_thread(),
|
| rtc::Thread::Current()));
|
| - media_monitor_->SignalUpdate.connect(this,
|
| - &RtpDataChannel::OnMediaMonitorUpdate);
|
| + media_monitor_->SignalUpdate.connect(
|
| + this, &DataChannel::OnMediaMonitorUpdate);
|
| media_monitor_->Start(cms);
|
| }
|
|
|
| -void RtpDataChannel::StopMediaMonitor() {
|
| +void DataChannel::StopMediaMonitor() {
|
| if (media_monitor_) {
|
| media_monitor_->Stop();
|
| media_monitor_->SignalUpdate.disconnect(this);
|
| @@ -2382,28 +2430,27 @@ void RtpDataChannel::StopMediaMonitor() {
|
| }
|
| }
|
|
|
| -void RtpDataChannel::OnMediaMonitorUpdate(DataMediaChannel* media_channel,
|
| - const DataMediaInfo& info) {
|
| +void DataChannel::OnMediaMonitorUpdate(
|
| + DataMediaChannel* media_channel, const DataMediaInfo& info) {
|
| RTC_DCHECK(media_channel == this->media_channel());
|
| SignalMediaMonitor(this, info);
|
| }
|
|
|
| -void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
|
| - const char* data,
|
| - size_t len) {
|
| +void DataChannel::OnDataReceived(
|
| + const ReceiveDataParams& params, const char* data, size_t len) {
|
| DataReceivedMessageData* msg = new DataReceivedMessageData(
|
| params, data, len);
|
| signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
|
| }
|
|
|
| -void RtpDataChannel::OnDataChannelError(uint32_t ssrc,
|
| - DataMediaChannel::Error err) {
|
| +void DataChannel::OnDataChannelError(uint32_t ssrc,
|
| + DataMediaChannel::Error err) {
|
| DataChannelErrorMessageData* data = new DataChannelErrorMessageData(
|
| ssrc, err);
|
| signaling_thread()->Post(RTC_FROM_HERE, this, MSG_CHANNEL_ERROR, data);
|
| }
|
|
|
| -void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
|
| +void DataChannel::OnDataChannelReadyToSend(bool writable) {
|
| // This is usded for congestion control to indicate that the stream is ready
|
| // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
|
| // that the transport channel is ready.
|
| @@ -2411,9 +2458,19 @@ void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
|
| new DataChannelReadyToSendMessageData(writable));
|
| }
|
|
|
| -void RtpDataChannel::GetSrtpCryptoSuites_n(
|
| - std::vector<int>* crypto_suites) const {
|
| +void DataChannel::GetSrtpCryptoSuites_n(std::vector<int>* crypto_suites) const {
|
| GetSupportedDataCryptoSuites(crypto_options(), crypto_suites);
|
| }
|
|
|
| +bool DataChannel::ShouldSetupDtlsSrtp_n() const {
|
| + return data_channel_type_ == DCT_RTP && BaseChannel::ShouldSetupDtlsSrtp_n();
|
| +}
|
| +
|
| +void DataChannel::OnStreamClosedRemotely(uint32_t sid) {
|
| + rtc::TypedMessageData<uint32_t>* message =
|
| + new rtc::TypedMessageData<uint32_t>(sid);
|
| + signaling_thread()->Post(RTC_FROM_HERE, this, MSG_STREAMCLOSEDREMOTELY,
|
| + message);
|
| +}
|
| +
|
| } // namespace cricket
|
|
|