attribute.rs (44061B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use libc::{c_float, size_t}; 6 use std::ptr; 7 use std::slice; 8 9 use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_OK}; 10 use rsdparsa::attribute_type::*; 11 use rsdparsa::SdpSession; 12 13 use network::{RustAddress, RustExplicitlyTypedAddress}; 14 use types::StringView; 15 16 #[no_mangle] 17 pub unsafe extern "C" fn num_attributes(session: *const SdpSession) -> u32 { 18 (*session).attribute.len() as u32 19 } 20 21 #[no_mangle] 22 pub unsafe extern "C" fn get_attribute_ptr( 23 session: *const SdpSession, 24 index: u32, 25 ret: *mut *const SdpAttribute, 26 ) -> nsresult { 27 match (&(*session).attribute).get(index as usize) { 28 Some(attribute) => { 29 *ret = attribute as *const SdpAttribute; 30 NS_OK 31 } 32 None => NS_ERROR_INVALID_ARG, 33 } 34 } 35 36 fn count_attribute(attributes: &[SdpAttribute], search: SdpAttributeType) -> usize { 37 let mut count = 0; 38 for attribute in (*attributes).iter() { 39 if SdpAttributeType::from(attribute) == search { 40 count += 1; 41 } 42 } 43 count 44 } 45 46 fn argsearch(attributes: &[SdpAttribute], attribute_type: SdpAttributeType) -> Option<usize> { 47 for (i, attribute) in (*attributes).iter().enumerate() { 48 if SdpAttributeType::from(attribute) == attribute_type { 49 return Some(i); 50 } 51 } 52 None 53 } 54 55 pub unsafe fn has_attribute( 56 attributes: *const Vec<SdpAttribute>, 57 attribute_type: SdpAttributeType, 58 ) -> bool { 59 argsearch((*attributes).as_slice(), attribute_type).is_some() 60 } 61 62 fn get_attribute( 63 attributes: &[SdpAttribute], 64 attribute_type: SdpAttributeType, 65 ) -> Option<&SdpAttribute> { 66 argsearch(attributes, attribute_type).map(|i| &attributes[i]) 67 } 68 69 #[repr(C)] 70 #[derive(Clone, Copy)] 71 pub enum RustSdpAttributeDtlsMessageType { 72 Client, 73 Server, 74 } 75 76 #[repr(C)] 77 #[derive(Clone, Copy)] 78 pub struct RustSdpAttributeDtlsMessage { 79 pub role: u8, 80 pub value: StringView, 81 } 82 83 impl<'a> From<&'a SdpAttributeDtlsMessage> for RustSdpAttributeDtlsMessage { 84 fn from(other: &SdpAttributeDtlsMessage) -> Self { 85 match other { 86 &SdpAttributeDtlsMessage::Client(ref x) => RustSdpAttributeDtlsMessage { 87 role: RustSdpAttributeDtlsMessageType::Client as u8, 88 value: StringView::from(x.as_str()), 89 }, 90 &SdpAttributeDtlsMessage::Server(ref x) => RustSdpAttributeDtlsMessage { 91 role: RustSdpAttributeDtlsMessageType::Server as u8, 92 value: StringView::from(x.as_str()), 93 }, 94 } 95 } 96 } 97 98 #[no_mangle] 99 pub unsafe extern "C" fn sdp_get_dtls_message( 100 attributes: *const Vec<SdpAttribute>, 101 ret: *mut RustSdpAttributeDtlsMessage, 102 ) -> nsresult { 103 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::DtlsMessage); 104 if let Some(&SdpAttribute::DtlsMessage(ref dtls_message)) = attr { 105 *ret = RustSdpAttributeDtlsMessage::from(dtls_message); 106 return NS_OK; 107 } 108 NS_ERROR_INVALID_ARG 109 } 110 111 #[no_mangle] 112 pub unsafe extern "C" fn sdp_get_iceufrag( 113 attributes: *const Vec<SdpAttribute>, 114 ret: *mut StringView, 115 ) -> nsresult { 116 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IceUfrag); 117 if let Some(&SdpAttribute::IceUfrag(ref string)) = attr { 118 *ret = StringView::from(string.as_str()); 119 return NS_OK; 120 } 121 NS_ERROR_INVALID_ARG 122 } 123 124 #[no_mangle] 125 pub unsafe extern "C" fn sdp_get_icepwd( 126 attributes: *const Vec<SdpAttribute>, 127 ret: *mut StringView, 128 ) -> nsresult { 129 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IcePwd); 130 if let Some(&SdpAttribute::IcePwd(ref string)) = attr { 131 *ret = StringView::from(string.as_str()); 132 return NS_OK; 133 } 134 NS_ERROR_INVALID_ARG 135 } 136 137 #[no_mangle] 138 pub unsafe extern "C" fn sdp_get_identity( 139 attributes: *const Vec<SdpAttribute>, 140 ret: *mut StringView, 141 ) -> nsresult { 142 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Identity); 143 if let Some(&SdpAttribute::Identity(ref string)) = attr { 144 *ret = StringView::from(string.as_str()); 145 return NS_OK; 146 } 147 NS_ERROR_INVALID_ARG 148 } 149 150 #[no_mangle] 151 pub unsafe extern "C" fn sdp_get_iceoptions( 152 attributes: *const Vec<SdpAttribute>, 153 ret: *mut *const Vec<String>, 154 ) -> nsresult { 155 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IceOptions); 156 if let Some(&SdpAttribute::IceOptions(ref options)) = attr { 157 *ret = options; 158 return NS_OK; 159 } 160 NS_ERROR_INVALID_ARG 161 } 162 163 #[no_mangle] 164 pub unsafe extern "C" fn sdp_get_maxptime( 165 attributes: *const Vec<SdpAttribute>, 166 ret: *mut u64, 167 ) -> nsresult { 168 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::MaxPtime); 169 if let Some(&SdpAttribute::MaxPtime(ref max_ptime)) = attr { 170 *ret = *max_ptime; 171 return NS_OK; 172 } 173 NS_ERROR_INVALID_ARG 174 } 175 176 #[repr(C)] 177 #[derive(Clone, Copy)] 178 pub struct RustSdpAttributeFingerprint { 179 hash_algorithm: u16, 180 fingerprint: *const Vec<u8>, 181 } 182 183 impl<'a> From<&'a SdpAttributeFingerprint> for RustSdpAttributeFingerprint { 184 fn from(other: &SdpAttributeFingerprint) -> Self { 185 RustSdpAttributeFingerprint { 186 hash_algorithm: other.hash_algorithm as u16, 187 fingerprint: &other.fingerprint, 188 } 189 } 190 } 191 192 #[no_mangle] 193 pub unsafe extern "C" fn sdp_get_fingerprint_count(attributes: *const Vec<SdpAttribute>) -> size_t { 194 count_attribute((*attributes).as_slice(), SdpAttributeType::Fingerprint) 195 } 196 197 #[no_mangle] 198 pub unsafe extern "C" fn sdp_get_fingerprints( 199 attributes: *const Vec<SdpAttribute>, 200 ret_size: size_t, 201 ret_fingerprints: *mut RustSdpAttributeFingerprint, 202 ) { 203 let attrs: Vec<_> = (*attributes) 204 .iter() 205 .filter_map(|x| { 206 if let SdpAttribute::Fingerprint(ref data) = *x { 207 Some(RustSdpAttributeFingerprint::from(data)) 208 } else { 209 None 210 } 211 }) 212 .collect(); 213 let fingerprints = slice::from_raw_parts_mut(ret_fingerprints, ret_size); 214 fingerprints.copy_from_slice(attrs.as_slice()); 215 } 216 217 #[repr(C)] 218 #[derive(Clone)] 219 pub enum RustSdpAttributeSetup { 220 Active, 221 Actpass, 222 Holdconn, 223 Passive, 224 } 225 226 impl<'a> From<&'a SdpAttributeSetup> for RustSdpAttributeSetup { 227 fn from(other: &SdpAttributeSetup) -> Self { 228 match *other { 229 SdpAttributeSetup::Active => RustSdpAttributeSetup::Active, 230 SdpAttributeSetup::Actpass => RustSdpAttributeSetup::Actpass, 231 SdpAttributeSetup::Holdconn => RustSdpAttributeSetup::Holdconn, 232 SdpAttributeSetup::Passive => RustSdpAttributeSetup::Passive, 233 } 234 } 235 } 236 237 #[no_mangle] 238 pub unsafe extern "C" fn sdp_get_setup( 239 attributes: *const Vec<SdpAttribute>, 240 ret: *mut RustSdpAttributeSetup, 241 ) -> nsresult { 242 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Setup); 243 if let Some(&SdpAttribute::Setup(ref setup)) = attr { 244 *ret = RustSdpAttributeSetup::from(setup); 245 return NS_OK; 246 } 247 NS_ERROR_INVALID_ARG 248 } 249 250 #[repr(C)] 251 #[derive(Clone, Copy)] 252 pub struct RustSdpAttributeSsrc { 253 pub id: u32, 254 pub attribute: StringView, 255 pub value: StringView, 256 } 257 258 impl<'a> From<&'a SdpAttributeSsrc> for RustSdpAttributeSsrc { 259 fn from(other: &SdpAttributeSsrc) -> Self { 260 RustSdpAttributeSsrc { 261 id: other.id, 262 attribute: StringView::from(&other.attribute), 263 value: StringView::from(&other.value), 264 } 265 } 266 } 267 268 #[no_mangle] 269 pub unsafe extern "C" fn sdp_get_ssrc_count(attributes: *const Vec<SdpAttribute>) -> size_t { 270 count_attribute((*attributes).as_slice(), SdpAttributeType::Ssrc) 271 } 272 273 #[no_mangle] 274 pub unsafe extern "C" fn sdp_get_ssrcs( 275 attributes: *const Vec<SdpAttribute>, 276 ret_size: size_t, 277 ret_ssrcs: *mut RustSdpAttributeSsrc, 278 ) { 279 let attrs: Vec<_> = (*attributes) 280 .iter() 281 .filter_map(|x| { 282 if let SdpAttribute::Ssrc(ref data) = *x { 283 Some(RustSdpAttributeSsrc::from(data)) 284 } else { 285 None 286 } 287 }) 288 .collect(); 289 let ssrcs = slice::from_raw_parts_mut(ret_ssrcs, ret_size); 290 ssrcs.copy_from_slice(attrs.as_slice()); 291 } 292 293 #[repr(C)] 294 #[derive(Clone, Copy)] 295 pub enum RustSdpSsrcGroupSemantic { 296 Duplication, 297 FlowIdentification, 298 ForwardErrorCorrection, 299 ForwardErrorCorrectionFr, 300 SIM, 301 } 302 303 impl<'a> From<&'a SdpSsrcGroupSemantic> for RustSdpSsrcGroupSemantic { 304 fn from(other: &SdpSsrcGroupSemantic) -> Self { 305 match *other { 306 SdpSsrcGroupSemantic::Duplication => RustSdpSsrcGroupSemantic::Duplication, 307 SdpSsrcGroupSemantic::FlowIdentification => { 308 RustSdpSsrcGroupSemantic::FlowIdentification 309 } 310 SdpSsrcGroupSemantic::ForwardErrorCorrection => { 311 RustSdpSsrcGroupSemantic::ForwardErrorCorrection 312 } 313 SdpSsrcGroupSemantic::ForwardErrorCorrectionFr => { 314 RustSdpSsrcGroupSemantic::ForwardErrorCorrectionFr 315 } 316 SdpSsrcGroupSemantic::Sim => RustSdpSsrcGroupSemantic::SIM, 317 } 318 } 319 } 320 321 #[repr(C)] 322 #[derive(Clone, Copy)] 323 pub struct RustSdpSsrcGroup { 324 pub semantic: RustSdpSsrcGroupSemantic, 325 pub ssrcs: *const Vec<SdpAttributeSsrc>, 326 } 327 328 #[no_mangle] 329 pub unsafe extern "C" fn sdp_get_ssrc_group_count(attributes: *const Vec<SdpAttribute>) -> size_t { 330 count_attribute((*attributes).as_slice(), SdpAttributeType::SsrcGroup) 331 } 332 333 #[no_mangle] 334 pub unsafe extern "C" fn sdp_get_ssrc_groups( 335 attributes: *const Vec<SdpAttribute>, 336 ret_size: size_t, 337 ret_ssrc_groups: *mut RustSdpSsrcGroup, 338 ) { 339 let attrs: Vec<_> = (*attributes) 340 .iter() 341 .filter_map(|x| { 342 if let SdpAttribute::SsrcGroup(ref semantic, ref ssrcs) = *x { 343 Some(RustSdpSsrcGroup { 344 semantic: RustSdpSsrcGroupSemantic::from(semantic), 345 ssrcs: ssrcs, 346 }) 347 } else { 348 None 349 } 350 }) 351 .collect(); 352 let ssrc_groups = slice::from_raw_parts_mut(ret_ssrc_groups, ret_size); 353 ssrc_groups.copy_from_slice(attrs.as_slice()); 354 } 355 356 #[repr(C)] 357 #[derive(Clone, Copy)] 358 pub struct RustSdpAttributeRtpmap { 359 pub payload_type: u8, 360 pub codec_name: StringView, 361 pub frequency: u32, 362 pub channels: u32, 363 } 364 365 impl<'a> From<&'a SdpAttributeRtpmap> for RustSdpAttributeRtpmap { 366 fn from(other: &SdpAttributeRtpmap) -> Self { 367 RustSdpAttributeRtpmap { 368 payload_type: other.payload_type as u8, 369 codec_name: StringView::from(other.codec_name.as_str()), 370 frequency: other.frequency as u32, 371 channels: other.channels.unwrap_or(0), 372 } 373 } 374 } 375 376 #[no_mangle] 377 pub unsafe extern "C" fn sdp_get_rtpmap_count(attributes: *const Vec<SdpAttribute>) -> size_t { 378 count_attribute((*attributes).as_slice(), SdpAttributeType::Rtpmap) 379 } 380 381 #[no_mangle] 382 pub unsafe extern "C" fn sdp_get_rtpmaps( 383 attributes: *const Vec<SdpAttribute>, 384 ret_size: size_t, 385 ret_rtpmaps: *mut RustSdpAttributeRtpmap, 386 ) { 387 let attrs: Vec<_> = (*attributes) 388 .iter() 389 .filter_map(|x| { 390 if let SdpAttribute::Rtpmap(ref data) = *x { 391 Some(RustSdpAttributeRtpmap::from(data)) 392 } else { 393 None 394 } 395 }) 396 .collect(); 397 let rtpmaps = slice::from_raw_parts_mut(ret_rtpmaps, ret_size); 398 rtpmaps.copy_from_slice(attrs.as_slice()); 399 } 400 401 #[repr(C)] 402 #[derive(Clone, Copy)] 403 pub struct RustRtxFmtpParameters { 404 pub apt: u8, 405 pub has_rtx_time: bool, 406 pub rtx_time: u32, 407 } 408 409 #[repr(C)] 410 #[derive(Clone, Copy)] 411 pub struct RustAv1FmtpParameters { 412 pub profile: u8, 413 pub has_profile: bool, 414 pub level_idx: u8, 415 pub has_level_idx: bool, 416 pub tier: u8, 417 pub has_tier: bool, 418 } 419 420 #[repr(C)] 421 #[derive(Clone, Copy)] 422 pub struct RustSdpAttributeFmtpParameters { 423 // H264 424 pub packetization_mode: u32, 425 pub level_asymmetry_allowed: bool, 426 pub profile_level_id: u32, 427 pub max_fs: u32, 428 pub max_cpb: u32, 429 pub max_dpb: u32, 430 pub max_br: u32, 431 pub max_mbps: u32, 432 433 // VP8 and VP9 434 // max_fs, already defined in H264 435 pub max_fr: u32, 436 437 // Opus 438 pub maxplaybackrate: u32, 439 pub maxaveragebitrate: u32, 440 pub usedtx: bool, 441 pub stereo: bool, 442 pub useinbandfec: bool, 443 pub cbr: bool, 444 pub ptime: u32, 445 pub minptime: u32, 446 pub maxptime: u32, 447 448 // telephone-event 449 pub dtmf_tones: StringView, 450 451 // AV1 452 pub av1: RustAv1FmtpParameters, 453 454 // RTX 455 pub rtx: RustRtxFmtpParameters, 456 457 // Red 458 pub encodings: *const Vec<u8>, 459 460 // Unknown 461 pub unknown_tokens: *const Vec<String>, 462 } 463 464 impl<'a> From<&'a SdpAttributeFmtpParameters> for RustSdpAttributeFmtpParameters { 465 fn from(other: &SdpAttributeFmtpParameters) -> Self { 466 let rtx = if let Some(rtx) = other.rtx { 467 RustRtxFmtpParameters { 468 apt: rtx.apt, 469 has_rtx_time: rtx.rtx_time.is_some(), 470 rtx_time: rtx.rtx_time.unwrap_or(0), 471 } 472 } else { 473 RustRtxFmtpParameters { 474 apt: 0, 475 has_rtx_time: false, 476 rtx_time: 0, 477 } 478 }; 479 let av1 = RustAv1FmtpParameters { 480 profile: other.profile.unwrap_or(0), 481 has_profile: other.profile.is_some(), 482 level_idx: other.level_idx.unwrap_or(0), 483 has_level_idx: other.level_idx.is_some(), 484 tier: other.tier.unwrap_or(0), 485 has_tier: other.tier.is_some(), 486 }; 487 488 RustSdpAttributeFmtpParameters { 489 packetization_mode: other.packetization_mode, 490 level_asymmetry_allowed: other.level_asymmetry_allowed, 491 profile_level_id: other.profile_level_id, 492 max_fs: other.max_fs, 493 max_cpb: other.max_cpb, 494 max_dpb: other.max_dpb, 495 max_br: other.max_br, 496 max_mbps: other.max_mbps, 497 usedtx: other.usedtx, 498 stereo: other.stereo, 499 useinbandfec: other.useinbandfec, 500 cbr: other.cbr, 501 max_fr: other.max_fr, 502 maxplaybackrate: other.maxplaybackrate, 503 maxaveragebitrate: other.maxaveragebitrate, 504 ptime: other.ptime, 505 minptime: other.minptime, 506 maxptime: other.maxptime, 507 dtmf_tones: StringView::from(other.dtmf_tones.as_str()), 508 av1, 509 rtx, 510 encodings: &other.encodings, 511 unknown_tokens: &other.unknown_tokens, 512 } 513 } 514 } 515 516 #[repr(C)] 517 #[derive(Clone, Copy)] 518 pub struct RustSdpAttributeFmtp { 519 pub payload_type: u8, 520 pub codec_name: StringView, 521 pub parameters: RustSdpAttributeFmtpParameters, 522 } 523 524 #[no_mangle] 525 pub unsafe extern "C" fn sdp_get_fmtp_count(attributes: *const Vec<SdpAttribute>) -> size_t { 526 count_attribute((*attributes).as_slice(), SdpAttributeType::Fmtp) 527 } 528 529 fn find_payload_type(attributes: &[SdpAttribute], payload_type: u8) -> Option<&SdpAttributeRtpmap> { 530 attributes 531 .iter() 532 .filter_map(|x| { 533 if let SdpAttribute::Rtpmap(ref data) = *x { 534 if data.payload_type == payload_type { 535 Some(data) 536 } else { 537 None 538 } 539 } else { 540 None 541 } 542 }) 543 .next() 544 } 545 546 #[no_mangle] 547 pub unsafe extern "C" fn sdp_get_fmtp( 548 attributes: *const Vec<SdpAttribute>, 549 ret_size: size_t, 550 ret_fmtp: *mut RustSdpAttributeFmtp, 551 ) -> size_t { 552 let fmtps = (*attributes).iter().filter_map(|x| { 553 if let SdpAttribute::Fmtp(ref data) = *x { 554 Some(data) 555 } else { 556 None 557 } 558 }); 559 let mut rust_fmtps = Vec::new(); 560 for fmtp in fmtps { 561 if let Some(rtpmap) = find_payload_type((*attributes).as_slice(), fmtp.payload_type) { 562 rust_fmtps.push(RustSdpAttributeFmtp { 563 payload_type: fmtp.payload_type as u8, 564 codec_name: StringView::from(rtpmap.codec_name.as_str()), 565 parameters: RustSdpAttributeFmtpParameters::from(&fmtp.parameters), 566 }); 567 } 568 } 569 let fmtps = if ret_size <= rust_fmtps.len() { 570 slice::from_raw_parts_mut(ret_fmtp, ret_size) 571 } else { 572 slice::from_raw_parts_mut(ret_fmtp, rust_fmtps.len()) 573 }; 574 fmtps.copy_from_slice(rust_fmtps.as_slice()); 575 fmtps.len() 576 } 577 578 #[no_mangle] 579 pub unsafe extern "C" fn sdp_get_ptime(attributes: *const Vec<SdpAttribute>) -> i64 { 580 for attribute in (*attributes).iter() { 581 if let SdpAttribute::Ptime(time) = *attribute { 582 return time as i64; 583 } 584 } 585 -1 586 } 587 588 #[no_mangle] 589 pub unsafe extern "C" fn sdp_get_max_msg_size(attributes: *const Vec<SdpAttribute>) -> i64 { 590 for attribute in (*attributes).iter() { 591 if let SdpAttribute::MaxMessageSize(max_msg_size) = *attribute { 592 return max_msg_size as i64; 593 } 594 } 595 -1 596 } 597 598 #[no_mangle] 599 pub unsafe extern "C" fn sdp_get_sctp_port(attributes: *const Vec<SdpAttribute>) -> i64 { 600 for attribute in (*attributes).iter() { 601 if let SdpAttribute::SctpPort(port) = *attribute { 602 return port as i64; 603 } 604 } 605 -1 606 } 607 608 #[repr(C)] 609 #[derive(Clone, Copy)] 610 pub struct RustSdpAttributeFlags { 611 pub ice_lite: bool, 612 pub rtcp_mux: bool, 613 pub rtcp_rsize: bool, 614 pub bundle_only: bool, 615 pub end_of_candidates: bool, 616 pub extmap_allow_mixed: bool, 617 } 618 619 #[no_mangle] 620 pub unsafe extern "C" fn sdp_get_attribute_flags( 621 attributes: *const Vec<SdpAttribute>, 622 ) -> RustSdpAttributeFlags { 623 let mut ret = RustSdpAttributeFlags { 624 ice_lite: false, 625 rtcp_mux: false, 626 rtcp_rsize: false, 627 bundle_only: false, 628 end_of_candidates: false, 629 extmap_allow_mixed: false, 630 }; 631 for attribute in (*attributes).iter() { 632 if let SdpAttribute::IceLite = *attribute { 633 ret.ice_lite = true; 634 } else if let SdpAttribute::RtcpMux = *attribute { 635 ret.rtcp_mux = true; 636 } else if let SdpAttribute::RtcpRsize = *attribute { 637 ret.rtcp_rsize = true; 638 } else if let SdpAttribute::BundleOnly = *attribute { 639 ret.bundle_only = true; 640 } else if let SdpAttribute::EndOfCandidates = *attribute { 641 ret.end_of_candidates = true; 642 } else if let SdpAttribute::ExtmapAllowMixed = *attribute { 643 ret.extmap_allow_mixed = true; 644 } 645 } 646 ret 647 } 648 649 #[no_mangle] 650 pub unsafe extern "C" fn sdp_get_mid( 651 attributes: *const Vec<SdpAttribute>, 652 ret: *mut StringView, 653 ) -> nsresult { 654 for attribute in (*attributes).iter() { 655 if let SdpAttribute::Mid(ref data) = *attribute { 656 *ret = StringView::from(data.as_str()); 657 return NS_OK; 658 } 659 } 660 NS_ERROR_INVALID_ARG 661 } 662 663 #[repr(C)] 664 #[derive(Clone, Copy)] 665 pub struct RustSdpAttributeMsid { 666 id: StringView, 667 appdata: StringView, 668 } 669 670 impl<'a> From<&'a SdpAttributeMsid> for RustSdpAttributeMsid { 671 fn from(other: &SdpAttributeMsid) -> Self { 672 RustSdpAttributeMsid { 673 id: StringView::from(other.id.as_str()), 674 appdata: StringView::from(&other.appdata), 675 } 676 } 677 } 678 679 #[no_mangle] 680 pub unsafe extern "C" fn sdp_get_msid_count(attributes: *const Vec<SdpAttribute>) -> size_t { 681 count_attribute((*attributes).as_slice(), SdpAttributeType::Msid) 682 } 683 684 #[no_mangle] 685 pub unsafe extern "C" fn sdp_get_msids( 686 attributes: *const Vec<SdpAttribute>, 687 ret_size: size_t, 688 ret_msids: *mut RustSdpAttributeMsid, 689 ) { 690 let attrs: Vec<_> = (*attributes) 691 .iter() 692 .filter_map(|x| { 693 if let SdpAttribute::Msid(ref data) = *x { 694 Some(RustSdpAttributeMsid::from(data)) 695 } else { 696 None 697 } 698 }) 699 .collect(); 700 let msids = slice::from_raw_parts_mut(ret_msids, ret_size); 701 msids.copy_from_slice(attrs.as_slice()); 702 } 703 704 // TODO: Finish msid attributes once parsing is changed upstream. 705 #[repr(C)] 706 #[derive(Clone, Copy)] 707 pub struct RustSdpAttributeMsidSemantic { 708 pub semantic: StringView, 709 pub msids: *const Vec<String>, 710 } 711 712 impl<'a> From<&'a SdpAttributeMsidSemantic> for RustSdpAttributeMsidSemantic { 713 fn from(other: &SdpAttributeMsidSemantic) -> Self { 714 RustSdpAttributeMsidSemantic { 715 semantic: StringView::from(other.semantic.as_str()), 716 msids: &other.msids, 717 } 718 } 719 } 720 721 #[no_mangle] 722 pub unsafe extern "C" fn sdp_get_msid_semantic_count( 723 attributes: *const Vec<SdpAttribute>, 724 ) -> size_t { 725 count_attribute((*attributes).as_slice(), SdpAttributeType::MsidSemantic) 726 } 727 728 #[no_mangle] 729 pub unsafe extern "C" fn sdp_get_msid_semantics( 730 attributes: *const Vec<SdpAttribute>, 731 ret_size: size_t, 732 ret_msid_semantics: *mut RustSdpAttributeMsidSemantic, 733 ) { 734 let attrs: Vec<_> = (*attributes) 735 .iter() 736 .filter_map(|x| { 737 if let SdpAttribute::MsidSemantic(ref data) = *x { 738 Some(RustSdpAttributeMsidSemantic::from(data)) 739 } else { 740 None 741 } 742 }) 743 .collect(); 744 let msid_semantics = slice::from_raw_parts_mut(ret_msid_semantics, ret_size); 745 msid_semantics.copy_from_slice(attrs.as_slice()); 746 } 747 748 #[repr(C)] 749 #[derive(Clone, Copy)] 750 pub enum RustSdpAttributeGroupSemantic { 751 LipSynchronization, 752 FlowIdentification, 753 SingleReservationFlow, 754 AlternateNetworkAddressType, 755 ForwardErrorCorrection, 756 DecodingDependency, 757 Bundle, 758 } 759 760 impl<'a> From<&'a SdpAttributeGroupSemantic> for RustSdpAttributeGroupSemantic { 761 fn from(other: &SdpAttributeGroupSemantic) -> Self { 762 match *other { 763 SdpAttributeGroupSemantic::LipSynchronization => { 764 RustSdpAttributeGroupSemantic::LipSynchronization 765 } 766 SdpAttributeGroupSemantic::FlowIdentification => { 767 RustSdpAttributeGroupSemantic::FlowIdentification 768 } 769 SdpAttributeGroupSemantic::SingleReservationFlow => { 770 RustSdpAttributeGroupSemantic::SingleReservationFlow 771 } 772 SdpAttributeGroupSemantic::AlternateNetworkAddressType => { 773 RustSdpAttributeGroupSemantic::AlternateNetworkAddressType 774 } 775 SdpAttributeGroupSemantic::ForwardErrorCorrection => { 776 RustSdpAttributeGroupSemantic::ForwardErrorCorrection 777 } 778 SdpAttributeGroupSemantic::DecodingDependency => { 779 RustSdpAttributeGroupSemantic::DecodingDependency 780 } 781 SdpAttributeGroupSemantic::Bundle => RustSdpAttributeGroupSemantic::Bundle, 782 } 783 } 784 } 785 786 #[repr(C)] 787 #[derive(Clone, Copy)] 788 pub struct RustSdpAttributeGroup { 789 pub semantic: RustSdpAttributeGroupSemantic, 790 pub tags: *const Vec<String>, 791 } 792 793 impl<'a> From<&'a SdpAttributeGroup> for RustSdpAttributeGroup { 794 fn from(other: &SdpAttributeGroup) -> Self { 795 RustSdpAttributeGroup { 796 semantic: RustSdpAttributeGroupSemantic::from(&other.semantics), 797 tags: &other.tags, 798 } 799 } 800 } 801 802 #[no_mangle] 803 pub unsafe extern "C" fn sdp_get_group_count(attributes: *const Vec<SdpAttribute>) -> size_t { 804 count_attribute((*attributes).as_slice(), SdpAttributeType::Group) 805 } 806 807 #[no_mangle] 808 pub unsafe extern "C" fn sdp_get_groups( 809 attributes: *const Vec<SdpAttribute>, 810 ret_size: size_t, 811 ret_groups: *mut RustSdpAttributeGroup, 812 ) { 813 let attrs: Vec<_> = (*attributes) 814 .iter() 815 .filter_map(|x| { 816 if let SdpAttribute::Group(ref data) = *x { 817 Some(RustSdpAttributeGroup::from(data)) 818 } else { 819 None 820 } 821 }) 822 .collect(); 823 let groups = slice::from_raw_parts_mut(ret_groups, ret_size); 824 groups.copy_from_slice(attrs.as_slice()); 825 } 826 827 #[repr(C)] 828 pub struct RustSdpAttributeRtcp { 829 pub port: u32, 830 pub unicast_addr: RustExplicitlyTypedAddress, 831 pub has_address: bool, 832 } 833 834 impl<'a> From<&'a SdpAttributeRtcp> for RustSdpAttributeRtcp { 835 fn from(other: &SdpAttributeRtcp) -> Self { 836 match other.unicast_addr { 837 Some(ref address) => RustSdpAttributeRtcp { 838 port: other.port as u32, 839 unicast_addr: address.into(), 840 has_address: true, 841 }, 842 None => RustSdpAttributeRtcp { 843 port: other.port as u32, 844 unicast_addr: RustExplicitlyTypedAddress::default(), 845 has_address: false, 846 }, 847 } 848 } 849 } 850 851 #[no_mangle] 852 pub unsafe extern "C" fn sdp_get_rtcp( 853 attributes: *const Vec<SdpAttribute>, 854 ret: *mut RustSdpAttributeRtcp, 855 ) -> nsresult { 856 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Rtcp); 857 if let Some(&SdpAttribute::Rtcp(ref data)) = attr { 858 *ret = RustSdpAttributeRtcp::from(data); 859 return NS_OK; 860 } 861 NS_ERROR_INVALID_ARG 862 } 863 864 #[repr(C)] 865 #[derive(Clone, Copy)] 866 pub struct RustSdpAttributeRtcpFb { 867 pub payload_type: u32, 868 pub feedback_type: u32, 869 pub parameter: StringView, 870 pub extra: StringView, 871 } 872 873 impl<'a> From<&'a SdpAttributeRtcpFb> for RustSdpAttributeRtcpFb { 874 fn from(other: &SdpAttributeRtcpFb) -> Self { 875 RustSdpAttributeRtcpFb { 876 payload_type: match other.payload_type { 877 SdpAttributePayloadType::Wildcard => u32::max_value(), 878 SdpAttributePayloadType::PayloadType(x) => x as u32, 879 }, 880 feedback_type: other.feedback_type.clone() as u32, 881 parameter: StringView::from(other.parameter.as_str()), 882 extra: StringView::from(other.extra.as_str()), 883 } 884 } 885 } 886 887 #[no_mangle] 888 pub unsafe extern "C" fn sdp_get_rtcpfb_count(attributes: *const Vec<SdpAttribute>) -> size_t { 889 count_attribute((*attributes).as_slice(), SdpAttributeType::Rtcpfb) 890 } 891 892 #[no_mangle] 893 pub unsafe extern "C" fn sdp_get_rtcpfbs( 894 attributes: *const Vec<SdpAttribute>, 895 ret_size: size_t, 896 ret_rtcpfbs: *mut RustSdpAttributeRtcpFb, 897 ) { 898 let attrs: Vec<_> = (*attributes) 899 .iter() 900 .filter_map(|x| { 901 if let SdpAttribute::Rtcpfb(ref data) = *x { 902 Some(RustSdpAttributeRtcpFb::from(data)) 903 } else { 904 None 905 } 906 }) 907 .collect(); 908 let rtcpfbs = slice::from_raw_parts_mut(ret_rtcpfbs, ret_size); 909 rtcpfbs.clone_from_slice(attrs.as_slice()); 910 } 911 912 #[repr(C)] 913 #[derive(Clone, Copy)] 914 pub struct RustSdpAttributeImageAttrXyRange { 915 // range 916 pub min: u32, 917 pub max: u32, 918 pub step: u32, 919 920 // discrete values 921 pub discrete_values: *const Vec<u32>, 922 } 923 924 impl<'a> From<&'a SdpAttributeImageAttrXyRange> for RustSdpAttributeImageAttrXyRange { 925 fn from(other: &SdpAttributeImageAttrXyRange) -> Self { 926 match other { 927 &SdpAttributeImageAttrXyRange::Range(min, max, step) => { 928 RustSdpAttributeImageAttrXyRange { 929 min, 930 max, 931 step: step.unwrap_or(1), 932 discrete_values: ptr::null(), 933 } 934 } 935 &SdpAttributeImageAttrXyRange::DiscreteValues(ref discrete_values) => { 936 RustSdpAttributeImageAttrXyRange { 937 min: 0, 938 max: 1, 939 step: 1, 940 discrete_values, 941 } 942 } 943 } 944 } 945 } 946 947 #[repr(C)] 948 #[derive(Clone, Copy)] 949 pub struct RustSdpAttributeImageAttrSRange { 950 // range 951 pub min: c_float, 952 pub max: c_float, 953 954 // discrete values 955 pub discrete_values: *const Vec<c_float>, 956 } 957 958 impl<'a> From<&'a SdpAttributeImageAttrSRange> for RustSdpAttributeImageAttrSRange { 959 fn from(other: &SdpAttributeImageAttrSRange) -> Self { 960 match other { 961 &SdpAttributeImageAttrSRange::Range(min, max) => RustSdpAttributeImageAttrSRange { 962 min, 963 max, 964 discrete_values: ptr::null(), 965 }, 966 &SdpAttributeImageAttrSRange::DiscreteValues(ref discrete_values) => { 967 RustSdpAttributeImageAttrSRange { 968 min: 0.0, 969 max: 1.0, 970 discrete_values, 971 } 972 } 973 } 974 } 975 } 976 977 #[repr(C)] 978 #[derive(Clone, Copy)] 979 pub struct RustSdpAttributeImageAttrPRange { 980 pub min: c_float, 981 pub max: c_float, 982 } 983 984 impl<'a> From<&'a SdpAttributeImageAttrPRange> for RustSdpAttributeImageAttrPRange { 985 fn from(other: &SdpAttributeImageAttrPRange) -> Self { 986 RustSdpAttributeImageAttrPRange { 987 min: other.min, 988 max: other.max, 989 } 990 } 991 } 992 993 #[repr(C)] 994 #[derive(Clone, Copy)] 995 pub struct RustSdpAttributeImageAttrSet { 996 pub x: RustSdpAttributeImageAttrXyRange, 997 pub y: RustSdpAttributeImageAttrXyRange, 998 999 pub has_sar: bool, 1000 pub sar: RustSdpAttributeImageAttrSRange, 1001 1002 pub has_par: bool, 1003 pub par: RustSdpAttributeImageAttrPRange, 1004 1005 pub q: c_float, 1006 } 1007 1008 impl<'a> From<&'a SdpAttributeImageAttrSet> for RustSdpAttributeImageAttrSet { 1009 fn from(other: &SdpAttributeImageAttrSet) -> Self { 1010 RustSdpAttributeImageAttrSet { 1011 x: RustSdpAttributeImageAttrXyRange::from(&other.x), 1012 y: RustSdpAttributeImageAttrXyRange::from(&other.y), 1013 1014 has_sar: other.sar.is_some(), 1015 sar: match other.sar { 1016 Some(ref x) => RustSdpAttributeImageAttrSRange::from(x), 1017 // This is just any valid value accepted by rust, 1018 // it might as well by uninitilized 1019 None => RustSdpAttributeImageAttrSRange::from( 1020 &SdpAttributeImageAttrSRange::DiscreteValues(vec![]), 1021 ), 1022 }, 1023 1024 has_par: other.par.is_some(), 1025 par: match other.par { 1026 Some(ref x) => RustSdpAttributeImageAttrPRange::from(x), 1027 // This is just any valid value accepted by rust, 1028 // it might as well by uninitilized 1029 None => RustSdpAttributeImageAttrPRange { min: 0.0, max: 1.0 }, 1030 }, 1031 1032 q: other.q.unwrap_or(0.5), 1033 } 1034 } 1035 } 1036 1037 #[repr(C)] 1038 #[derive(Clone, Copy)] 1039 pub struct RustSdpAttributeImageAttrSetList { 1040 pub sets: *const Vec<SdpAttributeImageAttrSet>, 1041 } 1042 1043 impl<'a> From<&'a SdpAttributeImageAttrSetList> for RustSdpAttributeImageAttrSetList { 1044 fn from(other: &SdpAttributeImageAttrSetList) -> Self { 1045 match other { 1046 &SdpAttributeImageAttrSetList::Wildcard => { 1047 RustSdpAttributeImageAttrSetList { sets: ptr::null() } 1048 } 1049 &SdpAttributeImageAttrSetList::Sets(ref sets) => { 1050 RustSdpAttributeImageAttrSetList { sets: sets } 1051 } 1052 } 1053 } 1054 } 1055 1056 #[no_mangle] 1057 pub unsafe extern "C" fn sdp_imageattr_get_set_count( 1058 sets: *const Vec<SdpAttributeImageAttrSet>, 1059 ) -> size_t { 1060 (*sets).len() 1061 } 1062 1063 #[no_mangle] 1064 pub unsafe extern "C" fn sdp_imageattr_get_sets( 1065 sets: *const Vec<SdpAttributeImageAttrSet>, 1066 ret_size: size_t, 1067 ret: *mut RustSdpAttributeImageAttrSet, 1068 ) { 1069 let rust_sets: Vec<_> = (*sets) 1070 .iter() 1071 .map(RustSdpAttributeImageAttrSet::from) 1072 .collect(); 1073 let sets = slice::from_raw_parts_mut(ret, ret_size); 1074 sets.clone_from_slice(rust_sets.as_slice()); 1075 } 1076 1077 #[repr(C)] 1078 #[derive(Clone, Copy)] 1079 pub struct RustSdpAttributeImageAttr { 1080 pub pt: u32, 1081 pub send: RustSdpAttributeImageAttrSetList, 1082 pub recv: RustSdpAttributeImageAttrSetList, 1083 } 1084 1085 impl<'a> From<&'a SdpAttributeImageAttr> for RustSdpAttributeImageAttr { 1086 fn from(other: &SdpAttributeImageAttr) -> Self { 1087 RustSdpAttributeImageAttr { 1088 pt: match other.pt { 1089 SdpAttributePayloadType::Wildcard => u32::max_value(), 1090 SdpAttributePayloadType::PayloadType(x) => x as u32, 1091 }, 1092 send: RustSdpAttributeImageAttrSetList::from(&other.send), 1093 recv: RustSdpAttributeImageAttrSetList::from(&other.recv), 1094 } 1095 } 1096 } 1097 1098 #[no_mangle] 1099 pub unsafe extern "C" fn sdp_get_imageattr_count(attributes: *const Vec<SdpAttribute>) -> size_t { 1100 count_attribute((*attributes).as_slice(), SdpAttributeType::ImageAttr) 1101 } 1102 1103 #[no_mangle] 1104 pub unsafe extern "C" fn sdp_get_imageattrs( 1105 attributes: *const Vec<SdpAttribute>, 1106 ret_size: size_t, 1107 ret_attrs: *mut RustSdpAttributeImageAttr, 1108 ) { 1109 let attrs: Vec<_> = (*attributes) 1110 .iter() 1111 .filter_map(|x| { 1112 if let SdpAttribute::ImageAttr(ref data) = *x { 1113 Some(RustSdpAttributeImageAttr::from(data)) 1114 } else { 1115 None 1116 } 1117 }) 1118 .collect(); 1119 let imageattrs = slice::from_raw_parts_mut(ret_attrs, ret_size); 1120 imageattrs.copy_from_slice(attrs.as_slice()); 1121 } 1122 1123 #[repr(C)] 1124 #[derive(Clone, Copy)] 1125 pub struct RustSdpAttributeSctpmap { 1126 pub port: u32, 1127 pub channels: u32, 1128 } 1129 1130 impl<'a> From<&'a SdpAttributeSctpmap> for RustSdpAttributeSctpmap { 1131 fn from(other: &SdpAttributeSctpmap) -> Self { 1132 RustSdpAttributeSctpmap { 1133 port: other.port as u32, 1134 channels: other.channels, 1135 } 1136 } 1137 } 1138 1139 #[no_mangle] 1140 pub unsafe extern "C" fn sdp_get_sctpmap_count(attributes: *const Vec<SdpAttribute>) -> size_t { 1141 count_attribute((*attributes).as_slice(), SdpAttributeType::Sctpmap) 1142 } 1143 1144 #[no_mangle] 1145 pub unsafe extern "C" fn sdp_get_sctpmaps( 1146 attributes: *const Vec<SdpAttribute>, 1147 ret_size: size_t, 1148 ret_sctpmaps: *mut RustSdpAttributeSctpmap, 1149 ) { 1150 let attrs: Vec<_> = (*attributes) 1151 .iter() 1152 .filter_map(|x| { 1153 if let SdpAttribute::Sctpmap(ref data) = *x { 1154 Some(RustSdpAttributeSctpmap::from(data)) 1155 } else { 1156 None 1157 } 1158 }) 1159 .collect(); 1160 let sctpmaps = slice::from_raw_parts_mut(ret_sctpmaps, ret_size); 1161 sctpmaps.copy_from_slice(attrs.as_slice()); 1162 } 1163 1164 #[repr(C)] 1165 #[derive(Clone, Copy)] 1166 pub struct RustSdpAttributeSimulcastId { 1167 pub id: StringView, 1168 pub paused: bool, 1169 } 1170 1171 impl<'a> From<&'a SdpAttributeSimulcastId> for RustSdpAttributeSimulcastId { 1172 fn from(other: &SdpAttributeSimulcastId) -> Self { 1173 RustSdpAttributeSimulcastId { 1174 id: StringView::from(other.id.as_str()), 1175 paused: other.paused, 1176 } 1177 } 1178 } 1179 1180 #[repr(C)] 1181 #[derive(Clone, Copy)] 1182 pub struct RustSdpAttributeSimulcastVersion { 1183 pub ids: *const Vec<SdpAttributeSimulcastId>, 1184 } 1185 1186 impl<'a> From<&'a SdpAttributeSimulcastVersion> for RustSdpAttributeSimulcastVersion { 1187 fn from(other: &SdpAttributeSimulcastVersion) -> Self { 1188 RustSdpAttributeSimulcastVersion { ids: &other.ids } 1189 } 1190 } 1191 1192 #[no_mangle] 1193 pub unsafe extern "C" fn sdp_simulcast_get_ids_count( 1194 ids: *const Vec<SdpAttributeSimulcastId>, 1195 ) -> size_t { 1196 (*ids).len() 1197 } 1198 1199 #[no_mangle] 1200 pub unsafe extern "C" fn sdp_simulcast_get_ids( 1201 ids: *const Vec<SdpAttributeSimulcastId>, 1202 ret_size: size_t, 1203 ret: *mut RustSdpAttributeSimulcastId, 1204 ) { 1205 let rust_ids: Vec<_> = (*ids) 1206 .iter() 1207 .map(RustSdpAttributeSimulcastId::from) 1208 .collect(); 1209 let ids = slice::from_raw_parts_mut(ret, ret_size); 1210 ids.clone_from_slice(rust_ids.as_slice()); 1211 } 1212 1213 #[repr(C)] 1214 pub struct RustSdpAttributeSimulcast { 1215 pub send: *const Vec<SdpAttributeSimulcastVersion>, 1216 pub receive: *const Vec<SdpAttributeSimulcastVersion>, 1217 } 1218 1219 impl<'a> From<&'a SdpAttributeSimulcast> for RustSdpAttributeSimulcast { 1220 fn from(other: &SdpAttributeSimulcast) -> Self { 1221 RustSdpAttributeSimulcast { 1222 send: &other.send, 1223 receive: &other.receive, 1224 } 1225 } 1226 } 1227 1228 #[no_mangle] 1229 pub unsafe extern "C" fn sdp_simulcast_get_version_count( 1230 version_list: *const Vec<SdpAttributeSimulcastVersion>, 1231 ) -> size_t { 1232 (*version_list).len() 1233 } 1234 1235 #[no_mangle] 1236 pub unsafe extern "C" fn sdp_simulcast_get_versions( 1237 version_list: *const Vec<SdpAttributeSimulcastVersion>, 1238 ret_size: size_t, 1239 ret: *mut RustSdpAttributeSimulcastVersion, 1240 ) { 1241 let rust_versions_list: Vec<_> = (*version_list) 1242 .iter() 1243 .map(RustSdpAttributeSimulcastVersion::from) 1244 .collect(); 1245 let versions = slice::from_raw_parts_mut(ret, ret_size); 1246 versions.clone_from_slice(rust_versions_list.as_slice()) 1247 } 1248 1249 #[no_mangle] 1250 pub unsafe extern "C" fn sdp_get_simulcast( 1251 attributes: *const Vec<SdpAttribute>, 1252 ret: *mut RustSdpAttributeSimulcast, 1253 ) -> nsresult { 1254 let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Simulcast); 1255 if let Some(&SdpAttribute::Simulcast(ref data)) = attr { 1256 *ret = RustSdpAttributeSimulcast::from(data); 1257 return NS_OK; 1258 } 1259 NS_ERROR_INVALID_ARG 1260 } 1261 1262 #[repr(C)] 1263 #[derive(Clone, Copy)] 1264 pub enum RustDirection { 1265 Recvonly, 1266 Sendonly, 1267 Sendrecv, 1268 Inactive, 1269 } 1270 1271 impl<'a> From<&'a Option<SdpAttributeDirection>> for RustDirection { 1272 fn from(other: &Option<SdpAttributeDirection>) -> Self { 1273 match *other { 1274 Some(ref direction) => match *direction { 1275 SdpAttributeDirection::Recvonly => RustDirection::Recvonly, 1276 SdpAttributeDirection::Sendonly => RustDirection::Sendonly, 1277 SdpAttributeDirection::Sendrecv => RustDirection::Sendrecv, 1278 }, 1279 None => RustDirection::Inactive, 1280 } 1281 } 1282 } 1283 1284 #[no_mangle] 1285 pub unsafe extern "C" fn sdp_get_direction(attributes: *const Vec<SdpAttribute>) -> RustDirection { 1286 for attribute in (*attributes).iter() { 1287 match *attribute { 1288 SdpAttribute::Recvonly => { 1289 return RustDirection::Recvonly; 1290 } 1291 SdpAttribute::Sendonly => { 1292 return RustDirection::Sendonly; 1293 } 1294 SdpAttribute::Sendrecv => { 1295 return RustDirection::Sendrecv; 1296 } 1297 SdpAttribute::Inactive => { 1298 return RustDirection::Inactive; 1299 } 1300 _ => (), 1301 } 1302 } 1303 RustDirection::Sendrecv 1304 } 1305 1306 #[repr(C)] 1307 pub struct RustSdpAttributeRemoteCandidate { 1308 pub component: u32, 1309 pub address: RustAddress, 1310 pub port: u32, 1311 } 1312 1313 impl<'a> From<&'a SdpAttributeRemoteCandidate> for RustSdpAttributeRemoteCandidate { 1314 fn from(other: &SdpAttributeRemoteCandidate) -> Self { 1315 RustSdpAttributeRemoteCandidate { 1316 component: other.component, 1317 address: RustAddress::from(&other.address), 1318 port: other.port, 1319 } 1320 } 1321 } 1322 1323 #[no_mangle] 1324 pub unsafe extern "C" fn sdp_get_remote_candidate_count( 1325 attributes: *const Vec<SdpAttribute>, 1326 ) -> size_t { 1327 count_attribute((*attributes).as_slice(), SdpAttributeType::RemoteCandidate) 1328 } 1329 1330 #[no_mangle] 1331 pub unsafe extern "C" fn sdp_get_remote_candidates( 1332 attributes: *const Vec<SdpAttribute>, 1333 ret_size: size_t, 1334 ret_candidates: *mut RustSdpAttributeRemoteCandidate, 1335 ) { 1336 let attrs = (*attributes).iter().filter_map(|x| { 1337 if let SdpAttribute::RemoteCandidate(ref data) = *x { 1338 Some(RustSdpAttributeRemoteCandidate::from(data)) 1339 } else { 1340 None 1341 } 1342 }); 1343 let candidates = slice::from_raw_parts_mut(ret_candidates, ret_size); 1344 for (source, destination) in attrs.zip(candidates) { 1345 *destination = source 1346 } 1347 } 1348 1349 #[no_mangle] 1350 pub unsafe extern "C" fn sdp_get_candidate_count(attributes: *const Vec<SdpAttribute>) -> size_t { 1351 count_attribute((*attributes).as_slice(), SdpAttributeType::Candidate) 1352 } 1353 1354 #[no_mangle] 1355 pub unsafe extern "C" fn sdp_get_candidates( 1356 attributes: *const Vec<SdpAttribute>, 1357 _ret_size: size_t, 1358 ret: *mut *const Vec<String>, 1359 ) { 1360 let attr_strings: Vec<String> = (*attributes) 1361 .iter() 1362 .filter_map(|x| { 1363 if let SdpAttribute::Candidate(ref attr) = *x { 1364 // The serialized attribute starts with "candidate:...", this needs to be removed 1365 Some(attr.to_string()) 1366 } else { 1367 None 1368 } 1369 }) 1370 .collect(); 1371 1372 *ret = Box::into_raw(Box::from(attr_strings)); 1373 } 1374 1375 #[repr(C)] 1376 #[derive(Clone, Copy)] 1377 pub struct RustSdpAttributeRidParameters { 1378 pub max_width: u32, 1379 pub max_height: u32, 1380 pub max_fps: u32, 1381 pub max_fs: u32, 1382 pub max_br: u32, 1383 pub max_pps: u32, 1384 pub unknown: *const Vec<String>, 1385 } 1386 1387 impl<'a> From<&'a SdpAttributeRidParameters> for RustSdpAttributeRidParameters { 1388 fn from(other: &SdpAttributeRidParameters) -> Self { 1389 RustSdpAttributeRidParameters { 1390 max_width: other.max_width, 1391 max_height: other.max_height, 1392 max_fps: other.max_fps, 1393 max_fs: other.max_fs, 1394 max_br: other.max_br, 1395 max_pps: other.max_pps, 1396 1397 unknown: &other.unknown, 1398 } 1399 } 1400 } 1401 1402 #[repr(C)] 1403 #[derive(Clone, Copy)] 1404 pub struct RustSdpAttributeRid { 1405 pub id: StringView, 1406 pub direction: u32, 1407 pub formats: *const Vec<u16>, 1408 pub params: RustSdpAttributeRidParameters, 1409 pub depends: *const Vec<String>, 1410 } 1411 1412 impl<'a> From<&'a SdpAttributeRid> for RustSdpAttributeRid { 1413 fn from(other: &SdpAttributeRid) -> Self { 1414 RustSdpAttributeRid { 1415 id: StringView::from(other.id.as_str()), 1416 direction: other.direction.clone() as u32, 1417 formats: &other.formats, 1418 params: RustSdpAttributeRidParameters::from(&other.params), 1419 depends: &other.depends, 1420 } 1421 } 1422 } 1423 1424 #[no_mangle] 1425 pub unsafe extern "C" fn sdp_get_rid_count(attributes: *const Vec<SdpAttribute>) -> size_t { 1426 count_attribute((*attributes).as_slice(), SdpAttributeType::Rid) 1427 } 1428 1429 #[no_mangle] 1430 pub unsafe extern "C" fn sdp_get_rids( 1431 attributes: *const Vec<SdpAttribute>, 1432 ret_size: size_t, 1433 ret_rids: *mut RustSdpAttributeRid, 1434 ) { 1435 let attrs: Vec<_> = (*attributes) 1436 .iter() 1437 .filter_map(|x| { 1438 if let SdpAttribute::Rid(ref data) = *x { 1439 Some(RustSdpAttributeRid::from(data)) 1440 } else { 1441 None 1442 } 1443 }) 1444 .collect(); 1445 let rids = slice::from_raw_parts_mut(ret_rids, ret_size); 1446 rids.clone_from_slice(attrs.as_slice()); 1447 } 1448 1449 #[repr(C)] 1450 #[derive(Clone, Copy)] 1451 pub struct RustSdpAttributeExtmap { 1452 pub id: u16, 1453 pub direction_specified: bool, 1454 pub direction: RustDirection, 1455 pub url: StringView, 1456 pub extension_attributes: StringView, 1457 } 1458 1459 impl<'a> From<&'a SdpAttributeExtmap> for RustSdpAttributeExtmap { 1460 fn from(other: &SdpAttributeExtmap) -> Self { 1461 let dir = if other.direction.is_some() { 1462 RustDirection::from(&other.direction) 1463 } else { 1464 RustDirection::from(&Some(SdpAttributeDirection::Sendrecv)) 1465 }; 1466 RustSdpAttributeExtmap { 1467 id: other.id as u16, 1468 direction_specified: other.direction.is_some(), 1469 direction: dir, 1470 url: StringView::from(other.url.as_str()), 1471 extension_attributes: StringView::from(&other.extension_attributes), 1472 } 1473 } 1474 } 1475 1476 #[no_mangle] 1477 pub unsafe extern "C" fn sdp_get_extmap_count(attributes: *const Vec<SdpAttribute>) -> size_t { 1478 count_attribute((*attributes).as_slice(), SdpAttributeType::Extmap) 1479 } 1480 1481 #[no_mangle] 1482 pub unsafe extern "C" fn sdp_get_extmaps( 1483 attributes: *const Vec<SdpAttribute>, 1484 ret_size: size_t, 1485 ret_rids: *mut RustSdpAttributeExtmap, 1486 ) { 1487 let attrs: Vec<_> = (*attributes) 1488 .iter() 1489 .filter_map(|x| { 1490 if let SdpAttribute::Extmap(ref data) = *x { 1491 Some(RustSdpAttributeExtmap::from(data)) 1492 } else { 1493 None 1494 } 1495 }) 1496 .collect(); 1497 let extmaps = slice::from_raw_parts_mut(ret_rids, ret_size); 1498 extmaps.copy_from_slice(attrs.as_slice()); 1499 }