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,92 @@
|
||||
"""Format-Erkennung. Dispatcher: schaut auf Magic + Dateinamen, leitet an
|
||||
den passenden Parser weiter. Liefert ein einheitliches Dict mit den Feldern,
|
||||
die in die DB gehen.
|
||||
|
||||
Aktuell unterstützt:
|
||||
- Huawei update.app (vollständig)
|
||||
|
||||
Geplant (Stubs als Hinweis):
|
||||
- MediaTek scatter (txt + bin)
|
||||
- Samsung Odin (.tar.md5 mit AP/BL/CP/CSC)
|
||||
- Qualcomm rawprogram*.xml
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import struct
|
||||
from pathlib import Path
|
||||
|
||||
from . import huawei
|
||||
|
||||
HUAWEI_MAGIC = struct.pack("<I", huawei.UPDATE_MAGIC)
|
||||
|
||||
|
||||
def _peek(path: Path, n: int = 0x200) -> bytes:
|
||||
try:
|
||||
with path.open("rb") as f:
|
||||
return f.read(n)
|
||||
except OSError:
|
||||
return b""
|
||||
|
||||
|
||||
def identify(path: Path, root: Path) -> dict:
|
||||
"""Rückgabe: dict für db.upsert. Enthält mindestens rel_path, size, mtime,
|
||||
format. Erkennungs-Misserfolg -> format='unknown'."""
|
||||
rel = str(path.resolve().relative_to(root.resolve())).replace("\\", "/")
|
||||
stat = path.stat()
|
||||
base: dict = {
|
||||
"rel_path": rel,
|
||||
"size": stat.st_size,
|
||||
"mtime": stat.st_mtime,
|
||||
"sha256": None,
|
||||
"format": "unknown",
|
||||
"vendor": None,
|
||||
"model": None,
|
||||
"soc": None,
|
||||
"version": None,
|
||||
"region": None,
|
||||
"extra_json": None,
|
||||
}
|
||||
|
||||
head = _peek(path)
|
||||
|
||||
# Huawei update.app — Magic taucht innerhalb der ersten 0x100 Bytes auf
|
||||
if HUAWEI_MAGIC in head[:0x200]:
|
||||
info = huawei.parse(path)
|
||||
if info is not None:
|
||||
base.update(
|
||||
format="huawei-update.app",
|
||||
vendor="Huawei",
|
||||
model=info.hardware_id or None,
|
||||
soc=huawei.soc_for(info.hardware_id) if info.hardware_id else None,
|
||||
version=info.earliest_date, # bessere Quelle wenn verfügbar
|
||||
region=_region_from_filename(path.name),
|
||||
extra_json=json.dumps({
|
||||
"section_count": info.section_count,
|
||||
"has_boot": info.has_boot,
|
||||
"has_system": info.has_system,
|
||||
"first_sections": [
|
||||
s.type for s in info.sections[:10]
|
||||
],
|
||||
}),
|
||||
)
|
||||
return base
|
||||
|
||||
# Fallback: Filename-Heuristik (MTK scatter etc. — TODO)
|
||||
name = path.name.lower()
|
||||
if name.startswith("mt") and name.endswith(".txt"):
|
||||
base["format"] = "mtk-scatter-candidate"
|
||||
elif name.endswith(".tar.md5"):
|
||||
base["format"] = "samsung-odin-candidate"
|
||||
base["vendor"] = "Samsung"
|
||||
|
||||
return base
|
||||
|
||||
|
||||
def _region_from_filename(name: str) -> str | None:
|
||||
"""Huawei-Region oft im Filename: '...C432B198...' -> 'C432'."""
|
||||
upper = name.upper()
|
||||
for marker in ("C432", "C636", "C185", "C233", "C605", "C10", "C461"):
|
||||
if marker in upper:
|
||||
return marker
|
||||
return None
|
||||
Reference in New Issue
Block a user