initial aubox skeleton: web-UI, kirin DLOAD, firmware library
- FastAPI Web-UI auf 127.0.0.1:8080 mit Geräte-Live-Erkennung, sandboxed File-Browser, Firmware-Library (SQLite + Auto-Identifikation) - Huawei update.app Parser: extrahiert Hardware-ID, Section-Layout, BOOT/SYSTEM-Vorhandensein direkt aus den Headern - Kirin Download-Mode: hisi-idt-Protokoll-Implementation gegen pyusb - USB-Erkennung für Huawei (DLOAD/Fastboot-D), Google, MediaTek, Qualcomm EDL - Huawei-P10-Lite-Workflow (eRecovery + Testpoint-DLOAD-Pfade) - Docker-Compose mit USB-Passthrough (Major 189) für Re-Enumeration - udev-Regeln + Setup-Script für Debian/Ubuntu/Pi-OS Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""USB-Geräte-Erkennung über VID:PID.
|
||||
|
||||
Erkennt die wichtigsten Hersteller-Modi und ordnet sie einem semantischen
|
||||
Status zu, damit Workflows wissen, in welchem Modus das Gerät gerade ist.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
import usb.core
|
||||
import usb.util
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DeviceMode:
|
||||
label: str
|
||||
vendor: str
|
||||
notes: str = ""
|
||||
|
||||
|
||||
# (vid, pid) -> Modus
|
||||
KNOWN: dict[tuple[int, int], DeviceMode] = {
|
||||
# Huawei / Kirin
|
||||
(0x12D1, 0x1100): DeviceMode("kirin-dload", "Huawei",
|
||||
"Kirin Download-Mode, wartet auf xloader via hisi-idt"),
|
||||
(0x12D1, 0x1052): DeviceMode("huawei-fastboot-d", "Huawei",
|
||||
"Erweiterter Fastboot-Mode (nach xloader)"),
|
||||
(0x12D1, 0x3609): DeviceMode("kirin-dload-alt", "Huawei",
|
||||
"Kirin DLOAD alternative PID"),
|
||||
(0x12D1, 0x107E): DeviceMode("huawei-hisuite", "Huawei",
|
||||
"HiSuite/MTP-Modus, kein Recovery-Zugriff"),
|
||||
# Google / Android Standard
|
||||
(0x18D1, 0x4EE0): DeviceMode("fastboot", "Google", "Standard-Fastboot"),
|
||||
(0x18D1, 0x4EE7): DeviceMode("adb", "Google", "ADB"),
|
||||
# MediaTek
|
||||
(0x0E8D, 0x0003): DeviceMode("mtk-preloader", "MediaTek",
|
||||
"Preloader (DA-Mode möglich)"),
|
||||
(0x0E8D, 0x2000): DeviceMode("mtk-brom", "MediaTek",
|
||||
"BROM — Ziel für mtkclient/kamakiri"),
|
||||
# Qualcomm EDL
|
||||
(0x05C6, 0x9008): DeviceMode("qc-edl", "Qualcomm",
|
||||
"Emergency Download (Firehose-fähig)"),
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class FoundDevice:
|
||||
vid: int
|
||||
pid: int
|
||||
mode: DeviceMode
|
||||
bus: int
|
||||
address: int
|
||||
|
||||
def __str__(self) -> str:
|
||||
return (f"[{self.bus:03d}:{self.address:03d}] "
|
||||
f"{self.vid:04x}:{self.pid:04x} {self.mode.vendor} "
|
||||
f"{self.mode.label}")
|
||||
|
||||
|
||||
def scan() -> list[FoundDevice]:
|
||||
"""Alle bekannten Hersteller-Modi auflisten, die gerade angeschlossen sind."""
|
||||
found: list[FoundDevice] = []
|
||||
for dev in usb.core.find(find_all=True):
|
||||
key = (dev.idVendor, dev.idProduct)
|
||||
mode = KNOWN.get(key)
|
||||
if mode is None:
|
||||
continue
|
||||
found.append(FoundDevice(
|
||||
vid=dev.idVendor,
|
||||
pid=dev.idProduct,
|
||||
mode=mode,
|
||||
bus=dev.bus,
|
||||
address=dev.address,
|
||||
))
|
||||
return found
|
||||
|
||||
|
||||
def find_first(label: str) -> FoundDevice | None:
|
||||
for d in scan():
|
||||
if d.mode.label == label:
|
||||
return d
|
||||
return None
|
||||
Reference in New Issue
Block a user