diff --git a/etc/schema.json b/etc/schema.json index 901b964a39..f0a8ba5af9 100644 --- a/etc/schema.json +++ b/etc/schema.json @@ -4158,15 +4158,27 @@ "type": "string" } }, - "time": { - "type": "string", - "optional": true, - "description": "Start and stop times for a session" - }, - "repeat_time": { - "type": "string", - "optional": true, - "description": "Specify repeat times for a session" + "time_descriptions": { + "type": "array", + "description": "A list of time descriptions for a session", + "minItems": 1, + "items": { + "type": "object", + "optional": true, + "properties": { + "time": { + "type": "string", + "optional": true, + "description": "Start and stop times for a session" + }, + "repeat_time": { + "type": "string", + "optional": true, + "description": "Specify repeat times for a session" + } + }, + "additionalProperties": false + } }, "timezone": { "type": "string", diff --git a/rust/src/sdp/logger.rs b/rust/src/sdp/logger.rs index 2951d772f8..5aeeadd12c 100644 --- a/rust/src/sdp/logger.rs +++ b/rust/src/sdp/logger.rs @@ -19,7 +19,7 @@ use crate::jsonbuilder::{JsonBuilder, JsonError}; -use super::parser::{MediaDescription, SdpMessage}; +use super::parser::{MediaDescription, SdpMessage, TimeDescription}; pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError> { js.open_object("sdp")?; @@ -45,10 +45,7 @@ pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError> if let Some(bws) = &msg.bandwidths { log_bandwidth(bws, js)?; } - js.set_string("time", &msg.time)?; - if let Some(repeat_time) = &msg.repeat_time { - js.set_string("repeat_time", repeat_time)?; - } + log_time_description(&msg.time_description, js)?; if let Some(tz) = &msg.time_zone { js.set_string("timezone", tz)?; } @@ -65,6 +62,22 @@ pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError> Ok(()) } +fn log_time_description( + time: &Vec, js: &mut JsonBuilder, +) -> Result<(), JsonError> { + js.open_array("time_descriptions")?; + for t in time { + js.start_object()?; + js.set_string("time", &t.time)?; + if let Some(repeat_time) = &t.repeat_time { + js.set_string("repeat_time", repeat_time)?; + } + js.close()?; + } + js.close()?; + Ok(()) +} + fn log_media_description( media: &Vec, js: &mut JsonBuilder, ) -> Result<(), JsonError> { diff --git a/rust/src/sdp/parser.rs b/rust/src/sdp/parser.rs index 2f2baed9fc..3ab9d932ca 100644 --- a/rust/src/sdp/parser.rs +++ b/rust/src/sdp/parser.rs @@ -48,8 +48,7 @@ pub struct SdpMessage { pub phone_number: Option, pub connection_data: Option, pub bandwidths: Option>, - pub time: String, - pub repeat_time: Option, + pub time_description: Vec, pub time_zone: Option, pub encryption_key: Option, pub attributes: Option>, @@ -66,6 +65,12 @@ pub struct MediaDescription { pub attributes: Option>, } +#[derive(Debug)] +pub struct TimeDescription { + pub time: String, + pub repeat_time: Option, +} + // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E #[inline] fn is_token_char(b: u8) -> bool { @@ -149,8 +154,7 @@ pub fn sdp_parse_message(i: &[u8]) -> IResult<&[u8], SdpMessage> { let (i, phone_number) = opt(parse_phone_number)(i)?; let (i, connection_data) = opt(parse_connection_data)(i)?; let (i, bandwidths) = opt(parse_bandwidth)(i)?; - let (i, time) = parse_time(i)?; - let (i, repeat_time) = opt(parse_repeat_times)(i)?; + let (i, time_description) = many1(parse_time_description)(i)?; let (i, time_zone) = opt(parse_time_zone)(i)?; let (i, encryption_key) = opt(parse_encryption_key)(i)?; let (i, attributes) = opt(parse_attributes)(i)?; @@ -167,8 +171,7 @@ pub fn sdp_parse_message(i: &[u8]) -> IResult<&[u8], SdpMessage> { phone_number, connection_data, bandwidths, - time, - repeat_time, + time_description, time_zone, encryption_key, attributes, @@ -309,6 +312,12 @@ fn parse_bandwidth(i: &[u8]) -> IResult<&[u8], Vec> { Ok((i, vec)) } +fn parse_time_description(i: &[u8]) -> IResult<&[u8], TimeDescription> { + let (i, time) = parse_time(i)?; + let (i, repeat_time) = opt(parse_repeat_times)(i)?; + Ok((i, TimeDescription { time, repeat_time })) +} + fn parse_time(i: &[u8]) -> IResult<&[u8], String> { let (i, (start_time, _, stop_time)) = preceded( tag("t="),