From: Thomas Karpiniec Date: Thu, 5 Jun 2025 09:21:28 +0000 (+1000) Subject: Make netclient work against mrefd X-Git-Url: https://code.octet-stream.net/m17rt/commitdiff_plain/e307431f908eedae321aa86565fd5e213d758216?hp=9a5a0d1e59e5f813f17239b674336ac9814c16b4 Make netclient work against mrefd --- diff --git a/m17app/src/error.rs b/m17app/src/error.rs index e820eae..6dbd8c2 100644 --- a/m17app/src/error.rs +++ b/m17app/src/error.rs @@ -11,9 +11,7 @@ pub enum M17Error { #[error("given callsign is {0} characters long; maximum is 9")] CallsignTooLong(usize), - #[error( - "provided packet payload is too large: provided {provided} bytes, capacity {capacity}" - )] + #[error("provided packet payload is too large: provided {provided} bytes, capacity {capacity}")] PacketTooLarge { provided: usize, capacity: usize }, #[error("provided path to RRC file could not be opened: {0}")] diff --git a/m17app/src/link_setup.rs b/m17app/src/link_setup.rs index b036006..2e960a7 100644 --- a/m17app/src/link_setup.rs +++ b/m17app/src/link_setup.rs @@ -1,7 +1,7 @@ use std::fmt::Display; use m17core::{ - address::{Address, Callsign, ALPHABET}, + address::{ALPHABET, Address, Callsign}, protocol::LsfFrame, }; diff --git a/m17app/src/reflector.rs b/m17app/src/reflector.rs index 9b383f7..b5825bb 100644 --- a/m17app/src/reflector.rs +++ b/m17app/src/reflector.rs @@ -2,9 +2,9 @@ use std::{ io::{self, Read, Write}, net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs, UdpSocket}, sync::{ + Arc, Mutex, atomic::{AtomicBool, Ordering}, mpsc::{self, Receiver, Sender}, - Arc, Mutex, }, thread, time::Duration, @@ -79,8 +79,9 @@ impl Write for ReflectorClientTnc { fn write(&mut self, buf: &[u8]) -> std::io::Result { let mut kiss = self.kiss_buffer.lock().unwrap(); let rem = kiss.buf_remaining(); - let sz = buf.len().max(rem.len()); + let sz = buf.len().min(rem.len()); rem[0..sz].copy_from_slice(&buf[0..sz]); + kiss.did_write(sz); if let Some(frame) = kiss.next_frame() { if Ok(KissCommand::DataFrame) == frame.command() && frame.port() == Ok(PORT_STREAM) { let mut payload = [0u8; 30]; @@ -196,6 +197,8 @@ fn spawn_runner( config.clone(), status.clone(), ); + // Cool off a bit if connect rejected, etc. + thread::sleep(Duration::from_secs(10)); } } status.lock().unwrap().status_changed(TncStatus::Closed); @@ -217,7 +220,7 @@ fn run_single_conn( }; let mut connect = Connect::new(); - connect.set_address(config.local_callsign.address().to_owned()); + connect.set_address(config.local_callsign.address()); connect.set_module(config.module); let _ = socket.send_to(connect.as_bytes(), dest); let mut converter = VoiceToRf::new(); @@ -263,12 +266,7 @@ fn run_single_conn( } ServerMessage::Ping(_ping) => { let mut pong = Pong::new(); - pong.set_address( - M17Address::from_callsign("VK7XT") - .unwrap() - .address() - .clone(), - ); + pong.set_address(config.local_callsign.address()); if socket.send_to(pong.as_bytes(), dest).is_err() { break; } diff --git a/m17app/src/rtlsdr.rs b/m17app/src/rtlsdr.rs index 269769b..72217cf 100644 --- a/m17app/src/rtlsdr.rs +++ b/m17app/src/rtlsdr.rs @@ -1,7 +1,7 @@ use std::{ io::Read, process::{Child, Command, Stdio}, - sync::{mpsc::SyncSender, Mutex}, + sync::{Mutex, mpsc::SyncSender}, }; use crate::{ diff --git a/m17app/src/soundcard.rs b/m17app/src/soundcard.rs index 9209de2..fb29282 100644 --- a/m17app/src/soundcard.rs +++ b/m17app/src/soundcard.rs @@ -1,16 +1,16 @@ use std::{ borrow::Borrow, sync::{ - mpsc::{sync_channel, Receiver, SyncSender}, Arc, RwLock, + mpsc::{Receiver, SyncSender, sync_channel}, }, time::{Duration, Instant}, }; use cpal::{ - traits::{DeviceTrait, HostTrait, StreamTrait}, BuildStreamError, DevicesError, PlayStreamError, SampleFormat, SampleRate, Stream, StreamError, SupportedStreamConfigRange, SupportedStreamConfigsError, + traits::{DeviceTrait, HostTrait, StreamTrait}, }; use thiserror::Error; diff --git a/m17app/src/soundmodem.rs b/m17app/src/soundmodem.rs index c0cbfbb..c782d86 100644 --- a/m17app/src/soundmodem.rs +++ b/m17app/src/soundmodem.rs @@ -9,8 +9,8 @@ use std::fmt::Display; use std::fs::File; use std::io::{self, Read, Write}; use std::path::PathBuf; -use std::sync::mpsc::{channel, sync_channel, Receiver, Sender, SyncSender, TryRecvError}; use std::sync::RwLock; +use std::sync::mpsc::{Receiver, Sender, SyncSender, TryRecvError, channel, sync_channel}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use thiserror::Error; diff --git a/m17app/src/util/out_buffer.rs b/m17app/src/util/out_buffer.rs index c24e0a9..06d8e91 100644 --- a/m17app/src/util/out_buffer.rs +++ b/m17app/src/util/out_buffer.rs @@ -2,7 +2,7 @@ use std::{ io::{self, ErrorKind, Read}, - sync::{mpsc::Receiver, Arc, Mutex}, + sync::{Arc, Mutex, mpsc::Receiver}, }; #[derive(Clone)] diff --git a/m17codec2/src/error.rs b/m17codec2/src/error.rs index 7fa6583..b1b3e62 100644 --- a/m17codec2/src/error.rs +++ b/m17codec2/src/error.rs @@ -14,7 +14,9 @@ pub enum M17Codec2Error { #[error("selected card '{0}' failed to list available output configs: '{1}'")] OutputConfigsUnavailable(String, #[source] cpal::SupportedStreamConfigsError), - #[error("selected card '{0}' did not offer a compatible output config type, either due to hardware limitations or because it is currently in use")] + #[error( + "selected card '{0}' did not offer a compatible output config type, either due to hardware limitations or because it is currently in use" + )] SupportedOutputUnavailable(String), #[error("selected card '{0}' was unable to build an output stream: '{1}'")] @@ -26,7 +28,9 @@ pub enum M17Codec2Error { #[error("selected card '{0}' failed to list available input configs: '{1}'")] InputConfigsUnavailable(String, #[source] cpal::SupportedStreamConfigsError), - #[error("selected card '{0}' did not offer a compatible input config type, either due to hardware limitations or because it is currently in use")] + #[error( + "selected card '{0}' did not offer a compatible input config type, either due to hardware limitations or because it is currently in use" + )] SupportedInputUnavailable(String), #[error("selected card '{0}' was unable to build an input stream: '{1}'")] diff --git a/m17codec2/src/rx.rs b/m17codec2/src/rx.rs index 5649519..455ce42 100644 --- a/m17codec2/src/rx.rs +++ b/m17codec2/src/rx.rs @@ -17,8 +17,8 @@ use std::fs::File; use std::io::Write; use std::path::Path; use std::sync::{ - mpsc::{channel, Receiver, Sender}, Arc, Mutex, + mpsc::{Receiver, Sender, channel}, }; /// Write one or more 8-byte chunks of 3200-bit Codec2 to a raw S16LE file diff --git a/m17codec2/src/tx.rs b/m17codec2/src/tx.rs index a54d864..d9028fb 100644 --- a/m17codec2/src/tx.rs +++ b/m17codec2/src/tx.rs @@ -1,24 +1,24 @@ use codec2::{Codec2, Codec2Mode}; +use cpal::SampleFormat; +use cpal::SampleRate; use cpal::traits::DeviceTrait; use cpal::traits::HostTrait; use cpal::traits::StreamTrait; -use cpal::SampleFormat; -use cpal::SampleRate; use log::debug; +use m17app::StreamFrame; use m17app::adapter::StreamAdapter; use m17app::app::TxHandle; use m17app::error::AdapterError; use m17app::link_setup::LinkSetup; use m17app::link_setup::M17Address; -use m17app::StreamFrame; use rubato::Resampler; use rubato::SincFixedOut; use rubato::SincInterpolationParameters; use std::path::PathBuf; -use std::sync::mpsc; -use std::sync::mpsc::channel; use std::sync::Arc; use std::sync::Mutex; +use std::sync::mpsc; +use std::sync::mpsc::channel; use std::time::Duration; use std::time::Instant; diff --git a/m17core/src/bits.rs b/m17core/src/bits.rs index 7b39995..4dea6d1 100644 --- a/m17core/src/bits.rs +++ b/m17core/src/bits.rs @@ -73,7 +73,7 @@ impl<'a> BitsMut<'a> { } pub(crate) fn set_bit(&mut self, idx: usize, value: u8) { - let slice = &mut self.0 .0; + let slice = &mut self.0.0; let existing = slice[idx / 8]; if value == 0 { slice[idx / 8] = existing & !(1 << (7 - (idx % 8))); diff --git a/m17core/src/decode.rs b/m17core/src/decode.rs index 3bd8164..4bc6288 100644 --- a/m17core/src/decode.rs +++ b/m17core/src/decode.rs @@ -3,8 +3,8 @@ use crate::{ fec::{self, p_1, p_2, p_3}, interleave::interleave, protocol::{ - LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, BERT_SYNC, END_OF_TRANSMISSION, - LSF_SYNC, PACKET_SYNC, PREAMBLE, STREAM_SYNC, + BERT_SYNC, END_OF_TRANSMISSION, LSF_SYNC, LsfFrame, PACKET_SYNC, PREAMBLE, PacketFrame, + PacketFrameCounter, STREAM_SYNC, StreamFrame, }, random::random_xor, }; diff --git a/m17core/src/encode.rs b/m17core/src/encode.rs index 5e0951e..94d280b 100644 --- a/m17core/src/encode.rs +++ b/m17core/src/encode.rs @@ -3,7 +3,7 @@ use crate::{ fec::{self, p_1, p_2, p_3}, interleave::interleave, protocol::{ - LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, LSF_SYNC, PACKET_SYNC, STREAM_SYNC, + LSF_SYNC, LsfFrame, PACKET_SYNC, PacketFrame, PacketFrameCounter, STREAM_SYNC, StreamFrame, }, random::random_xor, }; diff --git a/m17core/src/modem.rs b/m17core/src/modem.rs index 43ad5ac..255678f 100644 --- a/m17core/src/modem.rs +++ b/m17core/src/modem.rs @@ -1,5 +1,5 @@ use crate::decode::{ - parse_lsf, parse_packet, parse_stream, sync_burst_correlation, SyncBurst, SYNC_THRESHOLD, + SYNC_THRESHOLD, SyncBurst, parse_lsf, parse_packet, parse_stream, sync_burst_correlation, }; use crate::encode::{ encode_lsf, encode_packet, encode_stream, generate_end_of_transmission, generate_preamble, diff --git a/m17core/src/protocol.rs b/m17core/src/protocol.rs index be1eba1..251fa27 100644 --- a/m17core/src/protocol.rs +++ b/m17core/src/protocol.rs @@ -1,5 +1,5 @@ use crate::{ - address::{encode_address, Address}, + address::{Address, encode_address}, bits::BitsMut, }; diff --git a/m17core/src/reflector/convert.rs b/m17core/src/reflector/convert.rs index fd52df8..716e68a 100644 --- a/m17core/src/reflector/convert.rs +++ b/m17core/src/reflector/convert.rs @@ -70,7 +70,9 @@ pub struct RfToVoice { impl RfToVoice { pub fn new(lsf: LsfFrame) -> Self { - Self { lsf, stream_id: 0 } + // no_std "random" + let stream_id = &lsf as *const LsfFrame as u16; + Self { lsf, stream_id } } pub fn process_lsf(&mut self, lsf: LsfFrame) { diff --git a/m17core/src/reflector/packet.rs b/m17core/src/reflector/packet.rs index 3f746d6..3dc8378 100644 --- a/m17core/src/reflector/packet.rs +++ b/m17core/src/reflector/packet.rs @@ -185,7 +185,7 @@ macro_rules! impl_address { crate::address::decode_address(self.0[$from..($from + 6)].try_into().unwrap()) } - pub fn set_address(&mut self, address: Address) { + pub fn set_address(&mut self, address: &Address) { let encoded = crate::address::encode_address(&address); self.0[$from..($from + 6)].copy_from_slice(&encoded); self.recalculate_crc(); diff --git a/tools/m17rt-netclient/src/main.rs b/tools/m17rt-netclient/src/main.rs index fbcfb15..3204b5b 100644 --- a/tools/m17rt-netclient/src/main.rs +++ b/tools/m17rt-netclient/src/main.rs @@ -34,6 +34,14 @@ fn main() { .required(true) .help("Your callsign for reflector registration and transmissions"), ) + .arg( + Arg::new("reflector") + .long("reflector") + .short('r') + .value_parser(valid_callsign) + .required(true) + .help("Reflector designator/callsign, often starting with 'M17-'"), + ) .arg( Arg::new("module") .long("module") @@ -59,11 +67,20 @@ fn main() { let hostname = args.get_one::("hostname").unwrap(); let port = args.get_one::("port").unwrap(); let callsign = args.get_one::("callsign").unwrap(); + let reflector = args.get_one::("reflector").unwrap(); let module = args.get_one::("module").unwrap(); let input = args.get_one::("input"); let output = args.get_one::("output"); - let mut tx = Codec2TxAdapter::new(callsign.clone(), M17Address::new_broadcast()); + let ref_with_mod = format!("{} {}", reflector, module); + let Ok(reflector) = M17Address::from_callsign(&ref_with_mod) else { + println!( + "Unable to create valid destination address for reflector + callsign '{ref_with_mod}'" + ); + std::process::exit(1); + }; + + let mut tx = Codec2TxAdapter::new(callsign.clone(), reflector); if let Some(input) = input { tx.set_input_card(input); } diff --git a/tools/m17rt-rxpacket/src/main.rs b/tools/m17rt-rxpacket/src/main.rs index a18537e..adfc444 100644 --- a/tools/m17rt-rxpacket/src/main.rs +++ b/tools/m17rt-rxpacket/src/main.rs @@ -1,9 +1,9 @@ +use m17app::PacketType; use m17app::adapter::PacketAdapter; use m17app::app::M17App; use m17app::link_setup::LinkSetup; use m17app::soundcard::Soundcard; use m17app::soundmodem::{NullErrorHandler, NullOutputSink, NullPtt, Soundmodem}; -use m17app::PacketType; use std::sync::Arc; fn main() {