Skip to content

Commit

Permalink
events: Add support for multi-stream VoIP
Browse files Browse the repository at this point in the history
According to MSC3077 / Matrix 1.10
  • Loading branch information
zecakeh committed Apr 7, 2024
1 parent 3501c2b commit 2313217
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 4 deletions.
1 change: 1 addition & 0 deletions crates/ruma-events/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Improvements:
- Implement `From<JoinRule>` for `SpaceRoomJoinRule`
- Add `filename` and `formatted` fields to media event contents to support media captions
as per [MSC2530](https://github.com/matrix-org/matrix-spec-proposals/pull/2530) / Matrix 1.10
- Add support for multi-stream VoIP, according to MSC3077 / Matrix 1.10

# 0.27.11

Expand Down
38 changes: 38 additions & 0 deletions crates/ruma-events/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ pub mod notify;
pub mod reject;
pub mod select_answer;

use ruma_macros::StringEnum;
use serde::{Deserialize, Serialize};

use crate::PrivOwnedStr;

/// A VoIP session description.
///
/// This is the same type as WebRTC's [`RTCSessionDescriptionInit`].
Expand Down Expand Up @@ -44,6 +47,41 @@ impl SessionDescription {
}
}

/// Metadata about a VoIP stream.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct StreamMetadata {
/// The purpose of the stream.
pub purpose: StreamPurpose,
}

impl StreamMetadata {
/// Creates a new `StreamMetadata` with the given purpose.
pub fn new(purpose: StreamPurpose) -> Self {
Self { purpose }
}
}

/// The purpose of a VoIP stream.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, PartialEq, Eq, StringEnum)]
#[ruma_enum(rename_all = "m.snake_case")]
#[non_exhaustive]
pub enum StreamPurpose {
/// `m.usermedia`.
///
/// A stream that contains the webcam and/or microphone tracks.
Usermedia,

/// `m.screenshare`.
///
/// A stream with the screen-sharing tracks.
Screenshare,

#[doc(hidden)]
_Custom(PrivOwnedStr),
}

/// The capabilities of a client in a VoIP call.
#[cfg(feature = "unstable-msc2747")]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
Expand Down
12 changes: 11 additions & 1 deletion crates/ruma-events/src/call/answer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
//!
//! [`m.call.answer`]: https://spec.matrix.org/latest/client-server-api/#mcallanswer
use std::collections::BTreeMap;

use ruma_common::{OwnedVoipId, VoipVersionId};
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};

#[cfg(feature = "unstable-msc2747")]
use super::CallCapabilities;
use super::SessionDescription;
use super::{SessionDescription, StreamMetadata};

/// The content of an `m.call.answer` event.
///
Expand All @@ -34,6 +36,12 @@ pub struct CallAnswerEventContent {
/// The VoIP capabilities of the client.
#[serde(default, skip_serializing_if = "CallCapabilities::is_default")]
pub capabilities: CallCapabilities,

/// **Added in VoIP version 1.** Metadata describing the streams that will be sent.
///
/// This is a map of stream ID to metadata about the stream.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub sdp_stream_metadata: BTreeMap<String, StreamMetadata>,
}

impl CallAnswerEventContent {
Expand All @@ -46,6 +54,7 @@ impl CallAnswerEventContent {
version,
#[cfg(feature = "unstable-msc2747")]
capabilities: Default::default(),
sdp_stream_metadata: Default::default(),
}
}

Expand All @@ -69,6 +78,7 @@ impl CallAnswerEventContent {
version: VoipVersionId::V1,
#[cfg(feature = "unstable-msc2747")]
capabilities: Default::default(),
sdp_stream_metadata: Default::default(),
}
}
}
12 changes: 11 additions & 1 deletion crates/ruma-events/src/call/invite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
//!
//! [`m.call.invite`]: https://spec.matrix.org/latest/client-server-api/#mcallinvite
use std::collections::BTreeMap;

use js_int::UInt;
use ruma_common::{OwnedUserId, OwnedVoipId, VoipVersionId};
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};

#[cfg(feature = "unstable-msc2747")]
use super::CallCapabilities;
use super::SessionDescription;
use super::{SessionDescription, StreamMetadata};

/// The content of an `m.call.invite` event.
///
Expand Down Expand Up @@ -49,6 +51,12 @@ pub struct CallInviteEventContent {
/// The invite should be ignored if the invitee is set and doesn't match the user's ID.
#[serde(skip_serializing_if = "Option::is_none")]
pub invitee: Option<OwnedUserId>,

/// **Added in VoIP version 1.** Metadata describing the streams that will be sent.
///
/// This is a map of stream ID to metadata about the stream.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub sdp_stream_metadata: BTreeMap<String, StreamMetadata>,
}

impl CallInviteEventContent {
Expand All @@ -69,6 +77,7 @@ impl CallInviteEventContent {
#[cfg(feature = "unstable-msc2747")]
capabilities: Default::default(),
invitee: None,
sdp_stream_metadata: Default::default(),
}
}

Expand All @@ -95,6 +104,7 @@ impl CallInviteEventContent {
#[cfg(feature = "unstable-msc2747")]
capabilities: Default::default(),
invitee: None,
sdp_stream_metadata: Default::default(),
}
}
}
19 changes: 17 additions & 2 deletions crates/ruma-events/src/call/negotiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
//!
//! [`m.call.negotiate`]: https://spec.matrix.org/latest/client-server-api/#mcallnegotiate
use std::collections::BTreeMap;

use js_int::UInt;
use ruma_common::{OwnedVoipId, VoipVersionId};
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};

use super::SessionDescription;
use super::{SessionDescription, StreamMetadata};

/// **Added in VoIP version 1.** The content of an `m.call.negotiate` event.
///
Expand Down Expand Up @@ -37,6 +39,12 @@ pub struct CallNegotiateEventContent {

/// The session description of the negotiation.
pub description: SessionDescription,

/// Metadata describing the streams that will be sent.
///
/// This is a map of stream ID to metadata about the stream.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub sdp_stream_metadata: BTreeMap<String, StreamMetadata>,
}

impl CallNegotiateEventContent {
Expand All @@ -49,7 +57,14 @@ impl CallNegotiateEventContent {
lifetime: UInt,
description: SessionDescription,
) -> Self {
Self { call_id, party_id, version, lifetime, description }
Self {
call_id,
party_id,
version,
lifetime,
description,
sdp_stream_metadata: Default::default(),
}
}

/// Convenience method to create a version 1 `CallNegotiateEventContent` with all the required
Expand Down

0 comments on commit 2313217

Please sign in to comment.