OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/pc/mediasession.h" | 11 #include "webrtc/pc/mediasession.h" |
12 | 12 |
13 #include <algorithm> // For std::find_if, std::sort. | 13 #include <algorithm> // For std::find_if, std::sort. |
14 #include <functional> | 14 #include <functional> |
15 #include <map> | 15 #include <map> |
16 #include <memory> | 16 #include <memory> |
17 #include <set> | 17 #include <set> |
18 #include <unordered_map> | 18 #include <unordered_map> |
19 #include <utility> | 19 #include <utility> |
20 | 20 |
21 #include "webrtc/base/base64.h" | 21 #include "webrtc/base/base64.h" |
22 #include "webrtc/base/checks.h" | 22 #include "webrtc/base/checks.h" |
23 #include "webrtc/base/helpers.h" | 23 #include "webrtc/base/helpers.h" |
24 #include "webrtc/base/logging.h" | 24 #include "webrtc/base/logging.h" |
| 25 #include "webrtc/base/optional.h" |
25 #include "webrtc/base/stringutils.h" | 26 #include "webrtc/base/stringutils.h" |
26 #include "webrtc/common_types.h" | 27 #include "webrtc/common_types.h" |
27 #include "webrtc/common_video/h264/profile_level_id.h" | 28 #include "webrtc/common_video/h264/profile_level_id.h" |
28 #include "webrtc/media/base/cryptoparams.h" | 29 #include "webrtc/media/base/cryptoparams.h" |
29 #include "webrtc/media/base/mediaconstants.h" | 30 #include "webrtc/media/base/mediaconstants.h" |
30 #include "webrtc/p2p/base/p2pconstants.h" | 31 #include "webrtc/p2p/base/p2pconstants.h" |
31 #include "webrtc/pc/channelmanager.h" | 32 #include "webrtc/pc/channelmanager.h" |
32 #include "webrtc/pc/srtpfilter.h" | 33 #include "webrtc/pc/srtpfilter.h" |
33 | 34 |
34 namespace { | 35 namespace { |
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1423 return NULL; | 1424 return NULL; |
1424 } | 1425 } |
1425 } | 1426 } |
1426 | 1427 |
1427 return offer.release(); | 1428 return offer.release(); |
1428 } | 1429 } |
1429 | 1430 |
1430 SessionDescription* MediaSessionDescriptionFactory::CreateAnswer( | 1431 SessionDescription* MediaSessionDescriptionFactory::CreateAnswer( |
1431 const SessionDescription* offer, const MediaSessionOptions& options, | 1432 const SessionDescription* offer, const MediaSessionOptions& options, |
1432 const SessionDescription* current_description) const { | 1433 const SessionDescription* current_description) const { |
| 1434 if (!offer) { |
| 1435 return nullptr; |
| 1436 } |
1433 // The answer contains the intersection of the codecs in the offer with the | 1437 // The answer contains the intersection of the codecs in the offer with the |
1434 // codecs we support. As indicated by XEP-0167, we retain the same payload ids | 1438 // codecs we support. As indicated by XEP-0167, we retain the same payload ids |
1435 // from the offer in the answer. | 1439 // from the offer in the answer. |
1436 std::unique_ptr<SessionDescription> answer(new SessionDescription()); | 1440 std::unique_ptr<SessionDescription> answer(new SessionDescription()); |
1437 | 1441 |
1438 StreamParamsVec current_streams; | 1442 StreamParamsVec current_streams; |
1439 GetCurrentStreamParams(current_description, ¤t_streams); | 1443 GetCurrentStreamParams(current_description, ¤t_streams); |
1440 | 1444 |
1441 if (offer) { | 1445 // If the offer supports BUNDLE, and we want to use it too, create a BUNDLE |
1442 ContentInfos::const_iterator it = offer->contents().begin(); | 1446 // group in the answer with the appropriate content names. |
1443 for (; it != offer->contents().end(); ++it) { | 1447 const ContentGroup* offer_bundle = offer->GetGroupByName(GROUP_TYPE_BUNDLE); |
1444 if (IsMediaContentOfType(&*it, MEDIA_TYPE_AUDIO)) { | 1448 ContentGroup answer_bundle(GROUP_TYPE_BUNDLE); |
1445 if (!AddAudioContentForAnswer(offer, options, current_description, | 1449 // Transport info shared by the bundle group. |
1446 ¤t_streams, answer.get())) { | 1450 std::unique_ptr<TransportInfo> bundle_transport; |
1447 return NULL; | 1451 |
1448 } | 1452 ContentInfos::const_iterator it = offer->contents().begin(); |
1449 } else if (IsMediaContentOfType(&*it, MEDIA_TYPE_VIDEO)) { | 1453 for (; it != offer->contents().end(); ++it) { |
1450 if (!AddVideoContentForAnswer(offer, options, current_description, | 1454 if (IsMediaContentOfType(&*it, MEDIA_TYPE_AUDIO)) { |
1451 ¤t_streams, answer.get())) { | 1455 if (!AddAudioContentForAnswer(offer, options, current_description, |
1452 return NULL; | 1456 bundle_transport.get(), ¤t_streams, |
1453 } | 1457 answer.get())) { |
1454 } else { | 1458 return NULL; |
1455 RTC_DCHECK(IsMediaContentOfType(&*it, MEDIA_TYPE_DATA)); | |
1456 if (!AddDataContentForAnswer(offer, options, current_description, | |
1457 ¤t_streams, answer.get())) { | |
1458 return NULL; | |
1459 } | |
1460 } | 1459 } |
| 1460 } else if (IsMediaContentOfType(&*it, MEDIA_TYPE_VIDEO)) { |
| 1461 if (!AddVideoContentForAnswer(offer, options, current_description, |
| 1462 bundle_transport.get(), ¤t_streams, |
| 1463 answer.get())) { |
| 1464 return NULL; |
| 1465 } |
| 1466 } else { |
| 1467 RTC_DCHECK(IsMediaContentOfType(&*it, MEDIA_TYPE_DATA)); |
| 1468 if (!AddDataContentForAnswer(offer, options, current_description, |
| 1469 bundle_transport.get(), ¤t_streams, |
| 1470 answer.get())) { |
| 1471 return NULL; |
| 1472 } |
| 1473 } |
| 1474 // See if we can add the newly generated m= section to the BUNDLE group in |
| 1475 // the answer. |
| 1476 ContentInfo& added = answer->contents().back(); |
| 1477 if (!added.rejected && options.bundle_enabled && offer_bundle && |
| 1478 offer_bundle->HasContentName(added.name)) { |
| 1479 answer_bundle.AddContentName(added.name); |
| 1480 bundle_transport.reset( |
| 1481 new TransportInfo(*answer->GetTransportInfoByName(added.name))); |
1461 } | 1482 } |
1462 } | 1483 } |
1463 | 1484 |
1464 // If the offer supports BUNDLE, and we want to use it too, create a BUNDLE | 1485 // Only put BUNDLE group in answer if nonempty. |
1465 // group in the answer with the appropriate content names. | 1486 if (answer_bundle.FirstContentName()) { |
1466 if (offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled) { | 1487 answer->AddGroup(answer_bundle); |
1467 const ContentGroup* offer_bundle = offer->GetGroupByName(GROUP_TYPE_BUNDLE); | 1488 |
1468 ContentGroup answer_bundle(GROUP_TYPE_BUNDLE); | 1489 // Share the same ICE credentials and crypto params across all contents, |
1469 for (ContentInfos::const_iterator content = answer->contents().begin(); | 1490 // as BUNDLE requires. |
1470 content != answer->contents().end(); ++content) { | 1491 if (!UpdateTransportInfoForBundle(answer_bundle, answer.get())) { |
1471 if (!content->rejected && offer_bundle->HasContentName(content->name)) { | 1492 LOG(LS_ERROR) << "CreateAnswer failed to UpdateTransportInfoForBundle."; |
1472 answer_bundle.AddContentName(content->name); | 1493 return NULL; |
1473 } | |
1474 } | 1494 } |
1475 if (answer_bundle.FirstContentName()) { | |
1476 answer->AddGroup(answer_bundle); | |
1477 | 1495 |
1478 // Share the same ICE credentials and crypto params across all contents, | 1496 if (!UpdateCryptoParamsForBundle(answer_bundle, answer.get())) { |
1479 // as BUNDLE requires. | 1497 LOG(LS_ERROR) << "CreateAnswer failed to UpdateCryptoParamsForBundle."; |
1480 if (!UpdateTransportInfoForBundle(answer_bundle, answer.get())) { | 1498 return NULL; |
1481 LOG(LS_ERROR) << "CreateAnswer failed to UpdateTransportInfoForBundle."; | |
1482 return NULL; | |
1483 } | |
1484 | |
1485 if (!UpdateCryptoParamsForBundle(answer_bundle, answer.get())) { | |
1486 LOG(LS_ERROR) << "CreateAnswer failed to UpdateCryptoParamsForBundle."; | |
1487 return NULL; | |
1488 } | |
1489 } | 1499 } |
1490 } | 1500 } |
1491 | 1501 |
1492 return answer.release(); | 1502 return answer.release(); |
1493 } | 1503 } |
1494 | 1504 |
1495 const AudioCodecs& MediaSessionDescriptionFactory::GetAudioCodecsForOffer( | 1505 const AudioCodecs& MediaSessionDescriptionFactory::GetAudioCodecsForOffer( |
1496 const RtpTransceiverDirection& direction) const { | 1506 const RtpTransceiverDirection& direction) const { |
1497 // If stream is inactive - generate list as if sendrecv. | 1507 // If stream is inactive - generate list as if sendrecv. |
1498 if (direction.send == direction.recv) { | 1508 if (direction.send == direction.recv) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1627 LOG(LS_ERROR) | 1637 LOG(LS_ERROR) |
1628 << "Failed to AddTransportOffer, content name=" << content_name; | 1638 << "Failed to AddTransportOffer, content name=" << content_name; |
1629 } | 1639 } |
1630 return ret; | 1640 return ret; |
1631 } | 1641 } |
1632 | 1642 |
1633 TransportDescription* MediaSessionDescriptionFactory::CreateTransportAnswer( | 1643 TransportDescription* MediaSessionDescriptionFactory::CreateTransportAnswer( |
1634 const std::string& content_name, | 1644 const std::string& content_name, |
1635 const SessionDescription* offer_desc, | 1645 const SessionDescription* offer_desc, |
1636 const TransportOptions& transport_options, | 1646 const TransportOptions& transport_options, |
1637 const SessionDescription* current_desc) const { | 1647 const SessionDescription* current_desc, |
| 1648 bool require_transport_attributes) const { |
1638 if (!transport_desc_factory_) | 1649 if (!transport_desc_factory_) |
1639 return NULL; | 1650 return NULL; |
1640 const TransportDescription* offer_tdesc = | 1651 const TransportDescription* offer_tdesc = |
1641 GetTransportDescription(content_name, offer_desc); | 1652 GetTransportDescription(content_name, offer_desc); |
1642 const TransportDescription* current_tdesc = | 1653 const TransportDescription* current_tdesc = |
1643 GetTransportDescription(content_name, current_desc); | 1654 GetTransportDescription(content_name, current_desc); |
1644 return | 1655 return transport_desc_factory_->CreateAnswer(offer_tdesc, transport_options, |
1645 transport_desc_factory_->CreateAnswer(offer_tdesc, transport_options, | 1656 require_transport_attributes, |
1646 current_tdesc); | 1657 current_tdesc); |
1647 } | 1658 } |
1648 | 1659 |
1649 bool MediaSessionDescriptionFactory::AddTransportAnswer( | 1660 bool MediaSessionDescriptionFactory::AddTransportAnswer( |
1650 const std::string& content_name, | 1661 const std::string& content_name, |
1651 const TransportDescription& transport_desc, | 1662 const TransportDescription& transport_desc, |
1652 SessionDescription* answer_desc) const { | 1663 SessionDescription* answer_desc) const { |
1653 if (!answer_desc->AddTransportInfo(TransportInfo(content_name, | 1664 if (!answer_desc->AddTransportInfo(TransportInfo(content_name, |
1654 transport_desc))) { | 1665 transport_desc))) { |
1655 LOG(LS_ERROR) | 1666 LOG(LS_ERROR) |
1656 << "Failed to AddTransportAnswer, content name=" << content_name; | 1667 << "Failed to AddTransportAnswer, content name=" << content_name; |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1831 current_description, desc)) { | 1842 current_description, desc)) { |
1832 return false; | 1843 return false; |
1833 } | 1844 } |
1834 return true; | 1845 return true; |
1835 } | 1846 } |
1836 | 1847 |
1837 bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( | 1848 bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( |
1838 const SessionDescription* offer, | 1849 const SessionDescription* offer, |
1839 const MediaSessionOptions& options, | 1850 const MediaSessionOptions& options, |
1840 const SessionDescription* current_description, | 1851 const SessionDescription* current_description, |
| 1852 const TransportInfo* bundle_transport, |
1841 StreamParamsVec* current_streams, | 1853 StreamParamsVec* current_streams, |
1842 SessionDescription* answer) const { | 1854 SessionDescription* answer) const { |
1843 const ContentInfo* audio_content = GetFirstAudioContent(offer); | 1855 const ContentInfo* audio_content = GetFirstAudioContent(offer); |
1844 const AudioContentDescription* offer_audio = | 1856 const AudioContentDescription* offer_audio = |
1845 static_cast<const AudioContentDescription*>(audio_content->description); | 1857 static_cast<const AudioContentDescription*>(audio_content->description); |
1846 | 1858 |
1847 std::unique_ptr<TransportDescription> audio_transport(CreateTransportAnswer( | 1859 std::unique_ptr<TransportDescription> audio_transport( |
1848 audio_content->name, offer, | 1860 CreateTransportAnswer(audio_content->name, offer, |
1849 GetTransportOptions(options, audio_content->name), current_description)); | 1861 GetTransportOptions(options, audio_content->name), |
| 1862 current_description, bundle_transport != nullptr)); |
1850 if (!audio_transport) { | 1863 if (!audio_transport) { |
1851 return false; | 1864 return false; |
1852 } | 1865 } |
1853 | 1866 |
1854 // Pick codecs based on the requested communications direction in the offer. | 1867 // Pick codecs based on the requested communications direction in the offer. |
1855 const bool wants_send = | 1868 const bool wants_send = |
1856 options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_; | 1869 options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_; |
1857 auto wants_rtd = RtpTransceiverDirection(wants_send, options.recv_audio); | 1870 auto wants_rtd = RtpTransceiverDirection(wants_send, options.recv_audio); |
1858 auto offer_rtd = | 1871 auto offer_rtd = |
1859 RtpTransceiverDirection::FromMediaContentDirection( | 1872 RtpTransceiverDirection::FromMediaContentDirection( |
(...skipping 18 matching lines...) Expand all Loading... |
1878 sdes_policy, | 1891 sdes_policy, |
1879 GetCryptos(GetFirstAudioContentDescription(current_description)), | 1892 GetCryptos(GetFirstAudioContentDescription(current_description)), |
1880 audio_rtp_extensions_, | 1893 audio_rtp_extensions_, |
1881 current_streams, | 1894 current_streams, |
1882 add_legacy_, | 1895 add_legacy_, |
1883 bundle_enabled, | 1896 bundle_enabled, |
1884 audio_answer.get())) { | 1897 audio_answer.get())) { |
1885 return false; // Fails the session setup. | 1898 return false; // Fails the session setup. |
1886 } | 1899 } |
1887 | 1900 |
| 1901 bool secure = bundle_transport ? bundle_transport->description.secure() |
| 1902 : audio_transport->secure(); |
1888 bool rejected = !options.has_audio() || audio_content->rejected || | 1903 bool rejected = !options.has_audio() || audio_content->rejected || |
1889 !IsMediaProtocolSupported(MEDIA_TYPE_AUDIO, | 1904 !IsMediaProtocolSupported(MEDIA_TYPE_AUDIO, |
1890 audio_answer->protocol(), | 1905 audio_answer->protocol(), secure); |
1891 audio_transport->secure()); | |
1892 if (!rejected) { | 1906 if (!rejected) { |
1893 AddTransportAnswer(audio_content->name, *(audio_transport.get()), answer); | 1907 AddTransportAnswer(audio_content->name, *(audio_transport.get()), answer); |
1894 } else { | 1908 } else { |
1895 // RFC 3264 | 1909 // RFC 3264 |
1896 // The answer MUST contain the same number of m-lines as the offer. | 1910 // The answer MUST contain the same number of m-lines as the offer. |
1897 LOG(LS_INFO) << "Audio is not supported in the answer."; | 1911 LOG(LS_INFO) << "Audio is not supported in the answer."; |
1898 } | 1912 } |
1899 | 1913 |
1900 answer->AddContent(audio_content->name, audio_content->type, rejected, | 1914 answer->AddContent(audio_content->name, audio_content->type, rejected, |
1901 audio_answer.release()); | 1915 audio_answer.release()); |
1902 return true; | 1916 return true; |
1903 } | 1917 } |
1904 | 1918 |
1905 bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( | 1919 bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( |
1906 const SessionDescription* offer, | 1920 const SessionDescription* offer, |
1907 const MediaSessionOptions& options, | 1921 const MediaSessionOptions& options, |
1908 const SessionDescription* current_description, | 1922 const SessionDescription* current_description, |
| 1923 const TransportInfo* bundle_transport, |
1909 StreamParamsVec* current_streams, | 1924 StreamParamsVec* current_streams, |
1910 SessionDescription* answer) const { | 1925 SessionDescription* answer) const { |
1911 const ContentInfo* video_content = GetFirstVideoContent(offer); | 1926 const ContentInfo* video_content = GetFirstVideoContent(offer); |
1912 std::unique_ptr<TransportDescription> video_transport(CreateTransportAnswer( | 1927 std::unique_ptr<TransportDescription> video_transport( |
1913 video_content->name, offer, | 1928 CreateTransportAnswer(video_content->name, offer, |
1914 GetTransportOptions(options, video_content->name), current_description)); | 1929 GetTransportOptions(options, video_content->name), |
| 1930 current_description, bundle_transport != nullptr)); |
1915 if (!video_transport) { | 1931 if (!video_transport) { |
1916 return false; | 1932 return false; |
1917 } | 1933 } |
1918 | 1934 |
1919 std::unique_ptr<VideoContentDescription> video_answer( | 1935 std::unique_ptr<VideoContentDescription> video_answer( |
1920 new VideoContentDescription()); | 1936 new VideoContentDescription()); |
1921 // Do not require or create SDES cryptos if DTLS is used. | 1937 // Do not require or create SDES cryptos if DTLS is used. |
1922 cricket::SecurePolicy sdes_policy = | 1938 cricket::SecurePolicy sdes_policy = |
1923 video_transport->secure() ? cricket::SEC_DISABLED : secure(); | 1939 video_transport->secure() ? cricket::SEC_DISABLED : secure(); |
1924 bool bundle_enabled = | 1940 bool bundle_enabled = |
1925 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled; | 1941 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled; |
1926 if (!CreateMediaContentAnswer( | 1942 if (!CreateMediaContentAnswer( |
1927 static_cast<const VideoContentDescription*>( | 1943 static_cast<const VideoContentDescription*>( |
1928 video_content->description), | 1944 video_content->description), |
1929 options, | 1945 options, |
1930 video_codecs_, | 1946 video_codecs_, |
1931 sdes_policy, | 1947 sdes_policy, |
1932 GetCryptos(GetFirstVideoContentDescription(current_description)), | 1948 GetCryptos(GetFirstVideoContentDescription(current_description)), |
1933 video_rtp_extensions_, | 1949 video_rtp_extensions_, |
1934 current_streams, | 1950 current_streams, |
1935 add_legacy_, | 1951 add_legacy_, |
1936 bundle_enabled, | 1952 bundle_enabled, |
1937 video_answer.get())) { | 1953 video_answer.get())) { |
1938 return false; | 1954 return false; |
1939 } | 1955 } |
| 1956 bool secure = bundle_transport ? bundle_transport->description.secure() |
| 1957 : video_transport->secure(); |
1940 bool rejected = !options.has_video() || video_content->rejected || | 1958 bool rejected = !options.has_video() || video_content->rejected || |
1941 !IsMediaProtocolSupported(MEDIA_TYPE_VIDEO, | 1959 !IsMediaProtocolSupported(MEDIA_TYPE_VIDEO, |
1942 video_answer->protocol(), | 1960 video_answer->protocol(), secure); |
1943 video_transport->secure()); | |
1944 if (!rejected) { | 1961 if (!rejected) { |
1945 if (!AddTransportAnswer(video_content->name, *(video_transport.get()), | 1962 if (!AddTransportAnswer(video_content->name, *(video_transport.get()), |
1946 answer)) { | 1963 answer)) { |
1947 return false; | 1964 return false; |
1948 } | 1965 } |
1949 video_answer->set_bandwidth(options.video_bandwidth); | 1966 video_answer->set_bandwidth(options.video_bandwidth); |
1950 } else { | 1967 } else { |
1951 // RFC 3264 | 1968 // RFC 3264 |
1952 // The answer MUST contain the same number of m-lines as the offer. | 1969 // The answer MUST contain the same number of m-lines as the offer. |
1953 LOG(LS_INFO) << "Video is not supported in the answer."; | 1970 LOG(LS_INFO) << "Video is not supported in the answer."; |
1954 } | 1971 } |
1955 answer->AddContent(video_content->name, video_content->type, rejected, | 1972 answer->AddContent(video_content->name, video_content->type, rejected, |
1956 video_answer.release()); | 1973 video_answer.release()); |
1957 return true; | 1974 return true; |
1958 } | 1975 } |
1959 | 1976 |
1960 bool MediaSessionDescriptionFactory::AddDataContentForAnswer( | 1977 bool MediaSessionDescriptionFactory::AddDataContentForAnswer( |
1961 const SessionDescription* offer, | 1978 const SessionDescription* offer, |
1962 const MediaSessionOptions& options, | 1979 const MediaSessionOptions& options, |
1963 const SessionDescription* current_description, | 1980 const SessionDescription* current_description, |
| 1981 const TransportInfo* bundle_transport, |
1964 StreamParamsVec* current_streams, | 1982 StreamParamsVec* current_streams, |
1965 SessionDescription* answer) const { | 1983 SessionDescription* answer) const { |
1966 const ContentInfo* data_content = GetFirstDataContent(offer); | 1984 const ContentInfo* data_content = GetFirstDataContent(offer); |
1967 std::unique_ptr<TransportDescription> data_transport(CreateTransportAnswer( | 1985 std::unique_ptr<TransportDescription> data_transport( |
1968 data_content->name, offer, | 1986 CreateTransportAnswer(data_content->name, offer, |
1969 GetTransportOptions(options, data_content->name), current_description)); | 1987 GetTransportOptions(options, data_content->name), |
| 1988 current_description, bundle_transport != nullptr)); |
1970 if (!data_transport) { | 1989 if (!data_transport) { |
1971 return false; | 1990 return false; |
1972 } | 1991 } |
1973 bool is_sctp = (options.data_channel_type == DCT_SCTP); | 1992 bool is_sctp = (options.data_channel_type == DCT_SCTP); |
1974 std::vector<DataCodec> data_codecs(data_codecs_); | 1993 std::vector<DataCodec> data_codecs(data_codecs_); |
1975 FilterDataCodecs(&data_codecs, is_sctp); | 1994 FilterDataCodecs(&data_codecs, is_sctp); |
1976 | 1995 |
1977 std::unique_ptr<DataContentDescription> data_answer( | 1996 std::unique_ptr<DataContentDescription> data_answer( |
1978 new DataContentDescription()); | 1997 new DataContentDescription()); |
1979 // Do not require or create SDES cryptos if DTLS is used. | 1998 // Do not require or create SDES cryptos if DTLS is used. |
(...skipping 15 matching lines...) Expand all Loading... |
1995 data_answer.get())) { | 2014 data_answer.get())) { |
1996 return false; // Fails the session setup. | 2015 return false; // Fails the session setup. |
1997 } | 2016 } |
1998 | 2017 |
1999 // Respond with sctpmap if the offer uses sctpmap. | 2018 // Respond with sctpmap if the offer uses sctpmap. |
2000 const DataContentDescription* offer_data_description = | 2019 const DataContentDescription* offer_data_description = |
2001 static_cast<const DataContentDescription*>(data_content->description); | 2020 static_cast<const DataContentDescription*>(data_content->description); |
2002 bool offer_uses_sctpmap = offer_data_description->use_sctpmap(); | 2021 bool offer_uses_sctpmap = offer_data_description->use_sctpmap(); |
2003 data_answer->set_use_sctpmap(offer_uses_sctpmap); | 2022 data_answer->set_use_sctpmap(offer_uses_sctpmap); |
2004 | 2023 |
| 2024 bool secure = bundle_transport ? bundle_transport->description.secure() |
| 2025 : data_transport->secure(); |
| 2026 |
2005 bool rejected = !options.has_data() || data_content->rejected || | 2027 bool rejected = !options.has_data() || data_content->rejected || |
2006 !IsMediaProtocolSupported(MEDIA_TYPE_DATA, | 2028 !IsMediaProtocolSupported(MEDIA_TYPE_DATA, |
2007 data_answer->protocol(), | 2029 data_answer->protocol(), secure); |
2008 data_transport->secure()); | |
2009 if (!rejected) { | 2030 if (!rejected) { |
2010 data_answer->set_bandwidth(options.data_bandwidth); | 2031 data_answer->set_bandwidth(options.data_bandwidth); |
2011 if (!AddTransportAnswer(data_content->name, *(data_transport.get()), | 2032 if (!AddTransportAnswer(data_content->name, *(data_transport.get()), |
2012 answer)) { | 2033 answer)) { |
2013 return false; | 2034 return false; |
2014 } | 2035 } |
2015 } else { | 2036 } else { |
2016 // RFC 3264 | 2037 // RFC 3264 |
2017 // The answer MUST contain the same number of m-lines as the offer. | 2038 // The answer MUST contain the same number of m-lines as the offer. |
2018 LOG(LS_INFO) << "Data is not supported in the answer."; | 2039 LOG(LS_INFO) << "Data is not supported in the answer."; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2175 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); | 2196 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); |
2176 } | 2197 } |
2177 | 2198 |
2178 DataContentDescription* GetFirstDataContentDescription( | 2199 DataContentDescription* GetFirstDataContentDescription( |
2179 SessionDescription* sdesc) { | 2200 SessionDescription* sdesc) { |
2180 return static_cast<DataContentDescription*>( | 2201 return static_cast<DataContentDescription*>( |
2181 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); | 2202 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); |
2182 } | 2203 } |
2183 | 2204 |
2184 } // namespace cricket | 2205 } // namespace cricket |
OLD | NEW |