Skip to content

Commit 017b97f

Browse files
committed
add rtcp struct
1 parent eda5e89 commit 017b97f

File tree

1 file changed

+103
-9
lines changed

1 file changed

+103
-9
lines changed

src/lib.rs

Lines changed: 103 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,90 @@ impl Display for Fmtp {
472472
f.write_str(&self.as_string())
473473
}
474474
}
475+
/// RTCP port number and address to be used if not algorithmically derived
476+
/// from the RTP port described in the media line
477+
///
478+
/// See [RFC 3605 Section 2.1] https://datatracker.ietf.org/doc/html/rfc3605#section-2.1
479+
pub struct Rtcp {
480+
/// Port used for the media stream
481+
port: u16,
482+
/// Network Type
483+
nettype: NetType,
484+
/// Address type
485+
addrtype: AddrType,
486+
/// IP Address, unicast or multicast
487+
connection_address: IpAddr,
488+
}
489+
490+
impl Rtcp {
491+
/// Converts the Rtcp to String
492+
pub fn as_string(&self) -> String {
493+
format!(
494+
"{} {} {} {}",
495+
self.port, self.nettype, self.addrtype, self.connection_address
496+
)
497+
}
498+
}
499+
500+
impl FromStr for Rtcp {
501+
type Err = AttributeErr;
502+
503+
fn from_str(s: &str) -> Result<Self, Self::Err> {
504+
let mut i = s.split(' ');
505+
let Some(port) = i.next() else {
506+
return Err(AttributeErr(
507+
"No values for rtcp attribute, failed to get port number",
508+
));
509+
};
510+
511+
let Ok(port) = port.parse::<u16>() else {
512+
return Err(AttributeErr("Failed to parse port in rtcp"));
513+
};
514+
515+
let Some(nettype) = i.next() else {
516+
return Err(AttributeErr(
517+
"No values for rtcp attribute, failed to get network type",
518+
));
519+
};
520+
521+
let Ok(nettype) = NetType::from_str(nettype) else {
522+
return Err(AttributeErr("Failed to parse network type in rtcp"));
523+
};
524+
525+
let Some(addrtype) = i.next() else {
526+
return Err(AttributeErr(
527+
"No values for rtcp attribute, failed to get address type",
528+
));
529+
};
530+
531+
let Ok(addrtype) = AddrType::from_str(addrtype) else {
532+
return Err(AttributeErr("Failed to parse address type in rtcp"));
533+
};
534+
535+
let Some(connection_addr) = i.next() else {
536+
return Err(AttributeErr(
537+
"No values for rtcp attribute, failed to get connection address",
538+
));
539+
};
540+
541+
let Ok(connection_address) = connection_addr.parse() else {
542+
return Err(AttributeErr("Failed to parse connection address in rtcp"));
543+
};
544+
545+
Ok(Self {
546+
port,
547+
nettype,
548+
addrtype,
549+
connection_address,
550+
})
551+
}
552+
}
553+
554+
impl Display for Rtcp {
555+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
556+
f.write_str(&self.as_string())
557+
}
558+
}
475559

476560
/// Originator of the session.
477561
///
@@ -998,7 +1082,15 @@ a=fingerprint:sha-256 3A:96:6D:57:B2:C2:C7:61:A0:46:3E:1C:97:39:D3:F7:0A:88:A0:B
9981082
},
9991083
Attribute {
10001084
attribute: "rtcp".into(),
1001-
value: None,
1085+
value: Some(
1086+
Rtcp {
1087+
port: 53020,
1088+
nettype: NetType::In,
1089+
addrtype: AddrType::Ip4,
1090+
connection_address: IpAddr::V4(std::net::Ipv4Addr::new(126, 16, 64, 4)),
1091+
}
1092+
.as_string(),
1093+
),
10021094
},
10031095
],
10041096
};
@@ -1011,7 +1103,10 @@ a=fingerprint:sha-256 3A:96:6D:57:B2:C2:C7:61:A0:46:3E:1C:97:39:D3:F7:0A:88:A0:B
10111103
media.get_first_attribute_value("rtpmap"),
10121104
Ok(Some("99 h263-1998/90000"))
10131105
);
1014-
assert_eq!(media.get_first_attribute_value("rtcp"), Ok(None));
1106+
assert_eq!(
1107+
media.get_first_attribute_value("rtcp"),
1108+
Ok(Some("53020 IN IP4 126.16.64.4"))
1109+
);
10151110
assert_eq!(
10161111
media.get_first_attribute_value("foo"),
10171112
Err(AttributeNotFoundError)
@@ -1045,13 +1140,12 @@ a=fingerprint:sha-256 3A:96:6D:57:B2:C2:C7:61:A0:46:3E:1C:97:39:D3:F7:0A:88:A0:B
10451140
))
10461141
);
10471142

1048-
assert_eq!(
1049-
media
1050-
.get_attribute_values("rtcp")
1051-
.unwrap()
1052-
.collect::<Vec<_>>(),
1053-
&[None]
1054-
);
1143+
let r = media
1144+
.get_attribute_values_typed("rtcp")
1145+
.collect::<Vec<Result<Rtcp, AttributeErr>>>();
1146+
assert_eq!(r[0].as_ref().unwrap().addrtype, AddrType::Ip4);
1147+
assert_eq!(r[0].as_ref().unwrap().port, 53020);
1148+
10551149
assert!(media.get_attribute_values("foo").is_err());
10561150
}
10571151

0 commit comments

Comments
 (0)