sharing abstraction between command Tx and Rx
This commit is contained in:
parent
a707943d5a
commit
46ad3068d2
@ -1,11 +1,10 @@
|
||||
mod address;
|
||||
mod authenticate;
|
||||
mod connect;
|
||||
mod dissociate;
|
||||
mod heartbeat;
|
||||
mod packet;
|
||||
|
||||
pub mod authenticate;
|
||||
|
||||
pub use self::{
|
||||
address::Address, authenticate::Authenticate, connect::Connect, dissociate::Dissociate,
|
||||
heartbeat::Heartbeat, packet::Packet,
|
||||
|
@ -1,20 +1,37 @@
|
||||
use super::TaskRegister;
|
||||
use super::{
|
||||
side::{self, Side, SideMarker},
|
||||
TaskRegister,
|
||||
};
|
||||
use crate::protocol::{Authenticate as AuthenticateHeader, Header};
|
||||
|
||||
pub struct Authenticate {
|
||||
pub struct Authenticate<M>
|
||||
where
|
||||
M: SideMarker,
|
||||
{
|
||||
inner: Side<Tx, Rx>,
|
||||
_marker: M,
|
||||
}
|
||||
|
||||
pub struct Tx {
|
||||
header: Header,
|
||||
_task_reg: TaskRegister,
|
||||
}
|
||||
|
||||
impl Authenticate {
|
||||
pub struct Rx;
|
||||
|
||||
impl Authenticate<side::Tx> {
|
||||
pub(super) fn new(task_reg: TaskRegister, token: [u8; 8]) -> Self {
|
||||
Self {
|
||||
header: Header::Authenticate(AuthenticateHeader::new(token)),
|
||||
_task_reg: task_reg,
|
||||
inner: Side::Tx(Tx {
|
||||
header: Header::Authenticate(AuthenticateHeader::new(token)),
|
||||
_task_reg: task_reg,
|
||||
}),
|
||||
_marker: side::Tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn header(&self) -> &Header {
|
||||
&self.header
|
||||
let Side::Tx(tx) = &self.inner else { unreachable!() };
|
||||
&tx.header
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,37 @@
|
||||
use super::TaskRegister;
|
||||
use super::{
|
||||
side::{self, Side, SideMarker},
|
||||
TaskRegister,
|
||||
};
|
||||
use crate::protocol::{Address, Connect as ConnectHeader, Header};
|
||||
|
||||
pub struct Connect {
|
||||
pub struct Connect<M>
|
||||
where
|
||||
M: SideMarker,
|
||||
{
|
||||
inner: Side<Tx, Rx>,
|
||||
_marker: M,
|
||||
}
|
||||
|
||||
struct Tx {
|
||||
header: Header,
|
||||
_task_reg: TaskRegister,
|
||||
}
|
||||
|
||||
impl Connect {
|
||||
struct Rx;
|
||||
|
||||
impl Connect<side::Tx> {
|
||||
pub(super) fn new(task_reg: TaskRegister, addr: Address) -> Self {
|
||||
Self {
|
||||
header: Header::Connect(ConnectHeader::new(addr)),
|
||||
_task_reg: task_reg,
|
||||
inner: Side::Tx(Tx {
|
||||
header: Header::Connect(ConnectHeader::new(addr)),
|
||||
_task_reg: task_reg,
|
||||
}),
|
||||
_marker: side::Tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn header(&self) -> &Header {
|
||||
&self.header
|
||||
let Side::Tx(tx) = &self.inner else { unreachable!() };
|
||||
&tx.header
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,32 @@
|
||||
use super::TaskRegister;
|
||||
use super::side::{self, Side, SideMarker};
|
||||
use crate::protocol::{Dissociate as DissociateHeader, Header};
|
||||
|
||||
pub struct Dissociate {
|
||||
header: Header,
|
||||
_task_reg: TaskRegister,
|
||||
pub struct Dissociate<M>
|
||||
where
|
||||
M: SideMarker,
|
||||
{
|
||||
inner: Side<Tx, Rx>,
|
||||
_marker: M,
|
||||
}
|
||||
|
||||
impl Dissociate {
|
||||
pub(super) fn new(task_reg: TaskRegister, assoc_id: u16) -> Self {
|
||||
pub struct Tx {
|
||||
header: Header,
|
||||
}
|
||||
|
||||
pub struct Rx;
|
||||
|
||||
impl Dissociate<side::Tx> {
|
||||
pub(super) fn new(assoc_id: u16) -> Self {
|
||||
Self {
|
||||
header: Header::Dissociate(DissociateHeader::new(assoc_id)),
|
||||
_task_reg: task_reg,
|
||||
inner: Side::Tx(Tx {
|
||||
header: Header::Dissociate(DissociateHeader::new(assoc_id)),
|
||||
}),
|
||||
_marker: side::Tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn header(&self) -> &Header {
|
||||
&self.header
|
||||
let Side::Tx(tx) = &self.inner else { unreachable!() };
|
||||
&tx.header
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,32 @@
|
||||
use super::side::{self, Side, SideMarker};
|
||||
use crate::protocol::{Header, Heartbeat as HeartbeatHeader};
|
||||
|
||||
pub struct Heartbeat {
|
||||
pub struct Heartbeat<M>
|
||||
where
|
||||
M: SideMarker,
|
||||
{
|
||||
inner: Side<Tx, Rx>,
|
||||
_marker: M,
|
||||
}
|
||||
|
||||
pub struct Tx {
|
||||
header: Header,
|
||||
}
|
||||
|
||||
impl Heartbeat {
|
||||
pub struct Rx;
|
||||
|
||||
impl Heartbeat<side::Tx> {
|
||||
pub(super) fn new() -> Self {
|
||||
Self {
|
||||
header: Header::Heartbeat(HeartbeatHeader::new()),
|
||||
inner: Side::Tx(Tx {
|
||||
header: Header::Heartbeat(HeartbeatHeader::new()),
|
||||
}),
|
||||
_marker: side::Tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn header(&self) -> &Header {
|
||||
&self.header
|
||||
let Side::Tx(tx) = &self.inner else { unreachable!() };
|
||||
&tx.header
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,11 @@ mod heartbeat;
|
||||
mod packet;
|
||||
|
||||
pub use self::{
|
||||
authenticate::Authenticate, connect::Connect, dissociate::Dissociate, heartbeat::Heartbeat,
|
||||
packet::Packet,
|
||||
authenticate::Authenticate,
|
||||
connect::Connect,
|
||||
dissociate::Dissociate,
|
||||
heartbeat::Heartbeat,
|
||||
packet::{Fragment, Packet},
|
||||
};
|
||||
|
||||
pub struct Connection {
|
||||
@ -34,31 +37,28 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn authenticate(&self, token: [u8; 8]) -> Authenticate {
|
||||
pub fn send_authenticate(&self, token: [u8; 8]) -> Authenticate<side::Tx> {
|
||||
Authenticate::new(self.local_active_task_count.reg(), token)
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: Address) -> Connect {
|
||||
Connect::new(self.local_active_task_count.reg(), addr)
|
||||
pub fn send_connect(&self, addr: Address) -> Connect<side::Tx> {
|
||||
Connect::<side::Tx>::new(self.local_active_task_count.reg(), addr)
|
||||
}
|
||||
|
||||
pub fn packet<'a>(
|
||||
pub fn send_packet(
|
||||
&self,
|
||||
assoc_id: u16,
|
||||
addr: Address,
|
||||
payload: &'a [u8],
|
||||
frag_len: usize,
|
||||
) -> Packet<'a> {
|
||||
self.udp_sessions
|
||||
.lock()
|
||||
.send(assoc_id, addr, payload, frag_len)
|
||||
max_pkt_size: usize,
|
||||
) -> Packet<side::Tx> {
|
||||
self.udp_sessions.lock().send(assoc_id, addr, max_pkt_size)
|
||||
}
|
||||
|
||||
pub fn dissociate(&self, assoc_id: u16) -> Dissociate {
|
||||
pub fn send_dissociate(&self, assoc_id: u16) -> Dissociate<side::Tx> {
|
||||
self.udp_sessions.lock().dissociate(assoc_id)
|
||||
}
|
||||
|
||||
pub fn heartbeat(&self) -> Heartbeat {
|
||||
pub fn send_heartbeat(&self) -> Heartbeat<side::Tx> {
|
||||
Heartbeat::new()
|
||||
}
|
||||
|
||||
@ -98,22 +98,16 @@ impl UdpSessions {
|
||||
}
|
||||
}
|
||||
|
||||
fn send<'a>(
|
||||
&mut self,
|
||||
assoc_id: u16,
|
||||
addr: Address,
|
||||
payload: &'a [u8],
|
||||
frag_len: usize,
|
||||
) -> Packet<'a> {
|
||||
fn send<'a>(&mut self, assoc_id: u16, addr: Address, max_pkt_size: usize) -> Packet<side::Tx> {
|
||||
self.sessions
|
||||
.entry(assoc_id)
|
||||
.or_insert_with(|| UdpSession::new(self.local_active_task_count.reg()))
|
||||
.send(assoc_id, addr, payload, frag_len)
|
||||
.send(assoc_id, addr, max_pkt_size)
|
||||
}
|
||||
|
||||
fn dissociate(&mut self, assoc_id: u16) -> Dissociate {
|
||||
fn dissociate(&mut self, assoc_id: u16) -> Dissociate<side::Tx> {
|
||||
self.sessions.remove(&assoc_id);
|
||||
Dissociate::new(self.local_active_task_count.reg(), assoc_id)
|
||||
Dissociate::new(assoc_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,19 +124,26 @@ impl UdpSession {
|
||||
}
|
||||
}
|
||||
|
||||
fn send<'a>(
|
||||
&self,
|
||||
assoc_id: u16,
|
||||
addr: Address,
|
||||
payload: &'a [u8],
|
||||
frag_len: usize,
|
||||
) -> Packet<'a> {
|
||||
fn send<'a>(&self, assoc_id: u16, addr: Address, max_pkt_size: usize) -> Packet<side::Tx> {
|
||||
Packet::new(
|
||||
assoc_id,
|
||||
self.next_pkt_id.fetch_add(1, Ordering::AcqRel),
|
||||
addr,
|
||||
payload,
|
||||
frag_len,
|
||||
max_pkt_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub mod side {
|
||||
pub struct Tx;
|
||||
pub struct Rx;
|
||||
|
||||
pub trait SideMarker {}
|
||||
impl SideMarker for Tx {}
|
||||
impl SideMarker for Rx {}
|
||||
|
||||
pub(super) enum Side<T, R> {
|
||||
Tx(T),
|
||||
Rx(R),
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,60 @@
|
||||
use super::side::{self, Side, SideMarker};
|
||||
use crate::protocol::{Address, Header, Packet as PacketHeader};
|
||||
|
||||
pub struct Packet<'a> {
|
||||
pub struct Packet<M>
|
||||
where
|
||||
M: SideMarker,
|
||||
{
|
||||
inner: Side<Tx, Rx>,
|
||||
_marker: M,
|
||||
}
|
||||
|
||||
pub struct Tx {
|
||||
assoc_id: u16,
|
||||
pkt_id: u16,
|
||||
addr: Address,
|
||||
max_pkt_size: usize,
|
||||
}
|
||||
|
||||
pub struct Rx;
|
||||
|
||||
impl Packet<side::Tx> {
|
||||
pub(super) fn new(assoc_id: u16, pkt_id: u16, addr: Address, max_pkt_size: usize) -> Self {
|
||||
Self {
|
||||
inner: Side::Tx(Tx {
|
||||
assoc_id,
|
||||
pkt_id,
|
||||
addr,
|
||||
max_pkt_size,
|
||||
}),
|
||||
_marker: side::Tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_fragments<'a>(self, payload: &'a [u8]) -> Fragment<'a> {
|
||||
let Side::Tx(tx) = self.inner else { unreachable!() };
|
||||
Fragment::new(tx.assoc_id, tx.pkt_id, tx.addr, tx.max_pkt_size, payload)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Fragment<'a> {
|
||||
assoc_id: u16,
|
||||
pkt_id: u16,
|
||||
addr: Address,
|
||||
payload: &'a [u8],
|
||||
max_pkt_size: usize,
|
||||
frag_total: u8,
|
||||
next_frag_id: u8,
|
||||
next_frag_start: usize,
|
||||
payload: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> Packet<'a> {
|
||||
pub(super) fn new(
|
||||
impl<'a> Fragment<'a> {
|
||||
fn new(
|
||||
assoc_id: u16,
|
||||
pkt_id: u16,
|
||||
addr: Address,
|
||||
payload: &'a [u8],
|
||||
max_pkt_size: usize,
|
||||
payload: &'a [u8],
|
||||
) -> Self {
|
||||
let first_frag_size = max_pkt_size - PacketHeader::len_without_addr() - addr.len();
|
||||
let frag_size_addr_none =
|
||||
@ -33,16 +70,16 @@ impl<'a> Packet<'a> {
|
||||
assoc_id,
|
||||
pkt_id,
|
||||
addr,
|
||||
payload,
|
||||
max_pkt_size,
|
||||
frag_total,
|
||||
next_frag_id: 0,
|
||||
next_frag_start: 0,
|
||||
payload,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Packet<'a> {
|
||||
impl<'a> Iterator for Fragment<'a> {
|
||||
type Item = (Header, &'a [u8]);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
@ -72,7 +109,7 @@ impl<'a> Iterator for Packet<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for Packet<'_> {
|
||||
impl ExactSizeIterator for Fragment<'_> {
|
||||
fn len(&self) -> usize {
|
||||
self.frag_total as usize
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user