[Updt] Mtp 0.3.0

This commit is contained in:
Alex 2026-08-20 17:05:40 +02:00
commit ed060ed213
Signed by: alex
SSH key fingerprint: SHA256:D1+Ub8o0v4K5y1JNivW8IxEOelqLSvPmUzBbDIoZkRQ
27 changed files with 1066 additions and 284 deletions

View file

@ -16,37 +16,38 @@ use crate::{
use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataValue};
use mtp::host::AuthState;
use mtp::webserver::{WebMTPConnection, WebMtpReceiver, WebMtpSender};
use thiserror::Error;
pub type MtpSender = WebMtpSender;
pub type MtpReceiver = WebMtpReceiver;
/*
* MTP 0.3 exposes absent frame fields and data entries as Options. These
* adapters keep legacy control handlers explicit while Relay code uses the
* native optional accessors directly.
*/
pub(crate) trait MtpValueCompat {
fn get_id(&self) -> u32;
fn get_sender(&self) -> u64;
fn get_receiver(&self) -> u64;
fn get_data_opt(&self, data_type: DataType) -> Option<&DataValue>;
#[derive(Debug, Clone, Copy, Error, PartialEq, Eq)]
pub enum FrameValidationError {
#[error("message is missing an MTP id")]
MissingId,
#[error("message is missing an MTP sender")]
MissingSender,
#[error("message is missing an MTP receiver")]
MissingReceiver,
}
impl MtpValueCompat for CommunicationValue {
fn get_id(&self) -> u32 {
self.id().unwrap_or_default()
pub trait RequiredMtpFields {
fn require_id(&self) -> Result<u32, FrameValidationError>;
fn require_sender(&self) -> Result<u64, FrameValidationError>;
fn require_receiver(&self) -> Result<u64, FrameValidationError>;
}
impl RequiredMtpFields for CommunicationValue {
fn require_id(&self) -> Result<u32, FrameValidationError> {
self.id().ok_or(FrameValidationError::MissingId)
}
fn get_sender(&self) -> u64 {
self.sender().unwrap_or_default()
fn require_sender(&self) -> Result<u64, FrameValidationError> {
self.sender().ok_or(FrameValidationError::MissingSender)
}
fn get_receiver(&self) -> u64 {
self.receiver().unwrap_or_default()
}
fn get_data_opt(&self, data_type: DataType) -> Option<&DataValue> {
self.get_data(data_type)
fn require_receiver(&self) -> Result<u64, FrameValidationError> {
self.receiver().ok_or(FrameValidationError::MissingReceiver)
}
}
@ -55,6 +56,7 @@ pub(crate) trait OptionalDataValueCompat {
fn as_number(&self) -> Option<i128>;
fn as_signed_number(&self) -> Option<i128>;
fn as_str(&self) -> Option<&str>;
#[allow(dead_code)]
fn as_bytes(&self) -> Option<Vec<u8>>;
}
@ -80,6 +82,42 @@ impl OptionalDataValueCompat for Option<&DataValue> {
}
}
#[cfg(test)]
mod tests {
use super::{FrameValidationError, RequiredMtpFields};
use mtp::codec::{CommunicationType, CommunicationValue};
#[test]
fn required_fields_preserve_missing_field_errors() {
let frame = CommunicationValue::new(CommunicationType::Success)
.without_id()
.without_sender()
.without_receiver();
assert_eq!(frame.require_id(), Err(FrameValidationError::MissingId));
assert_eq!(
frame.require_sender(),
Err(FrameValidationError::MissingSender)
);
assert_eq!(
frame.require_receiver(),
Err(FrameValidationError::MissingReceiver)
);
}
#[test]
fn zero_is_a_present_routing_value() {
let frame = CommunicationValue::new(CommunicationType::Success)
.with_id(0)
.with_sender(0)
.with_receiver(0);
assert_eq!(frame.require_id(), Ok(0));
assert_eq!(frame.require_sender(), Ok(0));
assert_eq!(frame.require_receiver(), Ok(0));
}
}
/*
* How a connection identified itself during the mtp handshake driven by
* `server.rs` ("iota" / "client" authenticated logins, "anonymous"
@ -149,6 +187,10 @@ impl GeneralConnection {
}))
}
pub fn connection_kind(&self) -> ConnectionKind {
self.connection_kind
}
pub async fn handle(self: Arc<Self>) {
log_in!(0, PrintType::General, "General connection handler started");
if self.migrate().await {