Code improvements

This commit is contained in:
hodasemi 2023-09-24 07:35:21 +02:00
parent 1cf3e17faa
commit cf88642612
8 changed files with 111 additions and 79 deletions

View file

@ -90,9 +90,6 @@ class MideaCloud:
}) })
response:dict = {"code": -1} response:dict = {"code": -1}
print(header)
print(dump_data)
for i in range(0, 3): for i in range(0, 3):
try: try:
with self._api_lock: with self._api_lock:
@ -105,7 +102,6 @@ class MideaCloud:
pass pass
if int(response["code"]) == 0 and "data" in response: if int(response["code"]) == 0 and "data" in response:
return response["data"] return response["data"]
print(response)
return None return None
async def _get_login_id(self) -> str | None: async def _get_login_id(self) -> str | None:

View file

@ -71,6 +71,13 @@ def discover(discover_type=None, ip_address=None):
encrypt_data = data[40:-16] encrypt_data = data[40:-16]
reply = security.aes_decrypt(encrypt_data) reply = security.aes_decrypt(encrypt_data)
_LOGGER.debug(f"Declassified reply: {reply.hex()}") _LOGGER.debug(f"Declassified reply: {reply.hex()}")
start = 41
end = start + reply[40]
ssid_bytes = reply[start:end]
print(ssid_bytes)
ssid = reply[41:41 + reply[40]].decode("utf-8") ssid = reply[41:41 + reply[40]].decode("utf-8")
device_type = ssid.split("_")[1] device_type = ssid.split("_")[1]
port = bytes2port(reply[4:8]) port = bytes2port(reply[4:8])

View file

@ -13,9 +13,9 @@ async def test():
"Hoda.semi1" "Hoda.semi1"
) )
if await cl.login(): devices = discover.discover()
devices = discover.discover()
if await cl.login():
for device_id in devices: for device_id in devices:
keys = await cl.get_keys(device_id) keys = await cl.get_keys(device_id)

View file

@ -4,7 +4,7 @@ use std::{
time::{SystemTime, UNIX_EPOCH}, time::{SystemTime, UNIX_EPOCH},
}; };
use anyhow::{anyhow, bail, Error, Result}; use anyhow::{bail, Error, Result};
use base64::{engine::general_purpose, Engine}; use base64::{engine::general_purpose, Engine};
use chrono::Local; use chrono::Local;

View file

