DStarGateway

Struct DStarGateway 

Source
pub struct DStarGateway<T: Transport + Unpin + 'static> { /* private fields */ }
Expand description

Complete D-STAR gateway client for the TH-D75.

Manages the MMDVM session, tracks voice transmissions, decodes slow data messages, and maintains a last-heard list. This is the building block for D-STAR reflector clients — it handles the radio side of the gateway while the user provides the network side.

See the module-level documentation for architecture details and a full usage example.

Implementations§

Source§

impl<T: Transport + Unpin + 'static> DStarGateway<T>

Source

pub async fn start( radio: Radio<T>, config: DStarGatewayConfig, ) -> Result<Self, (Radio<T>, Error)>

Start the D-STAR gateway.

Enters MMDVM mode on the radio, initializes the modem for D-STAR operation, and returns a ready-to-use gateway. Consumes the Radio — call stop to exit and reclaim it.

§Errors

On failure, returns the Radio alongside the error so the caller can continue using CAT mode.

§Panics

Panics if MMDVM was entered and D-STAR init failed AND the subsequent MMDVM exit also failed. This indicates unrecoverable transport state; the caller’s only option is to drop any remaining handles and reconnect to the radio from scratch.

Source

pub async fn start_gateway_mode( radio: Radio<T>, config: DStarGatewayConfig, ) -> Result<Self, Error>

Start the D-STAR gateway on a radio already in MMDVM mode.

Use this when the radio was put into DV Gateway / Reflector Terminal Mode via MCP write (offset 0x1CA0 = 1). The transport already speaks MMDVM binary — no TN command is sent.

§Errors

Returns an error if the D-STAR initialization sequence fails.

Source

pub async fn stop(self) -> Result<Radio<T>, Error>

Stop the gateway, exiting MMDVM mode and returning the Radio.

§Errors

Returns an error if the MMDVM exit command fails.

Source

pub async fn next_event(&mut self) -> Result<Option<DStarEvent>, Error>

Process pending I/O and return the next event.

Each call waits up to Self::set_event_timeout for a new MMDVM event from the modem loop, translates it into a DStarEvent, and returns. Returns Ok(None) when no MMDVM event arrives within the timeout.

§Errors

Only returns errors if the underlying transport fails fatally. Malformed frames are swallowed by the mmdvm crate’s RX loop as debug diagnostics — propagating a decode error would kill the whole session on a single malformed byte.

Source

pub async fn send_header(&mut self, header: &DStarHeader) -> Result<(), Error>

Send a D-STAR voice header to the radio for transmission.

Enqueues the header in the mmdvm TX queue, which is drained when the modem reports enough D-STAR FIFO space.

§Errors

Returns Error::Transport if the modem loop has exited.

Source

pub async fn send_voice(&mut self, frame: &VoiceFrame) -> Result<(), Error>

Send a D-STAR voice data frame to the radio for transmission.

Enqueues the frame in the mmdvm TX queue. Pacing is handled inside the mmdvm modem loop — no host-side sleep is introduced here.

§Errors

Returns Error::Transport if the modem loop has exited.

Source

pub async fn send_voice_unpaced( &mut self, frame: &VoiceFrame, ) -> Result<(), Error>

Send a voice frame to the radio without any host-side pacing.

In the current architecture (mmdvm owns pacing via its buffer-gated TxQueue drain), this method and Self::send_voice are functionally equivalent; both simply enqueue the frame and let the modem loop drain when dstar_space allows. The alias is retained for back-compat with callers that historically preferred the unpaced variant.

§Errors

Returns Error::Transport if the modem loop has exited.

Source

pub async fn send_eot(&mut self) -> Result<(), Error>

Send end-of-transmission to the radio.

§Errors

Returns Error::Transport if the modem loop has exited.

Source

pub async fn send_status_header( &mut self, reflector: Option<(&str, char)>, ) -> Result<(), Error>

Send a status header to the radio indicating connection state.

When connected to a reflector, sets RPT1/RPT2 to the reflector name + module and UR to CQCQCQ. When disconnected, sets RPT1/RPT2 to “DIRECT”.

This updates the radio’s display to show the current gateway state, matching the behavior of d75link and BlueDV.

§Errors

Returns Error::Transport if the write fails.

Source

pub const fn set_event_timeout(&mut self, timeout: Duration)

Set the receive timeout for next_event polling.

Lower values make the event loop more responsive but increase CPU usage. Use short timeouts (10-50ms) when actively relaying voice from a reflector.

Source

pub const fn event_timeout(&self) -> Duration

Current receive timeout for next_event polling.

Mirrors Self::set_event_timeout. Callers that temporarily drop the timeout (e.g. during a tight event-drain loop) use this to save and restore the prior value.

Source

pub fn last_heard(&self) -> &[LastHeardEntry]

Get the last-heard list (newest first).

Source

pub async fn poll_status(&mut self) -> Result<ModemStatus, Error>

Poll the modem status.

Requests an immediate GetStatus and returns the next status event delivered by the modem loop. The mmdvm modem loop also polls status periodically (every 250 ms), so callers rarely need this.

§Errors

Returns an error if the status request fails or the modem loop exits before delivering a status event.

Source

pub const fn is_receiving(&self) -> bool

Check if a voice transmission is currently active (RX from radio).

Source

pub const fn current_header(&self) -> Option<&DStarHeader>

Get the current RX header, if a voice transmission is active.

Source

pub const fn config(&self) -> &DStarGatewayConfig

Get the current configuration.

Trait Implementations§

Source§

impl<T: Transport + Unpin + 'static> Debug for DStarGateway<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for DStarGateway<T>

§

impl<T> !RefUnwindSafe for DStarGateway<T>

§

impl<T> Send for DStarGateway<T>

§

impl<T> Sync for DStarGateway<T>

§

impl<T> Unpin for DStarGateway<T>

§

impl<T> !UnwindSafe for DStarGateway<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more