TP-Link: Space out HTTP requests a bit, retry connection for sending files

On firmware M7350(EU)_V9_9.0.2 Build 241021 (but not sooner), entryId=2
was being sent before entryId=1. entryId=2 is invalid if entryId=1 does
not exist yet. The reason it works is due to both requests firing
simultaneously, so sometimes entryId=1 is indeed being registered first.

We may also be hitting random race conditions on the backend, not 100%
sure. Try to alleviate them by sleeping 1 second between started
requests and waiting until the DOM is ready.

Also, on sluggish devices, it can happen that nc is not ready within
100ms. Fixing that with exponential backoff.
This commit is contained in:
Markus Unterwaditzer
2025-10-16 23:28:32 +02:00
committed by Cooper Quintin
parent cedfe2d4d7
commit fe2b8b3456
2 changed files with 53 additions and 16 deletions

View File

@@ -91,7 +91,7 @@ pub async fn telnet_send_file(
payload: &[u8],
wait_for_prompt: bool,
) -> Result<()> {
echo!("Sending file {filename} ... ");
echo!("Sending file {filename}... ");
let nc_output = {
let filename = filename.to_owned();
let handle = tokio::spawn(async move {
@@ -102,14 +102,31 @@ pub async fn telnet_send_file(
)
.await
});
// wait for nc to become available. if the installer fails with connection refused, this
// likely is not high enough.
sleep(Duration::from_millis(100)).await;
let mut addr = addr;
addr.set_port(8081);
let mut stream;
let mut attempts = 0;
loop {
// wait for nc to become available, with exponential backoff.
//
// if the installer fails with connection refused, this
// likely is not high enough.
sleep(Duration::from_millis(100 * (1 << attempts))).await;
stream = TcpStream::connect(addr).await;
attempts += 1;
if stream.is_ok() || attempts > 3 {
break;
}
echo!("attempt {attempts}... ");
}
{
let mut stream = TcpStream::connect(addr).await?;
let mut stream = stream?;
stream.write_all(payload).await?;
// if the orbic is sluggish, we need for nc to write the data to disk before
@@ -122,6 +139,7 @@ pub async fn telnet_send_file(
sleep(Duration::from_millis(1000)).await;
// ensure that stream is dropped before we wait for nc to terminate.
drop(stream);
}
handle.await??