From a9dbff82506855b6defd81cba8e6ce90ec916915 Mon Sep 17 00:00:00 2001 From: linuswck Date: Fri, 8 Mar 2024 16:30:15 +0800 Subject: [PATCH] Send Response Back to The Client after Recv Cmd --- src/main.rs | 16 ++++ src/net/cmd_handler.rs | 175 ++++++++++++++++++++++++++++++++--------- 2 files changed, 154 insertions(+), 37 deletions(-) diff --git a/src/main.rs b/src/main.rs index c75960a..da824ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,6 +43,7 @@ pub enum State { LoadFlashSettings, MainLoop, SaveFlashSettings, + PrepareForHardReset, HardReset, } @@ -218,6 +219,21 @@ fn main() -> ! { } } } + State::PrepareForHardReset => { + // State Transition + state = State::HardReset; + + wd.feed(); + laser.power_down(); + thermostat.power_down(); + net::net::for_each(|mut socket| { + if net::net::eth_is_socket_active(socket) { + unsafe { + net::cmd_handler::send_response(&mut ETH_DATA_BUFFER, net::cmd_handler::ResponseEnum::HardReset, None, &mut socket); + } + } + }); + } State::HardReset => { wd.feed(); laser.power_down(); diff --git a/src/net/cmd_handler.rs b/src/net/cmd_handler.rs index 24cb745..c637239 100644 --- a/src/net/cmd_handler.rs +++ b/src/net/cmd_handler.rs @@ -18,10 +18,43 @@ use crate::{laser_diode::{laser_diode::{ use crate::thermostat::thermostat::{Thermostat, ThermostatSettingsSummary}; use crate::thermostat::pid_state::PidSettings::*; use crate::device::{dfu, sys_timer}; -use log::info; +use log::{info, debug}; use crate::{DeviceSettings, State, IpSettings}; use smoltcp::iface::SocketHandle; +#[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)] +pub enum ResponseEnum { + #[default] + Reserved, + Acknowledge, + InvalidDatatype, + InvalidCmd, + HardReset, +} + +pub type MsgType = Option<&'static str>; + +#[derive(Deserialize, Serialize, Copy, Clone, Debug)] +pub struct Response<'a> { + msg_type: ResponseEnum, + msg: Option<&'a str>, +} + +impl Default for Response<'static>{ + fn default() -> Self { + Response{ + msg_type: ResponseEnum:: Reserved, + msg: None, + } + } +} + +#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)] +pub struct ResponseObj<'a>{ + #[serde(borrow)] + json: Response<'a> +} + #[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)] enum DeviceCmd { #[default] @@ -89,6 +122,15 @@ enum ThermostatCmdEnum { SetShBeta, } +const ERR_MSG_MISSING_DATA_F32 : &str = "Required field \"data_f32\" does not exist"; +const ERR_MSG_MISSING_DATA_BOOL: &str = "Required field \"bool\" does not exist"; +const ERR_MSG_MISSING_IP_SETTINGS: &str = "Required field \"ip_settings\" does not exist"; +const ERR_MSG_MISSING_TEMP_ADC_FILTER: &str = "Required field \"temp_adc_filter\" does not exist"; +const ERR_MSG_MISSING_SINC5SINC1ODR: &str = "Required field \"sinc5sinc1odr\" does not exist"; +const ERR_MSG_MISSING_SINC3ODR: &str = "Required field \"sinc3odr\" does not exist"; +const ERR_MSG_MISSING_POSTFILTER: &str = "Required field \"PostFilter\" does not exist"; +const ERR_MSG_MISSING_SINC3FINEODR: &str = "Required field \"sinc3fineodr\" does not exist"; + #[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)] pub struct CmdJsonObj{ laser_diode_cmd: Option, @@ -128,6 +170,19 @@ pub struct SettingsSummaryObj { json: SettingsSummary } +pub fn send_response(buffer: &mut [u8], msg_type: ResponseEnum, msg: MsgType, socket: &mut SocketHandle){ + let response = ResponseObj { + json: Response { + msg_type: msg_type, + msg: msg, + } + }; + debug!("{:?}", response.json); + + let num_bytes = response.get_json("/json", buffer).unwrap(); + net::eth_send(buffer, num_bytes, *socket); +} + pub fn send_settings_summary(buffer: &mut [u8], laser: &mut LdDrive, tec: &mut Thermostat, socket: &mut SocketHandle){ let settings_summary = SettingsSummaryObj { json: SettingsSummary { @@ -191,14 +246,16 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, socket: &mut SocketHan Some(DeviceCmd::SetIPSettings) => { match cmd.json.ip_settings { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); device_settings.ip_settings = val; } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_IP_SETTINGS), socket); } } } Some(DeviceCmd::Dfu) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); unsafe { dfu::set_dfu_trigger(); } @@ -207,31 +264,38 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, socket: &mut SocketHan Some(DeviceCmd::SetActiveReportMode) => { match cmd.json.data_bool{ Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); device_settings.report_readings = val; } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_BOOL), socket); } } } Some(DeviceCmd::GetStatusReport) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); send_status_report(buffer, laser, tec, socket); } Some(DeviceCmd::GetSettingsSummary) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); send_settings_summary(buffer, laser, tec, socket); } Some(DeviceCmd::SaveFlashSettings) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); *state = State::SaveFlashSettings; } Some(DeviceCmd::LoadFlashSettings) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); *state = State::LoadFlashSettings; } Some(DeviceCmd::HardReset) => { - *state = State::HardReset; + send_response(buffer, ResponseEnum::Acknowledge, None, socket); + *state = State::PrepareForHardReset; } None => { /* Do Nothing */} _ => { - info!("Unimplemented Command") + send_response(buffer, ResponseEnum::InvalidCmd, None, socket); + debug!("Unimplemented Command") } } @@ -239,81 +303,93 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, socket: &mut SocketHan Some(LdCmdEnum::SetDefaultPowerOn) => { match cmd.json.data_bool { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.set_default_pwr_on(val); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_BOOL), socket); } } } Some(LdCmdEnum::PowerUp) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.power_up() } Some(LdCmdEnum::PowerDown) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.power_down() } Some(LdCmdEnum::LdTermsShort) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.ld_short(); } Some(LdCmdEnum::LdTermsOpen) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.ld_open(); } Some(LdCmdEnum::SetI) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.ld_set_i(ElectricCurrent::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(LdCmdEnum::SetISoftLimit) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.set_ld_drive_current_limit(ElectricCurrent::new::(val)) } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(LdCmdEnum::SetPdResponsitivity) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.set_pd_responsitivity(ResponsitivityUnit {dimension: PhantomData, units: PhantomData, value: val}) } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(LdCmdEnum::SetPdDarkCurrent) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.set_pd_dark_current(ElectricCurrent::new::(val)) } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(LdCmdEnum::SetLdPwrLimit) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.set_ld_power_limit(Power::new::(val)) } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(LdCmdEnum::ClearAlarm) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); laser.pd_mon_clear_alarm() } None => { /* Do Nothing*/ } _ => { + send_response(buffer, ResponseEnum::InvalidCmd, Some(ERR_MSG_MISSING_DATA_F32), socket); info!("Unimplemented Command") } } @@ -322,128 +398,143 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, socket: &mut SocketHan Some(ThermostatCmdEnum::SetDefaultPowerOn) => { match cmd.json.data_bool { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_default_pwr_on(val); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } - Some(ThermostatCmdEnum::PowerUp) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.power_up() } Some(ThermostatCmdEnum::PowerDown) => { + send_response(buffer, ResponseEnum::Acknowledge, Some(ERR_MSG_MISSING_DATA_F32), socket); tec.power_down() } Some(ThermostatCmdEnum::SetTecMaxV) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_max_v(ElectricPotential::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetTecMaxIPos) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_max_i_pos(ElectricCurrent::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetTecMaxINeg) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_max_i_pos(ElectricCurrent::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetTecIOut) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_i(ElectricCurrent::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetTemperatureSetpoint) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_temperature_setpoint(ThermodynamicTemperature::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetPidEngage) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_pid_engaged(true); } Some(ThermostatCmdEnum::SetPidDisEngage) => { + send_response(buffer, ResponseEnum::Acknowledge, Some(ERR_MSG_MISSING_DATA_F32), socket); tec.set_pid_engaged(false); } Some(ThermostatCmdEnum::SetPidKp) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_pid(Kp, val); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetPidKi) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_pid(Ki, val); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetPidKd) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_pid(Kd, val); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetPidOutMin) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_pid(Min, val); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetPidOutMax) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_pid(Max, val); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetPidUpdateInterval) => { - info!("Not supported Yet") + send_response(buffer, ResponseEnum::InvalidCmd, None, socket); + debug!("Not supported Yet") } Some(ThermostatCmdEnum::ConfigTempAdcFilter) => { match cmd.json.temp_adc_filter { @@ -452,111 +543,121 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, socket: &mut SocketHan FilterType::Sinc5Sinc1With50hz60HzRejection => { match val.sinc5sinc1postfilter { Some(val2) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_temp_adc_sinc5_sinc1_with_postfilter(0, val2); } None => { - info!("sinc5sinc1postfilter field needs to be set for configuration"); + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_POSTFILTER), socket); } } } FilterType::Sinc5Sinc1 => { match val.sinc5sinc1odr { Some(val2) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_temp_adc_sinc5_sinc1_filter(0, val2); } None => { - info!("sinc5sinc1odr field needs to be set for configuration"); + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_SINC5SINC1ODR), socket); } } } FilterType::Sinc3WithFineODR => { match val.sinc3fineodr { Some(val2) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_temp_adc_sinc3_fine_filter(0, val2); } None => { - info!("data_f32 field needs to be set for configuration"); + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_SINC3FINEODR), socket); } } } FilterType::Sinc3 => { match val.sinc3odr { Some(val2) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_temp_adc_sinc3_filter(0, val2); } None => { - info!("sinc3_filter field needs to be set for configuration"); + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_SINC3ODR), socket); } } } } } None => { - info!("temp_adc_filter needs to be set for configuration") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_TEMP_ADC_FILTER), socket); } } } Some(ThermostatCmdEnum::SetTempMonUpperLimit) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_temp_mon_upper_limit(ThermodynamicTemperature::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetTempMonLowerLimit) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_temp_mon_lower_limit(ThermodynamicTemperature::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::ClearAlarm) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.clear_temp_mon_alarm(); } Some(ThermostatCmdEnum::SetShT0) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_sh_t0(ThermodynamicTemperature::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetShR0) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_sh_r0(ElectricalResistance::new::(val)); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } Some(ThermostatCmdEnum::SetShBeta) => { match cmd.json.data_f32 { Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); tec.set_sh_beta(val); } None => { - info!("Wrong Data type is received") + send_response(buffer, ResponseEnum::InvalidDatatype, Some(ERR_MSG_MISSING_DATA_F32), socket); } } } None => { /* Do Nothing*/ } _ => { - info!("Unimplemented Command") + send_response(buffer, ResponseEnum::InvalidCmd, None, socket); } } } - Err(err) => { - info!("Invalid Command: {:?}", err); + Err(_) => { + send_response(buffer, ResponseEnum::InvalidCmd, None, socket); } } }