From 37844ae5fa59fe8b91cbaa2d385cda0461e524fe Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sat, 5 Oct 2024 19:44:32 +0200 Subject: [PATCH] Notify devices of available updates through sync endpoint --- central_backend/src/devices/device.rs | 2 +- central_backend/src/ota/ota_update.rs | 9 +++++++ .../src/server/devices_api/mgmt_controller.rs | 25 +++++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/central_backend/src/devices/device.rs b/central_backend/src/devices/device.rs index 258cbcb..bcdfb3a 100644 --- a/central_backend/src/devices/device.rs +++ b/central_backend/src/devices/device.rs @@ -11,7 +11,7 @@ pub struct DeviceInfo { /// Device reference pub reference: String, /// Device firmware / software version - version: semver::Version, + pub version: semver::Version, /// Maximum number of relay that the device can support pub max_relays: usize, } diff --git a/central_backend/src/ota/ota_update.rs b/central_backend/src/ota/ota_update.rs index 4227720..2de832e 100644 --- a/central_backend/src/ota/ota_update.rs +++ b/central_backend/src/ota/ota_update.rs @@ -1,4 +1,5 @@ use std::fmt::{Display, Formatter}; +use std::str::FromStr; #[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone, Eq, PartialEq)] pub enum OTAPlatform { @@ -13,6 +14,14 @@ impl Display for OTAPlatform { } } +impl FromStr for OTAPlatform { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Ok(serde_json::from_str::(&format!("\"{s}\""))?) + } +} + /// Single OTA update information #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)] pub struct OTAUpdate { diff --git a/central_backend/src/server/devices_api/mgmt_controller.rs b/central_backend/src/server/devices_api/mgmt_controller.rs index 835486c..0eddb3b 100644 --- a/central_backend/src/server/devices_api/mgmt_controller.rs +++ b/central_backend/src/server/devices_api/mgmt_controller.rs @@ -2,12 +2,15 @@ use crate::app_config::AppConfig; use crate::devices::device::{DeviceId, DeviceInfo}; use crate::energy::energy_actor; use crate::energy::energy_actor::RelaySyncStatus; +use crate::ota::ota_manager; +use crate::ota::ota_update::OTAPlatform; use crate::server::custom_error::HttpResult; use crate::server::devices_api::jwt_parser::JWTRequest; use crate::server::WebEnergyActor; use actix_web::{web, HttpResponse}; use openssl::nid::Nid; use openssl::x509::X509Req; +use std::str::FromStr; #[derive(Debug, serde::Deserialize)] pub struct EnrollRequest { @@ -135,6 +138,7 @@ struct Claims { #[derive(serde::Serialize)] struct SyncResult { relays: Vec, + available_update: Option, } /// Synchronize device @@ -142,8 +146,25 @@ pub async fn sync_device(body: web::Json, actor: WebEnergyActor) -> let (device, claims) = body.0.parse_jwt::(actor.clone()).await?; let relays = actor - .send(energy_actor::SynchronizeDevice(device.id, claims.info)) + .send(energy_actor::SynchronizeDevice( + device.id, + claims.info.clone(), + )) .await??; - Ok(HttpResponse::Ok().json(SyncResult { relays })) + let mut available_update = None; + + // Check if the version is available + if let Some(desired) = device.desired_version { + if claims.info.version < desired + && ota_manager::update_exists(OTAPlatform::from_str(&claims.info.reference)?, &desired)? + { + available_update = Some(desired); + } + } + + Ok(HttpResponse::Ok().json(SyncResult { + relays, + available_update, + })) }