Add send-file utilities for wingtech and tplink

Since we never turn on ADB, it's a bit cumbersome to send files to the
device.
This commit is contained in:
Markus Unterwaditzer
2025-07-03 20:44:25 +02:00
committed by Markus Unterwaditzer
parent cf0875f2e3
commit b0d8307a14
2 changed files with 56 additions and 1 deletions
+38
View File
@@ -73,6 +73,16 @@ enum UtilSubCommand {
WingtechStartTelnet(WingtechArgs),
/// Root the Wingtech and launch adb.
WingtechStartAdb(WingtechArgs),
/// Send a file to the TP-Link device over telnet.
///
/// Before running this utility, you need to make telnet accessible with `installer util
/// tplink-start-telnet`.
TplinkSendFile(TplinkSendFile),
/// Send a file to the Wingtech device over telnet.
///
/// Before running this utility, you need to make telnet accessible with `installer util
/// wingtech-start-telnet`.
WingtechSendFile(WingtechSendFile),
}
#[derive(Parser, Debug)]
@@ -82,6 +92,28 @@ struct TplinkStartTelnet {
admin_ip: String,
}
#[derive(Parser, Debug)]
struct TplinkSendFile {
/// IP address for TP-Link admin interface, if custom.
#[arg(long, default_value = "192.168.0.1")]
admin_ip: String,
/// Local path to the file to send.
local_path: String,
/// Remote path where the file should be stored on the device.
remote_path: String,
}
#[derive(Parser, Debug)]
struct WingtechSendFile {
/// IP address for Wingtech admin interface, if custom.
#[arg(long, default_value = "192.168.1.1")]
admin_ip: String,
/// Local path to the file to send.
local_path: String,
/// Remote path where the file should be stored on the device.
remote_path: String,
}
#[derive(Parser, Debug)]
struct WingtechArgs {
/// IP address for Wingtech admin interface, if custom.
@@ -134,6 +166,12 @@ async fn run() -> Result<(), Error> {
UtilSubCommand::TplinkStartTelnet(options) => {
tplink::start_telnet(&options.admin_ip).await?;
}
UtilSubCommand::TplinkSendFile(options) => {
util::send_file(&options.admin_ip, &options.local_path, &options.remote_path).await?;
}
UtilSubCommand::WingtechSendFile(options) => {
util::send_file(&options.admin_ip, &options.local_path, &options.remote_path).await?;
}
UtilSubCommand::WingtechStartTelnet(args) => wingtech::start_telnet(&args.admin_ip, &args.admin_password).await.context("\nFailed to start telnet on the Wingtech CT2MHS01")?,
UtilSubCommand::WingtechStartAdb(args) => wingtech::start_adb(&args.admin_ip, &args.admin_password).await.context("\nFailed to start adb on the Wingtech CT2MHS01")?,
}
+18 -1
View File
@@ -1,8 +1,9 @@
use std::io::Write;
use std::net::SocketAddr;
use std::str::FromStr;
use std::time::Duration;
use anyhow::{Result, bail};
use anyhow::{Context, Result, bail};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use tokio::time::{sleep, timeout};
@@ -88,3 +89,19 @@ pub async fn telnet_send_file(addr: SocketAddr, filename: &str, payload: &[u8])
println!("ok");
Ok(())
}
pub async fn send_file(admin_ip: &str, local_path: &str, remote_path: &str) -> Result<()> {
let file_content = std::fs::read(local_path)
.with_context(|| format!("Failed to read local file: {}", local_path))?;
println!("Connecting to {admin_ip}");
let addr = SocketAddr::from_str(&format!("{admin_ip}:23"))
.with_context(|| format!("Invalid IP address: {}", admin_ip))?;
telnet_send_file(addr, remote_path, &file_content)
.await
.with_context(|| format!("Failed to send file {} to {}", local_path, remote_path))?;
println!("Successfully sent {} to {}", local_path, remote_path);
Ok(())
}