file up & download and delete
This commit is contained in:
parent
cd63e76469
commit
584d6df2d0
@ -159,7 +159,7 @@ edge-nal-embassy = "0.6.0"
|
||||
static_cell = "2.1.1"
|
||||
cfg-if = "1.0.3"
|
||||
edge-http = { version = "0.6.1", features = ["log"] }
|
||||
littlefs2 = { version = "0.6.1", features = ["c-stubs", "alloc", "serde"] }
|
||||
littlefs2 = { version = "0.6.1", features = ["c-stubs", "alloc"] }
|
||||
littlefs2-core = "0.1.1"
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ use anyhow::{anyhow, bail, Context};
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::hal::LittleFS2StorageAdapter::LittleFs2Filesystem;
|
||||
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
|
||||
use alloc::string::ToString;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::{format, string::String, vec::Vec};
|
||||
@ -34,7 +34,7 @@ use esp_wifi::wifi::{
|
||||
ScanTypeConfig, WifiController, WifiDevice, WifiEvent, WifiState,
|
||||
};
|
||||
use littlefs2::fs::Filesystem;
|
||||
use littlefs2_core::{FileType, PathBuf};
|
||||
use littlefs2_core::{DynFile, FileType, OpenSeekFrom, Path, PathBuf, SeekFrom};
|
||||
use log::{info, warn};
|
||||
|
||||
#[link_section = ".rtc.data"]
|
||||
@ -113,6 +113,79 @@ macro_rules! mk_static {
|
||||
}
|
||||
|
||||
impl Esp<'_> {
|
||||
pub(crate) async fn delete_file(&self, filename: String) -> anyhow::Result<()> {
|
||||
let file = PathBuf::try_from(filename.as_str()).unwrap();
|
||||
let access = self.fs.lock().await;
|
||||
access
|
||||
.remove(&*file)
|
||||
.map_err(|err| anyhow!("Could not delete file: {:?}", err))?;
|
||||
Ok(())
|
||||
}
|
||||
pub(crate) async fn write_file(
|
||||
&mut self,
|
||||
filename: String,
|
||||
offset: u32,
|
||||
buf: &[u8],
|
||||
) -> anyhow::Result<()> {
|
||||
let file = PathBuf::try_from(filename.as_str()).unwrap();
|
||||
let access = self.fs.lock().await;
|
||||
info!("write file {} at offset {}", filename, offset);
|
||||
match access.open_file_with_options_and_then(
|
||||
|options| options.read(true).write(true).create(true),
|
||||
&*file,
|
||||
|file| {
|
||||
file.seek(SeekFrom::Start(offset))?;
|
||||
file.write(buf)?;
|
||||
Ok(())
|
||||
},
|
||||
) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
bail!(format!("{err:?}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) async fn get_file(
|
||||
&mut self,
|
||||
filename: String,
|
||||
chunk: u32,
|
||||
) -> anyhow::Result<([u8; 128], usize)> {
|
||||
use littlefs2::io::Error as lfs2Error;
|
||||
|
||||
let file = PathBuf::try_from(filename.as_str()).unwrap();
|
||||
let access = self.fs.lock().await;
|
||||
let mut buf = [0_u8; 128];
|
||||
let mut read = 0;
|
||||
let offset = chunk * 128;
|
||||
info!("read file {} at offset {}", filename, offset);
|
||||
match access.open_file_with_options_and_then(
|
||||
|options| options.read(true),
|
||||
&*file,
|
||||
|file| {
|
||||
let length = file.len()? as u32;
|
||||
info!("file length {}", length);
|
||||
if length == 0 {
|
||||
Err(lfs2Error::IO)
|
||||
} else if length > offset {
|
||||
file.seek(SeekFrom::Start(offset))?;
|
||||
info!("seek to {}", offset);
|
||||
read = file.read(&mut buf)?;
|
||||
info!("read {} bytes", read);
|
||||
Ok(())
|
||||
} else {
|
||||
//exactly at end, do nothing
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
bail!(format!("{err:?}"))
|
||||
}
|
||||
}
|
||||
Ok((buf, read))
|
||||
}
|
||||
|
||||
pub(crate) fn get_ota_slot(&mut self) -> String {
|
||||
match self.ota.current_slot() {
|
||||
Ok(slot) => {
|
||||
@ -435,12 +508,13 @@ impl Esp<'_> {
|
||||
match self.fs.lock().await.read_dir_and_then(&path, |dir| {
|
||||
for entry in dir {
|
||||
let e = entry?;
|
||||
|
||||
if e.file_type() == FileType::File {
|
||||
result.files.push(FileInfo {
|
||||
filename: e.path().to_string(),
|
||||
size: e.metadata().len(),
|
||||
});
|
||||
}
|
||||
}
|
||||
Result::Ok(())
|
||||
}) {
|
||||
Ok(_) => {}
|
||||
@ -450,16 +524,7 @@ impl Esp<'_> {
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
pub(crate) async fn delete_file(&self, _filename: &str) -> anyhow::Result<()> {
|
||||
bail!("todo");
|
||||
// let filepath = Path::new(Self::BASE_PATH).join(Path::new(filename));
|
||||
// match fs::remove_file(filepath) {
|
||||
// OkStd(_) => anyhow::Ok(()),
|
||||
// Err(err) => {
|
||||
// bail!(format!("{err:?}"))
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// pub(crate) async fn get_file_handle(
|
||||
// &self,
|
||||
// filename: &str,
|
||||
@ -473,13 +538,17 @@ impl Esp<'_> {
|
||||
// })
|
||||
// }
|
||||
|
||||
pub(crate) fn init_rtc_deepsleep_memory(&self, init_rtc_store: bool, to_config_mode: bool) {
|
||||
pub(crate) async fn init_rtc_deepsleep_memory(
|
||||
&self,
|
||||
init_rtc_store: bool,
|
||||
to_config_mode: bool,
|
||||
) {
|
||||
if init_rtc_store {
|
||||
unsafe {
|
||||
LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
|
||||
CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
|
||||
LOW_VOLTAGE_DETECTED = false;
|
||||
crate::log::init();
|
||||
crate::log::init().await;
|
||||
RESTART_TO_CONF = to_config_mode;
|
||||
};
|
||||
} else {
|
||||
@ -493,14 +562,16 @@ impl Esp<'_> {
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
);
|
||||
)
|
||||
.await;
|
||||
log(
|
||||
LogMessage::LowVoltage,
|
||||
LOW_VOLTAGE_DETECTED as u32,
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
);
|
||||
)
|
||||
.await;
|
||||
for i in 0..PLANT_COUNT {
|
||||
log::info!(
|
||||
"LAST_WATERING_TIMESTAMP[{}] = UTC {}",
|
||||
|
@ -1,8 +1,8 @@
|
||||
use embedded_storage::{ReadStorage, Storage};
|
||||
use esp_bootloader_esp_idf::partitions::FlashRegion;
|
||||
use esp_storage::FlashStorage;
|
||||
use littlefs2::consts::U1 as lfs2Array1;
|
||||
use littlefs2::consts::U512 as lfs2Array512;
|
||||
use littlefs2::consts::U512 as lfsCache;
|
||||
use littlefs2::consts::U512 as lfsLookahead;
|
||||
use littlefs2::driver::Storage as lfs2Storage;
|
||||
use littlefs2::fs::Filesystem as lfs2Filesystem;
|
||||
use littlefs2::io::Error as lfs2Error;
|
||||
@ -14,20 +14,15 @@ pub struct LittleFs2Filesystem {
|
||||
}
|
||||
|
||||
impl lfs2Storage for LittleFs2Filesystem {
|
||||
const READ_SIZE: usize = 512;
|
||||
const READ_SIZE: usize = 256;
|
||||
const WRITE_SIZE: usize = 512;
|
||||
const BLOCK_SIZE: usize = 1024; //usually optimal for flash access
|
||||
const BLOCK_COUNT: usize = 8 * 1024 * 1024 / 1024; //8mb in 32kb blocks
|
||||
const BLOCK_SIZE: usize = 512; //usually optimal for flash access
|
||||
const BLOCK_COUNT: usize = 8 * 1024 * 1024 / 512; //8mb in 32kb blocks
|
||||
const BLOCK_CYCLES: isize = 100;
|
||||
type CACHE_SIZE = lfs2Array512;
|
||||
type LOOKAHEAD_SIZE = lfs2Array1;
|
||||
type CACHE_SIZE = lfsCache;
|
||||
type LOOKAHEAD_SIZE = lfsLookahead;
|
||||
|
||||
fn read(&mut self, off: usize, buf: &mut [u8]) -> lfs2Result<usize> {
|
||||
info!(
|
||||
"Littlefs2Filesystem read at offset {} with len {}",
|
||||
off,
|
||||
buf.len()
|
||||
);
|
||||
let read_size: usize = Self::READ_SIZE;
|
||||
assert_eq!(off % read_size, 0);
|
||||
assert_eq!(buf.len() % read_size, 0);
|
@ -1,7 +1,7 @@
|
||||
mod LittleFS2StorageAdapter;
|
||||
pub(crate) mod battery;
|
||||
pub mod esp;
|
||||
mod initial_hal;
|
||||
mod little_fs2storage_adapter;
|
||||
mod rtc;
|
||||
//mod water;
|
||||
|
||||
@ -34,12 +34,10 @@ use esp_bootloader_esp_idf::partitions::{
|
||||
};
|
||||
use esp_hal::clock::CpuClock;
|
||||
use esp_hal::gpio::{Input, InputConfig, Pull};
|
||||
use esp_println::println;
|
||||
use measurements::{Current, Voltage};
|
||||
|
||||
use crate::hal::LittleFS2StorageAdapter::LittleFs2Filesystem;
|
||||
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
|
||||
use esp_alloc as _;
|
||||
use esp_backtrace as _;
|
||||
use esp_bootloader_esp_idf::ota::Slot;
|
||||
@ -182,6 +180,7 @@ impl PlantHal {
|
||||
let peripherals: Peripherals = esp_hal::init(config);
|
||||
|
||||
esp_alloc::heap_allocator!(size: 64 * 1024);
|
||||
esp_alloc::heap_allocator!(#[link_section = ".dram2_uninit"] size: 64000);
|
||||
let systimer = SystemTimer::new(peripherals.SYSTIMER);
|
||||
|
||||
let boot_button = Input::new(
|
||||
@ -364,9 +363,11 @@ impl PlantHal {
|
||||
to_config_mode as u32,
|
||||
"",
|
||||
&format!("{reasons:?}"),
|
||||
);
|
||||
)
|
||||
.await;
|
||||
|
||||
esp.init_rtc_deepsleep_memory(init_rtc_store, to_config_mode);
|
||||
esp.init_rtc_deepsleep_memory(init_rtc_store, to_config_mode)
|
||||
.await;
|
||||
|
||||
let config = esp.load_config().await;
|
||||
|
||||
@ -453,7 +454,8 @@ impl PlantHal {
|
||||
0,
|
||||
"",
|
||||
&err.to_string(),
|
||||
);
|
||||
)
|
||||
.await;
|
||||
HAL {
|
||||
board_hal: initial_hal::create_initial_board(
|
||||
free_pins,
|
||||
|
@ -31,8 +31,6 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::mutex::{Mutex, MutexGuard};
|
||||
use embassy_sync::once_lock::OnceLock;
|
||||
use embassy_time::Timer;
|
||||
use esp_alloc::heap_allocator;
|
||||
use esp_bootloader_esp_idf::ota::OtaImageState;
|
||||
use esp_hal::rom::ets_delay_us;
|
||||
use esp_hal::system::software_reset;
|
||||
use esp_println::{logger, println};
|
||||
@ -317,8 +315,7 @@ async fn safe_main(spawner: Spawner) -> anyhow::Result<()> {
|
||||
info!("executing config mode override");
|
||||
//config upload will trigger reboot!
|
||||
let reboot_now = Arc::new(AtomicBool::new(false));
|
||||
//TODO
|
||||
//let _webserver = httpd(reboot_now.clone());
|
||||
//spawner.spawn(httpd(reboot_now.clone(), stack))?;
|
||||
let board = BOARD_ACCESS.get().await.lock().await;
|
||||
wait_infinity(board, WaitType::ConfigButton, reboot_now.clone()).await;
|
||||
} else {
|
||||
@ -667,7 +664,8 @@ pub async fn do_secure_pump(
|
||||
current_ma as u32,
|
||||
plant_config.max_pump_current_ma.to_string().as_str(),
|
||||
step.to_string().as_str(),
|
||||
);
|
||||
)
|
||||
.await;
|
||||
board.board_hal.general_fault(true).await;
|
||||
board.board_hal.fault(plant_id, true).await?;
|
||||
if !plant_config.ignore_current_error {
|
||||
@ -686,7 +684,8 @@ pub async fn do_secure_pump(
|
||||
current_ma as u32,
|
||||
plant_config.min_pump_current_ma.to_string().as_str(),
|
||||
step.to_string().as_str(),
|
||||
);
|
||||
)
|
||||
.await;
|
||||
board.board_hal.general_fault(true).await;
|
||||
board.board_hal.fault(plant_id, true).await?;
|
||||
if !plant_config.ignore_current_error {
|
||||
@ -706,7 +705,8 @@ pub async fn do_secure_pump(
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
);
|
||||
)
|
||||
.await;
|
||||
error = true;
|
||||
break;
|
||||
} else {
|
||||
@ -840,7 +840,7 @@ async fn update_charge_indicator(board: &mut MutexGuard<'_, CriticalSectionRawMu
|
||||
// }
|
||||
|
||||
async fn publish_firmware_info(
|
||||
mut board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
|
||||
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
|
||||
version: VersionInfo,
|
||||
ip_address: &String,
|
||||
timezone_time: &String,
|
||||
@ -867,17 +867,6 @@ async fn publish_firmware_info(
|
||||
let _ = esp.mqtt_publish("/state", "online".as_bytes()).await;
|
||||
}
|
||||
|
||||
fn state_to_string(state: OtaImageState) -> &'static str {
|
||||
match state {
|
||||
OtaImageState::New => "New",
|
||||
OtaImageState::PendingVerify => "PendingVerify",
|
||||
OtaImageState::Valid => "Valid",
|
||||
OtaImageState::Invalid => "Invalid",
|
||||
OtaImageState::Aborted => "Aborted",
|
||||
OtaImageState::Undefined => "Undefined",
|
||||
}
|
||||
}
|
||||
|
||||
async fn try_connect_wifi_sntp_mqtt() -> NetworkMode {
|
||||
let board = &mut BOARD_ACCESS.get().await.lock().await;
|
||||
let nw_conf = &board.board_hal.get_config().network.clone();
|
||||
|
@ -3,6 +3,8 @@
|
||||
use crate::config::PlantControllerConfig;
|
||||
use crate::{get_version, log::LogMessage, BOARD_ACCESS};
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::fmt::format;
|
||||
use alloc::format;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
@ -21,6 +23,7 @@ use embassy_net::Stack;
|
||||
use embassy_time::Instant;
|
||||
use embedded_io_async::{Read, Write};
|
||||
use esp_println::println;
|
||||
use littlefs2_core::Path;
|
||||
use log::info;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -294,15 +297,6 @@ pub struct NightLampCommand {
|
||||
// anyhow::Ok(None)
|
||||
// }
|
||||
//
|
||||
// fn query_param(uri: &str, param_name: &str) -> Option<std::string::String> {
|
||||
// log::info!("{uri} get {param_name}");
|
||||
// let parsed = Url::parse(&format!("http://127.0.0.1/{uri}")).unwrap();
|
||||
// let value = parsed.query_pairs().find(|it| it.0 == param_name);
|
||||
// match value {
|
||||
// Some(found) => Some(found.1.into_owned()),
|
||||
// None => None,
|
||||
// }
|
||||
// }
|
||||
|
||||
struct HttpHandler {
|
||||
reboot_now: Arc<AtomicBool>,
|
||||
@ -324,10 +318,98 @@ impl Handler for HttpHandler {
|
||||
let method = headers.method;
|
||||
let path = headers.path;
|
||||
|
||||
let status = match method {
|
||||
let prefix = "/file?filename=";
|
||||
let status = if path.starts_with(prefix) {
|
||||
let filename = &path[prefix.len()..];
|
||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||
info!("file request for {} with method {}", filename, method);
|
||||
match method {
|
||||
Method::Delete => {
|
||||
board
|
||||
.board_hal
|
||||
.get_esp()
|
||||
.delete_file(filename.to_owned())
|
||||
.await
|
||||
.unwrap();
|
||||
Some(200)
|
||||
}
|
||||
Method::Get => {
|
||||
let disp = format!("attachment; filename=\"{filename}\"");
|
||||
conn.initiate_response(
|
||||
200,
|
||||
Some("OK"),
|
||||
&[
|
||||
("Content-Type", "application/octet-stream"),
|
||||
("Content-Disposition", disp.as_str()),
|
||||
],
|
||||
)
|
||||
.await?;
|
||||
let mut chunk = 0;
|
||||
loop {
|
||||
let read_chunk = board
|
||||
.board_hal
|
||||
.get_esp()
|
||||
.get_file(filename.to_owned(), chunk)
|
||||
.await
|
||||
.unwrap();
|
||||
let length = read_chunk.1;
|
||||
info!("read {} bytes for file request for {}", length, filename);
|
||||
if length == 0 {
|
||||
info!("file request for {} finished", filename);
|
||||
break;
|
||||
}
|
||||
let data = &read_chunk.0[0..length];
|
||||
conn.write_all(data).await?;
|
||||
if length < 128 {
|
||||
info!("file request for {} finished", filename);
|
||||
break;
|
||||
}
|
||||
chunk = chunk + 1;
|
||||
}
|
||||
Some(200)
|
||||
}
|
||||
Method::Post => {
|
||||
//ensure file is deleted, otherwise we would need to truncate the file which will not work with streaming
|
||||
let _ = board
|
||||
.board_hal
|
||||
.get_esp()
|
||||
.delete_file(filename.to_owned())
|
||||
.await;
|
||||
let mut offset = 0_usize;
|
||||
loop {
|
||||
let mut buf = [0_u8; 1024];
|
||||
let to_write = conn.read(&mut buf).await?;
|
||||
if to_write == 0 {
|
||||
info!("file request for {} finished", filename);
|
||||
break;
|
||||
} else {
|
||||
info!(
|
||||
"writing {} bytes for file request for {}",
|
||||
to_write, filename
|
||||
);
|
||||
board
|
||||
.board_hal
|
||||
.get_esp()
|
||||
.write_file(filename.to_owned(), offset as u32, &buf[0..to_write])
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
offset = offset + to_write
|
||||
}
|
||||
|
||||
Some(200)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
match method {
|
||||
Method::Get => match path {
|
||||
"/favicon.ico" => {
|
||||
conn.initiate_response(200, Some("OK"), &[("Content-Type", "image/x-icon")])
|
||||
conn.initiate_response(
|
||||
200,
|
||||
Some("OK"),
|
||||
&[("Content-Type", "image/x-icon")],
|
||||
)
|
||||
.await?;
|
||||
conn.write_all(include_bytes!("favicon.ico")).await?;
|
||||
Some(200)
|
||||
@ -339,7 +421,11 @@ impl Handler for HttpHandler {
|
||||
Some(200)
|
||||
}
|
||||
"/bundle.js" => {
|
||||
conn.initiate_response(200, Some("OK"), &[("Content-Type", "text/javascript")])
|
||||
conn.initiate_response(
|
||||
200,
|
||||
Some("OK"),
|
||||
&[("Content-Type", "text/javascript")],
|
||||
)
|
||||
.await?;
|
||||
conn.write_all(include_bytes!("bundle.js")).await?;
|
||||
Some(200)
|
||||
@ -382,6 +468,7 @@ impl Handler for HttpHandler {
|
||||
}
|
||||
Method::Options | Method::Delete | Method::Head | Method::Put => None,
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
let code = match status {
|
||||
None => {
|
||||
@ -390,6 +477,7 @@ impl Handler for HttpHandler {
|
||||
}
|
||||
Some(code) => code,
|
||||
};
|
||||
|
||||
conn.complete().await?;
|
||||
let response_time = Instant::now().duration_since(start).as_millis();
|
||||
|
||||
@ -398,16 +486,87 @@ impl Handler for HttpHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// fn set_config(
|
||||
// request: &mut Request<&mut EspHttpConnection>,
|
||||
// ) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||
// let all = read_up_to_bytes_from_request(request, Some(4096))?;
|
||||
// let config: PlantControllerConfig = serde_json::from_slice(&all)?;
|
||||
//
|
||||
// let mut board = BOARD_ACCESS.lock().expect("board access");
|
||||
// board.board_hal.set_config(config)?;
|
||||
// anyhow::Ok(Some("saved".to_owned()))
|
||||
// .fn_handler("/file", Method::Get, move |request| {
|
||||
// let filename = query_param(request.uri(), "filename").unwrap();
|
||||
// let file_handle = BOARD_ACCESS
|
||||
// .lock()
|
||||
// .unwrap()
|
||||
// .board_hal
|
||||
// .get_esp()
|
||||
// .get_file_handle(&filename, false);
|
||||
// match file_handle {
|
||||
// Ok(mut file_handle) => {
|
||||
// let headers = [("Access-Control-Allow-Origin", "*")];
|
||||
// let mut response = request.into_response(200, None, &headers)?;
|
||||
// const BUFFER_SIZE: usize = 512;
|
||||
// let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
// let mut total_read: usize = 0;
|
||||
// loop {
|
||||
// unsafe { vTaskDelay(1) };
|
||||
// let read = std::io::Read::read(&mut file_handle, &mut buffer)?;
|
||||
// total_read += read;
|
||||
// let to_write = &buffer[0..read];
|
||||
// response.write(to_write)?;
|
||||
// if read == 0 {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// log::info!("wrote {total_read} for file {filename}");
|
||||
// drop(file_handle);
|
||||
// response.flush()?;
|
||||
// }
|
||||
// Err(err) => {
|
||||
// //todo set headers here for filename to be error
|
||||
// let error_text = err.to_string();
|
||||
// log::info!("error handling get file {}", error_text);
|
||||
// cors_response(request, 500, &error_text)?;
|
||||
// }
|
||||
// }
|
||||
// anyhow::Ok(())
|
||||
// })
|
||||
// .unwrap();
|
||||
// server
|
||||
// .fn_handler("/file", Method::Post, move |mut request| {
|
||||
// let filename = query_param(request.uri(), "filename").unwrap();
|
||||
// let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
// let file_handle = board.board_hal.get_esp().get_file_handle(&filename, true);
|
||||
// match file_handle {
|
||||
// //TODO get free filesystem size, check against during write if not to large
|
||||
// Ok(mut file_handle) => {
|
||||
// const BUFFER_SIZE: usize = 512;
|
||||
// let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
// let mut total_read: usize = 0;
|
||||
// let mut lastiter = 0;
|
||||
// loop {
|
||||
// let iter = (total_read / 1024) % 8;
|
||||
// if iter != lastiter {
|
||||
// for i in 0..PLANT_COUNT {
|
||||
// let _ = board.board_hal.fault(i, iter == i);
|
||||
// }
|
||||
// lastiter = iter;
|
||||
// }
|
||||
//
|
||||
// let read = request.read(&mut buffer)?;
|
||||
// total_read += read;
|
||||
// let to_write = &buffer[0..read];
|
||||
// std::io::Write::write(&mut file_handle, to_write)?;
|
||||
// if read == 0 {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// cors_response(request, 200, &format!("saved {total_read} bytes"))?;
|
||||
// }
|
||||
// Err(err) => {
|
||||
// //todo set headers here for filename to be error
|
||||
// let error_text = err.to_string();
|
||||
// log::info!("error handling get file {}", error_text);
|
||||
// cors_response(request, 500, &error_text)?;
|
||||
// }
|
||||
// }
|
||||
// drop(board);
|
||||
// anyhow::Ok(())
|
||||
// })
|
||||
// .unwrap();
|
||||
|
||||
async fn set_config<T, const N: usize>(
|
||||
request: &mut Connection<'_, T, N>,
|
||||
@ -703,87 +862,7 @@ pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'static>) {
|
||||
// })
|
||||
// .unwrap();
|
||||
// server
|
||||
// .fn_handler("/file", Method::Get, move |request| {
|
||||
// let filename = query_param(request.uri(), "filename").unwrap();
|
||||
// let file_handle = BOARD_ACCESS
|
||||
// .lock()
|
||||
// .unwrap()
|
||||
// .board_hal
|
||||
// .get_esp()
|
||||
// .get_file_handle(&filename, false);
|
||||
// match file_handle {
|
||||
// Ok(mut file_handle) => {
|
||||
// let headers = [("Access-Control-Allow-Origin", "*")];
|
||||
// let mut response = request.into_response(200, None, &headers)?;
|
||||
// const BUFFER_SIZE: usize = 512;
|
||||
// let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
// let mut total_read: usize = 0;
|
||||
// loop {
|
||||
// unsafe { vTaskDelay(1) };
|
||||
// let read = std::io::Read::read(&mut file_handle, &mut buffer)?;
|
||||
// total_read += read;
|
||||
// let to_write = &buffer[0..read];
|
||||
// response.write(to_write)?;
|
||||
// if read == 0 {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// log::info!("wrote {total_read} for file {filename}");
|
||||
// drop(file_handle);
|
||||
// response.flush()?;
|
||||
// }
|
||||
// Err(err) => {
|
||||
// //todo set headers here for filename to be error
|
||||
// let error_text = err.to_string();
|
||||
// log::info!("error handling get file {}", error_text);
|
||||
// cors_response(request, 500, &error_text)?;
|
||||
// }
|
||||
// }
|
||||
// anyhow::Ok(())
|
||||
// })
|
||||
// .unwrap();
|
||||
// server
|
||||
// .fn_handler("/file", Method::Post, move |mut request| {
|
||||
// let filename = query_param(request.uri(), "filename").unwrap();
|
||||
// let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
// let file_handle = board.board_hal.get_esp().get_file_handle(&filename, true);
|
||||
// match file_handle {
|
||||
// //TODO get free filesystem size, check against during write if not to large
|
||||
// Ok(mut file_handle) => {
|
||||
// const BUFFER_SIZE: usize = 512;
|
||||
// let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
// let mut total_read: usize = 0;
|
||||
// let mut lastiter = 0;
|
||||
// loop {
|
||||
// let iter = (total_read / 1024) % 8;
|
||||
// if iter != lastiter {
|
||||
// for i in 0..PLANT_COUNT {
|
||||
// let _ = board.board_hal.fault(i, iter == i);
|
||||
// }
|
||||
// lastiter = iter;
|
||||
// }
|
||||
//
|
||||
// let read = request.read(&mut buffer)?;
|
||||
// total_read += read;
|
||||
// let to_write = &buffer[0..read];
|
||||
// std::io::Write::write(&mut file_handle, to_write)?;
|
||||
// if read == 0 {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// cors_response(request, 200, &format!("saved {total_read} bytes"))?;
|
||||
// }
|
||||
// Err(err) => {
|
||||
// //todo set headers here for filename to be error
|
||||
// let error_text = err.to_string();
|
||||
// log::info!("error handling get file {}", error_text);
|
||||
// cors_response(request, 500, &error_text)?;
|
||||
// }
|
||||
// }
|
||||
// drop(board);
|
||||
// anyhow::Ok(())
|
||||
// })
|
||||
// .unwrap();
|
||||
|
||||
//
|
||||
// server
|
||||
// .fn_handler("/file", Method::Delete, move |request| {
|
||||
|
Loading…
x
Reference in New Issue
Block a user