use crate::jsonbuilder::{JsonBuilder, JsonError};
-use super::parser::{ConnectionData, MediaDescription, SdpMessage};
+use super::parser::{MediaDescription, SdpMessage};
pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError> {
js.open_object("sdp")?;
- let origin = format!(
- "{} {} {} {} {} {}",
- &msg.origin.username,
- &msg.origin.sess_id,
- &msg.origin.sess_version,
- &msg.origin.nettype,
- &msg.origin.addrtype,
- &msg.origin.unicast_address
- );
-
- js.set_string("origin", &origin)?;
+ js.set_string("origin", &msg.origin)?;
js.set_string("session_name", &msg.session_name)?;
if let Some(session_info) = &msg.session_info {
js.set_string("phone_number", phone_number)?;
}
if let Some(conn_data) = &msg.connection_data {
- log_connection_data(conn_data, js)?;
+ js.set_string("connection_data", conn_data)?;
}
if let Some(bws) = &msg.bandwidths {
log_bandwidth(bws, js)?;
js.open_array("media_descriptions")?;
for m in media {
js.start_object()?;
- let port = if let Some(num_ports) = m.number_of_ports {
- format!("{}/{}", m.port, num_ports)
- } else {
- format!("{}", m.port)
- };
- let mut media = format!("{} {} {}", &m.media, &port, &m.proto);
- for f in &m.fmt {
- media = format!("{} {}", media, f);
- }
- js.set_string("media", &media)?;
-
+ js.set_string("media", &m.media)?;
if let Some(session_info) = &m.session_info {
js.set_string("media_info", session_info)?;
};
log_bandwidth(bws, js)?;
}
if let Some(conn_data) = &m.connection_data {
- log_connection_data(conn_data, js)?;
+ js.set_string("connection_data", conn_data)?;
}
if let Some(enc_key) = &m.encryption_key {
js.set_string("encryption_key", enc_key)?;
Ok(())
}
-fn log_connection_data(conn_data: &ConnectionData, js: &mut JsonBuilder) -> Result<(), JsonError> {
- let mut conn = format!(
- "{} {} {}",
- &conn_data.nettype,
- &conn_data.addrtype,
- &conn_data.connection_address.to_string()
- );
- if let Some(ttl) = conn_data.ttl {
- conn = format!("{}/{}", conn, ttl);
- js.set_uint("ttl", ttl as u64)?;
- }
- if let Some(num_addrs) = conn_data.number_of_addresses {
- conn = format!("{}/{}", conn, num_addrs);
- }
- js.set_string("connection_data", &conn)?;
- Ok(())
-}
-
fn log_attributes(attrs: &Vec<String>, js: &mut JsonBuilder) -> Result<(), JsonError> {
if !attrs.is_empty() {
js.open_array("attributes")?;
#[derive(Debug)]
pub struct SdpMessage {
pub version: u32,
- pub origin: OriginField,
+ pub origin: String,
pub session_name: String,
pub session_info: Option<String>,
pub uri: Option<String>,
pub email: Option<String>,
pub phone_number: Option<String>,
- pub connection_data: Option<ConnectionData>,
+ pub connection_data: Option<String>,
pub bandwidths: Option<Vec<String>>,
pub time: String,
pub repeat_time: Option<String>,
pub media_description: Option<Vec<MediaDescription>>,
}
-#[derive(Debug)]
-pub struct OriginField {
- pub username: String,
- pub sess_id: String,
- pub sess_version: String,
- pub nettype: String,
- pub addrtype: String,
- pub unicast_address: String,
-}
-
-#[derive(Debug)]
-pub struct ConnectionData {
- pub nettype: String,
- pub addrtype: String,
- pub connection_address: IpAddr,
- pub ttl: Option<u8>,
- pub number_of_addresses: Option<u8>,
-}
-
#[derive(Debug)]
pub struct MediaDescription {
pub media: String,
- pub port: u16,
- pub number_of_ports: Option<u16>,
- pub proto: String,
- pub fmt: Vec<String>,
pub session_info: Option<String>,
- pub connection_data: Option<ConnectionData>,
+ pub connection_data: Option<String>,
pub bandwidths: Option<Vec<String>>,
pub encryption_key: Option<String>,
pub attributes: Option<Vec<String>>,
Ok((i, 0))
}
-fn parse_origin_line(i: &[u8]) -> IResult<&[u8], OriginField> {
+fn parse_origin_line(i: &[u8]) -> IResult<&[u8], String> {
let (i, _) = tag("o=")(i)?;
let (i, username) = map_res(take_while(is_token_char), std::str::from_utf8)(i)?;
let (i, _) = space1(i)?;
let (i, unicast_address) = map_res(take_till(is_line_ending), std::str::from_utf8)(i)?;
let (i, _) = line_ending(i)?;
- Ok((
- i,
- OriginField {
- username: username.to_string(),
- sess_id: sess_id.to_string(),
- sess_version: sess_version.to_string(),
- nettype: nettype.to_string(),
- addrtype: addrtype.to_string(),
- unicast_address: unicast_address.to_string(),
- },
- ))
+ let origin_line = format!(
+ "{} {} {} {} {} {}",
+ username, sess_id, sess_version, nettype, addrtype, unicast_address
+ );
+
+ Ok((i, origin_line))
}
fn parse_session_name(i: &[u8]) -> IResult<&[u8], String> {
Ok((i, uri.to_string()))
}
-fn parse_connection_data(i: &[u8]) -> IResult<&[u8], ConnectionData> {
+fn parse_connection_data(i: &[u8]) -> IResult<&[u8], String> {
let (i, _) = tag("c=")(i)?;
let (i, nettype) = map_res(take_while(is_alphabetic), std::str::from_utf8)(i)?;
let (i, _) = space1(i)?;
_ => (None, None),
};
- Ok((
- i,
- ConnectionData {
- nettype: nettype.to_string(),
- addrtype: addrtype.to_string(),
- connection_address,
- ttl,
- number_of_addresses,
- },
- ))
+ let mut connection_data = format!(
+ "{} {} {}",
+ &nettype,
+ &addrtype,
+ &connection_address.to_string()
+ );
+ if let Some(ttl) = ttl {
+ connection_data = format!("{}/{}", connection_data, ttl);
+ }
+ if let Some(num_addrs) = number_of_addresses {
+ connection_data = format!("{}/{}", connection_data, num_addrs);
+ }
+
+ Ok((i, connection_data))
}
fn parse_email(i: &[u8]) -> IResult<&[u8], String> {
let (i, encryption_key) = opt(parse_encryption_key)(i)?;
let (i, attributes) = opt(parse_attributes)(i)?;
- let port = match port.parse::<u16>() {
+ let port: u16 = match port.parse::<u16>() {
Ok(p) => p,
- Err(_) => return Err(Err::Error(make_error(i, ErrorKind::HexDigit)))
+ Err(_) => return Err(Err::Error(make_error(i, ErrorKind::HexDigit))),
};
- let number_of_ports = match number_of_ports {
+ let number_of_ports: Option<u16> = match number_of_ports {
Some(num_str) => num_str.parse().ok(),
None => None,
};
+ let port = if let Some(num_ports) = number_of_ports {
+ format!("{}/{}", port, num_ports)
+ } else {
+ format!("{}", port)
+ };
+ let mut media_str = format!("{} {} {}", &media, &port, &proto);
+ let fmt: Vec<String> = fmt.into_iter().map(String::from).collect();
+ for f in &fmt {
+ media_str = format!("{} {}", media_str, f);
+ }
Ok((
i,
MediaDescription {
- media,
- port,
- number_of_ports,
- proto,
- fmt: fmt.into_iter().map(String::from).collect(),
+ media: media_str,
session_info,
connection_data,
bandwidths,
let buf: &[u8] = "o=Clarent 120386 120387 IN IP4 200.57.7.196\r\n".as_bytes();
let (_, o) = parse_origin_line(buf).expect("parsing failed");
- assert_eq!(o.username, "Clarent");
- assert_eq!(o.sess_id, "120386");
- assert_eq!(o.sess_version, "120387");
- assert_eq!(o.nettype, "IN");
- assert_eq!(o.addrtype, "IP4");
- assert_eq!(o.unicast_address, "200.57.7.196");
+ assert_eq!(o, "Clarent 120386 120387 IN IP4 200.57.7.196");
}
#[test]
let buf: &[u8] = "c=IN IP4 224.2.36.42/127\r\n".as_bytes();
let (_, c) = parse_connection_data(buf).expect("parsing failed");
- assert_eq!(c.nettype, "IN");
- assert_eq!(c.addrtype, "IP4");
- assert_eq!(
- c.connection_address,
- IpAddr::from_str("224.2.36.42").unwrap()
- );
- assert_eq!(c.ttl, Some(127));
- assert_eq!(c.number_of_addresses, None);
+ assert_eq!(c, "IN IP4 224.2.36.42/127");
}
#[test]
let buf: &[u8] = "c=IN IP6 FF15::101/3\r\n".as_bytes();
let (_, c) = parse_connection_data(buf).expect("parsing failed");
- assert_eq!(c.nettype, "IN");
- assert_eq!(c.addrtype, "IP6");
- assert_eq!(c.connection_address, IpAddr::from_str("FF15::101").unwrap());
- assert_eq!(c.ttl, None);
- assert_eq!(c.number_of_addresses, Some(3));
+ assert_eq!(c, "IN IP6 ff15::101/3");
}
#[test]
let buf: &[u8] = "c=IN IP4 224.2.36.42/127/2\r\n".as_bytes();
let (_, c) = parse_connection_data(buf).expect("parsing failed");
- assert_eq!(c.nettype, "IN");
- assert_eq!(c.addrtype, "IP4");
- assert_eq!(
- c.connection_address,
- IpAddr::from_str("224.2.36.42").unwrap()
- );
- assert_eq!(c.ttl, Some(127));
- assert_eq!(c.number_of_addresses, Some(2));
+ assert_eq!(c, "IN IP4 224.2.36.42/127/2");
}
#[test]
let buf: &[u8] = "c=IN IP4 8.8.8.8\r\n".as_bytes();
let (_, c) = parse_connection_data(buf).expect("parsing failed");
- assert_eq!(c.nettype, "IN");
- assert_eq!(c.addrtype, "IP4");
- assert_eq!(c.connection_address, IpAddr::from_str("8.8.8.8").unwrap());
- assert_eq!(c.ttl, None);
- assert_eq!(c.number_of_addresses, None);
+ assert_eq!(c, "IN IP4 8.8.8.8");
}
#[test]
let buf: &[u8] = "c=IN IP6 FF15::101\r\n".as_bytes();
let (_, c) = parse_connection_data(buf).expect("parsing failed");
- assert_eq!(c.nettype, "IN");
- assert_eq!(c.addrtype, "IP6");
- assert_eq!(c.connection_address, IpAddr::from_str("FF15::101").unwrap());
- assert_eq!(c.ttl, None);
- assert_eq!(c.number_of_addresses, None);
+ assert_eq!(c, "IN IP6 ff15::101");
}
#[test]
fn test_media_line() {
let buf: &[u8] = "m=audio 40392 RTP/AVP 8 0\r\n".as_bytes();
let (_, m) = parse_media_description(buf).expect("parsing failed");
- assert_eq!(m.media, "audio");
- assert_eq!(m.port, 40392);
- assert_eq!(m.number_of_ports, None);
- assert_eq!(m.proto, "RTP/AVP");
- assert_eq!(m.fmt.first().unwrap(), "8");
- assert_eq!(m.fmt.get(1).unwrap(), "0");
+ assert_eq!(m.media, "audio 40392 RTP/AVP 8 0");
}
#[test]