formatted some rust docs

This commit is contained in:
2026-05-11 16:24:40 -03:00
parent 760027b925
commit 6b3ce96c18
10 changed files with 77 additions and 48 deletions

View File

@@ -131,8 +131,8 @@ impl UasPlatformCoTPayload {
None => (escape_xml(&self.vehicle_type_tag), None), None => (escape_xml(&self.vehicle_type_tag), None),
}; };
let now = Utc::now().to_rfc3339_opts(SecondsFormat::Millis, true); let now = Utc::now().to_rfc3339_opts(SecondsFormat::Millis, true);
let stale = let stale = (Utc::now() + Duration::milliseconds(3500))
(Utc::now() + Duration::milliseconds(3500)).to_rfc3339_opts(SecondsFormat::Millis, true); .to_rfc3339_opts(SecondsFormat::Millis, true);
let mut xml = String::new(); let mut xml = String::new();
xml.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); xml.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
@@ -153,8 +153,7 @@ impl UasPlatformCoTPayload {
xml.push_str("<_uastool extendedCot=\"true\" activeRoute=\"false\"/>"); xml.push_str("<_uastool extendedCot=\"true\" activeRoute=\"false\"/>");
xml.push_str(&format!( xml.push_str(&format!(
"<track course=\"{}\" slope=\"0.0\" speed=\"{}\"/>", "<track course=\"{}\" slope=\"0.0\" speed=\"{}\"/>",
self.track_course, self.track_course, self.track_speed,
self.track_speed,
)); ));
xml.push_str(&format!( xml.push_str(&format!(
"<sensor elevation=\"{}\" vfov=\"{}\" north=\"0.0\" roll=\"0.0\" range=\"{}\" azimuth=\"{}\" fov=\"{}\" type=\"r-e\" version=\"0.6\"/>", "<sensor elevation=\"{}\" vfov=\"{}\" north=\"0.0\" roll=\"0.0\" range=\"{}\" azimuth=\"{}\" fov=\"{}\" type=\"r-e\" version=\"0.6\"/>",
@@ -186,7 +185,10 @@ impl UasPlatformCoTPayload {
} else { } else {
xml.push_str("<__video></__video>"); xml.push_str("<__video></__video>");
} }
xml.push_str(&format!("<link uid=\"{}\" type=\"a-f-G-U-C\" relation=\"p-p\" />", link_uid)); xml.push_str(&format!(
"<link uid=\"{}\" type=\"a-f-G-U-C\" relation=\"p-p\" />",
link_uid
));
xml.push_str("</detail></event>"); xml.push_str("</detail></event>");
xml xml
} }
@@ -326,5 +328,3 @@ impl UasSensorCoTPayload {
xml xml
} }
} }

View File

