This commit is contained in:
Mateusz Gruszczyński
2026-08-23 22:31:30 +02:00
parent d834284695
commit 08d0cea016
17 changed files with 97 additions and 20 deletions
+15 -4
View File
@@ -244,6 +244,15 @@ impl GreeClient {
bail!("unable to bind device ({})", errors.join("; "))
}
/// GREE Wi-Fi modules use the 12-hex device id as a protocol identifier.
/// Older V1 modules (notably 502cc6...) can silently ignore bind/status
/// packets when tcid/mac casing differs from the lowercase value returned
/// by discovery. Keep the database/display representation independent from
/// the on-wire representation and always send canonical lowercase hex.
fn wire_mac(device: &Device) -> String {
device.mac.replace([':', '-'], "").to_ascii_lowercase()
}
async fn bind_attempt(&self, device: &Device, version: u8) -> Result<String> {
let target = self.device_target(device)?;
let target_hint = match target { SocketAddr::V4(addr) => Some(*addr.ip()), SocketAddr::V6(_) => None };
@@ -271,7 +280,8 @@ impl GreeClient {
}
}
let inner = json!({"mac": device.mac, "t": "bind", "uid": 0});
let wire_mac = Self::wire_mac(device);
let inner = json!({"mac": wire_mac, "t": "bind", "uid": 0});
let generic_key = if version == 2 { GENERIC_GREE_V2_KEY } else { GENERIC_GREE_V1_KEY };
let response = self.request_on_socket(device, &inner, generic_key, true, version, &socket).await?;
let kind = response.get("t").and_then(Value::as_str).unwrap_or_default();
@@ -309,7 +319,7 @@ impl GreeClient {
}
async fn status_request(&self, device: &Device, key: &str, cols: &[&str]) -> Result<Value> {
let inner = json!({"cols": cols, "mac": device.mac, "t": "status"});
let inner = json!({"cols": cols, "mac": Self::wire_mac(device), "t": "status"});
self.request(device, &inner, key, false, device.protocol_version).await
}
@@ -382,11 +392,12 @@ impl GreeClient {
let target = self.device_target(device)?;
let version = if protocol_version == 2 { 2 } else { 1 };
let inner_bytes = serde_json::to_vec(inner)?;
let wire_mac = Self::wire_mac(device);
let mut outer = json!({
"cid": "app",
"i": if binding { 1 } else { 0 },
"t": "pack",
"tcid": device.mac,
"tcid": wire_mac,
"uid": 0
});
if version == 2 {
@@ -397,7 +408,7 @@ impl GreeClient {
outer["pack"] = json!(encrypt_v1(key, &inner_bytes)?);
}
let payload = serde_json::to_vec(&outer)?;
tracing::debug!(target=%target, local=%socket.local_addr()?, protocol=version, interface=%self.interface.as_deref().unwrap_or("auto"), binding, "Sending GREE request");
tracing::debug!(target=%target, local=%socket.local_addr()?, protocol=version, wire_mac=%wire_mac, interface=%self.interface.as_deref().unwrap_or("auto"), binding, "Sending GREE request");
socket.send_to(&payload, target).await?;
let deadline = Instant::now() + Duration::from_secs(4);