Bug 1436080: Implemented RsdparsaSdp::AddMediaSection, r=dminor

Implemented RsdparsaSdp::AddMediaSection
Added sdp_add_media_section to Rust/C++ glue code
Added SdpSession::add_media in Rust
Added C++ unit test CheckAddMediaSection

MozReview-Commit-ID: 8cUviY3atsb

--HG--
extra : rebase_source : 8efee17758cdfd4927f630c383ec281db5a6a9ef
This commit is contained in:
Johannes Willbold 2018-06-14 11:20:50 -07:00
parent 0331e56e23
commit 6b5105b7a1
5 changed files with 190 additions and 4 deletions

View File

@ -3983,6 +3983,80 @@ TEST_P(NewSdpTest, CheckClearCodecs) {
HasAttribute(SdpAttribute::kRtpmapAttribute));
}
TEST_P(NewSdpTest, CheckAddMediaSection) {
ParseSdp(kBasicAudioVideoOffer);
ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
<< "Wrong number of media sections";
mSdp->AddMediaSection(SdpMediaSection::kVideo,
SdpDirectionAttribute::Direction::kSendrecv,
58000, SdpMediaSection::kUdpDtlsSctp,sdp::kIPv4,
"127.0.0.1");
ASSERT_EQ(4U, mSdp->GetMediaSectionCount())
<< "Wrong number of media sections after adding media section";
const SdpMediaSection& newMediaSection = mSdp->GetMediaSection(3);
ASSERT_EQ(SdpMediaSection::kVideo, newMediaSection.GetMediaType());
ASSERT_EQ(SdpDirectionAttribute::Direction::kSendrecv,
newMediaSection.GetDirectionAttribute().mValue);
ASSERT_EQ(58000U, newMediaSection.GetPort());
ASSERT_EQ(SdpMediaSection::kUdpDtlsSctp, newMediaSection.GetProtocol());
ASSERT_EQ(sdp::kIPv4, newMediaSection.GetConnection().GetAddrType());
ASSERT_EQ("127.0.0.1", newMediaSection.GetConnection().GetAddress());
mSdp->AddMediaSection(SdpMediaSection::kAudio,
SdpDirectionAttribute::Direction::kSendonly,
14006, SdpMediaSection::kTcpTlsRtpSavpf, sdp::kIPv6,
"2607:f8b0:4004:801::2013");
ASSERT_EQ(5U, mSdp->GetMediaSectionCount())
<< "Wrong number of media sections after adding media section";
const SdpMediaSection& nextNewMediaSection = mSdp->GetMediaSection(4);
ASSERT_EQ(SdpMediaSection::kAudio, nextNewMediaSection.GetMediaType());
ASSERT_EQ(SdpDirectionAttribute::Direction::kSendonly,
nextNewMediaSection.GetDirectionAttribute().mValue);
ASSERT_EQ(14006U, nextNewMediaSection.GetPort());
ASSERT_EQ(SdpMediaSection::kTcpTlsRtpSavpf,
nextNewMediaSection.GetProtocol());
ASSERT_EQ(sdp::kIPv6, nextNewMediaSection.GetConnection().GetAddrType());
ASSERT_EQ("2607:f8b0:4004:801::2013",
nextNewMediaSection.GetConnection().GetAddress());
if(!IsParsingWithSipccParser()) {
// All following AddMediaSection calls are expected to fail
// SdpMediaSection::kDccpRtpAvp is expected to cause a failure
mSdp->AddMediaSection(SdpMediaSection::kAudio,
SdpDirectionAttribute::Direction::kSendonly,
14006, SdpMediaSection::kDccpRtpAvp, sdp::kIPv6,
"2607:f8b0:4004:801::2013");
ASSERT_EQ(5U, mSdp->GetMediaSectionCount())
<< "Wrong number of media sections after adding media section";
// sdp::kAddrTypeNone is expected to cause a failure
mSdp->AddMediaSection(SdpMediaSection::kAudio,
SdpDirectionAttribute::Direction::kSendonly,
14006, SdpMediaSection::kDtlsSctp, sdp::kAddrTypeNone,
"2607:f8b0:4004:801::2013");
ASSERT_EQ(5U, mSdp->GetMediaSectionCount())
<< "Wrong number of media sections after adding media section";
// "NOT:AN.IP.ADDRESS" is expected to cause a failure
mSdp->AddMediaSection(SdpMediaSection::kAudio,
SdpDirectionAttribute::Direction::kSendonly,
14006, SdpMediaSection::kTcpTlsRtpSavpf, sdp::kIPv6,
"NOT:AN.IP.ADDRESS");
ASSERT_EQ(5U, mSdp->GetMediaSectionCount())
<< "Wrong number of media sections after adding media section";
}
}
TEST(NewSdpTestNoFixture, CheckAttributeTypeSerialize) {
for (auto a = static_cast<size_t>(SdpAttribute::kFirstAttribute);
a <= static_cast<size_t>(SdpAttribute::kLastAttribute);

View File

@ -8,6 +8,7 @@
#include "mozilla/UniquePtr.h"
#include "mozilla/Assertions.h"
#include "nsError.h"
#include <iostream>
#include "signaling/src/sdp/SdpErrorHolder.h"
@ -85,8 +86,28 @@ RsdparsaSdp::AddMediaSection(SdpMediaSection::MediaType mediaType,
SdpMediaSection::Protocol protocol,
sdp::AddrType addrType, const std::string& addr)
{
//TODO: See Bug 1436080
MOZ_CRASH("Method not implemented");
StringView rustAddr{addr.c_str(),addr.size()};
auto nr = sdp_add_media_section(mSession.get(),mediaType,dir,port,
protocol,addrType,rustAddr);
if (NS_SUCCEEDED(nr)) {
std::cout << "Hello World" << std::endl;
size_t level = mMediaSections.values.size();
RsdparsaSessionHandle newSessHandle(sdp_new_reference(mSession.get()));
auto rustMediaSection = sdp_get_media_section(mSession.get(), level);
auto mediaSection = new RsdparsaSdpMediaSection(level,
std::move(newSessHandle),
rustMediaSection,
mAttributeList.get());
mMediaSections.values.push_back(mediaSection);
return *mediaSection;
} else {
// Return the last media section if the construction of this one fails
return GetMediaSection(mMediaSections.values.size()-1);
}
}
void

View File

@ -241,6 +241,10 @@ RustAttributeList* get_sdp_session_attributes(const RustSdpSession* aSess);
size_t sdp_media_section_count(const RustSdpSession* aSess);
RustMediaSection* sdp_get_media_section(const RustSdpSession* aSess,
size_t aLevel);
nsresult sdp_add_media_section(RustSdpSession* aSess, uint32_t aMediaType,
uint32_t aDirection, uint32_t aPort,
uint32_t aProtocol, uint32_t aAddrType,
StringView aAddr);
RustSdpMediaValue sdp_rust_get_media_type(const RustMediaSection* aMediaSec);
RustSdpProtocolValue
sdp_get_media_protocol(const RustMediaSection* aMediaSec);

View File

@ -7,6 +7,7 @@ extern crate serde_derive;
extern crate serde;
use std::net::IpAddr;
use std::str::FromStr;
use std::fmt;
pub mod attribute_type;
@ -17,7 +18,8 @@ pub mod unsupported_types;
use attribute_type::{SdpAttribute, SdpAttributeType, parse_attribute};
use error::{SdpParserInternalError, SdpParserError};
use media_type::{SdpMedia, SdpMediaLine, parse_media, parse_media_vector};
use media_type::{SdpMedia, SdpMediaLine, parse_media, parse_media_vector, SdpProtocolValue,
SdpMediaValue, SdpFormatList};
use network::{parse_addrtype, parse_nettype, parse_unicast_addr};
use unsupported_types::{parse_email, parse_information, parse_key, parse_phone, parse_repeat,
parse_uri, parse_zone};
@ -182,6 +184,30 @@ impl SdpSession {
pub fn has_media(&self) -> bool {
!self.media.is_empty()
}
pub fn add_media(&mut self, media_type: SdpMediaValue, direction: SdpAttribute, port: u32,
protocol: SdpProtocolValue, addr: String)
-> Result<(),SdpParserInternalError> {
let mut media = SdpMedia::new(SdpMediaLine {
media: media_type,
port,
port_count: 1,
proto: protocol,
formats: SdpFormatList::Integers(Vec::new()),
});
media.add_attribute(&direction)?;
media.set_connection(&SdpConnection {
addr: IpAddr::from_str(addr.as_str())?,
ttl: None,
amount: None,
})?;
self.media.push(media);
Ok(())
}
}
fn parse_session(value: &str) -> Result<SdpType, SdpParserInternalError> {

View File

@ -15,7 +15,8 @@ use std::rc::Rc;
use nserror::{nsresult, NS_OK, NS_ERROR_INVALID_ARG};
use rsdparsa::{SdpTiming, SdpBandwidth, SdpSession};
use rsdparsa::error::SdpParserError;
use rsdparsa::attribute_type::SdpAttribute;
use rsdparsa::media_type::{SdpMediaValue, SdpProtocolValue};
use rsdparsa::attribute_type::{SdpAttribute};
pub mod types;
pub mod network;
@ -140,6 +141,66 @@ pub unsafe extern "C" fn sdp_get_session_connection(session: *const SdpSession,
}
}
#[no_mangle]
pub unsafe extern "C" fn sdp_add_media_section(session: *mut SdpSession,
media_type: u32, direction: u32,
port: u16, protocol: u32,
addr_type: u32, addr: StringView) -> nsresult {
let addr_str:String = match addr.into() {
Ok(x) => x,
Err(boxed_error) => {
println!("Error while pasing string, description: {:?}", (*boxed_error).description());
return NS_ERROR_INVALID_ARG;
}
};
let media_type = match media_type {
0 => SdpMediaValue::Audio, // MediaType::kAudio
1 => SdpMediaValue::Video, // MediaType::kVideo
3 => SdpMediaValue::Application, // MediaType::kApplication
_ => {
return NS_ERROR_INVALID_ARG;
}
};
let protocol = match protocol {
20 => SdpProtocolValue::RtpSavpf, // Protocol::kRtpSavpf
24 => SdpProtocolValue::UdpTlsRtpSavpf, // Protocol::kUdpTlsRtpSavpf
25 => SdpProtocolValue::TcpTlsRtpSavpf, // Protocol::kTcpTlsRtpSavpf
37 => SdpProtocolValue::DtlsSctp, // Protocol::kDtlsSctp
38 => SdpProtocolValue::UdpDtlsSctp, // Protocol::kUdpDtlsSctp
39 => SdpProtocolValue::TcpDtlsSctp, // Protocol::kTcpDtlsSctp
_ => {
println!("INVALID PROTOCOL");
return NS_ERROR_INVALID_ARG;
}
};
let direction = match direction {
1 => SdpAttribute::Sendonly,
2 => SdpAttribute::Recvonly,
3 => SdpAttribute::Sendrecv,
_ => {
return NS_ERROR_INVALID_ARG;
}
};
// Check that the provided address type is valid. The rust parser will find out
// on his own which address type was provided
match addr_type {
// enum AddrType { kAddrTypeNone, kIPv4, kIPv6 };
// kAddrTypeNone is explicitly not covered as it is an 'invalid' flag
1...2 => (),
_ => {
return NS_ERROR_INVALID_ARG;
}
}
match (*session).add_media(media_type, direction, port as u32, protocol, addr_str) {
Ok(_) => NS_OK,
Err(_) => NS_ERROR_INVALID_ARG
}
}
#[repr(C)]
#[derive(Clone)]
pub struct RustSdpTiming {