From e5339f7c6c86f5e588620511a1070ba4a32cdaa4 Mon Sep 17 00:00:00 2001 From: Tobias Maier Date: Sun, 19 Jan 2025 15:43:04 +0100 Subject: [PATCH] Updates --- dev/IoT-API/Get Devices.bru | 2 +- dev/IoT-API/PUT firmware.bru | 2 +- src/main.rs | 56 ++++++++++++++++++++++++------------ src/schemas.rs | 4 ++- src/util.rs | 9 +++--- 5 files changed, 47 insertions(+), 26 deletions(-) diff --git a/dev/IoT-API/Get Devices.bru b/dev/IoT-API/Get Devices.bru index 7a5d435..7167480 100644 --- a/dev/IoT-API/Get Devices.bru +++ b/dev/IoT-API/Get Devices.bru @@ -5,7 +5,7 @@ meta { } get { - url: http://localhost:8484/device + url: http://localhost:8282/device body: none auth: none } diff --git a/dev/IoT-API/PUT firmware.bru b/dev/IoT-API/PUT firmware.bru index ae8a5a0..3c42d77 100644 --- a/dev/IoT-API/PUT firmware.bru +++ b/dev/IoT-API/PUT firmware.bru @@ -5,7 +5,7 @@ meta { } put { - url: http://localhost:8282/firmware/waterlevel/INA233/1.0.0 + url: http://localhost:8282/firmware/waterlevel/INA226/1.0.3 body: multipartForm auth: none } diff --git a/src/main.rs b/src/main.rs index 05eb748..a858830 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ use dotenvy::dotenv; use log::{debug, error, info}; use schemas::{BoardConfig, BoardType, Device, OTAConfiguration, OTAConfigurationList}; use sqlx::types::mac_address::MacAddress; -use util::parse_mac_address; +use util::{get_files, parse_mac_address}; mod database; mod schemas; @@ -15,6 +15,8 @@ mod util; struct AppState { db: Database, + firmwares_path: PathBuf, + hostname: String } #[post("/telemetry/{device_id}")] @@ -124,16 +126,17 @@ async fn get_devices(data: web::Data) -> impl Responder { HttpResponse::Ok().json(devices) } -#[put("/firmware/{product}/{config}/{version}")] -async fn upload_firmware(path: web::Path<(String, String, String)>, body: web::Bytes) -> impl Responder { - let (product, config, version) = path.into_inner(); - let version = version.replace(".", "_"); - let firmware_root_path = PathBuf::from(env::var("FIMRWARE_FOLDER").unwrap_or("./firmware".to_string())); +#[put("/firmware/{device}/{config}/{version}")] +async fn upload_firmware(data: web::Data, path: web::Path<(String, String, String)>, body: web::Bytes) -> impl Responder { + let (device, config, version) = path.into_inner(); + let version = version.replace(".", "-"); - let firmware_folder = firmware_root_path.join(&product).join(&config); - let firmware_path = firmware_folder.join(format!("ver_{}", &version)).with_extension("bin"); + let firmware_root_path = &data.firmwares_path; - info!("Uploading firmware with product: {product}, config: {config} and version: {version} to {firmware_path:?}"); + let firmware_folder = firmware_root_path.join(&device); + let firmware_path = firmware_folder.join(format!("firmware_{config}_{version}")).with_extension("bin"); + + info!("Uploading firmware with product: {device}, config: {config} and version: {version} to {firmware_path:?}"); fs::create_dir_all(&firmware_folder).unwrap(); let x = tokio::fs::write(&firmware_path, &body).await; @@ -142,18 +145,32 @@ async fn upload_firmware(path: web::Path<(String, String, String)>, body: web::B HttpResponse::Ok().body(format!("Firmware version {} uploaded successfully", version)) } -#[get("/firmware/{product}/{config}/{version}")] -async fn get_firmware_json(path: web::Path<(String, String, String)>) -> impl Responder { - let (product, config, version) = path.into_inner(); - let version = version.replace(".", "_"); - - - let mut configs = Vec::new(); +#[get("/firmware/{device}")] +async fn get_firmware_json(data: web::Data, path: web::Path) -> impl Responder { + let device = path.into_inner(); + let fw_path = &data.firmwares_path.join(device); + if fw_path.is_dir() { + match get_files(fw_path, &data.hostname) { + Ok(cfg) => HttpResponse::Ok().json(OTAConfigurationList{configurations: cfg} ), + Err(e) => HttpResponse::InternalServerError().body(e.to_string()) + } + } else { + HttpResponse::Ok().json(OTAConfigurationList{configurations: vec![]} ) + } - - HttpResponse::Ok().json(OTAConfigurationList{configurations: configs} ) } +// #[get("/firmware/{product}/{config}/{version}")] +// async fn get_firmware_json(path: web::Path<(String, String, String)>, data: web::Data) -> impl Responder { +// let (product, config, version) = path.into_inner(); +// let version = version.replace(".", "-"); + +// match get_files(&data.firmwares_path, &data.hostname) { +// Ok(cfg) => HttpResponse::Ok().json(OTAConfigurationList{configurations: cfg} ), +// Err(e) => HttpResponse::InternalServerError().body(e.to_string()) +// } +// } + #[get("/firmware/waterlevel/firmware_INA233_1.0.0.bin")] async fn serve_firmware() -> impl Responder { let file_path = PathBuf::from("./firmware/waterlevel/firmware_INA233_1.0.0.bin"); @@ -178,6 +195,7 @@ async fn main() -> std::io::Result<()> { env_logger::init(); info!("Starting"); + let db_url = match env::var("DATABASE_URL") { Ok(url) => url, Err(e) => { @@ -192,7 +210,7 @@ async fn main() -> std::io::Result<()> { HttpServer::new(move || { App::new() - .app_data(web::Data::new(AppState { db: db.clone() })) + .app_data(web::Data::new(AppState { db: db.clone(), firmwares_path: PathBuf::from("./fw"), hostname: "127.0.0.1".to_string() })) .app_data(web::PayloadConfig::new(256 * 1024 * 1024)) //256MB .service(receive_telemetry) .service(get_telemetry) diff --git a/src/schemas.rs b/src/schemas.rs index ea7229a..66f7775 100644 --- a/src/schemas.rs +++ b/src/schemas.rs @@ -1,3 +1,5 @@ +use std::path::PathBuf; + use chrono::NaiveDateTime; use serde::{ser::SerializeStruct, Deserialize, Serialize}; use sqlx::types::mac_address::MacAddress; @@ -89,4 +91,4 @@ pub enum BoardType { pub enum BoardConfig { INA226, INA233 -} +} \ No newline at end of file diff --git a/src/util.rs b/src/util.rs index 10b594a..a1c708b 100644 --- a/src/util.rs +++ b/src/util.rs @@ -52,12 +52,13 @@ pub fn get_files(root_path: &PathBuf, hostname: &str) -> Result = path.file_name().ok_or(GetFilesError::Filename)?.to_str().ok_or(GetFilesError::Filename)?.split("_").collect(); - let version = split_name[2].strip_suffix(".bin").ok_or(GetFilesError::Extension)?; + let version = split_name[2].strip_suffix(".bin").ok_or(GetFilesError::Extension)?.replace("-", "."); let board_config = BoardConfig::from_str(split_name[1])?; let board_type = BoardType::from_str(&product_name).unwrap(); let version_replaced = version.replace(".", "_"); @@ -85,8 +86,8 @@ mod tests { let expected_2 = OTAConfiguration{ version: "4.5.6".to_string(), url: "example.com/firmware/waterlevel/INA226/4_5_6.bin".to_string(), board: Some(BoardType::Waterlevel), config: Some(BoardConfig::INA226) }; let loaded_configs = get_files(&PathBuf::from("./test/waterlevel"), "example.com").unwrap(); - assert_eq!(loaded_configs[0], expected_1); - assert_eq!(loaded_configs[1], expected_2); + assert_eq!(loaded_configs[1], expected_1); + assert_eq!(loaded_configs[0], expected_2); } #[test]