mirror of
https://codeberg.org/icewind/tasmota-mqtt-client.git
synced 2026-06-03 10:14:10 +02:00
proper error when a client disconnects mid-download
This commit is contained in:
parent
f211f59c38
commit
3395e052bd
3 changed files with 20 additions and 3 deletions
|
|
@ -1,9 +1,11 @@
|
|||
use crate::error::DownloadError;
|
||||
use crate::mqtt::MqttHelper;
|
||||
use crate::Result;
|
||||
use crate::{DeviceUpdate, Result};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use md5::{Digest, Md5};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::select;
|
||||
use tokio::sync::broadcast::Receiver;
|
||||
use tracing::debug;
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
|
@ -47,6 +49,7 @@ pub async fn download_config(
|
|||
mqtt: &MqttHelper,
|
||||
client: &str,
|
||||
password: &str,
|
||||
mut device_update: Receiver<DeviceUpdate>,
|
||||
) -> Result<DownloadedFile> {
|
||||
let mut rx = mqtt
|
||||
.subscribe(format!("stat/{client}/FILEDOWNLOAD"))
|
||||
|
|
@ -66,7 +69,19 @@ pub async fn download_config(
|
|||
let mut state = DownloadState::default();
|
||||
|
||||
loop {
|
||||
let msg = rx.recv().await.unwrap();
|
||||
let msg = select! {
|
||||
msg = rx.recv() => {
|
||||
msg.unwrap()
|
||||
}
|
||||
discovery = device_update.recv() => {
|
||||
if let Ok(DeviceUpdate::Removed(device)) = discovery {
|
||||
if device.as_str() == client {
|
||||
return Err(DownloadError::Gone.into());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if let Ok(response) = serde_json::from_slice::<DownloadResponse>(msg.payload.as_ref()) {
|
||||
debug!(message = ?response, "processing download status message");
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ pub enum DownloadError {
|
|||
InvalidHash,
|
||||
#[error("Received data doesn't match the expected md5 hash, expected {0:x?} got {1:x?}")]
|
||||
MismatchedHash([u8; 16], [u8; 16]),
|
||||
#[error("Device has disconnected during the download")]
|
||||
Gone,
|
||||
}
|
||||
|
||||
impl From<FromHexError> for DownloadError {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ impl TasmotaClient {
|
|||
/// The password is the mqtt password used by the device, which might be different from the mqtt password used by this client
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub async fn download_config(&self, client: &str, password: &str) -> Result<DownloadedFile> {
|
||||
download_config(&self.mqtt, client, password).await
|
||||
download_config(&self.mqtt, client, password, self.device_update.subscribe()).await
|
||||
}
|
||||
|
||||
/// Get the list of known devices at this point in time
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue