From aea6105268e7fabc38ea47461bceec8df97a3b8c Mon Sep 17 00:00:00 2001 From: clerie Date: Thu, 26 Dec 2024 12:17:10 +0100 Subject: [PATCH] Configure WiFi settings --- src/improv.rs | 32 ++++++++++++++++++++++++++++++-- src/main.rs | 25 +++++++++++++++++++++---- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/improv.rs b/src/improv.rs index 83326fa..9a7c448 100644 --- a/src/improv.rs +++ b/src/improv.rs @@ -123,7 +123,7 @@ impl std::fmt::Display for ErrorState { #[derive(Clone)] #[repr(u8)] pub enum RPCCommand { - SendWifiSettings = 0x01, + SendWiFiSettings = 0x01, RequestCurrentState = 0x02, RequestDeviceInformation = 0x03, RequestScannedWiFiNetworks = 0x04, @@ -134,7 +134,7 @@ impl TryFrom<&u8> for RPCCommand { fn try_from(b: &u8) -> Result { match b { - 0x01 => Ok(Self::SendWifiSettings), + 0x01 => Ok(Self::SendWiFiSettings), 0x02 => Ok(Self::RequestCurrentState), 0x03 => Ok(Self::RequestDeviceInformation), 0x04 => Ok(Self::RequestScannedWiFiNetworks), @@ -310,6 +310,34 @@ impl ImprovDataFromPacket for ErrorStatePacket { } } +pub struct SendWiFiSettingsPacket { + pub ssid: String, + pub password: String, +} + +impl ImprovDataPacketType for SendWiFiSettingsPacket { + const packet_type: PacketType = PacketType::RPCCommand; +} + +impl ImprovDataToPacket for SendWiFiSettingsPacket { + fn to_bytes(self: &Self) -> Vec { + let ssid_bytes = self.ssid.as_bytes(); + let ssid_len: u8 = ssid_bytes.len().try_into().unwrap(); + + let password_bytes = self.password.as_bytes(); + let password_len: u8 = password_bytes.len().try_into().unwrap(); + + let mut out = Vec::new(); + out.push(RPCCommand::SendWiFiSettings as u8); + out.push(1 + ssid_len + 1 + password_len); // data len + out.push(ssid_len); + out.extend_from_slice(ssid_bytes); + out.push(password_len); + out.extend_from_slice(password_bytes); + return out; + } +} + pub struct RequestCurrentStatePacket { } diff --git a/src/main.rs b/src/main.rs index c47f679..f6afd3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ use env_logger; use improv_setup::improv::{ RawPacket, ImprovPacket, + SendWiFiSettingsPacket, RequestCurrentStatePacket, RequestDeviceInformationPacket, RequestScannedWiFiNetworksPacket, @@ -22,8 +23,8 @@ use tokio_serial; enum DeviceCommands { /// Request current state State, - /// Set wifi credentials - SetWifi { + /// Connect to wifi network + Connect { /// SSID of the network ssid: String, /// Password for the SSID @@ -102,8 +103,24 @@ async fn main() -> Result<()>{ println!("Error state: {}", &error_state.error_state); } }, - DeviceCommands::SetWifi {ssid, password} => { - println!("Not implemented"); + DeviceCommands::Connect{ssid, password} => { + let send_wifi_settings_packet = SendWiFiSettingsPacket { + ssid: ssid.clone(), + password: password.clone(), + }; + + let mut serial_interface = serial::SerialInterface::new(path, *baud_rate).context("Couldn't init serial interface")?; + + serial_interface.send(&send_wifi_settings_packet).context("Failed to send improv packet")?; + + let result_bytes = serial_interface.recv_bytes().context("Couldn't receive any improv packet")?; + let raw_packet = RawPacket::try_from_bytes(&result_bytes).context("Failed to deserialize packet")?; + + if let ImprovPacket::RPCResult(rpc_result) = ImprovPacket::try_from_raw_packet(&raw_packet).context("Failed to read packet")? { + for r in rpc_result.results { + println!("{}", &r); + } + } }, DeviceCommands::Info => { let request_device_information_packet = RequestDeviceInformationPacket {};