Skip to content

Latest commit

 

History

History
199 lines (172 loc) · 8.38 KB

File metadata and controls

199 lines (172 loc) · 8.38 KB

Hytera S1 mini U1 (HYT-S10) codeplug patcher

Утилита parser читает бинарный codeplug (.rdt) радиостанции Hytera S1 mini U1 (HYTS10) и, при указании выходного файла, записывает в него набор каналов LPD (первые 16 каналов), корректно формируя внутренние ссылки на записи каналов.

Проект полезен для быстрого аудита настроек и автоматической генерации типовых конфигураций на основе шаблонов прошивки.

Возможности

  • Парсинг .rdt:
  • чтение списка каналов (RX/TX частоты, CTCSS/CDCSS, служебные поля);
  • чтение отдельных настроек (кнопки, флаги/режимы, выбранный канал и пр. — по мере reverse);
  • запись - при указании out_path утилита строит новый блок каналов и перезаписывает его в выходной .rdt, добавляя первые 16 LPD-каналов.

Важно: при программировании в радио версии RCDB в файле codeplug и в радиостанции должны совпадать. Но, скорее всего, программа не даст записать codeplug от неверной версии

Требования

  • Python 3.8+
  • construct

Установка зависимостей:

python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt

# или просто:
pip install construct

Структура репозитория

.
├── parser.py
├── *.py                    # остальные файлы проекта
├── templates/              # эталонные codeplug-файлы под разные версии прошивки
   ├── HYTS10_V1.1.20.009.rdt
   ├── HYTS10_V1.1.20.010.rdt
   └── ...
└── README.md

templates/ содержит «чистые»/минимальные codeplug для разных версий прошивки HYTS10. Рекомендуется брать исходник именно из совместимой версии — это снижает риск несовместимости полей.

Использование

Просмотр содержимого codeplug:

python3 parser.py path/to/input.rdt

Пример вывода:

== parsed codeplug:
Container: 
    magic = b'HYTX' (total 4)
    version_1_firmware = u'V1.1.20.009' (total 11)
    version_2_rcdb_data = u'V1.1.20.009' (total 11)
    model = u'HYT-S10' (total 7)
    model_number = u'S101-00S00001-Uc-1-D' (total 20)
    freq_range = Container: 
        from = 43000000
        to = 47000000
    serial = /* skipped */
    device_alias = /* skipped */
    buttons = Container: 
        pwr_short = 133
        unknown1 = 28
        unknown2 = 66
        volume_up_long = 135
        unknown3 = 66
        volume_down_long = 255
    settings_13d = Container: 
        KEYPRESS_SOUND = True
        POWER_ONOFF_SOUND = True
        SERVICE_SOUND = True
        b4 = True
        b5 = True
        b6 = True
        b7 = True
    vox_level = 247
    vox_sensitivity = {'raw': 247, 'value': <VOXSensitivity.MID: 1>}
    squelch_settings = Container: 
        SQUELCH_ENABLED = True
        SQUELCH_NORMAL = True
    call_battery_save_time = 3
    settings_1f7 = Container: 
        b1 = True
        CALL_CTCSS_TAIL_REVERSE_180 = True
        b5 = True
    settings_1f8 = Container: 
        BACKLIGHT_LED = True
        VOICE_NOTIFICATIONS = True
        CALL_CTCSS_TAIL_REVERT = True
        b5 = True
        b6 = True
        b7 = True
    backlight_duration = 3
    settings_1fb = Container: 
        TXPOW_HIGH_1 = True
        TXPOW_HIGH_2 = True
        CALL_PRE_EMPHASIS = True
    settings_1fc = Container: 
        b2 = True
        b3 = True
        b4 = True
        b5 = True
    settings_1fd = Container: 
        b2 = True
        ALLOW_CHANNEL_COPY = True
    settings_1fe = Container: 
        b0 = True
        b1 = True
        b3 = True
    selected_channel = 1
    mic_gain = 32
    settings_220 = 241
    tx_allow_mode = {'raw': 241, 'value': <TXAllowMode.AllowIfChannelFree: 1>}
    call_timeout = 12
    settings_22d = Container: 
        b1 = True
        ALLOW_AIRCLONE = True
        b4 = True
        b5 = True
        b6 = True
        b7 = True
    write_password = None
    read_password = None
    <...>

== parsed channels:
H-01
    RX: 433.07500 MHz squelch: CTCSS, tone: 67.0 Hz
    TX: 433.07500 MHz squelch: CTCSS, tone: 67.0 Hz
H-02
    RX: 433.10000 MHz
    TX: 433.10000 MHz squelch: CTCSS, tone: 88.0 Hz
H-03
    RX: 433.12500 MHz squelch: DCS, octal code: 023
    TX: 433.12500 MHz
H-04
    RX: 433.15000 MHz squelch: DCS_INVERT, octal code: 023
    TX: 433.15000 MHz
H-05
    RX: 433.17500 MHz squelch: DCS, octal code: 666
    TX: 433.17500 MHz

Запись 16 первых LPD каналов

python3 parser.py path/to/input.rdt path/to/output.rdt

input.rdt — исходный codeplug (обычно берём из templates/ под нужную версию прошивки или дамп из вашей радиостанции). output.rdt — файл назначения. В него будет записан новый блок каналов с LPD 1–16.

Где берутся LPD-каналы?

Список формируется в функции create_channels() (см. код). По умолчанию — первые 16 LPD (433.0750 … 433.4000) с нейтральными тонами (или как задано в проекте). Вы можете изменить частоты/субтоны, отредактировав эту функцию.

Замечания по совместимости

RCDB/firmware: используйте шаблон из templates/, соответствующий версии вашего радио. Неверная версия может привести к отказу загрузки или некорректной работе.

Типовой рабочий процесс

  1. Определите версию прошивки своей станции.
  2. Возьмите подходящий шаблон из templates/ (или снимите дамп из радио).
  3. Запустите парсер для проверки, что файл читается:
python3 parser.py templates/HYTS10_V1.1.20.009.rdt
  1. Сгенерируйте выходной файл с LPD 1–16:
python3 parser.py templates/HYTS10_V1.1.20.009.rdt LPD16.rdt
  1. Загрузите LPD16.rdt в радио штатным способом.

Кастомизация каналов

Если хотите другой набор - отредактируйте create_channels():

def create_channels():
    return [
        dict(rx_freq=433.07500, tx_freq=433.07500,
        rx_tone_squelch={"kind": "none"}, tx_tone_squelch={"kind": "none"},
        padding=0xFFFFFFFF),
        # добавляйте свои каналы здесь…
    ]

Парсер корректно проставит prev/next, упакует частоты и допишет блок в целевой файл.

Ограничения и планы

  • В записи поддерживается перегенерация целого блока каналов «с нуля». Редактирование точечно «на месте» возможно, но пока не вынесено в CLI.
  • Часть сервисных полей ещё исследуется (флаги/кнопки/маски) — по мере открытия будут добавляться в схему construct.
  • Для прошивок, отличных от V1.1.20.009, смещения/биасы могут отличаться.

Дисклеймер

Все файлы и скрипты предоставлены «как есть». Используйте на свой страх и риск. Перед записью делайте резервную копию исходного codeplug. Совместимость с конкретной версией прошивки должна подтверждаться вашим тестом.