refactor: legacy и apk перенесены в docs/, дедупликация исходников legacy

- docs/legacy/: рабочая раскладка изменённого форка (main.py + пакет
  aircon/); плоские дубликаты .py удалены, вложенный .git клона удалён
  (это изменённая копия, а не чистый клон), __pycache__ и .gitignore
  апстрима убраны. Локальный config_kata.json не версионируется
  (содержит lanip_key устройства).
- docs/apk/: манифест APK; бинарники *.apk и icon.png не версионируются.
- Обновлены пути в документации и tools/.
This commit is contained in:
2026-09-17 19:47:28 +03:00
parent 024b290b89
commit 790cee3c78
22 changed files with 15 additions and 15 deletions

6
.gitignore vendored
View File

@@ -1,5 +1,5 @@
# Первоисточник для анализа — бинарники APK не версионируем (файлы лежат локально)
apk/*.apk
docs/apk/*.apk
# Python
__pycache__/
@@ -7,5 +7,5 @@ __pycache__/
.venv/
venv/
# Вложенный клон апстрима legacy-скрипта (https://github.com/gyro-labs/AirCon)
legacy/aircon/
# Локальный конфиг устройства (содержит lanip_key)
docs/legacy/config_kata.json

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -1,4 +1,4 @@
# Анализ legacy-скрипта (`legacy/`): соответствие протоколу и найденные проблемы
# Анализ legacy-скрипта (`docs/legacy/`): соответствие протоколу и найденные проблемы
Скрипт — форк проекта hisense_ac (deiger), адаптированный под FGLair. Общая логика
протокола воспроизведена верно, но есть критические расхождения с APK и поведением

View File

@@ -33,7 +33,7 @@ cffi-wheel — рабочий путь (HA-контейнеры: x86_64/aarch64
(extern "C"-шейм ядра);
* `pyfglair/session.py` — pythonic-обёртка: `Session(cfg)`, колбэки ядра
мостятся в `asyncio` через `loop.call_soon_threadsafe`;
* `pyfglair/provision.py` — облачный discovery (перенос `legacy/discovery.py`
* `pyfglair/provision.py` — облачный discovery (перенос `docs/legacy/aircon/discovery.py`
на современный aiohttp): вход e-mail/пароль/регион → dsn, ip, oem_model,
lanip_key, lanip_key_id;
* CLI: `python -m pyfglair discover` / `python -m pyfglair monitor`.

View File

@@ -3,7 +3,7 @@
Документ реконструирован по декомпилированному APK FGLair 3.4.3 (`com.fujitsu.fglair`,
SDK `com.aylanetworks.aylasdk`, см. `AylaLanModule.java`, `AylaEncryption.java`,
`AylaLanMessage.java`, `CreateDatapointCommand.java`, `AylaHttpServer.java`,
`com.cafbit.netlib.dns.NetThread`) и сверён с существующим скриптом `legacy/`.
`com.cafbit.netlib.dns.NetThread`) и сверён с существующим скриптом `docs/legacy/`.
Всё, что помечено **[APK]**, подтверждено кодом приложения; **[LEGACY]** — известно
только из скрипта; **[ПРОВЕРЕНО НА ПРИБОРЕ]** — проверено живыми экспериментами
на AP-WC1E (сентябрь 2026, см. §10); **[HYP]** — правдоподобная гипотеза,
@@ -100,7 +100,7 @@ key = HMAC_SHA256(K, HMAC_SHA256(K, msg) || msg) # 32 байта
* **app-ключи** (приложение шифрует/подписывает, модуль проверяет) — из `msg_app`;
* **dev-ключи** (модуль шифрует, приложение проверяет) — из `msg_dev`.
Совпадает с `legacy/config.py`. **[APK: AylaEncryption.generateSessionKeys]**
Совпадает с `docs/legacy/aircon/config.py`. **[APK: AylaEncryption.generateSessionKeys]**
### 3.3. Формат защищённого сообщения (envelope)
@@ -347,7 +347,7 @@ data: {"id":"<id команды>","ack_status":200,"ack_message":0,"dsn":"..."}
* CN: `app_id=FGLairField-cn-id`, `app_secret=FGLairField-cn-zezg7Y60YpAvy3HPwxvWLnd4Oh4`
`app_secret` = `<prefix>-<base64url-nopad(секрет)>`; байты секрета — в
`legacy/app_mappings.py` (проверено: EU совпадает).
`docs/legacy/aircon/app_mappings.py` (проверено: EU совпадает).
Endpoints:
@@ -487,7 +487,7 @@ building_name, wifi_led_enable, service_contact_*, device_capabilities, refresh.
## 10. Проверено на приборе / осталось неизвестным
Проверено на AP-WC1E (fw 2.6.17-fgl2, ключ из `config_kata.json`), см. также §2,
Проверено на AP-WC1E (fw 2.6.17-fgl2, ключ из `docs/legacy/config_kata.json`), см. также §2,
§4.1, §4.4, §5.1, §5.3, §6: полный цикл сессии, KDF/CBC-цепочка/подписи в обе
стороны, GET/запись свойств, re-key, 401/400-игнорирование, 2 слота + 503,
delete_session, mDNS :10276. Рабочий эталонный клиент: `tools/probe_reference.py`.

View File

@@ -12,8 +12,9 @@
| `PLAN_CORE_LIBRARY.md` | План C++20-библиотеки `fglair-core` (Linux + ESP-IDF). |
| `PLAN_HOME_ASSISTANT.md` | План HA-интеграции (`pyfglair` wheel + custom component). |
| `PLAN_ESPHOME.md` | План external component для ESPHome (только ESP-IDF framework). |
| `../tools/probe_reference.py` | Эталонный клиент протокола (проверен на приборе). |
| `../tools/probe_mdns.py` | mDNS-проба (`<DSN>.local`, порт 10276). |
| `legacy/` | Изменённый legacy-скрипт (форк [gyro-labs/AirCon](https://github.com/gyro-labs/AirCon) / hisense_ac): `main.py` + пакет `aircon/` + рабочий конфиг `config_kata.json`. |
| `apk/` | Материалы анализа APK FGLair 3.4.3 (`manifest.json`; сами .apk лежат локально, не версионируются). |
## Краткая выжимка протокола
@@ -59,8 +60,7 @@
* APK FGLair 3.4.3 (`apk/com.fujitsu.fglair.apk`): классы
`com.aylanetworks.aylasdk.lan.*`, `com.fujitsugeneral.aylasdk.*`,
`com.cafbit.netlib.dns.NetThread`, JS-бандл `assets/www/dist/build.js`.
* Legacy-скрипт (`legacy/`) — форк hisense_ac; вложенный клон апстрима:
https://github.com/gyro-labs/AirCon (лежит в `legacy/aircon/`, не версионируется).
* Legacy-скрипт (`legacy/`) — изменённый форк gyro-labs/AirCon (hisense_ac).
* Живые эксперименты на AP-WC1E (сентябрь 2026): сессии, re-key, 401/400,
слоты/503, delete_session, записи, mDNS. Пробы: `tools/probe_*.py`
(история — сессия анализа; рабочие артефакты оставлены в tools/).

View File

@@ -11,9 +11,9 @@ docs/PROTOCOL.md, включая поведение, подтверждённо
- delete_session при выходе (освобождает один из 2 слотов модуля).
Использование:
python probe_reference.py config_kata.json monitor 60
python probe_reference.py config_kata.json get operation_mode fan_speed
python probe_reference.py config_kata.json set fan_speed 3
python probe_reference.py docs/legacy/config_kata.json monitor 60
python probe_reference.py docs/legacy/config_kata.json get operation_mode fan_speed
python probe_reference.py docs/legacy/config_kata.json set fan_speed 3
Зависимости: pycryptodome."""
import base64, hmac, json, random, socket, string, sys, threading, time
import http.client