@@ -13,7 +13,9 @@ fn parse_video_url(url: &str) -> Option<(String, String, String, String)> {
Some((authority, path)) => (authority, format!("/{}", path)), Some((authority, path)) => (authority, format!("/{}", path)),
None => (rest, String::new()), None => (rest, String::new()),
}; };
let host_port = authority.rsplit_once('@').map_or(authority, |(_, host_port)| host_port); let host_port = authority
.rsplit_once('@')
.map_or(authority, |(_, host_port)| host_port);
let (address, port) = host_port.rsplit_once(':')?; let (address, port) = host_port.rsplit_once(':')?;
if protocol.is_empty() || address.is_empty() || port.is_empty() { if protocol.is_empty() || address.is_empty() || port.is_empty() {
@@ -35,10 +37,7 @@ pub fn video_detail_xml(video_url: &str, uid: &str, callsign: &str) -> String {
} }
let Some((protocol, address, port, path)) = parse_video_url(trimmed_url) else { let Some((protocol, address, port, path)) = parse_video_url(trimmed_url) else {
return format!( return format!("<__video url=\"{}\"/>", escape_xml_attribute(trimmed_url));
"<__video url=\"{}\"/>",
escape_xml_attribute(trimmed_url)
);
}; };
format!( format!(

View File

@@ -5,6 +5,7 @@ mod mdns;
mod structs; mod structs;
mod tcp; mod tcp;
mod tests; mod tests;
mod uas;
mod udp_socket; mod udp_socket;
mod video_stream; mod video_stream;

View File

@@ -23,7 +23,13 @@ fn detect_local_ipv4() -> Result<Ipv4Addr, String> {
fn sanitize_label(value: &str, fallback: &str) -> String { fn sanitize_label(value: &str, fallback: &str) -> String {
let mut sanitized = value let mut sanitized = value
.chars() .chars()
.map(|c| if c.is_ascii_alphanumeric() || c == '-' { c } else { '-' }) .map(|c| {
if c.is_ascii_alphanumeric() || c == '-' {
c
} else {
'-'
}
})
.collect::<String>() .collect::<String>()
.trim_matches('-') .trim_matches('-')
.to_string(); .to_string();
@@ -67,7 +73,13 @@ fn push_record(buf: &mut Vec<u8>, name: &str, rr_type: u16, rr_class: u16, ttl:
buf.extend_from_slice(rdata); buf.extend_from_slice(rdata);
} }
fn build_mdns_packet(instance_name: &str, host_name: &str, ip: Ipv4Addr, port: u16, video_uri: &str) -> Vec<u8> { fn build_mdns_packet(
instance_name: &str,
host_name: &str,
ip: Ipv4Addr,
port: u16,
video_uri: &str,
) -> Vec<u8> {
let service_type = "_mavlink._udp.local"; let service_type = "_mavlink._udp.local";
let instance_fqdn = format!("{}.{}", instance_name, service_type); let instance_fqdn = format!("{}.{}", instance_name, service_type);
let host_fqdn = format!("{}.local", host_name); let host_fqdn = format!("{}.local", host_name);
@@ -122,7 +134,11 @@ pub fn start_uas_advertisement(
let local_ip = match detect_local_ipv4() { let local_ip = match detect_local_ipv4() {
Ok(ip) => ip, Ok(ip) => ip,
Err(error) => { Err(error) => {
let _ = ctx.callback_data("MDNS ERROR", "Failed to determine local IPv4", error.clone()); let _ = ctx.callback_data(
"MDNS ERROR",
"Failed to determine local IPv4",
error.clone(),
);
return "mdns local IPv4 error"; return "mdns local IPv4 error";
} }
}; };
@@ -161,7 +177,10 @@ pub fn start_uas_advertisement(
loop { loop {
match socket.send_to(&packet, multicast_addr) { match socket.send_to(&packet, multicast_addr) {
Ok(size) => info!("Sent mDNS UAS advertisement ({} bytes) to {}", size, multicast_addr), Ok(size) => info!(
"Sent mDNS UAS advertisement ({} bytes) to {}",
size, multicast_addr
),
Err(error) => info!("Failed sending mDNS UAS advertisement: {}", error), Err(error) => info!("Failed sending mDNS UAS advertisement: {}", error),
} }
@@ -172,7 +191,10 @@ pub fn start_uas_advertisement(
} }
} }
info!("Stopped mDNS UAS advertisement for instance={}", safe_instance); info!(
"Stopped mDNS UAS advertisement for instance={}",
safe_instance
);
}); });
let _ = ctx.callback_data( let _ = ctx.callback_data(

View File

@@ -54,9 +54,7 @@ fn send_over_stream(
) -> Result<(), String> { ) -> Result<(), String> {
let message_len = message.len(); let message_len = message.len();
info!("Sending TCP payload ({} bytes)", message_len); info!("Sending TCP payload ({} bytes)", message_len);
stream stream.write_message(message.as_bytes()).map_err(|e| {
.write_message(message.as_bytes())
.map_err(|e| {
let message = e.to_string(); let message = e.to_string();
let _ = context.callback_data( let _ = context.callback_data(
"TCP SOCKET ERROR", "TCP SOCKET ERROR",
@@ -145,10 +143,14 @@ impl TcpClient {
let mut pending_messages: VecDeque<(String, Context)> = VecDeque::new(); let mut pending_messages: VecDeque<(String, Context)> = VecDeque::new();
let (connect_tx, connect_rx) = mpsc::channel(); let (connect_tx, connect_rx) = mpsc::channel();
info!("TCP worker thread started with config: {}", config_description); info!(
"TCP worker thread started with config: {}",
config_description
);
let tcp_thread = thread::spawn(move || { let tcp_thread = thread::spawn(move || {
let connect_result = panic::catch_unwind(AssertUnwindSafe(|| connect_stream(&config))); let connect_result =
panic::catch_unwind(AssertUnwindSafe(|| connect_stream(&config)));
match connect_result { match connect_result {
Ok(Ok(stream)) => { Ok(Ok(stream)) => {
@@ -184,7 +186,8 @@ impl TcpClient {
match &mut state { match &mut state {
ConnectionState::Connected => { ConnectionState::Connected => {
if let Some(stream) = connection.as_mut() { if let Some(stream) = connection.as_mut() {
if let Err(error) = send_over_stream(stream, &context, message) { if let Err(error) = send_over_stream(stream, &context, message)
{
info!("Failed to send message: {}", error); info!("Failed to send message: {}", error);
state = ConnectionState::Failed(error); state = ConnectionState::Failed(error);
connection = None; connection = None;

View File

@@ -50,10 +50,7 @@ pub fn send_uas_platform_cot(
"Sending UAS Platform main CoT to TCP server" "Sending UAS Platform main CoT to TCP server"
} }
pub fn send_uas_video_cot( pub fn send_uas_video_cot(ctx: Context, payload: cot::uas::UasVideoCoTPayload) -> &'static str {
ctx: Context,
payload: cot::uas::UasVideoCoTPayload,
) -> &'static str {
let xml = payload.to_xml(); let xml = payload.to_xml();
if !xml.is_empty() { if !xml.is_empty() {
send_payload(ctx, xml); send_payload(ctx, xml);
@@ -62,10 +59,7 @@ pub fn send_uas_video_cot(
"Sending UAS Video (b-i-v) CoT to TCP server" "Sending UAS Video (b-i-v) CoT to TCP server"
} }
pub fn send_uas_sensor_cot( pub fn send_uas_sensor_cot(ctx: Context, payload: cot::uas::UasSensorCoTPayload) -> &'static str {
ctx: Context,
payload: cot::uas::UasSensorCoTPayload,
) -> &'static str {
let xml = payload.to_xml(); let xml = payload.to_xml();
send_payload(ctx, xml); send_payload(ctx, xml);

View File

@@ -6,8 +6,8 @@ use std::fs::File;
use std::io::BufReader; use std::io::BufReader;
use std::io::Cursor; use std::io::Cursor;
use std::net::{SocketAddr, TcpStream, ToSocketAddrs}; use std::net::{SocketAddr, TcpStream, ToSocketAddrs};
use std::time::Duration;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use crate::tcp::transport::TransportStream; use crate::tcp::transport::TransportStream;
@@ -65,7 +65,12 @@ fn resolve_address(address: &str) -> Result<SocketAddr, String> {
.to_socket_addrs() .to_socket_addrs()
.map_err(|e| format!("failed to resolve {}: {}", address, e))? .map_err(|e| format!("failed to resolve {}: {}", address, e))?
.next() .next()
.ok_or_else(|| format!("failed to resolve {}: no socket addresses returned", address)) .ok_or_else(|| {
format!(
"failed to resolve {}: no socket addresses returned",
address
)
})
} }
fn connect_tcp(address: &str) -> Result<TcpStream, String> { fn connect_tcp(address: &str) -> Result<TcpStream, String> {

View File

@@ -1,5 +1,5 @@
use rcgen::{CertificateParams, DistinguishedName, DnType, KeyPair, PKCS_RSA_SHA256};
use log::info; use log::info;
use rcgen::{CertificateParams, DistinguishedName, DnType, KeyPair, PKCS_RSA_SHA256};
use reqwest::blocking::Client; use reqwest::blocking::Client;
use serde::Deserialize; use serde::Deserialize;
use uuid::Uuid; use uuid::Uuid;
@@ -198,10 +198,7 @@ pub fn enroll_and_connect(
}; };
info!( info!(
"Starting enroll_and_connect for host={} enroll_port={} server_name={} client_uid={}", "Starting enroll_and_connect for host={} enroll_port={} server_name={} client_uid={}",
host, host, enroll_port, server_name, normalized_client_uid
enroll_port,
server_name,
normalized_client_uid
); );
let enrollment_config = fetch_enrollment_config(host, enroll_port)?; let enrollment_config = fetch_enrollment_config(host, enroll_port)?;

View File

@@ -35,7 +35,12 @@ fn connect_plain(address: &str) -> Result<TransportStream, String> {
.to_socket_addrs() .to_socket_addrs()
.map_err(|e| format!("failed to resolve {}: {}", address, e))? .map_err(|e| format!("failed to resolve {}: {}", address, e))?
.next() .next()
.ok_or_else(|| format!("failed to resolve {}: no socket addresses returned", address))?; .ok_or_else(|| {
format!(
"failed to resolve {}: no socket addresses returned",
address
)
})?;
info!( info!(
"Opening plain TCP connection to {} (resolved={}) with timeout {:?}", "Opening plain TCP connection to {} (resolved={}) with timeout {:?}",

View File

@@ -70,7 +70,10 @@ pub fn start_stream(
let rtsp_url = if username.is_empty() || password.is_empty() { let rtsp_url = if username.is_empty() || password.is_empty() {
format!("rtsp://{}:{}/{}", address, port, stream_path) format!("rtsp://{}:{}/{}", address, port, stream_path)
} else { } else {
format!("rtsp://{}:{}@{}:{}/{}", username, password, address, port, stream_path) format!(
"rtsp://{}:{}@{}:{}/{}",
username, password, address, port, stream_path
)
}; };
let mut cmd = Command::new("ffmpeg"); let mut cmd = Command::new("ffmpeg");