use crate::messages::{
DTLSMessageEvent, MessageEvent, RTPMessageEvent, STUNMessageEvent, TaggedMessageEvent,
};
use log::{debug, error};
use retty::channel::{Context, Handler};
use retty::transport::TaggedBytesMut;
fn match_range(lower: u8, upper: u8, buf: &[u8]) -> bool {
if buf.is_empty() {
return false;
}
let b = buf[0];
b >= lower && b <= upper
}
fn match_dtls(b: &[u8]) -> bool {
match_range(20, 63, b)
}
fn match_srtp(b: &[u8]) -> bool {
match_range(128, 191, b)
}
#[derive(Default)]
pub struct DemuxerHandler;
impl DemuxerHandler {
pub fn new() -> Self {
DemuxerHandler
}
}
impl Handler for DemuxerHandler {
type Rin = TaggedBytesMut;
type Rout = TaggedMessageEvent;
type Win = TaggedMessageEvent;
type Wout = TaggedBytesMut;
fn name(&self) -> &str {
"DemuxerHandler"
}
fn handle_read(
&mut self,
ctx: &Context<Self::Rin, Self::Rout, Self::Win, Self::Wout>,
msg: Self::Rin,
) {
if msg.message.is_empty() {
error!("drop invalid packet due to zero length");
} else if match_dtls(&msg.message) {
ctx.fire_read(TaggedMessageEvent {
now: msg.now,
transport: msg.transport,
message: MessageEvent::Dtls(DTLSMessageEvent::Raw(msg.message)),
});
} else if match_srtp(&msg.message) {
ctx.fire_read(TaggedMessageEvent {
now: msg.now,
transport: msg.transport,
message: MessageEvent::Rtp(RTPMessageEvent::Raw(msg.message)),
});
} else {
ctx.fire_read(TaggedMessageEvent {
now: msg.now,
transport: msg.transport,
message: MessageEvent::Stun(STUNMessageEvent::Raw(msg.message)),
});
}
}
fn poll_write(
&mut self,
ctx: &Context<Self::Rin, Self::Rout, Self::Win, Self::Wout>,
) -> Option<Self::Wout> {
if let Some(msg) = ctx.fire_poll_write() {
match msg.message {
MessageEvent::Stun(STUNMessageEvent::Raw(message))
| MessageEvent::Dtls(DTLSMessageEvent::Raw(message))
| MessageEvent::Rtp(RTPMessageEvent::Raw(message)) => Some(TaggedBytesMut {
now: msg.now,
transport: msg.transport,
message,
}),
_ => {
debug!("drop non-RAW packet {:?}", msg.message);
None
}
}
} else {
None
}
}
}