1
0

sharing abstraction between command Tx and Rx

This commit is contained in:
EAimTY 2023-01-24 19:20:11 +09:00
parent a707943d5a
commit 46ad3068d2
7 changed files with 166 additions and 68 deletions

View File

@ -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,

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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),
}
}

View File

@ -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
}