Skip to content

Commit

Permalink
Add offer/answer/pranswer constructors for RTCSessionDescription
Browse files Browse the repository at this point in the history
  • Loading branch information
sax authored and rainliu committed Mar 18, 2022
1 parent 2382fc4 commit b614887
Showing 1 changed file with 114 additions and 1 deletion.
115 changes: 114 additions & 1 deletion src/peer_connection/sdp/session_description.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,54 @@ pub struct RTCSessionDescription {
pub(crate) parsed: Option<SessionDescription>,
}

/// Unmarshal is a helper to deserialize the sdp
impl RTCSessionDescription {
/// Given SDP representing an answer, wrap it in an RTCSessionDescription
/// that can be given to an RTCPeerConnection.
pub fn answer(sdp: String) -> Result<RTCSessionDescription> {
let mut desc = RTCSessionDescription {
sdp,
sdp_type: RTCSdpType::Answer,
parsed: None,
};

let parsed = desc.unmarshal()?;
desc.parsed = Some(parsed);

Ok(desc)
}

/// Given SDP representing an offer, wrap it in an RTCSessionDescription
/// that can be given to an RTCPeerConnection.
pub fn offer(sdp: String) -> Result<RTCSessionDescription> {
let mut desc = RTCSessionDescription {
sdp,
sdp_type: RTCSdpType::Offer,
parsed: None,
};

let parsed = desc.unmarshal()?;
desc.parsed = Some(parsed);

Ok(desc)
}

/// Given SDP representing an answer, wrap it in an RTCSessionDescription
/// that can be given to an RTCPeerConnection. `pranswer` is used when the
/// answer may not be final, or when updating a previously sent pranswer.
pub fn pranswer(sdp: String) -> Result<RTCSessionDescription> {
let mut desc = RTCSessionDescription {
sdp,
sdp_type: RTCSdpType::Pranswer,
parsed: None,
};

let parsed = desc.unmarshal()?;
desc.parsed = Some(parsed);

Ok(desc)
}

/// Unmarshal is a helper to deserialize the sdp
pub fn unmarshal(&self) -> Result<SessionDescription> {
let mut reader = Cursor::new(self.sdp.as_bytes());
let parsed = SessionDescription::unmarshal(&mut reader)?;
Expand Down Expand Up @@ -94,6 +140,73 @@ mod test {
}
}

#[tokio::test]
async fn test_session_description_answer() -> Result<()> {
let mut m = MediaEngine::default();
m.register_default_codecs()?;
let api = APIBuilder::new().with_media_engine(m).build();

let offer_pc = api.new_peer_connection(RTCConfiguration::default()).await?;
let answer_pc = api.new_peer_connection(RTCConfiguration::default()).await?;

let _ = offer_pc.create_data_channel("foo", None).await?;
let offer = offer_pc.create_offer(None).await?;
answer_pc.set_remote_description(offer).await?;

let answer = answer_pc.create_answer(None).await?;

let desc = RTCSessionDescription::answer(answer.sdp.clone())?;

assert!(desc.sdp_type == RTCSdpType::Answer);
assert!(desc.parsed.is_some());

assert_eq!(answer.unmarshal()?.marshal(), desc.unmarshal()?.marshal());

Ok(())
}

#[tokio::test]
async fn test_session_description_offer() -> Result<()> {
let mut m = MediaEngine::default();
m.register_default_codecs()?;
let api = APIBuilder::new().with_media_engine(m).build();

let pc = api.new_peer_connection(RTCConfiguration::default()).await?;
let offer = pc.create_offer(None).await?;

let desc = RTCSessionDescription::offer(offer.sdp.clone())?;

assert!(desc.sdp_type == RTCSdpType::Offer);
assert!(desc.parsed.is_some());

assert_eq!(offer.unmarshal()?.marshal(), desc.unmarshal()?.marshal());

Ok(())
}

#[tokio::test]
async fn test_session_description_pranswer() -> Result<()> {
let mut m = MediaEngine::default();
m.register_default_codecs()?;
let api = APIBuilder::new().with_media_engine(m).build();

let offer_pc = api.new_peer_connection(RTCConfiguration::default()).await?;
let answer_pc = api.new_peer_connection(RTCConfiguration::default()).await?;

let _ = offer_pc.create_data_channel("foo", None).await?;
let offer = offer_pc.create_offer(None).await?;
answer_pc.set_remote_description(offer).await?;

let answer = answer_pc.create_answer(None).await?;

let desc = RTCSessionDescription::pranswer(answer.sdp.clone())?;

assert!(desc.sdp_type == RTCSdpType::Pranswer);
assert!(desc.parsed.is_some());

Ok(())
}

#[tokio::test]
async fn test_session_description_unmarshal() -> Result<()> {
let mut m = MediaEngine::default();
Expand Down

0 comments on commit b614887

Please sign in to comment.