Fix connect
This commit is contained in:
parent
1fdd2a3f1e
commit
d3fb193e8d
6 changed files with 108 additions and 71 deletions
3
cloud.py
3
cloud.py
|
@ -127,6 +127,9 @@ class MideaCloud:
|
||||||
data.update({
|
data.update({
|
||||||
"udpid": udp_id
|
"udpid": udp_id
|
||||||
})
|
})
|
||||||
|
|
||||||
|
print(data)
|
||||||
|
|
||||||
response = await self._api_request(
|
response = await self._api_request(
|
||||||
endpoint="/v1/iot/secure/getToken",
|
endpoint="/v1/iot/secure/getToken",
|
||||||
data=data
|
data=data
|
||||||
|
|
82
midea.py
82
midea.py
|
@ -16,57 +16,57 @@ async def test():
|
||||||
devices = discover.discover()
|
devices = discover.discover()
|
||||||
|
|
||||||
if len(devices) > 0:
|
if len(devices) > 0:
|
||||||
for device_id in devices:
|
# for device_id in devices:
|
||||||
token = "702b9dfc3ac6c82979986ee3a053a76f75f9e9c763ce5c25af5c2cc982f797a9409adff3745e23fee3a464d745e005c839efb0b84082acc962e59ab8683e0299"
|
# token = "702b9dfc3ac6c82979986ee3a053a76f75f9e9c763ce5c25af5c2cc982f797a9409adff3745e23fee3a464d745e005c839efb0b84082acc962e59ab8683e0299"
|
||||||
key = "52b2feee353841588994e630dcb59819ec71ce1ffacb48628f4f436f5c54f11e"
|
# key = "52b2feee353841588994e630dcb59819ec71ce1ffacb48628f4f436f5c54f11e"
|
||||||
|
|
||||||
device_info = devices[device_id]
|
# device_info = devices[device_id]
|
||||||
|
|
||||||
dev = device.MiedaDevice(
|
# dev = device.MiedaDevice(
|
||||||
name="",
|
# name="",
|
||||||
device_id=device_id,
|
# device_id=device_id,
|
||||||
device_type=225,
|
# device_type=225,
|
||||||
ip_address=device_info['ip_address'],
|
# ip_address=device_info['ip_address'],
|
||||||
port=device_info['port'],
|
# port=device_info['port'],
|
||||||
token=token,
|
# token=token,
|
||||||
key=key,
|
# key=key,
|
||||||
protocol=3,
|
# protocol=3,
|
||||||
model=device_info['model'],
|
# model=device_info['model'],
|
||||||
attributes={}
|
# attributes={}
|
||||||
)
|
# )
|
||||||
|
|
||||||
if dev.connect(False):
|
# if dev.connect(False):
|
||||||
print("success")
|
# print("success")
|
||||||
else:
|
# else:
|
||||||
print("fail")
|
# print("fail")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# if await cl.login():
|
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)
|
||||||
|
|
||||||
# for k in keys:
|
for k in keys:
|
||||||
# token = keys[k]['token']
|
token = keys[k]['token']
|
||||||
# key = keys[k]['key']
|
key = keys[k]['key']
|
||||||
|
|
||||||
# device_info = devices[device_id]
|
device_info = devices[device_id]
|
||||||
|
|
||||||
# dev = device.MiedaDevice(
|
dev = device.MiedaDevice(
|
||||||
# name="",
|
name="",
|
||||||
# device_id=device_id,
|
device_id=device_id,
|
||||||
# device_type=225,
|
device_type=225,
|
||||||
# ip_address=device_info['ip_address'],
|
ip_address=device_info['ip_address'],
|
||||||
# port=device_info['port'],
|
port=device_info['port'],
|
||||||
# token=token,
|
token=token,
|
||||||
# key=key,
|
key=key,
|
||||||
# protocol=3,
|
protocol=3,
|
||||||
# model=device_info['model'],
|
model=device_info['model'],
|
||||||
# attributes={}
|
attributes={}
|
||||||
# )
|
)
|
||||||
|
|
||||||
# if dev.connect(False):
|
if dev.connect(False):
|
||||||
# return dev
|
return dev
|
||||||
|
|
||||||
dev = asyncio.run(test())
|
dev = asyncio.run(test())
|
||||||
|
|
||||||
|
|
16
security.py
16
security.py
|
@ -59,6 +59,8 @@ class CloudSecurity:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_udp_id(appliance_id, method=0):
|
def get_udp_id(appliance_id, method=0):
|
||||||
|
print()
|
||||||
|
|
||||||
if method == 0:
|
if method == 0:
|
||||||
bytes_id = bytes(reversed(appliance_id.to_bytes(8, "big")))
|
bytes_id = bytes(reversed(appliance_id.to_bytes(8, "big")))
|
||||||
elif method == 1:
|
elif method == 1:
|
||||||
|
@ -67,10 +69,22 @@ class CloudSecurity:
|
||||||
bytes_id = appliance_id.to_bytes(6, "little")
|
bytes_id = appliance_id.to_bytes(6, "little")
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
print(bytes_id)
|
||||||
|
|
||||||
data = bytearray(sha256(bytes_id).digest())
|
data = bytearray(sha256(bytes_id).digest())
|
||||||
|
|
||||||
|
print(data)
|
||||||
|
|
||||||
for i in range(0, 16):
|
for i in range(0, 16):
|
||||||
data[i] ^= data[i + 16]
|
data[i] ^= data[i + 16]
|
||||||
return data[0: 16].hex()
|
|
||||||
|
hex = data[0: 16].hex()
|
||||||
|
|
||||||
|
print(hex)
|
||||||
|
print()
|
||||||
|
|
||||||
|
return hex
|
||||||
|
|
||||||
def set_aes_keys(self, key, iv):
|
def set_aes_keys(self, key, iv):
|
||||||
if isinstance(key, str):
|
if isinstance(key, str):
|
||||||
|
|
22
src/cloud.rs
22
src/cloud.rs
|
@ -239,18 +239,38 @@ impl Cloud {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn keys(&self, device_id: u64) -> Result<(String, String)> {
|
pub async fn keys(&self, device_id: u64) -> Result<(String, String)> {
|
||||||
for method in [2] {
|
for method in [1, 2] {
|
||||||
let udp_id = CloudSecurity::udp_id(device_id, method);
|
let udp_id = CloudSecurity::udp_id(device_id, method);
|
||||||
|
|
||||||
|
// 1: "a79479839b272432f3bbf971f9faed30"
|
||||||
|
// 2: "a153e4273b29c04db85763c739d45203"
|
||||||
|
|
||||||
let mut data = self.make_general_data();
|
let mut data = self.make_general_data();
|
||||||
data.insert("udpid".to_string(), udp_id.clone());
|
data.insert("udpid".to_string(), udp_id.clone());
|
||||||
|
|
||||||
|
// {
|
||||||
|
// 'appVersion': '3.0.2',
|
||||||
|
// 'src': '10',
|
||||||
|
// 'format': '2',
|
||||||
|
// 'stamp': '20230925115743',
|
||||||
|
// 'platformId': '1',
|
||||||
|
// 'deviceId': 'c1bdb9d159aa18fe',
|
||||||
|
// 'reqId': '3e593c7a186f25ccca0d010d4316af0d',
|
||||||
|
// 'uid': '4c48146bdedaca956c465d53cf7dd9a3',
|
||||||
|
// 'clientType': '1',
|
||||||
|
// 'appId': '1010',
|
||||||
|
// 'udpid': '53c18d6f4682867654bee60c9ea047f4'
|
||||||
|
// }
|
||||||
|
|
||||||
let response = Response::from_str(
|
let response = Response::from_str(
|
||||||
&self
|
&self
|
||||||
.api_request("/v1/iot/secure/getToken", to_string(&data)?)
|
.api_request("/v1/iot/secure/getToken", to_string(&data)?)
|
||||||
.await?,
|
.await?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// '76697C9A0685778C6B4F487A70497F4DB3CDD2C0949138B5BA798DADC5AE0712ECF6C3559C7EE68B96B2BB2DC140CF6172D9F1587065D4A536A75D492031E22E'
|
||||||
|
// '025f9ff7bd3c4aceb1e559ab13d5e73f6fb2358e2bcf4bb883ab62225d6b9d2d'
|
||||||
|
|
||||||
for token in response.token_list() {
|
for token in response.token_list() {
|
||||||
if token.udpId == udp_id {
|
if token.udpId == udp_id {
|
||||||
return Ok((
|
return Ok((
|
||||||
|
|
|
@ -94,14 +94,14 @@ impl CloudSecurity {
|
||||||
let bytes_id: Vec<u8> = match method {
|
let bytes_id: Vec<u8> = match method {
|
||||||
0 => device_id.to_be_bytes().into_iter().rev().collect(),
|
0 => device_id.to_be_bytes().into_iter().rev().collect(),
|
||||||
1 => {
|
1 => {
|
||||||
let mut v = device_id.to_be_bytes().to_vec();
|
let b = device_id.to_be_bytes();
|
||||||
v.truncate(6);
|
let v = b[2..8].to_vec();
|
||||||
|
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
let mut v = device_id.to_le_bytes().to_vec();
|
let b = device_id.to_le_bytes();
|
||||||
v.truncate(6);
|
let v = b[0..6].to_vec();
|
||||||
|
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
@ -109,19 +109,22 @@ impl CloudSecurity {
|
||||||
_ => return String::new(),
|
_ => return String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut data = Sha256::digest(&bytes_id);
|
let data = Sha256::digest(&bytes_id);
|
||||||
|
let mut v: Vec<u8> = data.into_iter().collect();
|
||||||
|
|
||||||
for i in 0..16 {
|
for i in 0..16 {
|
||||||
data[i] ^= data[i + 16];
|
v[i] ^= v[i + 16];
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut v: Vec<u8> = data.into_iter().collect();
|
|
||||||
v.truncate(16);
|
v.truncate(16);
|
||||||
|
|
||||||
v.iter()
|
let hex = v
|
||||||
|
.iter()
|
||||||
.map(|b| format!("{b:02x}"))
|
.map(|b| format!("{b:02x}"))
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join("")
|
.join("");
|
||||||
|
|
||||||
|
hex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,4 +157,20 @@ mod test {
|
||||||
"ac57663c18c81ad0423edb235d5b1059d792c2a18d5fad70a83a4afa92affabb"
|
"ac57663c18c81ad0423edb235d5b1059d792c2a18d5fad70a83a4afa92affabb"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn udp_id() {
|
||||||
|
const DEVICE_ID: u64 = 152832116426242;
|
||||||
|
|
||||||
|
const UDP: [&str; 2] = [
|
||||||
|
"53c18d6f4682867654bee60c9ea047f4",
|
||||||
|
"a153e4273b29c04db85763c739d45203",
|
||||||
|
];
|
||||||
|
|
||||||
|
for method in [1, 2] {
|
||||||
|
let res = CloudSecurity::udp_id(DEVICE_ID, method);
|
||||||
|
|
||||||
|
assert_eq!(res, UDP[method as usize - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,11 +64,6 @@ impl Device {
|
||||||
.security
|
.security
|
||||||
.encode_8370(&self.token, MsgType::HANDSHAKE_REQUEST)?;
|
.encode_8370(&self.token, MsgType::HANDSHAKE_REQUEST)?;
|
||||||
|
|
||||||
const PY_REQUEST :&[u8;72] = b"\x83p\x00@ \x00\x00\x00p+\x9d\xfc:\xc6\xc8)y\x98n\xe3\xa0S\xa7ou\xf9\xe9\xc7c\xce\\%\xaf\\,\xc9\x82\xf7\x97\xa9@\x9a\xdf\xf3t^#\xfe\xe3\xa4d\xd7E\xe0\x05\xc89\xef\xb0\xb8@\x82\xac\xc9b\xe5\x9a\xb8h>\x02\x99";
|
|
||||||
|
|
||||||
// assert_eq!(request, PY_REQUEST);
|
|
||||||
|
|
||||||
println!("writing request to stream: {request:?}");
|
|
||||||
self.socket.write(&request)?;
|
self.socket.write(&request)?;
|
||||||
|
|
||||||
let mut buffer = [0; 512];
|
let mut buffer = [0; 512];
|
||||||
|
@ -135,20 +130,6 @@ mod test {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn connect_rust_token() -> Result<()> {
|
|
||||||
let devices = Startup::discover().await?;
|
|
||||||
|
|
||||||
const TOKEN: &str = "702b9dfc3ac6c82979986ee3a053a76f75f9e9c763ce5c25af5c2cc982f797a9409adff3745e23fee3a464d745e005c839efb0b84082acc962e59ab8683e0299";
|
|
||||||
const KEY: &str = "52b2feee353841588994e630dcb59819ec71ce1ffacb48628f4f436f5c54f11e";
|
|
||||||
|
|
||||||
for device_info in devices {
|
|
||||||
Device::connect(device_info, TOKEN, KEY)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn full_flow() -> Result<()> {
|
async fn full_flow() -> Result<()> {
|
||||||
|
|
Loading…
Reference in a new issue