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]
num_attributes(session: *const SdpSession) -> u3217 pub unsafe extern "C" fn num_attributes(session: *const SdpSession) -> u32 {
18     (*session).attribute.len() as u32
19 }
20 
21 #[no_mangle]
get_attribute_ptr( session: *const SdpSession, index: u32, ret: *mut *const SdpAttribute, ) -> nsresult22 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 
count_attribute(attributes: &[SdpAttribute], search: SdpAttributeType) -> usize36 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 
argsearch(attributes: &[SdpAttribute], attribute_type: SdpAttributeType) -> Option<usize>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 
has_attribute( attributes: *const Vec<SdpAttribute>, attribute_type: SdpAttributeType, ) -> bool55 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 
get_attribute( attributes: &[SdpAttribute], attribute_type: SdpAttributeType, ) -> Option<&SdpAttribute>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 {
from(other: &SdpAttributeDtlsMessage) -> Self84     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]
sdp_get_dtls_message( attributes: *const Vec<SdpAttribute>, ret: *mut RustSdpAttributeDtlsMessage, ) -> nsresult99 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]
sdp_get_iceufrag( attributes: *const Vec<SdpAttribute>, ret: *mut StringView, ) -> nsresult112 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]
sdp_get_icepwd( attributes: *const Vec<SdpAttribute>, ret: *mut StringView, ) -> nsresult125 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]
sdp_get_identity( attributes: *const Vec<SdpAttribute>, ret: *mut StringView, ) -> nsresult138 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]
sdp_get_iceoptions( attributes: *const Vec<SdpAttribute>, ret: *mut *const Vec<String>, ) -> nsresult151 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]
sdp_get_maxptime( attributes: *const Vec<SdpAttribute>, ret: *mut u64, ) -> nsresult164 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 {
from(other: &SdpAttributeFingerprint) -> Self184     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]
sdp_get_fingerprint_count(attributes: *const Vec<SdpAttribute>) -> size_t193 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]
sdp_get_fingerprints( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_fingerprints: *mut RustSdpAttributeFingerprint, )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 {
from(other: &SdpAttributeSetup) -> Self227     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]
sdp_get_setup( attributes: *const Vec<SdpAttribute>, ret: *mut RustSdpAttributeSetup, ) -> nsresult238 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 {
from(other: &SdpAttributeSsrc) -> Self259     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]
sdp_get_ssrc_count(attributes: *const Vec<SdpAttribute>) -> size_t269 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]
sdp_get_ssrcs( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_ssrcs: *mut RustSdpAttributeSsrc, )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 {
from(other: &SdpSsrcGroupSemantic) -> Self304     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]
sdp_get_ssrc_group_count(attributes: *const Vec<SdpAttribute>) -> size_t329 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]
sdp_get_ssrc_groups( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_ssrc_groups: *mut RustSdpSsrcGroup, )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 {
from(other: &SdpAttributeRtpmap) -> Self366     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]
sdp_get_rtpmap_count(attributes: *const Vec<SdpAttribute>) -> size_t377 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]
sdp_get_rtpmaps( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rtpmaps: *mut RustSdpAttributeRtpmap, )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 RustSdpAttributeFmtpParameters {
412     // H264
413     pub packetization_mode: u32,
414     pub level_asymmetry_allowed: bool,
415     pub profile_level_id: u32,
416     pub max_fs: u32,
417     pub max_cpb: u32,
418     pub max_dpb: u32,
419     pub max_br: u32,
420     pub max_mbps: u32,
421 
422     // VP8 and VP9
423     // max_fs, already defined in H264
424     pub max_fr: u32,
425 
426     // Opus
427     pub maxplaybackrate: u32,
428     pub maxaveragebitrate: u32,
429     pub usedtx: bool,
430     pub stereo: bool,
431     pub useinbandfec: bool,
432     pub cbr: bool,
433     pub ptime: u32,
434     pub minptime: u32,
435     pub maxptime: u32,
436 
437     // telephone-event
438     pub dtmf_tones: StringView,
439 
440     // RTX
441     pub rtx: RustRtxFmtpParameters,
442 
443     // Red
444     pub encodings: *const Vec<u8>,
445 
446     // Unknown
447     pub unknown_tokens: *const Vec<String>,
448 }
449 
450 impl<'a> From<&'a SdpAttributeFmtpParameters> for RustSdpAttributeFmtpParameters {
from(other: &SdpAttributeFmtpParameters) -> Self451     fn from(other: &SdpAttributeFmtpParameters) -> Self {
452         let rtx = if let Some(rtx) = other.rtx {
453             RustRtxFmtpParameters {
454                 apt: rtx.apt,
455                 has_rtx_time: rtx.rtx_time.is_some(),
456                 rtx_time: rtx.rtx_time.unwrap_or(0),
457             }
458         } else {
459             RustRtxFmtpParameters {
460                 apt: 0,
461                 has_rtx_time: false,
462                 rtx_time: 0,
463             }
464         };
465 
466         RustSdpAttributeFmtpParameters {
467             packetization_mode: other.packetization_mode,
468             level_asymmetry_allowed: other.level_asymmetry_allowed,
469             profile_level_id: other.profile_level_id,
470             max_fs: other.max_fs,
471             max_cpb: other.max_cpb,
472             max_dpb: other.max_dpb,
473             max_br: other.max_br,
474             max_mbps: other.max_mbps,
475             usedtx: other.usedtx,
476             stereo: other.stereo,
477             useinbandfec: other.useinbandfec,
478             cbr: other.cbr,
479             max_fr: other.max_fr,
480             maxplaybackrate: other.maxplaybackrate,
481             maxaveragebitrate: other.maxaveragebitrate,
482             ptime: other.ptime,
483             minptime: other.minptime,
484             maxptime: other.maxptime,
485             dtmf_tones: StringView::from(other.dtmf_tones.as_str()),
486             rtx,
487             encodings: &other.encodings,
488             unknown_tokens: &other.unknown_tokens,
489         }
490     }
491 }
492 
493 #[repr(C)]
494 #[derive(Clone, Copy)]
495 pub struct RustSdpAttributeFmtp {
496     pub payload_type: u8,
497     pub codec_name: StringView,
498     pub parameters: RustSdpAttributeFmtpParameters,
499 }
500 
501 #[no_mangle]
sdp_get_fmtp_count(attributes: *const Vec<SdpAttribute>) -> size_t502 pub unsafe extern "C" fn sdp_get_fmtp_count(attributes: *const Vec<SdpAttribute>) -> size_t {
503     count_attribute((*attributes).as_slice(), SdpAttributeType::Fmtp)
504 }
505 
find_payload_type(attributes: &[SdpAttribute], payload_type: u8) -> Option<&SdpAttributeRtpmap>506 fn find_payload_type(attributes: &[SdpAttribute], payload_type: u8) -> Option<&SdpAttributeRtpmap> {
507     attributes
508         .iter()
509         .filter_map(|x| {
510             if let SdpAttribute::Rtpmap(ref data) = *x {
511                 if data.payload_type == payload_type {
512                     Some(data)
513                 } else {
514                     None
515                 }
516             } else {
517                 None
518             }
519         })
520         .next()
521 }
522 
523 #[no_mangle]
sdp_get_fmtp( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_fmtp: *mut RustSdpAttributeFmtp, ) -> size_t524 pub unsafe extern "C" fn sdp_get_fmtp(
525     attributes: *const Vec<SdpAttribute>,
526     ret_size: size_t,
527     ret_fmtp: *mut RustSdpAttributeFmtp,
528 ) -> size_t {
529     let fmtps = (*attributes).iter().filter_map(|x| {
530         if let SdpAttribute::Fmtp(ref data) = *x {
531             Some(data)
532         } else {
533             None
534         }
535     });
536     let mut rust_fmtps = Vec::new();
537     for fmtp in fmtps {
538         if let Some(rtpmap) = find_payload_type((*attributes).as_slice(), fmtp.payload_type) {
539             rust_fmtps.push(RustSdpAttributeFmtp {
540                 payload_type: fmtp.payload_type as u8,
541                 codec_name: StringView::from(rtpmap.codec_name.as_str()),
542                 parameters: RustSdpAttributeFmtpParameters::from(&fmtp.parameters),
543             });
544         }
545     }
546     let fmtps = if ret_size <= rust_fmtps.len() {
547         slice::from_raw_parts_mut(ret_fmtp, ret_size)
548     } else {
549         slice::from_raw_parts_mut(ret_fmtp, rust_fmtps.len())
550     };
551     fmtps.copy_from_slice(rust_fmtps.as_slice());
552     fmtps.len()
553 }
554 
555 #[no_mangle]
sdp_get_ptime(attributes: *const Vec<SdpAttribute>) -> i64556 pub unsafe extern "C" fn sdp_get_ptime(attributes: *const Vec<SdpAttribute>) -> i64 {
557     for attribute in (*attributes).iter() {
558         if let SdpAttribute::Ptime(time) = *attribute {
559             return time as i64;
560         }
561     }
562     -1
563 }
564 
565 #[no_mangle]
sdp_get_max_msg_size(attributes: *const Vec<SdpAttribute>) -> i64566 pub unsafe extern "C" fn sdp_get_max_msg_size(attributes: *const Vec<SdpAttribute>) -> i64 {
567     for attribute in (*attributes).iter() {
568         if let SdpAttribute::MaxMessageSize(max_msg_size) = *attribute {
569             return max_msg_size as i64;
570         }
571     }
572     -1
573 }
574 
575 #[no_mangle]
sdp_get_sctp_port(attributes: *const Vec<SdpAttribute>) -> i64576 pub unsafe extern "C" fn sdp_get_sctp_port(attributes: *const Vec<SdpAttribute>) -> i64 {
577     for attribute in (*attributes).iter() {
578         if let SdpAttribute::SctpPort(port) = *attribute {
579             return port as i64;
580         }
581     }
582     -1
583 }
584 
585 #[repr(C)]
586 #[derive(Clone, Copy)]
587 pub struct RustSdpAttributeFlags {
588     pub ice_lite: bool,
589     pub rtcp_mux: bool,
590     pub rtcp_rsize: bool,
591     pub bundle_only: bool,
592     pub end_of_candidates: bool,
593 }
594 
595 #[no_mangle]
sdp_get_attribute_flags( attributes: *const Vec<SdpAttribute>, ) -> RustSdpAttributeFlags596 pub unsafe extern "C" fn sdp_get_attribute_flags(
597     attributes: *const Vec<SdpAttribute>,
598 ) -> RustSdpAttributeFlags {
599     let mut ret = RustSdpAttributeFlags {
600         ice_lite: false,
601         rtcp_mux: false,
602         rtcp_rsize: false,
603         bundle_only: false,
604         end_of_candidates: false,
605     };
606     for attribute in (*attributes).iter() {
607         if let SdpAttribute::IceLite = *attribute {
608             ret.ice_lite = true;
609         } else if let SdpAttribute::RtcpMux = *attribute {
610             ret.rtcp_mux = true;
611         } else if let SdpAttribute::RtcpRsize = *attribute {
612             ret.rtcp_rsize = true;
613         } else if let SdpAttribute::BundleOnly = *attribute {
614             ret.bundle_only = true;
615         } else if let SdpAttribute::EndOfCandidates = *attribute {
616             ret.end_of_candidates = true;
617         }
618     }
619     ret
620 }
621 
622 #[no_mangle]
sdp_get_mid( attributes: *const Vec<SdpAttribute>, ret: *mut StringView, ) -> nsresult623 pub unsafe extern "C" fn sdp_get_mid(
624     attributes: *const Vec<SdpAttribute>,
625     ret: *mut StringView,
626 ) -> nsresult {
627     for attribute in (*attributes).iter() {
628         if let SdpAttribute::Mid(ref data) = *attribute {
629             *ret = StringView::from(data.as_str());
630             return NS_OK;
631         }
632     }
633     NS_ERROR_INVALID_ARG
634 }
635 
636 #[repr(C)]
637 #[derive(Clone, Copy)]
638 pub struct RustSdpAttributeMsid {
639     id: StringView,
640     appdata: StringView,
641 }
642 
643 impl<'a> From<&'a SdpAttributeMsid> for RustSdpAttributeMsid {
from(other: &SdpAttributeMsid) -> Self644     fn from(other: &SdpAttributeMsid) -> Self {
645         RustSdpAttributeMsid {
646             id: StringView::from(other.id.as_str()),
647             appdata: StringView::from(&other.appdata),
648         }
649     }
650 }
651 
652 #[no_mangle]
sdp_get_msid_count(attributes: *const Vec<SdpAttribute>) -> size_t653 pub unsafe extern "C" fn sdp_get_msid_count(attributes: *const Vec<SdpAttribute>) -> size_t {
654     count_attribute((*attributes).as_slice(), SdpAttributeType::Msid)
655 }
656 
657 #[no_mangle]
sdp_get_msids( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_msids: *mut RustSdpAttributeMsid, )658 pub unsafe extern "C" fn sdp_get_msids(
659     attributes: *const Vec<SdpAttribute>,
660     ret_size: size_t,
661     ret_msids: *mut RustSdpAttributeMsid,
662 ) {
663     let attrs: Vec<_> = (*attributes)
664         .iter()
665         .filter_map(|x| {
666             if let SdpAttribute::Msid(ref data) = *x {
667                 Some(RustSdpAttributeMsid::from(data))
668             } else {
669                 None
670             }
671         })
672         .collect();
673     let msids = slice::from_raw_parts_mut(ret_msids, ret_size);
674     msids.copy_from_slice(attrs.as_slice());
675 }
676 
677 // TODO: Finish msid attributes once parsing is changed upstream.
678 #[repr(C)]
679 #[derive(Clone, Copy)]
680 pub struct RustSdpAttributeMsidSemantic {
681     pub semantic: StringView,
682     pub msids: *const Vec<String>,
683 }
684 
685 impl<'a> From<&'a SdpAttributeMsidSemantic> for RustSdpAttributeMsidSemantic {
from(other: &SdpAttributeMsidSemantic) -> Self686     fn from(other: &SdpAttributeMsidSemantic) -> Self {
687         RustSdpAttributeMsidSemantic {
688             semantic: StringView::from(other.semantic.as_str()),
689             msids: &other.msids,
690         }
691     }
692 }
693 
694 #[no_mangle]
sdp_get_msid_semantic_count( attributes: *const Vec<SdpAttribute>, ) -> size_t695 pub unsafe extern "C" fn sdp_get_msid_semantic_count(
696     attributes: *const Vec<SdpAttribute>,
697 ) -> size_t {
698     count_attribute((*attributes).as_slice(), SdpAttributeType::MsidSemantic)
699 }
700 
701 #[no_mangle]
sdp_get_msid_semantics( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_msid_semantics: *mut RustSdpAttributeMsidSemantic, )702 pub unsafe extern "C" fn sdp_get_msid_semantics(
703     attributes: *const Vec<SdpAttribute>,
704     ret_size: size_t,
705     ret_msid_semantics: *mut RustSdpAttributeMsidSemantic,
706 ) {
707     let attrs: Vec<_> = (*attributes)
708         .iter()
709         .filter_map(|x| {
710             if let SdpAttribute::MsidSemantic(ref data) = *x {
711                 Some(RustSdpAttributeMsidSemantic::from(data))
712             } else {
713                 None
714             }
715         })
716         .collect();
717     let msid_semantics = slice::from_raw_parts_mut(ret_msid_semantics, ret_size);
718     msid_semantics.copy_from_slice(attrs.as_slice());
719 }
720 
721 #[repr(C)]
722 #[derive(Clone, Copy)]
723 pub enum RustSdpAttributeGroupSemantic {
724     LipSynchronization,
725     FlowIdentification,
726     SingleReservationFlow,
727     AlternateNetworkAddressType,
728     ForwardErrorCorrection,
729     DecodingDependency,
730     Bundle,
731 }
732 
733 impl<'a> From<&'a SdpAttributeGroupSemantic> for RustSdpAttributeGroupSemantic {
from(other: &SdpAttributeGroupSemantic) -> Self734     fn from(other: &SdpAttributeGroupSemantic) -> Self {
735         match *other {
736             SdpAttributeGroupSemantic::LipSynchronization => {
737                 RustSdpAttributeGroupSemantic::LipSynchronization
738             }
739             SdpAttributeGroupSemantic::FlowIdentification => {
740                 RustSdpAttributeGroupSemantic::FlowIdentification
741             }
742             SdpAttributeGroupSemantic::SingleReservationFlow => {
743                 RustSdpAttributeGroupSemantic::SingleReservationFlow
744             }
745             SdpAttributeGroupSemantic::AlternateNetworkAddressType => {
746                 RustSdpAttributeGroupSemantic::AlternateNetworkAddressType
747             }
748             SdpAttributeGroupSemantic::ForwardErrorCorrection => {
749                 RustSdpAttributeGroupSemantic::ForwardErrorCorrection
750             }
751             SdpAttributeGroupSemantic::DecodingDependency => {
752                 RustSdpAttributeGroupSemantic::DecodingDependency
753             }
754             SdpAttributeGroupSemantic::Bundle => RustSdpAttributeGroupSemantic::Bundle,
755         }
756     }
757 }
758 
759 #[repr(C)]
760 #[derive(Clone, Copy)]
761 pub struct RustSdpAttributeGroup {
762     pub semantic: RustSdpAttributeGroupSemantic,
763     pub tags: *const Vec<String>,
764 }
765 
766 impl<'a> From<&'a SdpAttributeGroup> for RustSdpAttributeGroup {
from(other: &SdpAttributeGroup) -> Self767     fn from(other: &SdpAttributeGroup) -> Self {
768         RustSdpAttributeGroup {
769             semantic: RustSdpAttributeGroupSemantic::from(&other.semantics),
770             tags: &other.tags,
771         }
772     }
773 }
774 
775 #[no_mangle]
sdp_get_group_count(attributes: *const Vec<SdpAttribute>) -> size_t776 pub unsafe extern "C" fn sdp_get_group_count(attributes: *const Vec<SdpAttribute>) -> size_t {
777     count_attribute((*attributes).as_slice(), SdpAttributeType::Group)
778 }
779 
780 #[no_mangle]
sdp_get_groups( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_groups: *mut RustSdpAttributeGroup, )781 pub unsafe extern "C" fn sdp_get_groups(
782     attributes: *const Vec<SdpAttribute>,
783     ret_size: size_t,
784     ret_groups: *mut RustSdpAttributeGroup,
785 ) {
786     let attrs: Vec<_> = (*attributes)
787         .iter()
788         .filter_map(|x| {
789             if let SdpAttribute::Group(ref data) = *x {
790                 Some(RustSdpAttributeGroup::from(data))
791             } else {
792                 None
793             }
794         })
795         .collect();
796     let groups = slice::from_raw_parts_mut(ret_groups, ret_size);
797     groups.copy_from_slice(attrs.as_slice());
798 }
799 
800 #[repr(C)]
801 pub struct RustSdpAttributeRtcp {
802     pub port: u32,
803     pub unicast_addr: RustExplicitlyTypedAddress,
804     pub has_address: bool,
805 }
806 
807 impl<'a> From<&'a SdpAttributeRtcp> for RustSdpAttributeRtcp {
from(other: &SdpAttributeRtcp) -> Self808     fn from(other: &SdpAttributeRtcp) -> Self {
809         match other.unicast_addr {
810             Some(ref address) => RustSdpAttributeRtcp {
811                 port: other.port as u32,
812                 unicast_addr: address.into(),
813                 has_address: true,
814             },
815             None => RustSdpAttributeRtcp {
816                 port: other.port as u32,
817                 unicast_addr: RustExplicitlyTypedAddress::default(),
818                 has_address: false,
819             },
820         }
821     }
822 }
823 
824 #[no_mangle]
sdp_get_rtcp( attributes: *const Vec<SdpAttribute>, ret: *mut RustSdpAttributeRtcp, ) -> nsresult825 pub unsafe extern "C" fn sdp_get_rtcp(
826     attributes: *const Vec<SdpAttribute>,
827     ret: *mut RustSdpAttributeRtcp,
828 ) -> nsresult {
829     let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Rtcp);
830     if let Some(&SdpAttribute::Rtcp(ref data)) = attr {
831         *ret = RustSdpAttributeRtcp::from(data);
832         return NS_OK;
833     }
834     NS_ERROR_INVALID_ARG
835 }
836 
837 #[repr(C)]
838 #[derive(Clone, Copy)]
839 pub struct RustSdpAttributeRtcpFb {
840     pub payload_type: u32,
841     pub feedback_type: u32,
842     pub parameter: StringView,
843     pub extra: StringView,
844 }
845 
846 impl<'a> From<&'a SdpAttributeRtcpFb> for RustSdpAttributeRtcpFb {
from(other: &SdpAttributeRtcpFb) -> Self847     fn from(other: &SdpAttributeRtcpFb) -> Self {
848         RustSdpAttributeRtcpFb {
849             payload_type: match other.payload_type {
850                 SdpAttributePayloadType::Wildcard => u32::max_value(),
851                 SdpAttributePayloadType::PayloadType(x) => x as u32,
852             },
853             feedback_type: other.feedback_type.clone() as u32,
854             parameter: StringView::from(other.parameter.as_str()),
855             extra: StringView::from(other.extra.as_str()),
856         }
857     }
858 }
859 
860 #[no_mangle]
sdp_get_rtcpfb_count(attributes: *const Vec<SdpAttribute>) -> size_t861 pub unsafe extern "C" fn sdp_get_rtcpfb_count(attributes: *const Vec<SdpAttribute>) -> size_t {
862     count_attribute((*attributes).as_slice(), SdpAttributeType::Rtcpfb)
863 }
864 
865 #[no_mangle]
sdp_get_rtcpfbs( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rtcpfbs: *mut RustSdpAttributeRtcpFb, )866 pub unsafe extern "C" fn sdp_get_rtcpfbs(
867     attributes: *const Vec<SdpAttribute>,
868     ret_size: size_t,
869     ret_rtcpfbs: *mut RustSdpAttributeRtcpFb,
870 ) {
871     let attrs: Vec<_> = (*attributes)
872         .iter()
873         .filter_map(|x| {
874             if let SdpAttribute::Rtcpfb(ref data) = *x {
875                 Some(RustSdpAttributeRtcpFb::from(data))
876             } else {
877                 None
878             }
879         })
880         .collect();
881     let rtcpfbs = slice::from_raw_parts_mut(ret_rtcpfbs, ret_size);
882     rtcpfbs.clone_from_slice(attrs.as_slice());
883 }
884 
885 #[repr(C)]
886 #[derive(Clone, Copy)]
887 pub struct RustSdpAttributeImageAttrXYRange {
888     // range
889     pub min: u32,
890     pub max: u32,
891     pub step: u32,
892 
893     // discrete values
894     pub discrete_values: *const Vec<u32>,
895 }
896 
897 impl<'a> From<&'a SdpAttributeImageAttrXYRange> for RustSdpAttributeImageAttrXYRange {
from(other: &SdpAttributeImageAttrXYRange) -> Self898     fn from(other: &SdpAttributeImageAttrXYRange) -> Self {
899         match other {
900             &SdpAttributeImageAttrXYRange::Range(min, max, step) => {
901                 RustSdpAttributeImageAttrXYRange {
902                     min,
903                     max,
904                     step: step.unwrap_or(1),
905                     discrete_values: ptr::null(),
906                 }
907             }
908             &SdpAttributeImageAttrXYRange::DiscreteValues(ref discrete_values) => {
909                 RustSdpAttributeImageAttrXYRange {
910                     min: 0,
911                     max: 1,
912                     step: 1,
913                     discrete_values,
914                 }
915             }
916         }
917     }
918 }
919 
920 #[repr(C)]
921 #[derive(Clone, Copy)]
922 pub struct RustSdpAttributeImageAttrSRange {
923     // range
924     pub min: c_float,
925     pub max: c_float,
926 
927     // discrete values
928     pub discrete_values: *const Vec<c_float>,
929 }
930 
931 impl<'a> From<&'a SdpAttributeImageAttrSRange> for RustSdpAttributeImageAttrSRange {
from(other: &SdpAttributeImageAttrSRange) -> Self932     fn from(other: &SdpAttributeImageAttrSRange) -> Self {
933         match other {
934             &SdpAttributeImageAttrSRange::Range(min, max) => RustSdpAttributeImageAttrSRange {
935                 min,
936                 max,
937                 discrete_values: ptr::null(),
938             },
939             &SdpAttributeImageAttrSRange::DiscreteValues(ref discrete_values) => {
940                 RustSdpAttributeImageAttrSRange {
941                     min: 0.0,
942                     max: 1.0,
943                     discrete_values,
944                 }
945             }
946         }
947     }
948 }
949 
950 #[repr(C)]
951 #[derive(Clone, Copy)]
952 pub struct RustSdpAttributeImageAttrPRange {
953     pub min: c_float,
954     pub max: c_float,
955 }
956 
957 impl<'a> From<&'a SdpAttributeImageAttrPRange> for RustSdpAttributeImageAttrPRange {
from(other: &SdpAttributeImageAttrPRange) -> Self958     fn from(other: &SdpAttributeImageAttrPRange) -> Self {
959         RustSdpAttributeImageAttrPRange {
960             min: other.min,
961             max: other.max,
962         }
963     }
964 }
965 
966 #[repr(C)]
967 #[derive(Clone, Copy)]
968 pub struct RustSdpAttributeImageAttrSet {
969     pub x: RustSdpAttributeImageAttrXYRange,
970     pub y: RustSdpAttributeImageAttrXYRange,
971 
972     pub has_sar: bool,
973     pub sar: RustSdpAttributeImageAttrSRange,
974 
975     pub has_par: bool,
976     pub par: RustSdpAttributeImageAttrPRange,
977 
978     pub q: c_float,
979 }
980 
981 impl<'a> From<&'a SdpAttributeImageAttrSet> for RustSdpAttributeImageAttrSet {
from(other: &SdpAttributeImageAttrSet) -> Self982     fn from(other: &SdpAttributeImageAttrSet) -> Self {
983         RustSdpAttributeImageAttrSet {
984             x: RustSdpAttributeImageAttrXYRange::from(&other.x),
985             y: RustSdpAttributeImageAttrXYRange::from(&other.y),
986 
987             has_sar: other.sar.is_some(),
988             sar: match other.sar {
989                 Some(ref x) => RustSdpAttributeImageAttrSRange::from(x),
990                 // This is just any valid value accepted by rust,
991                 // it might as well by uninitilized
992                 None => RustSdpAttributeImageAttrSRange::from(
993                     &SdpAttributeImageAttrSRange::DiscreteValues(vec![]),
994                 ),
995             },
996 
997             has_par: other.par.is_some(),
998             par: match other.par {
999                 Some(ref x) => RustSdpAttributeImageAttrPRange::from(x),
1000                 // This is just any valid value accepted by rust,
1001                 // it might as well by uninitilized
1002                 None => RustSdpAttributeImageAttrPRange { min: 0.0, max: 1.0 },
1003             },
1004 
1005             q: other.q.unwrap_or(0.5),
1006         }
1007     }
1008 }
1009 
1010 #[repr(C)]
1011 #[derive(Clone, Copy)]
1012 pub struct RustSdpAttributeImageAttrSetList {
1013     pub sets: *const Vec<SdpAttributeImageAttrSet>,
1014 }
1015 
1016 impl<'a> From<&'a SdpAttributeImageAttrSetList> for RustSdpAttributeImageAttrSetList {
from(other: &SdpAttributeImageAttrSetList) -> Self1017     fn from(other: &SdpAttributeImageAttrSetList) -> Self {
1018         match other {
1019             &SdpAttributeImageAttrSetList::Wildcard => {
1020                 RustSdpAttributeImageAttrSetList { sets: ptr::null() }
1021             }
1022             &SdpAttributeImageAttrSetList::Sets(ref sets) => {
1023                 RustSdpAttributeImageAttrSetList { sets: sets }
1024             }
1025         }
1026     }
1027 }
1028 
1029 #[no_mangle]
sdp_imageattr_get_set_count( sets: *const Vec<SdpAttributeImageAttrSet>, ) -> size_t1030 pub unsafe extern "C" fn sdp_imageattr_get_set_count(
1031     sets: *const Vec<SdpAttributeImageAttrSet>,
1032 ) -> size_t {
1033     (*sets).len()
1034 }
1035 
1036 #[no_mangle]
sdp_imageattr_get_sets( sets: *const Vec<SdpAttributeImageAttrSet>, ret_size: size_t, ret: *mut RustSdpAttributeImageAttrSet, )1037 pub unsafe extern "C" fn sdp_imageattr_get_sets(
1038     sets: *const Vec<SdpAttributeImageAttrSet>,
1039     ret_size: size_t,
1040     ret: *mut RustSdpAttributeImageAttrSet,
1041 ) {
1042     let rust_sets: Vec<_> = (*sets)
1043         .iter()
1044         .map(RustSdpAttributeImageAttrSet::from)
1045         .collect();
1046     let sets = slice::from_raw_parts_mut(ret, ret_size);
1047     sets.clone_from_slice(rust_sets.as_slice());
1048 }
1049 
1050 #[repr(C)]
1051 #[derive(Clone, Copy)]
1052 pub struct RustSdpAttributeImageAttr {
1053     pub pt: u32,
1054     pub send: RustSdpAttributeImageAttrSetList,
1055     pub recv: RustSdpAttributeImageAttrSetList,
1056 }
1057 
1058 impl<'a> From<&'a SdpAttributeImageAttr> for RustSdpAttributeImageAttr {
from(other: &SdpAttributeImageAttr) -> Self1059     fn from(other: &SdpAttributeImageAttr) -> Self {
1060         RustSdpAttributeImageAttr {
1061             pt: match other.pt {
1062                 SdpAttributePayloadType::Wildcard => u32::max_value(),
1063                 SdpAttributePayloadType::PayloadType(x) => x as u32,
1064             },
1065             send: RustSdpAttributeImageAttrSetList::from(&other.send),
1066             recv: RustSdpAttributeImageAttrSetList::from(&other.recv),
1067         }
1068     }
1069 }
1070 
1071 #[no_mangle]
sdp_get_imageattr_count(attributes: *const Vec<SdpAttribute>) -> size_t1072 pub unsafe extern "C" fn sdp_get_imageattr_count(attributes: *const Vec<SdpAttribute>) -> size_t {
1073     count_attribute((*attributes).as_slice(), SdpAttributeType::ImageAttr)
1074 }
1075 
1076 #[no_mangle]
sdp_get_imageattrs( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_attrs: *mut RustSdpAttributeImageAttr, )1077 pub unsafe extern "C" fn sdp_get_imageattrs(
1078     attributes: *const Vec<SdpAttribute>,
1079     ret_size: size_t,
1080     ret_attrs: *mut RustSdpAttributeImageAttr,
1081 ) {
1082     let attrs: Vec<_> = (*attributes)
1083         .iter()
1084         .filter_map(|x| {
1085             if let SdpAttribute::ImageAttr(ref data) = *x {
1086                 Some(RustSdpAttributeImageAttr::from(data))
1087             } else {
1088                 None
1089             }
1090         })
1091         .collect();
1092     let imageattrs = slice::from_raw_parts_mut(ret_attrs, ret_size);
1093     imageattrs.copy_from_slice(attrs.as_slice());
1094 }
1095 
1096 #[repr(C)]
1097 #[derive(Clone, Copy)]
1098 pub struct RustSdpAttributeSctpmap {
1099     pub port: u32,
1100     pub channels: u32,
1101 }
1102 
1103 impl<'a> From<&'a SdpAttributeSctpmap> for RustSdpAttributeSctpmap {
from(other: &SdpAttributeSctpmap) -> Self1104     fn from(other: &SdpAttributeSctpmap) -> Self {
1105         RustSdpAttributeSctpmap {
1106             port: other.port as u32,
1107             channels: other.channels,
1108         }
1109     }
1110 }
1111 
1112 #[no_mangle]
sdp_get_sctpmap_count(attributes: *const Vec<SdpAttribute>) -> size_t1113 pub unsafe extern "C" fn sdp_get_sctpmap_count(attributes: *const Vec<SdpAttribute>) -> size_t {
1114     count_attribute((*attributes).as_slice(), SdpAttributeType::Sctpmap)
1115 }
1116 
1117 #[no_mangle]
sdp_get_sctpmaps( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_sctpmaps: *mut RustSdpAttributeSctpmap, )1118 pub unsafe extern "C" fn sdp_get_sctpmaps(
1119     attributes: *const Vec<SdpAttribute>,
1120     ret_size: size_t,
1121     ret_sctpmaps: *mut RustSdpAttributeSctpmap,
1122 ) {
1123     let attrs: Vec<_> = (*attributes)
1124         .iter()
1125         .filter_map(|x| {
1126             if let SdpAttribute::Sctpmap(ref data) = *x {
1127                 Some(RustSdpAttributeSctpmap::from(data))
1128             } else {
1129                 None
1130             }
1131         })
1132         .collect();
1133     let sctpmaps = slice::from_raw_parts_mut(ret_sctpmaps, ret_size);
1134     sctpmaps.copy_from_slice(attrs.as_slice());
1135 }
1136 
1137 #[repr(C)]
1138 #[derive(Clone, Copy)]
1139 pub struct RustSdpAttributeSimulcastId {
1140     pub id: StringView,
1141     pub paused: bool,
1142 }
1143 
1144 impl<'a> From<&'a SdpAttributeSimulcastId> for RustSdpAttributeSimulcastId {
from(other: &SdpAttributeSimulcastId) -> Self1145     fn from(other: &SdpAttributeSimulcastId) -> Self {
1146         RustSdpAttributeSimulcastId {
1147             id: StringView::from(other.id.as_str()),
1148             paused: other.paused,
1149         }
1150     }
1151 }
1152 
1153 #[repr(C)]
1154 #[derive(Clone, Copy)]
1155 pub struct RustSdpAttributeSimulcastVersion {
1156     pub ids: *const Vec<SdpAttributeSimulcastId>,
1157 }
1158 
1159 impl<'a> From<&'a SdpAttributeSimulcastVersion> for RustSdpAttributeSimulcastVersion {
from(other: &SdpAttributeSimulcastVersion) -> Self1160     fn from(other: &SdpAttributeSimulcastVersion) -> Self {
1161         RustSdpAttributeSimulcastVersion { ids: &other.ids }
1162     }
1163 }
1164 
1165 #[no_mangle]
sdp_simulcast_get_ids_count( ids: *const Vec<SdpAttributeSimulcastId>, ) -> size_t1166 pub unsafe extern "C" fn sdp_simulcast_get_ids_count(
1167     ids: *const Vec<SdpAttributeSimulcastId>,
1168 ) -> size_t {
1169     (*ids).len()
1170 }
1171 
1172 #[no_mangle]
sdp_simulcast_get_ids( ids: *const Vec<SdpAttributeSimulcastId>, ret_size: size_t, ret: *mut RustSdpAttributeSimulcastId, )1173 pub unsafe extern "C" fn sdp_simulcast_get_ids(
1174     ids: *const Vec<SdpAttributeSimulcastId>,
1175     ret_size: size_t,
1176     ret: *mut RustSdpAttributeSimulcastId,
1177 ) {
1178     let rust_ids: Vec<_> = (*ids)
1179         .iter()
1180         .map(RustSdpAttributeSimulcastId::from)
1181         .collect();
1182     let ids = slice::from_raw_parts_mut(ret, ret_size);
1183     ids.clone_from_slice(rust_ids.as_slice());
1184 }
1185 
1186 #[repr(C)]
1187 pub struct RustSdpAttributeSimulcast {
1188     pub send: *const Vec<SdpAttributeSimulcastVersion>,
1189     pub receive: *const Vec<SdpAttributeSimulcastVersion>,
1190 }
1191 
1192 impl<'a> From<&'a SdpAttributeSimulcast> for RustSdpAttributeSimulcast {
from(other: &SdpAttributeSimulcast) -> Self1193     fn from(other: &SdpAttributeSimulcast) -> Self {
1194         RustSdpAttributeSimulcast {
1195             send: &other.send,
1196             receive: &other.receive,
1197         }
1198     }
1199 }
1200 
1201 #[no_mangle]
sdp_simulcast_get_version_count( version_list: *const Vec<SdpAttributeSimulcastVersion>, ) -> size_t1202 pub unsafe extern "C" fn sdp_simulcast_get_version_count(
1203     version_list: *const Vec<SdpAttributeSimulcastVersion>,
1204 ) -> size_t {
1205     (*version_list).len()
1206 }
1207 
1208 #[no_mangle]
sdp_simulcast_get_versions( version_list: *const Vec<SdpAttributeSimulcastVersion>, ret_size: size_t, ret: *mut RustSdpAttributeSimulcastVersion, )1209 pub unsafe extern "C" fn sdp_simulcast_get_versions(
1210     version_list: *const Vec<SdpAttributeSimulcastVersion>,
1211     ret_size: size_t,
1212     ret: *mut RustSdpAttributeSimulcastVersion,
1213 ) {
1214     let rust_versions_list: Vec<_> = (*version_list)
1215         .iter()
1216         .map(RustSdpAttributeSimulcastVersion::from)
1217         .collect();
1218     let versions = slice::from_raw_parts_mut(ret, ret_size);
1219     versions.clone_from_slice(rust_versions_list.as_slice())
1220 }
1221 
1222 #[no_mangle]
sdp_get_simulcast( attributes: *const Vec<SdpAttribute>, ret: *mut RustSdpAttributeSimulcast, ) -> nsresult1223 pub unsafe extern "C" fn sdp_get_simulcast(
1224     attributes: *const Vec<SdpAttribute>,
1225     ret: *mut RustSdpAttributeSimulcast,
1226 ) -> nsresult {
1227     let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Simulcast);
1228     if let Some(&SdpAttribute::Simulcast(ref data)) = attr {
1229         *ret = RustSdpAttributeSimulcast::from(data);
1230         return NS_OK;
1231     }
1232     NS_ERROR_INVALID_ARG
1233 }
1234 
1235 #[repr(C)]
1236 #[derive(Clone, Copy)]
1237 pub enum RustDirection {
1238     Recvonly,
1239     Sendonly,
1240     Sendrecv,
1241     Inactive,
1242 }
1243 
1244 impl<'a> From<&'a Option<SdpAttributeDirection>> for RustDirection {
from(other: &Option<SdpAttributeDirection>) -> Self1245     fn from(other: &Option<SdpAttributeDirection>) -> Self {
1246         match *other {
1247             Some(ref direction) => match *direction {
1248                 SdpAttributeDirection::Recvonly => RustDirection::Recvonly,
1249                 SdpAttributeDirection::Sendonly => RustDirection::Sendonly,
1250                 SdpAttributeDirection::Sendrecv => RustDirection::Sendrecv,
1251             },
1252             None => RustDirection::Inactive,
1253         }
1254     }
1255 }
1256 
1257 #[no_mangle]
sdp_get_direction(attributes: *const Vec<SdpAttribute>) -> RustDirection1258 pub unsafe extern "C" fn sdp_get_direction(attributes: *const Vec<SdpAttribute>) -> RustDirection {
1259     for attribute in (*attributes).iter() {
1260         match *attribute {
1261             SdpAttribute::Recvonly => {
1262                 return RustDirection::Recvonly;
1263             }
1264             SdpAttribute::Sendonly => {
1265                 return RustDirection::Sendonly;
1266             }
1267             SdpAttribute::Sendrecv => {
1268                 return RustDirection::Sendrecv;
1269             }
1270             SdpAttribute::Inactive => {
1271                 return RustDirection::Inactive;
1272             }
1273             _ => (),
1274         }
1275     }
1276     RustDirection::Sendrecv
1277 }
1278 
1279 #[repr(C)]
1280 pub struct RustSdpAttributeRemoteCandidate {
1281     pub component: u32,
1282     pub address: RustAddress,
1283     pub port: u32,
1284 }
1285 
1286 impl<'a> From<&'a SdpAttributeRemoteCandidate> for RustSdpAttributeRemoteCandidate {
from(other: &SdpAttributeRemoteCandidate) -> Self1287     fn from(other: &SdpAttributeRemoteCandidate) -> Self {
1288         RustSdpAttributeRemoteCandidate {
1289             component: other.component,
1290             address: RustAddress::from(&other.address),
1291             port: other.port,
1292         }
1293     }
1294 }
1295 
1296 #[no_mangle]
sdp_get_remote_candidate_count( attributes: *const Vec<SdpAttribute>, ) -> size_t1297 pub unsafe extern "C" fn sdp_get_remote_candidate_count(
1298     attributes: *const Vec<SdpAttribute>,
1299 ) -> size_t {
1300     count_attribute((*attributes).as_slice(), SdpAttributeType::RemoteCandidate)
1301 }
1302 
1303 #[no_mangle]
sdp_get_remote_candidates( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_candidates: *mut RustSdpAttributeRemoteCandidate, )1304 pub unsafe extern "C" fn sdp_get_remote_candidates(
1305     attributes: *const Vec<SdpAttribute>,
1306     ret_size: size_t,
1307     ret_candidates: *mut RustSdpAttributeRemoteCandidate,
1308 ) {
1309     let attrs = (*attributes).iter().filter_map(|x| {
1310         if let SdpAttribute::RemoteCandidate(ref data) = *x {
1311             Some(RustSdpAttributeRemoteCandidate::from(data))
1312         } else {
1313             None
1314         }
1315     });
1316     let candidates = slice::from_raw_parts_mut(ret_candidates, ret_size);
1317     for (source, destination) in attrs.zip(candidates) {
1318         *destination = source
1319     }
1320 }
1321 
1322 #[no_mangle]
sdp_get_candidate_count(attributes: *const Vec<SdpAttribute>) -> size_t1323 pub unsafe extern "C" fn sdp_get_candidate_count(attributes: *const Vec<SdpAttribute>) -> size_t {
1324     count_attribute((*attributes).as_slice(), SdpAttributeType::Candidate)
1325 }
1326 
1327 #[no_mangle]
sdp_get_candidates( attributes: *const Vec<SdpAttribute>, _ret_size: size_t, ret: *mut *const Vec<String>, )1328 pub unsafe extern "C" fn sdp_get_candidates(
1329     attributes: *const Vec<SdpAttribute>,
1330     _ret_size: size_t,
1331     ret: *mut *const Vec<String>,
1332 ) {
1333     let attr_strings: Vec<String> = (*attributes)
1334         .iter()
1335         .filter_map(|x| {
1336             if let SdpAttribute::Candidate(ref attr) = *x {
1337                 // The serialized attribute starts with "candidate:...", this needs to be removed
1338                 Some(attr.to_string())
1339             } else {
1340                 None
1341             }
1342         })
1343         .collect();
1344 
1345     *ret = Box::into_raw(Box::from(attr_strings));
1346 }
1347 
1348 #[repr(C)]
1349 #[derive(Clone, Copy)]
1350 pub struct RustSdpAttributeRidParameters {
1351     pub max_width: u32,
1352     pub max_height: u32,
1353     pub max_fps: u32,
1354     pub max_fs: u32,
1355     pub max_br: u32,
1356     pub max_pps: u32,
1357     pub unknown: *const Vec<String>,
1358 }
1359 
1360 impl<'a> From<&'a SdpAttributeRidParameters> for RustSdpAttributeRidParameters {
from(other: &SdpAttributeRidParameters) -> Self1361     fn from(other: &SdpAttributeRidParameters) -> Self {
1362         RustSdpAttributeRidParameters {
1363             max_width: other.max_width,
1364             max_height: other.max_height,
1365             max_fps: other.max_fps,
1366             max_fs: other.max_fs,
1367             max_br: other.max_br,
1368             max_pps: other.max_pps,
1369 
1370             unknown: &other.unknown,
1371         }
1372     }
1373 }
1374 
1375 #[repr(C)]
1376 #[derive(Clone, Copy)]
1377 pub struct RustSdpAttributeRid {
1378     pub id: StringView,
1379     pub direction: u32,
1380     pub formats: *const Vec<u16>,
1381     pub params: RustSdpAttributeRidParameters,
1382     pub depends: *const Vec<String>,
1383 }
1384 
1385 impl<'a> From<&'a SdpAttributeRid> for RustSdpAttributeRid {
from(other: &SdpAttributeRid) -> Self1386     fn from(other: &SdpAttributeRid) -> Self {
1387         RustSdpAttributeRid {
1388             id: StringView::from(other.id.as_str()),
1389             direction: other.direction.clone() as u32,
1390             formats: &other.formats,
1391             params: RustSdpAttributeRidParameters::from(&other.params),
1392             depends: &other.depends,
1393         }
1394     }
1395 }
1396 
1397 #[no_mangle]
sdp_get_rid_count(attributes: *const Vec<SdpAttribute>) -> size_t1398 pub unsafe extern "C" fn sdp_get_rid_count(attributes: *const Vec<SdpAttribute>) -> size_t {
1399     count_attribute((*attributes).as_slice(), SdpAttributeType::Rid)
1400 }
1401 
1402 #[no_mangle]
sdp_get_rids( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rids: *mut RustSdpAttributeRid, )1403 pub unsafe extern "C" fn sdp_get_rids(
1404     attributes: *const Vec<SdpAttribute>,
1405     ret_size: size_t,
1406     ret_rids: *mut RustSdpAttributeRid,
1407 ) {
1408     let attrs: Vec<_> = (*attributes)
1409         .iter()
1410         .filter_map(|x| {
1411             if let SdpAttribute::Rid(ref data) = *x {
1412                 Some(RustSdpAttributeRid::from(data))
1413             } else {
1414                 None
1415             }
1416         })
1417         .collect();
1418     let rids = slice::from_raw_parts_mut(ret_rids, ret_size);
1419     rids.clone_from_slice(attrs.as_slice());
1420 }
1421 
1422 #[repr(C)]
1423 #[derive(Clone, Copy)]
1424 pub struct RustSdpAttributeExtmap {
1425     pub id: u16,
1426     pub direction_specified: bool,
1427     pub direction: RustDirection,
1428     pub url: StringView,
1429     pub extension_attributes: StringView,
1430 }
1431 
1432 impl<'a> From<&'a SdpAttributeExtmap> for RustSdpAttributeExtmap {
from(other: &SdpAttributeExtmap) -> Self1433     fn from(other: &SdpAttributeExtmap) -> Self {
1434         let dir = if other.direction.is_some() {
1435             RustDirection::from(&other.direction)
1436         } else {
1437             RustDirection::from(&Some(SdpAttributeDirection::Sendrecv))
1438         };
1439         RustSdpAttributeExtmap {
1440             id: other.id as u16,
1441             direction_specified: other.direction.is_some(),
1442             direction: dir,
1443             url: StringView::from(other.url.as_str()),
1444             extension_attributes: StringView::from(&other.extension_attributes),
1445         }
1446     }
1447 }
1448 
1449 #[no_mangle]
sdp_get_extmap_count(attributes: *const Vec<SdpAttribute>) -> size_t1450 pub unsafe extern "C" fn sdp_get_extmap_count(attributes: *const Vec<SdpAttribute>) -> size_t {
1451     count_attribute((*attributes).as_slice(), SdpAttributeType::Extmap)
1452 }
1453 
1454 #[no_mangle]
sdp_get_extmaps( attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rids: *mut RustSdpAttributeExtmap, )1455 pub unsafe extern "C" fn sdp_get_extmaps(
1456     attributes: *const Vec<SdpAttribute>,
1457     ret_size: size_t,
1458     ret_rids: *mut RustSdpAttributeExtmap,
1459 ) {
1460     let attrs: Vec<_> = (*attributes)
1461         .iter()
1462         .filter_map(|x| {
1463             if let SdpAttribute::Extmap(ref data) = *x {
1464                 Some(RustSdpAttributeExtmap::from(data))
1465             } else {
1466                 None
1467             }
1468         })
1469         .collect();
1470     let extmaps = slice::from_raw_parts_mut(ret_rids, ret_size);
1471     extmaps.copy_from_slice(attrs.as_slice());
1472 }
1473