Skip to content

Commit b614887

Browse files
saxrainliu
authored andcommitted
Add offer/answer/pranswer constructors for RTCSessionDescription
1 parent 2382fc4 commit b614887

File tree

1 file changed

+114
-1
lines changed

1 file changed

+114
-1
lines changed

src/peer_connection/sdp/session_description.rs

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,54 @@ pub struct RTCSessionDescription {
1919
pub(crate) parsed: Option<SessionDescription>,
2020
}
2121

22-
/// Unmarshal is a helper to deserialize the sdp
2322
impl RTCSessionDescription {
23+
/// Given SDP representing an answer, wrap it in an RTCSessionDescription
24+
/// that can be given to an RTCPeerConnection.
25+
pub fn answer(sdp: String) -> Result<RTCSessionDescription> {
26+
let mut desc = RTCSessionDescription {
27+
sdp,
28+
sdp_type: RTCSdpType::Answer,
29+
parsed: None,
30+
};
31+
32+
let parsed = desc.unmarshal()?;
33+
desc.parsed = Some(parsed);
34+
35+
Ok(desc)
36+
}
37+
38+
/// Given SDP representing an offer, wrap it in an RTCSessionDescription
39+
/// that can be given to an RTCPeerConnection.
40+
pub fn offer(sdp: String) -> Result<RTCSessionDescription> {
41+
let mut desc = RTCSessionDescription {
42+
sdp,
43+
sdp_type: RTCSdpType::Offer,
44+
parsed: None,
45+
};
46+
47+
let parsed = desc.unmarshal()?;
48+
desc.parsed = Some(parsed);
49+
50+
Ok(desc)
51+
}
52+
53+
/// Given SDP representing an answer, wrap it in an RTCSessionDescription
54+
/// that can be given to an RTCPeerConnection. `pranswer` is used when the
55+
/// answer may not be final, or when updating a previously sent pranswer.
56+
pub fn pranswer(sdp: String) -> Result<RTCSessionDescription> {
57+
let mut desc = RTCSessionDescription {
58+
sdp,
59+
sdp_type: RTCSdpType::Pranswer,
60+
parsed: None,
61+
};
62+
63+
let parsed = desc.unmarshal()?;
64+
desc.parsed = Some(parsed);
65+
66+
Ok(desc)
67+
}
68+
69+
/// Unmarshal is a helper to deserialize the sdp
2470
pub fn unmarshal(&self) -> Result<SessionDescription> {
2571
let mut reader = Cursor::new(self.sdp.as_bytes());
2672
let parsed = SessionDescription::unmarshal(&mut reader)?;
@@ -94,6 +140,73 @@ mod test {
94140
}
95141
}
96142

143+
#[tokio::test]
144+
async fn test_session_description_answer() -> Result<()> {
145+
let mut m = MediaEngine::default();
146+
m.register_default_codecs()?;
147+
let api = APIBuilder::new().with_media_engine(m).build();
148+
149+
let offer_pc = api.new_peer_connection(RTCConfiguration::default()).await?;
150+
let answer_pc = api.new_peer_connection(RTCConfiguration::default()).await?;
151+
152+
let _ = offer_pc.create_data_channel("foo", None).await?;
153+
let offer = offer_pc.create_offer(None).await?;
154+
answer_pc.set_remote_description(offer).await?;
155+
156+
let answer = answer_pc.create_answer(None).await?;
157+
158+
let desc = RTCSessionDescription::answer(answer.sdp.clone())?;
159+
160+
assert!(desc.sdp_type == RTCSdpType::Answer);
161+
assert!(desc.parsed.is_some());
162+
163+
assert_eq!(answer.unmarshal()?.marshal(), desc.unmarshal()?.marshal());
164+
165+
Ok(())
166+
}
167+
168+
#[tokio::test]
169+
async fn test_session_description_offer() -> Result<()> {
170+
let mut m = MediaEngine::default();
171+
m.register_default_codecs()?;
172+
let api = APIBuilder::new().with_media_engine(m).build();
173+
174+
let pc = api.new_peer_connection(RTCConfiguration::default()).await?;
175+
let offer = pc.create_offer(None).await?;
176+
177+
let desc = RTCSessionDescription::offer(offer.sdp.clone())?;
178+
179+
assert!(desc.sdp_type == RTCSdpType::Offer);
180+
assert!(desc.parsed.is_some());
181+
182+
assert_eq!(offer.unmarshal()?.marshal(), desc.unmarshal()?.marshal());
183+
184+
Ok(())
185+
}
186+
187+
#[tokio::test]
188+
async fn test_session_description_pranswer() -> Result<()> {
189+
let mut m = MediaEngine::default();
190+
m.register_default_codecs()?;
191+
let api = APIBuilder::new().with_media_engine(m).build();
192+
193+
let offer_pc = api.new_peer_connection(RTCConfiguration::default()).await?;
194+
let answer_pc = api.new_peer_connection(RTCConfiguration::default()).await?;
195+
196+
let _ = offer_pc.create_data_channel("foo", None).await?;
197+
let offer = offer_pc.create_offer(None).await?;
198+
answer_pc.set_remote_description(offer).await?;
199+
200+
let answer = answer_pc.create_answer(None).await?;
201+
202+
let desc = RTCSessionDescription::pranswer(answer.sdp.clone())?;
203+
204+
assert!(desc.sdp_type == RTCSdpType::Pranswer);
205+
assert!(desc.parsed.is_some());
206+
207+
Ok(())
208+
}
209+
97210
#[tokio::test]
98211
async fn test_session_description_unmarshal() -> Result<()> {
99212
let mut m = MediaEngine::default();

0 commit comments

Comments
 (0)