From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs | 298 ++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs (limited to 'dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs') diff --git a/dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs b/dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs new file mode 100644 index 0000000000..20a13900a2 --- /dev/null +++ b/dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs @@ -0,0 +1,298 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +extern crate libc; +extern crate nserror; +extern crate rsdparsa; + +use std::ffi::CString; +use std::os::raw::c_char; +use std::ptr; + +use libc::size_t; + +use std::rc::Rc; + +use std::convert::{TryFrom, TryInto}; + +use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_OK}; +use rsdparsa::address::ExplicitlyTypedAddress; +use rsdparsa::anonymizer::{AnonymizingClone, StatefulSdpAnonymizer}; +use rsdparsa::attribute_type::SdpAttribute; +use rsdparsa::error::SdpParserError; +use rsdparsa::media_type::{SdpMediaValue, SdpProtocolValue}; +use rsdparsa::{SdpBandwidth, SdpSession, SdpTiming}; + +#[macro_use] +extern crate log; + +pub mod attribute; +pub mod media_section; +pub mod network; +pub mod types; + +use network::{ + get_bandwidth, origin_view_helper, RustAddressType, RustSdpConnection, RustSdpOrigin, +}; +pub use types::{StringView, NULL_STRING}; + +#[no_mangle] +pub unsafe extern "C" fn parse_sdp( + sdp: StringView, + fail_on_warning: bool, + session: *mut *const SdpSession, + parser_error: *mut *const SdpParserError, +) -> nsresult { + let sdp_str: String = match sdp.try_into() { + Ok(string) => string, + Err(boxed_error) => { + *session = ptr::null(); + *parser_error = Box::into_raw(Box::new(SdpParserError::Sequence { + message: format!("{}", boxed_error), + line_number: 0, + })); + return NS_ERROR_INVALID_ARG; + } + }; + + let parser_result = rsdparsa::parse_sdp(&sdp_str, fail_on_warning); + match parser_result { + Ok(mut parsed) => { + *parser_error = match parsed.warnings.len() { + 0 => ptr::null(), + _ => Box::into_raw(Box::new(parsed.warnings.remove(0))), + }; + *session = Rc::into_raw(Rc::new(parsed)); + NS_OK + } + Err(e) => { + *session = ptr::null(); + error!("Error parsing SDP in rust: {}", e); + *parser_error = Box::into_raw(Box::new(e)); + NS_ERROR_INVALID_ARG + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn create_anonymized_sdp_clone( + session: *const SdpSession, +) -> *const SdpSession { + Rc::into_raw(Rc::new( + (*session).masked_clone(&mut StatefulSdpAnonymizer::new()), + )) +} + +#[no_mangle] +pub unsafe extern "C" fn create_sdp_clone(session: *const SdpSession) -> *const SdpSession { + Rc::into_raw(Rc::new((*session).clone())) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_free_session(sdp_ptr: *mut SdpSession) { + let sdp = Rc::from_raw(sdp_ptr); + drop(sdp); +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_new_reference(session: *mut SdpSession) -> *const SdpSession { + let original = Rc::from_raw(session); + let ret = Rc::into_raw(Rc::clone(&original)); + Rc::into_raw(original); // So the original reference doesn't get dropped + ret +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_error_line_num(parser_error: *mut SdpParserError) -> size_t { + match *parser_error { + SdpParserError::Line { line_number, .. } + | SdpParserError::Unsupported { line_number, .. } + | SdpParserError::Sequence { line_number, .. } => line_number, + } +} + +#[no_mangle] +// Callee must check that a nullptr is not returned +pub unsafe extern "C" fn sdp_get_error_message(parser_error: *mut SdpParserError) -> *mut c_char { + let message = format!("{}", *parser_error); + return match CString::new(message.as_str()) { + Ok(c_char_ptr) => c_char_ptr.into_raw(), + Err(_) => 0 as *mut c_char, + }; +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_free_error_message(message: *mut c_char) { + if message != 0 as *mut c_char { + let _tmp = CString::from_raw(message); + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_free_error(parser_error: *mut SdpParserError) { + let e = Box::from_raw(parser_error); + drop(e); +} + +#[no_mangle] +pub unsafe extern "C" fn get_version(session: *const SdpSession) -> u64 { + (*session).get_version() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_origin(session: *const SdpSession) -> RustSdpOrigin { + origin_view_helper((*session).get_origin()) +} + +#[no_mangle] +pub unsafe extern "C" fn session_view(session: *const SdpSession) -> StringView { + StringView::from((*session).get_session()) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_session_has_connection(session: *const SdpSession) -> bool { + (*session).connection.is_some() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_session_connection( + session: *const SdpSession, + connection: *mut RustSdpConnection, +) -> nsresult { + match (*session).connection { + Some(ref c) => { + *connection = RustSdpConnection::from(c); + NS_OK + } + None => NS_ERROR_INVALID_ARG, + } +} + +#[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, + address: StringView, +) -> nsresult { + let addr_type = match RustAddressType::try_from(addr_type) { + Ok(a) => a.into(), + Err(e) => { + return e; + } + }; + let address_string: String = match address.try_into() { + Ok(x) => x, + Err(boxed_error) => { + error!("Error while parsing string, description: {}", boxed_error); + return NS_ERROR_INVALID_ARG; + } + }; + let address = match ExplicitlyTypedAddress::try_from((addr_type, address_string.as_str())) { + Ok(a) => a, + Err(_) => { + 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 + 21 => SdpProtocolValue::UdpTlsRtpSavp, // Protocol::kUdpTlsRtpSavp + 22 => SdpProtocolValue::TcpDtlsRtpSavp, // Protocol::kTcpDtlsRtpSavp + 24 => SdpProtocolValue::UdpTlsRtpSavpf, // Protocol::kUdpTlsRtpSavpf + 25 => SdpProtocolValue::TcpDtlsRtpSavpf, // Protocol::kTcpTlsRtpSavpf + 37 => SdpProtocolValue::DtlsSctp, // Protocol::kDtlsSctp + 38 => SdpProtocolValue::UdpDtlsSctp, // Protocol::kUdpDtlsSctp + 39 => SdpProtocolValue::TcpDtlsSctp, // Protocol::kTcpDtlsSctp + _ => { + return NS_ERROR_INVALID_ARG; + } + }; + let direction = match direction { + 1 => SdpAttribute::Sendonly, + 2 => SdpAttribute::Recvonly, + 3 => SdpAttribute::Sendrecv, + _ => { + return NS_ERROR_INVALID_ARG; + } + }; + + match (*session).add_media(media_type, direction, port as u32, protocol, address) { + Ok(_) => NS_OK, + Err(_) => NS_ERROR_INVALID_ARG, + } +} + +#[repr(C)] +#[derive(Clone)] +pub struct RustSdpTiming { + pub start: u64, + pub stop: u64, +} + +impl<'a> From<&'a SdpTiming> for RustSdpTiming { + fn from(timing: &SdpTiming) -> Self { + RustSdpTiming { + start: timing.start, + stop: timing.stop, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_session_has_timing(session: *const SdpSession) -> bool { + (*session).timing.is_some() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_session_timing( + session: *const SdpSession, + timing: *mut RustSdpTiming, +) -> nsresult { + match (*session).timing { + Some(ref t) => { + *timing = RustSdpTiming::from(t); + NS_OK + } + None => NS_ERROR_INVALID_ARG, + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_media_section_count(session: *const SdpSession) -> size_t { + (*session).media.len() +} + +#[no_mangle] +pub unsafe extern "C" fn get_sdp_bandwidth( + session: *const SdpSession, + bandwidth_type: *const c_char, +) -> u32 { + get_bandwidth(&(*session).bandwidth, bandwidth_type) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_session_bandwidth_vec( + session: *const SdpSession, +) -> *const Vec { + &(*session).bandwidth +} + +#[no_mangle] +pub unsafe extern "C" fn get_sdp_session_attributes( + session: *const SdpSession, +) -> *const Vec { + &(*session).attribute +} -- cgit v1.2.3