@ -99,8 +99,8 @@ impl CloudSecurity {
v v
} }
1 => { 2 => {
let mut v = device_id.to_be_bytes().to_vec(); let mut v = device_id.to_le_bytes().to_vec();
v.truncate(6); v.truncate(6);
v v

67
src/device.rs Normal file
View file

@ -0,0 +1,67 @@
use std::{net::UdpSocket, time::Duration};
use anyhow::Result;
use crate::{
security::{MsgType, Security},
DeviceInfo,
};
pub struct Device {
info: DeviceInfo,
socket: UdpSocket,
security: Security,
}
impl Device {
pub fn connect(info: DeviceInfo) -> Result<Self> {
let socket = UdpSocket::bind("0.0.0.0:0")?;
socket.set_write_timeout(Some(Duration::from_secs(10)))?;
socket.set_read_timeout(Some(Duration::from_secs(10)))?;
socket.connect(info.addr)?;
let mut me = Self {
info,
socket,
security: Security::default(),
};
if me.info.protocol == 3 {
me.authenticate()?;
}
me.refresh_status()?;
Ok(me)
}
fn authenticate(&mut self) -> Result<()> {
let request = self.security.encode_8370(MsgType::HANDSHAKE_REQUEST)?;
Ok(())
}
pub fn refresh_status(&self) -> Result<()> {
//
Ok(())
}
}
#[cfg(test)]
mod test {
use anyhow::Result;
use crate::{device::Device, Startup};
#[tokio::test]
async fn connect() -> Result<()> {
for device_info in Startup::discover().await? {
Device::connect(device_info)?;
}
Ok(())
}
}

View file

@ -7,62 +7,17 @@ use std::{
use anyhow::Result; use anyhow::Result;
use crate::{ use crate::{hex, security::Security};
hex,
security::{MsgType, Security},
};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DeviceInfo { pub struct DeviceInfo {
pub id: u64, pub id: u64,
model: String, pub model: String,
sn: String, pub sn: String,
protocol: u8, pub protocol: u8,
pub device_type: u32,
addr: SocketAddr, pub addr: SocketAddr,
}
pub struct Device {
info: DeviceInfo,
socket: UdpSocket,
security: Security,
}
impl Device {
pub fn connect(info: DeviceInfo) -> Result<Self> {
let socket = UdpSocket::bind("0.0.0.0:0")?;
socket.set_write_timeout(Some(Duration::from_secs(10)))?;
socket.set_read_timeout(Some(Duration::from_secs(10)))?;
socket.connect(info.addr)?;
let mut me = Self {
info,
socket,
security: Security::default(),
};
if me.info.protocol == 3 {
me.authenticate()?;
}
me.refresh_status()?;
Ok(me)
}
fn authenticate(&mut self) -> Result<()> {
let request = self.security.encode_8370(MsgType::HANDSHAKE_REQUEST)?;
Ok(())
}
pub fn refresh_status(&self) -> Result<()> {
//
Ok(())
}
} }
pub struct Startup; pub struct Startup;
@ -119,12 +74,23 @@ impl Startup {
let len = bytes.len(); let len = bytes.len();
let encrypt_data = Security::decrypt(&mut bytes[40..(len - 16)]); let encrypt_data = Security::decrypt(&mut bytes[40..(len - 16)]);
let start = 41;
let upper = start + encrypt_data[40] as usize;
let ssid = from_utf8(&encrypt_data[start..upper])?;
let device_type = u32::from_str_radix(ssid.split('_').nth(1).unwrap(), 16)?;
let model = from_utf8(&encrypt_data[17..25])?; let model = from_utf8(&encrypt_data[17..25])?;
let sn = from_utf8(&encrypt_data[8..40])?; let sn = from_utf8(&encrypt_data[8..40])?;
devices.insert( devices.insert(
device_id, device_id,
(addr, model.to_string(), sn.to_string(), protocol), (
addr,
model.to_string(),
sn.to_string(),
protocol,
device_type,
),
); );
} }
} }
@ -132,14 +98,17 @@ impl Startup {
Ok(devices Ok(devices
.into_iter() .into_iter()
.map(|(id, (addr, model, sn, protocol))| DeviceInfo { .map(
id, |(id, (addr, model, sn, protocol, device_type))| DeviceInfo {
model, id,
sn, model,
protocol, sn,
protocol,
device_type,
addr, addr,
}) },
)
.collect()) .collect())
} }
} }
@ -182,7 +151,7 @@ impl Startup {
mod test { mod test {
use anyhow::Result; use anyhow::Result;
use super::{Device, Startup}; use super::Startup;
#[tokio::test] #[tokio::test]
async fn discover() -> Result<()> { async fn discover() -> Result<()> {
@ -192,13 +161,4 @@ mod test {
Ok(()) Ok(())
} }
#[tokio::test]
async fn connect() -> Result<()> {
for device_info in Startup::discover().await? {
Device::connect(device_info)?;
}
Ok(())
}
} }

View file

@ -2,6 +2,7 @@ use std::num::ParseIntError;
mod cloud; mod cloud;
mod cloud_security; mod cloud_security;
mod device;
mod discover; mod discover;
mod security; mod security;
@ -13,4 +14,5 @@ fn hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
} }
pub use cloud::Cloud; pub use cloud::Cloud;
pub use discover::{Device, DeviceInfo, Startup}; pub use device::Device;
pub use discover::{DeviceInfo, Startup};