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:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,5 +1,5 @@
|
|||||||
# Первоисточник для анализа — бинарники APK не версионируем (файлы лежат локально)
|
# Первоисточник для анализа — бинарники APK не версионируем (файлы лежат локально)
|
||||||
apk/*.apk
|
docs/apk/*.apk
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
__pycache__/
|
__pycache__/
|
||||||
@@ -7,5 +7,5 @@ __pycache__/
|
|||||||
.venv/
|
.venv/
|
||||||
venv/
|
venv/
|
||||||
|
|
||||||
# Вложенный клон апстрима legacy-скрипта (https://github.com/gyro-labs/AirCon)
|
# Локальный конфиг устройства (содержит lanip_key)
|
||||||
legacy/aircon/
|
docs/legacy/config_kata.json
|
||||||
|
|||||||
BIN
apk/icon.png
BIN
apk/icon.png
Binary file not shown.
|
Before Width: | Height: | Size: 5.5 KiB |
@@ -1,4 +1,4 @@
|
|||||||
# Анализ legacy-скрипта (`legacy/`): соответствие протоколу и найденные проблемы
|
# Анализ legacy-скрипта (`docs/legacy/`): соответствие протоколу и найденные проблемы
|
||||||
|
|
||||||
Скрипт — форк проекта hisense_ac (deiger), адаптированный под FGLair. Общая логика
|
Скрипт — форк проекта hisense_ac (deiger), адаптированный под FGLair. Общая логика
|
||||||
протокола воспроизведена верно, но есть критические расхождения с APK и поведением
|
протокола воспроизведена верно, но есть критические расхождения с APK и поведением
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ cffi-wheel — рабочий путь (HA-контейнеры: x86_64/aarch64
|
|||||||
(extern "C"-шейм ядра);
|
(extern "C"-шейм ядра);
|
||||||
* `pyfglair/session.py` — pythonic-обёртка: `Session(cfg)`, колбэки ядра
|
* `pyfglair/session.py` — pythonic-обёртка: `Session(cfg)`, колбэки ядра
|
||||||
мостятся в `asyncio` через `loop.call_soon_threadsafe`;
|
мостятся в `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,
|
на современный aiohttp): вход e-mail/пароль/регион → dsn, ip, oem_model,
|
||||||
lanip_key, lanip_key_id;
|
lanip_key, lanip_key_id;
|
||||||
* CLI: `python -m pyfglair discover` / `python -m pyfglair monitor`.
|
* CLI: `python -m pyfglair discover` / `python -m pyfglair monitor`.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Документ реконструирован по декомпилированному APK FGLair 3.4.3 (`com.fujitsu.fglair`,
|
Документ реконструирован по декомпилированному APK FGLair 3.4.3 (`com.fujitsu.fglair`,
|
||||||
SDK `com.aylanetworks.aylasdk`, см. `AylaLanModule.java`, `AylaEncryption.java`,
|
SDK `com.aylanetworks.aylasdk`, см. `AylaLanModule.java`, `AylaEncryption.java`,
|
||||||
`AylaLanMessage.java`, `CreateDatapointCommand.java`, `AylaHttpServer.java`,
|
`AylaLanMessage.java`, `CreateDatapointCommand.java`, `AylaHttpServer.java`,
|
||||||
`com.cafbit.netlib.dns.NetThread`) и сверён с существующим скриптом `legacy/`.
|
`com.cafbit.netlib.dns.NetThread`) и сверён с существующим скриптом `docs/legacy/`.
|
||||||
Всё, что помечено **[APK]**, подтверждено кодом приложения; **[LEGACY]** — известно
|
Всё, что помечено **[APK]**, подтверждено кодом приложения; **[LEGACY]** — известно
|
||||||
только из скрипта; **[ПРОВЕРЕНО НА ПРИБОРЕ]** — проверено живыми экспериментами
|
только из скрипта; **[ПРОВЕРЕНО НА ПРИБОРЕ]** — проверено живыми экспериментами
|
||||||
на AP-WC1E (сентябрь 2026, см. §10); **[HYP]** — правдоподобная гипотеза,
|
на AP-WC1E (сентябрь 2026, см. §10); **[HYP]** — правдоподобная гипотеза,
|
||||||
@@ -100,7 +100,7 @@ key = HMAC_SHA256(K, HMAC_SHA256(K, msg) || msg) # 32 байта
|
|||||||
* **app-ключи** (приложение шифрует/подписывает, модуль проверяет) — из `msg_app`;
|
* **app-ключи** (приложение шифрует/подписывает, модуль проверяет) — из `msg_app`;
|
||||||
* **dev-ключи** (модуль шифрует, приложение проверяет) — из `msg_dev`.
|
* **dev-ключи** (модуль шифрует, приложение проверяет) — из `msg_dev`.
|
||||||
|
|
||||||
Совпадает с `legacy/config.py`. **[APK: AylaEncryption.generateSessionKeys]**
|
Совпадает с `docs/legacy/aircon/config.py`. **[APK: AylaEncryption.generateSessionKeys]**
|
||||||
|
|
||||||
### 3.3. Формат защищённого сообщения (envelope)
|
### 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`
|
* CN: `app_id=FGLairField-cn-id`, `app_secret=FGLairField-cn-zezg7Y60YpAvy3HPwxvWLnd4Oh4`
|
||||||
|
|
||||||
`app_secret` = `<prefix>-<base64url-nopad(секрет)>`; байты секрета — в
|
`app_secret` = `<prefix>-<base64url-nopad(секрет)>`; байты секрета — в
|
||||||
`legacy/app_mappings.py` (проверено: EU совпадает).
|
`docs/legacy/aircon/app_mappings.py` (проверено: EU совпадает).
|
||||||
|
|
||||||
Endpoints:
|
Endpoints:
|
||||||
|
|
||||||
@@ -487,7 +487,7 @@ building_name, wifi_led_enable, service_contact_*, device_capabilities, refresh.
|
|||||||
|
|
||||||
## 10. Проверено на приборе / осталось неизвестным
|
## 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-цепочка/подписи в обе
|
§4.1, §4.4, §5.1, §5.3, §6: полный цикл сессии, KDF/CBC-цепочка/подписи в обе
|
||||||
стороны, GET/запись свойств, re-key, 401/400-игнорирование, 2 слота + 503,
|
стороны, GET/запись свойств, re-key, 401/400-игнорирование, 2 слота + 503,
|
||||||
delete_session, mDNS :10276. Рабочий эталонный клиент: `tools/probe_reference.py`.
|
delete_session, mDNS :10276. Рабочий эталонный клиент: `tools/probe_reference.py`.
|
||||||
|
|||||||
@@ -12,8 +12,9 @@
|
|||||||
| `PLAN_CORE_LIBRARY.md` | План C++20-библиотеки `fglair-core` (Linux + ESP-IDF). |
|
| `PLAN_CORE_LIBRARY.md` | План C++20-библиотеки `fglair-core` (Linux + ESP-IDF). |
|
||||||
| `PLAN_HOME_ASSISTANT.md` | План HA-интеграции (`pyfglair` wheel + custom component). |
|
| `PLAN_HOME_ASSISTANT.md` | План HA-интеграции (`pyfglair` wheel + custom component). |
|
||||||
| `PLAN_ESPHOME.md` | План external component для ESPHome (только ESP-IDF framework). |
|
| `PLAN_ESPHOME.md` | План external component для ESPHome (только ESP-IDF framework). |
|
||||||
| `../tools/probe_reference.py` | Эталонный клиент протокола (проверен на приборе). |
|
|
||||||
| `../tools/probe_mdns.py` | mDNS-проба (`<DSN>.local`, порт 10276). |
|
| `../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`): классы
|
* APK FGLair 3.4.3 (`apk/com.fujitsu.fglair.apk`): классы
|
||||||
`com.aylanetworks.aylasdk.lan.*`, `com.fujitsugeneral.aylasdk.*`,
|
`com.aylanetworks.aylasdk.lan.*`, `com.fujitsugeneral.aylasdk.*`,
|
||||||
`com.cafbit.netlib.dns.NetThread`, JS-бандл `assets/www/dist/build.js`.
|
`com.cafbit.netlib.dns.NetThread`, JS-бандл `assets/www/dist/build.js`.
|
||||||
* Legacy-скрипт (`legacy/`) — форк hisense_ac; вложенный клон апстрима:
|
* Legacy-скрипт (`legacy/`) — изменённый форк gyro-labs/AirCon (hisense_ac).
|
||||||
https://github.com/gyro-labs/AirCon (лежит в `legacy/aircon/`, не версионируется).
|
|
||||||
* Живые эксперименты на AP-WC1E (сентябрь 2026): сессии, re-key, 401/400,
|
* Живые эксперименты на AP-WC1E (сентябрь 2026): сессии, re-key, 401/400,
|
||||||
слоты/503, delete_session, записи, mDNS. Пробы: `tools/probe_*.py`
|
слоты/503, delete_session, записи, mDNS. Пробы: `tools/probe_*.py`
|
||||||
(история — сессия анализа; рабочие артефакты оставлены в tools/).
|
(история — сессия анализа; рабочие артефакты оставлены в tools/).
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ docs/PROTOCOL.md, включая поведение, подтверждённо
|
|||||||
- delete_session при выходе (освобождает один из 2 слотов модуля).
|
- delete_session при выходе (освобождает один из 2 слотов модуля).
|
||||||
|
|
||||||
Использование:
|
Использование:
|
||||||
python probe_reference.py config_kata.json monitor 60
|
python probe_reference.py docs/legacy/config_kata.json monitor 60
|
||||||
python probe_reference.py config_kata.json get operation_mode fan_speed
|
python probe_reference.py docs/legacy/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 set fan_speed 3
|
||||||
Зависимости: pycryptodome."""
|
Зависимости: pycryptodome."""
|
||||||
import base64, hmac, json, random, socket, string, sys, threading, time
|
import base64, hmac, json, random, socket, string, sys, threading, time
|
||||||
import http.client
|
import http.client
|
||||||
|
|||||||
Reference in New Issue
Block a user