use bytes::{Bytes, BytesMut}; use rsip::message::SipMessage; use rtp::packet::Packet as RtpPacket; use tokio_util::codec::{Decoder, Encoder}; use tracing::{event, instrument, Level}; use webrtc_util::marshal::Unmarshal; pub struct SipCodec {} impl Decoder for SipCodec { type Item = SipMessage; type Error = std::io::Error; fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { if src.is_empty() { Ok(None) } else { // We're assuming we get an entire sip message at once here. match SipMessage::try_from(src.as_ref()) { Ok(msg) => { src.clear(); Ok(Some(msg)) } Err(e) => { src.clear(); // Still clear the buf to be ready for the next packet event!(Level::ERROR, error = %e, "Error decoding SIP message."); Ok(None) } } } } } impl Encoder for SipCodec { type Error = std::io::Error; #[instrument(level = "debug", skip(self, item, dst))] fn encode(&mut self, item: SipMessage, dst: &mut BytesMut) -> Result<(), Self::Error> { let stuff: Bytes = item.into(); dst.reserve(stuff.len()); dst.extend_from_slice(&stuff); Ok(()) } } pub struct RtpCodec {} impl Decoder for RtpCodec { type Item = RtpPacket; type Error = std::io::Error; fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { if src.is_empty() { Ok(None) } else { match RtpPacket::unmarshal(src) { Ok(p) => Ok(Some(p)), Err(e) => Err(Self::Error::new(std::io::ErrorKind::Other, e.to_string())), } } } }