1use std::collections::HashMap;
2use std::convert::TryFrom;
3use std::time::{Duration, SystemTime, UNIX_EPOCH};
4use std::{fmt, io};
5
6use url::Url;
7
8use crate::lexer::*;
9use crate::util::*;
10use shared::error::{Error, Result};
11
12use super::common::*;
13use super::media::*;
14
15pub const ATTR_KEY_CANDIDATE: &str = "candidate";
17pub const ATTR_KEY_END_OF_CANDIDATES: &str = "end-of-candidates";
18pub const ATTR_KEY_IDENTITY: &str = "identity";
19pub const ATTR_KEY_GROUP: &str = "group";
20pub const ATTR_KEY_SSRC: &str = "ssrc";
21pub const ATTR_KEY_SSRC_GROUP: &str = "ssrc-group";
22pub const ATTR_KEY_MSID: &str = "msid";
23pub const ATTR_KEY_MSID_SEMANTIC: &str = "msid-semantic";
24pub const ATTR_KEY_CONNECTION_SETUP: &str = "setup";
25pub const ATTR_KEY_MID: &str = "mid";
26pub const ATTR_KEY_ICELITE: &str = "ice-lite";
27pub const ATTR_KEY_RTCPMUX: &str = "rtcp-mux";
28pub const ATTR_KEY_RTCPRSIZE: &str = "rtcp-rsize";
29pub const ATTR_KEY_INACTIVE: &str = "inactive";
30pub const ATTR_KEY_RECV_ONLY: &str = "recvonly";
31pub const ATTR_KEY_SEND_ONLY: &str = "sendonly";
32pub const ATTR_KEY_SEND_RECV: &str = "sendrecv";
33pub const ATTR_KEY_EXT_MAP: &str = "extmap";
34pub const ATTR_KEY_EXTMAP_ALLOW_MIXED: &str = "extmap-allow-mixed";
35pub const ATTR_KEY_MAX_MESSAGE_SIZE: &str = "max-message-size";
36
37pub const SEMANTIC_TOKEN_LIP_SYNCHRONIZATION: &str = "LS";
39pub const SEMANTIC_TOKEN_FLOW_IDENTIFICATION: &str = "FID";
40pub const SEMANTIC_TOKEN_FORWARD_ERROR_CORRECTION: &str = "FEC";
41pub const SEMANTIC_TOKEN_FORWARD_ERROR_CORRECTION_FRAMEWORK: &str = "FEC-FR";
43pub const SEMANTIC_TOKEN_WEBRTC_MEDIA_STREAMS: &str = "WMS";
44
45pub type Version = isize;
48
49#[derive(Debug, Default, Clone)]
52pub struct Origin {
53 pub username: String,
54 pub session_id: u64,
55 pub session_version: u64,
56 pub network_type: String,
57 pub address_type: String,
58 pub unicast_address: String,
59}
60
61impl fmt::Display for Origin {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(
64 f,
65 "{} {} {} {} {} {}",
66 self.username,
67 self.session_id,
68 self.session_version,
69 self.network_type,
70 self.address_type,
71 self.unicast_address,
72 )
73 }
74}
75
76impl Origin {
77 pub fn new() -> Self {
78 Origin {
79 username: "".to_owned(),
80 session_id: 0,
81 session_version: 0,
82 network_type: "".to_owned(),
83 address_type: "".to_owned(),
84 unicast_address: "".to_owned(),
85 }
86 }
87}
88
89pub type SessionName = String;
92
93pub type EmailAddress = String;
97
98pub type PhoneNumber = String;
102
103#[derive(Debug, Default, Clone)]
106pub struct TimeZone {
107 pub adjustment_time: u64,
108 pub offset: i64,
109}
110
111impl fmt::Display for TimeZone {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(f, "{} {}", self.adjustment_time, self.offset)
114 }
115}
116
117#[derive(Debug, Default, Clone)]
121pub struct TimeDescription {
122 pub timing: Timing,
126
127 pub repeat_times: Vec<RepeatTime>,
131}
132
133#[derive(Debug, Default, Clone)]
136pub struct Timing {
137 pub start_time: u64,
138 pub stop_time: u64,
139}
140
141impl fmt::Display for Timing {
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 write!(f, "{} {}", self.start_time, self.stop_time)
144 }
145}
146
147#[derive(Debug, Default, Clone)]
150pub struct RepeatTime {
151 pub interval: i64,
152 pub duration: i64,
153 pub offsets: Vec<i64>,
154}
155
156impl fmt::Display for RepeatTime {
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 write!(f, "{} {}", self.interval, self.duration)?;
159
160 for value in &self.offsets {
161 write!(f, " {value}")?;
162 }
163 Ok(())
164 }
165}
166
167#[derive(Debug, Default, Clone)]
170pub struct SessionDescription {
171 pub version: Version,
175
176 pub origin: Origin,
180
181 pub session_name: SessionName,
185
186 pub session_information: Option<Information>,
190
191 pub uri: Option<Url>,
195
196 pub email_address: Option<EmailAddress>,
200
201 pub phone_number: Option<PhoneNumber>,
205
206 pub connection_information: Option<ConnectionInformation>,
210
211 pub bandwidth: Vec<Bandwidth>,
215
216 pub time_descriptions: Vec<TimeDescription>,
219
220 pub time_zones: Vec<TimeZone>,
224
225 pub encryption_key: Option<EncryptionKey>,
231
232 pub attributes: Vec<Attribute>,
238
239 pub media_descriptions: Vec<MediaDescription>,
241}
242
243impl fmt::Display for SessionDescription {
244 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245 write_key_value(f, "v=", Some(&self.version))?;
246 write_key_value(f, "o=", Some(&self.origin))?;
247 write_key_value(f, "s=", Some(&self.session_name))?;
248
249 write_key_value(f, "i=", self.session_information.as_ref())?;
250
251 if let Some(uri) = &self.uri {
252 write_key_value(f, "u=", Some(uri))?;
253 }
254 write_key_value(f, "e=", self.email_address.as_ref())?;
255 write_key_value(f, "p=", self.phone_number.as_ref())?;
256 if let Some(connection_information) = &self.connection_information {
257 write_key_value(f, "c=", Some(&connection_information))?;
258 }
259
260 for bandwidth in &self.bandwidth {
261 write_key_value(f, "b=", Some(&bandwidth))?;
262 }
263 for time_description in &self.time_descriptions {
264 write_key_value(f, "t=", Some(&time_description.timing))?;
265 for repeat_time in &time_description.repeat_times {
266 write_key_value(f, "r=", Some(&repeat_time))?;
267 }
268 }
269
270 write_key_slice_of_values(f, "z=", &self.time_zones)?;
271
272 write_key_value(f, "k=", self.encryption_key.as_ref())?;
273 for attribute in &self.attributes {
274 write_key_value(f, "a=", Some(&attribute))?;
275 }
276
277 for media_description in &self.media_descriptions {
278 write_key_value(f, "m=", Some(&media_description.media_name))?;
279 write_key_value(f, "i=", media_description.media_title.as_ref())?;
280 if let Some(connection_information) = &media_description.connection_information {
281 write_key_value(f, "c=", Some(&connection_information))?;
282 }
283 for bandwidth in &media_description.bandwidth {
284 write_key_value(f, "b=", Some(&bandwidth))?;
285 }
286 write_key_value(f, "k=", media_description.encryption_key.as_ref())?;
287 for attribute in &media_description.attributes {
288 write_key_value(f, "a=", Some(&attribute))?;
289 }
290 }
291
292 Ok(())
293 }
294}
295
296impl SessionDescription {
298 pub fn new_jsep_session_description(identity: bool) -> Self {
303 let d = SessionDescription {
304 version: 0,
305 origin: Origin {
306 username: "-".to_string(),
307 session_id: new_session_id(),
308 session_version: SystemTime::now()
309 .duration_since(UNIX_EPOCH)
310 .unwrap_or_else(|_| Duration::from_secs(0))
311 .subsec_nanos() as u64,
312 network_type: "IN".to_string(),
313 address_type: "IP4".to_string(),
314 unicast_address: "0.0.0.0".to_string(),
315 },
316 session_name: "-".to_string(),
317 session_information: None,
318 uri: None,
319 email_address: None,
320 phone_number: None,
321 connection_information: None,
322 bandwidth: vec![],
323 time_descriptions: vec![TimeDescription {
324 timing: Timing {
325 start_time: 0,
326 stop_time: 0,
327 },
328 repeat_times: vec![],
329 }],
330 time_zones: vec![],
331 encryption_key: None,
332 attributes: vec![], media_descriptions: vec![],
334 };
335
336 if identity {
337 d.with_property_attribute(ATTR_KEY_IDENTITY.to_string())
338 } else {
339 d
340 }
341 }
342
343 pub fn with_property_attribute(mut self, key: String) -> Self {
345 self.attributes.push(Attribute::new(key, None));
346 self
347 }
348
349 pub fn with_value_attribute(mut self, key: String, value: String) -> Self {
351 self.attributes.push(Attribute::new(key, Some(value)));
352 self
353 }
354
355 pub fn with_fingerprint(self, algorithm: String, value: String) -> Self {
357 self.with_value_attribute("fingerprint".to_string(), algorithm + " " + value.as_str())
358 }
359
360 pub fn with_media(mut self, md: MediaDescription) -> Self {
362 self.media_descriptions.push(md);
363 self
364 }
365
366 fn build_codec_map(&self) -> HashMap<u8, Codec> {
367 let mut codecs: HashMap<u8, Codec> = HashMap::new();
368
369 for m in &self.media_descriptions {
370 codecs.extend(m.codecs());
371 }
372
373 codecs
374 }
375
376 pub fn get_codec_for_payload_type(&self, payload_type: u8) -> Result<Codec> {
378 let codecs = self.build_codec_map();
379
380 if let Some(codec) = codecs.get(&payload_type) {
381 Ok(codec.clone())
382 } else {
383 Err(Error::PayloadTypeNotFound)
384 }
385 }
386
387 pub fn get_payload_type_for_codec(&self, wanted: &Codec) -> Result<u8> {
390 let codecs = self.build_codec_map();
391
392 for (payload_type, codec) in codecs.iter() {
393 if codecs_match(wanted, codec) {
394 return Ok(*payload_type);
395 }
396 }
397
398 Err(Error::CodecNotFound)
399 }
400
401 pub fn has_attribute(&self, key: &str) -> bool {
403 self.attributes.iter().any(|a| a.key == key)
404 }
405
406 pub fn attribute(&self, key: &str) -> Option<&String> {
408 for a in &self.attributes {
409 if a.key == key {
410 return a.value.as_ref();
411 }
412 }
413 None
414 }
415
416 pub fn marshal(&self) -> String {
450 self.to_string()
451 }
452
453 pub fn unmarshal<R: io::BufRead + io::Seek>(reader: &mut R) -> Result<Self> {
532 let mut lexer = Lexer {
533 desc: SessionDescription {
534 version: 0,
535 origin: Origin::new(),
536 session_name: "".to_owned(),
537 session_information: None,
538 uri: None,
539 email_address: None,
540 phone_number: None,
541 connection_information: None,
542 bandwidth: vec![],
543 time_descriptions: vec![],
544 time_zones: vec![],
545 encryption_key: None,
546 attributes: vec![],
547 media_descriptions: vec![],
548 },
549 reader,
550 };
551
552 let mut state = Some(StateFn { f: s1 });
553 while let Some(s) = state {
554 state = (s.f)(&mut lexer)?;
555 }
556
557 Ok(lexer.desc)
558 }
559}
560
561impl From<SessionDescription> for String {
562 fn from(sdp: SessionDescription) -> String {
563 sdp.marshal()
564 }
565}
566
567impl TryFrom<String> for SessionDescription {
568 type Error = Error;
569 fn try_from(sdp_string: String) -> Result<Self> {
570 let mut reader = io::Cursor::new(sdp_string.as_bytes());
571 let session_description = SessionDescription::unmarshal(&mut reader)?;
572 Ok(session_description)
573 }
574}
575
576fn s1<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
577 let (key, _) = read_type(lexer.reader)?;
578 if &key == b"v=" {
579 return Ok(Some(StateFn {
580 f: unmarshal_protocol_version,
581 }));
582 }
583
584 Err(Error::SdpInvalidSyntax(String::from_utf8(key)?))
585}
586
587fn s2<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
588 let (key, _) = read_type(lexer.reader)?;
589 if &key == b"o=" {
590 return Ok(Some(StateFn {
591 f: unmarshal_origin,
592 }));
593 }
594
595 Err(Error::SdpInvalidSyntax(String::from_utf8(key)?))
596}
597
598fn s3<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
599 let (key, _) = read_type(lexer.reader)?;
600 if &key == b"s=" {
601 return Ok(Some(StateFn {
602 f: unmarshal_session_name,
603 }));
604 }
605
606 Err(Error::SdpInvalidSyntax(String::from_utf8(key)?))
607}
608
609fn s4<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
610 let (key, _) = read_type(lexer.reader)?;
611 match key.as_slice() {
612 b"i=" => Ok(Some(StateFn {
613 f: unmarshal_session_information,
614 })),
615 b"u=" => Ok(Some(StateFn { f: unmarshal_uri })),
616 b"e=" => Ok(Some(StateFn { f: unmarshal_email })),
617 b"p=" => Ok(Some(StateFn { f: unmarshal_phone })),
618 b"c=" => Ok(Some(StateFn {
619 f: unmarshal_session_connection_information,
620 })),
621 b"b=" => Ok(Some(StateFn {
622 f: unmarshal_session_bandwidth,
623 })),
624 b"t=" => Ok(Some(StateFn {
625 f: unmarshal_timing,
626 })),
627 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
628 }
629}
630
631fn s5<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
632 let (key, _) = read_type(lexer.reader)?;
633 match key.as_slice() {
634 b"b=" => Ok(Some(StateFn {
635 f: unmarshal_session_bandwidth,
636 })),
637 b"t=" => Ok(Some(StateFn {
638 f: unmarshal_timing,
639 })),
640 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
641 }
642}
643
644fn s6<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
645 let (key, _) = read_type(lexer.reader)?;
646 match key.as_slice() {
647 b"p=" => Ok(Some(StateFn { f: unmarshal_phone })),
648 b"c=" => Ok(Some(StateFn {
649 f: unmarshal_session_connection_information,
650 })),
651 b"b=" => Ok(Some(StateFn {
652 f: unmarshal_session_bandwidth,
653 })),
654 b"t=" => Ok(Some(StateFn {
655 f: unmarshal_timing,
656 })),
657 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
658 }
659}
660
661fn s7<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
662 let (key, _) = read_type(lexer.reader)?;
663 match key.as_slice() {
664 b"u=" => Ok(Some(StateFn { f: unmarshal_uri })),
665 b"e=" => Ok(Some(StateFn { f: unmarshal_email })),
666 b"p=" => Ok(Some(StateFn { f: unmarshal_phone })),
667 b"c=" => Ok(Some(StateFn {
668 f: unmarshal_session_connection_information,
669 })),
670 b"b=" => Ok(Some(StateFn {
671 f: unmarshal_session_bandwidth,
672 })),
673 b"t=" => Ok(Some(StateFn {
674 f: unmarshal_timing,
675 })),
676 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
677 }
678}
679
680fn s8<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
681 let (key, _) = read_type(lexer.reader)?;
682 match key.as_slice() {
683 b"c=" => Ok(Some(StateFn {
684 f: unmarshal_session_connection_information,
685 })),
686 b"b=" => Ok(Some(StateFn {
687 f: unmarshal_session_bandwidth,
688 })),
689 b"t=" => Ok(Some(StateFn {
690 f: unmarshal_timing,
691 })),
692 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
693 }
694}
695
696fn s9<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
697 let (key, num_bytes) = read_type(lexer.reader)?;
698 if key.is_empty() && num_bytes == 0 {
699 return Ok(None);
700 }
701
702 match key.as_slice() {
703 b"z=" => Ok(Some(StateFn {
704 f: unmarshal_time_zones,
705 })),
706 b"k=" => Ok(Some(StateFn {
707 f: unmarshal_session_encryption_key,
708 })),
709 b"a=" => Ok(Some(StateFn {
710 f: unmarshal_session_attribute,
711 })),
712 b"r=" => Ok(Some(StateFn {
713 f: unmarshal_repeat_times,
714 })),
715 b"t=" => Ok(Some(StateFn {
716 f: unmarshal_timing,
717 })),
718 b"m=" => Ok(Some(StateFn {
719 f: unmarshal_media_description,
720 })),
721 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
722 }
723}
724
725fn s10<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
726 let (key, _) = read_type(lexer.reader)?;
727 match key.as_slice() {
728 b"e=" => Ok(Some(StateFn { f: unmarshal_email })),
729 b"p=" => Ok(Some(StateFn { f: unmarshal_phone })),
730 b"c=" => Ok(Some(StateFn {
731 f: unmarshal_session_connection_information,
732 })),
733 b"b=" => Ok(Some(StateFn {
734 f: unmarshal_session_bandwidth,
735 })),
736 b"t=" => Ok(Some(StateFn {
737 f: unmarshal_timing,
738 })),
739 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
740 }
741}
742
743fn s11<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
744 let (key, num_bytes) = read_type(lexer.reader)?;
745 if key.is_empty() && num_bytes == 0 {
746 return Ok(None);
747 }
748
749 match key.as_slice() {
750 b"a=" => Ok(Some(StateFn {
751 f: unmarshal_session_attribute,
752 })),
753 b"m=" => Ok(Some(StateFn {
754 f: unmarshal_media_description,
755 })),
756 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
757 }
758}
759
760fn s12<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
761 let (key, num_bytes) = read_type(lexer.reader)?;
762 if key.is_empty() && num_bytes == 0 {
763 return Ok(None);
764 }
765
766 match key.as_slice() {
767 b"a=" => Ok(Some(StateFn {
768 f: unmarshal_media_attribute,
769 })),
770 b"k=" => Ok(Some(StateFn {
771 f: unmarshal_media_encryption_key,
772 })),
773 b"b=" => Ok(Some(StateFn {
774 f: unmarshal_media_bandwidth,
775 })),
776 b"c=" => Ok(Some(StateFn {
777 f: unmarshal_media_connection_information,
778 })),
779 b"i=" => Ok(Some(StateFn {
780 f: unmarshal_media_title,
781 })),
782 b"m=" => Ok(Some(StateFn {
783 f: unmarshal_media_description,
784 })),
785 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
786 }
787}
788
789fn s13<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
790 let (key, num_bytes) = read_type(lexer.reader)?;
791 if key.is_empty() && num_bytes == 0 {
792 return Ok(None);
793 }
794
795 match key.as_slice() {
796 b"a=" => Ok(Some(StateFn {
797 f: unmarshal_session_attribute,
798 })),
799 b"k=" => Ok(Some(StateFn {
800 f: unmarshal_session_encryption_key,
801 })),
802 b"m=" => Ok(Some(StateFn {
803 f: unmarshal_media_description,
804 })),
805 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
806 }
807}
808
809fn s14<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
810 let (key, num_bytes) = read_type(lexer.reader)?;
811 if key.is_empty() && num_bytes == 0 {
812 return Ok(None);
813 }
814
815 match key.as_slice() {
816 b"a=" => Ok(Some(StateFn {
817 f: unmarshal_media_attribute,
818 })),
819 b"k=" => Ok(Some(StateFn {
821 f: unmarshal_media_encryption_key,
822 })),
823 b"b=" => Ok(Some(StateFn {
825 f: unmarshal_media_bandwidth,
826 })),
827 b"c=" => Ok(Some(StateFn {
829 f: unmarshal_media_connection_information,
830 })),
831 b"i=" => Ok(Some(StateFn {
833 f: unmarshal_media_title,
834 })),
835 b"m=" => Ok(Some(StateFn {
836 f: unmarshal_media_description,
837 })),
838 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
839 }
840}
841
842fn s15<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
843 let (key, num_bytes) = read_type(lexer.reader)?;
844 if key.is_empty() && num_bytes == 0 {
845 return Ok(None);
846 }
847
848 match key.as_slice() {
849 b"a=" => Ok(Some(StateFn {
850 f: unmarshal_media_attribute,
851 })),
852 b"k=" => Ok(Some(StateFn {
853 f: unmarshal_media_encryption_key,
854 })),
855 b"b=" => Ok(Some(StateFn {
856 f: unmarshal_media_bandwidth,
857 })),
858 b"c=" => Ok(Some(StateFn {
859 f: unmarshal_media_connection_information,
860 })),
861 b"i=" => Ok(Some(StateFn {
863 f: unmarshal_media_title,
864 })),
865 b"m=" => Ok(Some(StateFn {
866 f: unmarshal_media_description,
867 })),
868 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
869 }
870}
871
872fn s16<'a, R: io::BufRead + io::Seek>(lexer: &mut Lexer<'a, R>) -> Result<Option<StateFn<'a, R>>> {
873 let (key, num_bytes) = read_type(lexer.reader)?;
874 if key.is_empty() && num_bytes == 0 {
875 return Ok(None);
876 }
877
878 match key.as_slice() {
879 b"a=" => Ok(Some(StateFn {
880 f: unmarshal_media_attribute,
881 })),
882 b"k=" => Ok(Some(StateFn {
883 f: unmarshal_media_encryption_key,
884 })),
885 b"c=" => Ok(Some(StateFn {
886 f: unmarshal_media_connection_information,
887 })),
888 b"b=" => Ok(Some(StateFn {
889 f: unmarshal_media_bandwidth,
890 })),
891 b"i=" => Ok(Some(StateFn {
893 f: unmarshal_media_title,
894 })),
895 b"m=" => Ok(Some(StateFn {
896 f: unmarshal_media_description,
897 })),
898 _ => Err(Error::SdpInvalidSyntax(String::from_utf8(key)?)),
899 }
900}
901
902fn unmarshal_protocol_version<'a, R: io::BufRead + io::Seek>(
903 lexer: &mut Lexer<'a, R>,
904) -> Result<Option<StateFn<'a, R>>> {
905 let (value, _) = read_value(lexer.reader)?;
906
907 let version = value.parse::<u32>()?;
908
909 if version != 0 {
912 return Err(Error::SdpInvalidSyntax(value));
913 }
914
915 Ok(Some(StateFn { f: s2 }))
916}
917
918fn unmarshal_origin<'a, R: io::BufRead + io::Seek>(
919 lexer: &mut Lexer<'a, R>,
920) -> Result<Option<StateFn<'a, R>>> {
921 let (value, _) = read_value(lexer.reader)?;
922
923 let fields: Vec<&str> = value.split_whitespace().collect();
924 if fields.len() != 6 {
925 return Err(Error::SdpInvalidSyntax(format!("`o={value}`")));
926 }
927
928 let session_id = fields[1].parse::<u64>()?;
929 let session_version = fields[2].parse::<u64>()?;
930
931 let i = index_of(fields[3], &["IN"]);
934 if i == -1 {
935 return Err(Error::SdpInvalidValue(fields[3].to_owned()));
936 }
937
938 let i = index_of(fields[4], &["IP4", "IP6"]);
941 if i == -1 {
942 return Err(Error::SdpInvalidValue(fields[4].to_owned()));
943 }
944
945 lexer.desc.origin = Origin {
948 username: fields[0].to_owned(),
949 session_id,
950 session_version,
951 network_type: fields[3].to_owned(),
952 address_type: fields[4].to_owned(),
953 unicast_address: fields[5].to_owned(),
954 };
955
956 Ok(Some(StateFn { f: s3 }))
957}
958
959fn unmarshal_session_name<'a, R: io::BufRead + io::Seek>(
960 lexer: &mut Lexer<'a, R>,
961) -> Result<Option<StateFn<'a, R>>> {
962 let (value, _) = read_value(lexer.reader)?;
963 lexer.desc.session_name = value;
964 Ok(Some(StateFn { f: s4 }))
965}
966
967fn unmarshal_session_information<'a, R: io::BufRead + io::Seek>(
968 lexer: &mut Lexer<'a, R>,
969) -> Result<Option<StateFn<'a, R>>> {
970 let (value, _) = read_value(lexer.reader)?;
971 lexer.desc.session_information = Some(value);
972 Ok(Some(StateFn { f: s7 }))
973}
974
975fn unmarshal_uri<'a, R: io::BufRead + io::Seek>(
976 lexer: &mut Lexer<'a, R>,
977) -> Result<Option<StateFn<'a, R>>> {
978 let (value, _) = read_value(lexer.reader)?;
979 lexer.desc.uri = Some(Url::parse(&value)?);
980 Ok(Some(StateFn { f: s10 }))
981}
982
983fn unmarshal_email<'a, R: io::BufRead + io::Seek>(
984 lexer: &mut Lexer<'a, R>,
985) -> Result<Option<StateFn<'a, R>>> {
986 let (value, _) = read_value(lexer.reader)?;
987 lexer.desc.email_address = Some(value);
988 Ok(Some(StateFn { f: s6 }))
989}
990
991fn unmarshal_phone<'a, R: io::BufRead + io::Seek>(
992 lexer: &mut Lexer<'a, R>,
993) -> Result<Option<StateFn<'a, R>>> {
994 let (value, _) = read_value(lexer.reader)?;
995 lexer.desc.phone_number = Some(value);
996 Ok(Some(StateFn { f: s8 }))
997}
998
999fn unmarshal_session_connection_information<'a, R: io::BufRead + io::Seek>(
1000 lexer: &mut Lexer<'a, R>,
1001) -> Result<Option<StateFn<'a, R>>> {
1002 let (value, _) = read_value(lexer.reader)?;
1003 lexer.desc.connection_information = unmarshal_connection_information(&value)?;
1004 Ok(Some(StateFn { f: s5 }))
1005}
1006
1007fn unmarshal_connection_information(value: &str) -> Result<Option<ConnectionInformation>> {
1008 let fields: Vec<&str> = value.split_whitespace().collect();
1009 if fields.len() < 2 {
1010 return Err(Error::SdpInvalidSyntax(format!("`c={value}`")));
1011 }
1012
1013 let i = index_of(fields[0], &["IN"]);
1016 if i == -1 {
1017 return Err(Error::SdpInvalidValue(fields[0].to_owned()));
1018 }
1019
1020 let i = index_of(fields[1], &["IP4", "IP6"]);
1023 if i == -1 {
1024 return Err(Error::SdpInvalidValue(fields[1].to_owned()));
1025 }
1026
1027 let address = if fields.len() > 2 {
1028 Some(Address {
1029 address: fields[2].to_owned(),
1030 ttl: None,
1031 range: None,
1032 })
1033 } else {
1034 None
1035 };
1036
1037 Ok(Some(ConnectionInformation {
1038 network_type: fields[0].to_owned(),
1039 address_type: fields[1].to_owned(),
1040 address,
1041 }))
1042}
1043
1044fn unmarshal_session_bandwidth<'a, R: io::BufRead + io::Seek>(
1045 lexer: &mut Lexer<'a, R>,
1046) -> Result<Option<StateFn<'a, R>>> {
1047 let (value, _) = read_value(lexer.reader)?;
1048 lexer.desc.bandwidth.push(unmarshal_bandwidth(&value)?);
1049 Ok(Some(StateFn { f: s5 }))
1050}
1051
1052fn unmarshal_bandwidth(value: &str) -> Result<Bandwidth> {
1053 let mut parts: Vec<&str> = value.split(':').collect();
1054 if parts.len() != 2 {
1055 return Err(Error::SdpInvalidSyntax(format!("`b={value}`")));
1056 }
1057
1058 let experimental = parts[0].starts_with("X-");
1059 if experimental {
1060 parts[0] = parts[0].trim_start_matches("X-");
1061 }
1062 let bandwidth = parts[1].parse::<u64>()?;
1066
1067 Ok(Bandwidth {
1068 experimental,
1069 bandwidth_type: parts[0].to_owned(),
1070 bandwidth,
1071 })
1072}
1073
1074fn unmarshal_timing<'a, R: io::BufRead + io::Seek>(
1075 lexer: &mut Lexer<'a, R>,
1076) -> Result<Option<StateFn<'a, R>>> {
1077 let (value, _) = read_value(lexer.reader)?;
1078
1079 let fields: Vec<&str> = value.split_whitespace().collect();
1080 if fields.len() < 2 {
1081 return Err(Error::SdpInvalidSyntax(format!("`t={value}`")));
1082 }
1083
1084 let start_time = fields[0].parse::<u64>()?;
1085 let stop_time = fields[1].parse::<u64>()?;
1086
1087 lexer.desc.time_descriptions.push(TimeDescription {
1088 timing: Timing {
1089 start_time,
1090 stop_time,
1091 },
1092 repeat_times: vec![],
1093 });
1094
1095 Ok(Some(StateFn { f: s9 }))
1096}
1097
1098fn unmarshal_repeat_times<'a, R: io::BufRead + io::Seek>(
1099 lexer: &mut Lexer<'a, R>,
1100) -> Result<Option<StateFn<'a, R>>> {
1101 let (value, _) = read_value(lexer.reader)?;
1102
1103 let fields: Vec<&str> = value.split_whitespace().collect();
1104 if fields.len() < 3 {
1105 return Err(Error::SdpInvalidSyntax(format!("`r={value}`")));
1106 }
1107
1108 if let Some(latest_time_desc) = lexer.desc.time_descriptions.last_mut() {
1109 let interval = parse_time_units(fields[0])?;
1110 let duration = parse_time_units(fields[1])?;
1111 let mut offsets = vec![];
1112 for field in fields.iter().skip(2) {
1113 let offset = parse_time_units(field)?;
1114 offsets.push(offset);
1115 }
1116 latest_time_desc.repeat_times.push(RepeatTime {
1117 interval,
1118 duration,
1119 offsets,
1120 });
1121
1122 Ok(Some(StateFn { f: s9 }))
1123 } else {
1124 Err(Error::SdpEmptyTimeDescription)
1125 }
1126}
1127
1128fn unmarshal_time_zones<'a, R: io::BufRead + io::Seek>(
1129 lexer: &mut Lexer<'a, R>,
1130) -> Result<Option<StateFn<'a, R>>> {
1131 let (value, _) = read_value(lexer.reader)?;
1132
1133 let fields: Vec<&str> = value.split_whitespace().collect();
1137 if !fields.len().is_multiple_of(2) {
1138 return Err(Error::SdpInvalidSyntax(format!("`t={value}`")));
1139 }
1140
1141 for i in (0..fields.len()).step_by(2) {
1142 let adjustment_time = fields[i].parse::<u64>()?;
1143 let offset = parse_time_units(fields[i + 1])?;
1144
1145 lexer.desc.time_zones.push(TimeZone {
1146 adjustment_time,
1147 offset,
1148 });
1149 }
1150
1151 Ok(Some(StateFn { f: s13 }))
1152}
1153
1154fn unmarshal_session_encryption_key<'a, R: io::BufRead + io::Seek>(
1155 lexer: &mut Lexer<'a, R>,
1156) -> Result<Option<StateFn<'a, R>>> {
1157 let (value, _) = read_value(lexer.reader)?;
1158 lexer.desc.encryption_key = Some(value);
1159 Ok(Some(StateFn { f: s11 }))
1160}
1161
1162fn unmarshal_session_attribute<'a, R: io::BufRead + io::Seek>(
1163 lexer: &mut Lexer<'a, R>,
1164) -> Result<Option<StateFn<'a, R>>> {
1165 let (value, _) = read_value(lexer.reader)?;
1166
1167 let fields: Vec<&str> = value.splitn(2, ':').collect();
1168 let attribute = if fields.len() == 2 {
1169 Attribute {
1170 key: fields[0].to_owned(),
1171 value: Some(fields[1].to_owned()),
1172 }
1173 } else {
1174 Attribute {
1175 key: fields[0].to_owned(),
1176 value: None,
1177 }
1178 };
1179 lexer.desc.attributes.push(attribute);
1180
1181 Ok(Some(StateFn { f: s11 }))
1182}
1183
1184fn unmarshal_media_description<'a, R: io::BufRead + io::Seek>(
1185 lexer: &mut Lexer<'a, R>,
1186) -> Result<Option<StateFn<'a, R>>> {
1187 let (value, _) = read_value(lexer.reader)?;
1188
1189 let fields: Vec<&str> = value.split_whitespace().collect();
1190 if fields.len() < 4 {
1191 return Err(Error::SdpInvalidSyntax(format!("`m={value}`")));
1192 }
1193
1194 let i = index_of(
1200 fields[0],
1201 &["audio", "video", "text", "application", "message", "image"],
1202 );
1203 if i == -1 {
1204 return Err(Error::SdpInvalidValue(fields[0].to_owned()));
1205 }
1206
1207 let parts: Vec<&str> = fields[1].split('/').collect();
1209 let port_value = parts[0].parse::<u16>()? as isize;
1210 let port_range = if parts.len() > 1 {
1211 Some(parts[1].parse::<i32>()? as isize)
1212 } else {
1213 None
1214 };
1215
1216 let mut protos = vec![];
1225 for proto in fields[2].split('/').collect::<Vec<&str>>() {
1226 if proto.is_empty() {
1227 return Err(Error::SdpInvalidValue(fields[2].to_owned()));
1228 }
1229 protos.push(proto.to_owned());
1230 }
1231
1232 let mut formats = vec![];
1234 for field in fields.iter().skip(3) {
1235 formats.push(field.to_string());
1236 }
1237
1238 lexer.desc.media_descriptions.push(MediaDescription {
1239 media_name: MediaName {
1240 media: fields[0].to_owned(),
1241 port: RangedPort {
1242 value: port_value,
1243 range: port_range,
1244 },
1245 protos,
1246 formats,
1247 },
1248 media_title: None,
1249 connection_information: None,
1250 bandwidth: vec![],
1251 encryption_key: None,
1252 attributes: vec![],
1253 });
1254
1255 Ok(Some(StateFn { f: s12 }))
1256}
1257
1258fn unmarshal_media_title<'a, R: io::BufRead + io::Seek>(
1259 lexer: &mut Lexer<'a, R>,
1260) -> Result<Option<StateFn<'a, R>>> {
1261 let (value, _) = read_value(lexer.reader)?;
1262
1263 if let Some(latest_media_desc) = lexer.desc.media_descriptions.last_mut() {
1264 latest_media_desc.media_title = Some(value);
1265 Ok(Some(StateFn { f: s16 }))
1266 } else {
1267 Err(Error::SdpEmptyTimeDescription)
1268 }
1269}
1270
1271fn unmarshal_media_connection_information<'a, R: io::BufRead + io::Seek>(
1272 lexer: &mut Lexer<'a, R>,
1273) -> Result<Option<StateFn<'a, R>>> {
1274 let (value, _) = read_value(lexer.reader)?;
1275
1276 if let Some(latest_media_desc) = lexer.desc.media_descriptions.last_mut() {
1277 latest_media_desc.connection_information = unmarshal_connection_information(&value)?;
1278 Ok(Some(StateFn { f: s15 }))
1279 } else {
1280 Err(Error::SdpEmptyTimeDescription)
1281 }
1282}
1283
1284fn unmarshal_media_bandwidth<'a, R: io::BufRead + io::Seek>(
1285 lexer: &mut Lexer<'a, R>,
1286) -> Result<Option<StateFn<'a, R>>> {
1287 let (value, _) = read_value(lexer.reader)?;
1288
1289 if let Some(latest_media_desc) = lexer.desc.media_descriptions.last_mut() {
1290 let bandwidth = unmarshal_bandwidth(&value)?;
1291 latest_media_desc.bandwidth.push(bandwidth);
1292 Ok(Some(StateFn { f: s15 }))
1293 } else {
1294 Err(Error::SdpEmptyTimeDescription)
1295 }
1296}
1297
1298fn unmarshal_media_encryption_key<'a, R: io::BufRead + io::Seek>(
1299 lexer: &mut Lexer<'a, R>,
1300) -> Result<Option<StateFn<'a, R>>> {
1301 let (value, _) = read_value(lexer.reader)?;
1302
1303 if let Some(latest_media_desc) = lexer.desc.media_descriptions.last_mut() {
1304 latest_media_desc.encryption_key = Some(value);
1305 Ok(Some(StateFn { f: s14 }))
1306 } else {
1307 Err(Error::SdpEmptyTimeDescription)
1308 }
1309}
1310
1311fn unmarshal_media_attribute<'a, R: io::BufRead + io::Seek>(
1312 lexer: &mut Lexer<'a, R>,
1313) -> Result<Option<StateFn<'a, R>>> {
1314 let (value, _) = read_value(lexer.reader)?;
1315
1316 let fields: Vec<&str> = value.splitn(2, ':').collect();
1317 let attribute = if fields.len() == 2 {
1318 Attribute {
1319 key: fields[0].to_owned(),
1320 value: Some(fields[1].to_owned()),
1321 }
1322 } else {
1323 Attribute {
1324 key: fields[0].to_owned(),
1325 value: None,
1326 }
1327 };
1328
1329 if let Some(latest_media_desc) = lexer.desc.media_descriptions.last_mut() {
1330 latest_media_desc.attributes.push(attribute);
1331 Ok(Some(StateFn { f: s14 }))
1332 } else {
1333 Err(Error::SdpEmptyTimeDescription)
1334 }
1335}
1336
1337fn parse_time_units(value: &str) -> Result<i64> {
1338 let val = value.as_bytes();
1341 let len = val.len();
1342 let (num, factor) = match val.last() {
1343 Some(b'd') => (&value[..len - 1], 86400), Some(b'h') => (&value[..len - 1], 3600), Some(b'm') => (&value[..len - 1], 60), Some(b's') => (&value[..len - 1], 1), _ => (value, 1),
1348 };
1349 num.parse::<i64>()?
1350 .checked_mul(factor)
1351 .ok_or_else(|| Error::SdpInvalidValue(value.to_owned()))
1352}