Понимание протокола ZMODEM
Мне нужно включить основные подпрограммы отправки и получения файлов в мою программу, и это должно быть через протокол ZMODEM. Проблема в том, что у меня проблемы с пониманием спецификации.
Для справки, вот спецификация.
Спецификация не определяет различные константы, поэтому вот файл заголовка от Google.
Мне кажется, что в этом документе многое не определено:
- Это постоянно относится к ZDLE-кодированию, но что это? Когда именно я использую это, и когда я не использую это?
- После фрейма данных ZFILE передаются метаданные файла (имя файла, дата изменения, размер и т. Д.). За этим следует блок ZCRCW, а затем блок, тип которого не определен в соответствии со спецификацией. Блок ZCRCW предположительно содержит 16-битный CRC, но спецификация не определяет, по каким данным вычисляется CRC.
-
Он не определяет полином CRC, который он использует.Я случайно обнаружил, что CRC32 poly является стандартом CRC32, но мне не повезло с CRC16 poly.Неважно, я нашел это методом проб и ошибок. Поли CRC16 является 0x1021.
Я искал справочный код, но все, что я могу найти, это нечитаемые, недокументированные C-файлы начала 90-х. Я также нашел этот набор документов из MSDN, но он крайне расплывчатый и противоречивый для тестов, которые я провел: http://msdn.microsoft.com/en-us/library/ms817878.aspx (вам может понадобиться чтобы просмотреть это через кеш Google)
Чтобы проиллюстрировать мои трудности, вот простой пример. Я создал текстовый файл на сервере, содержащий "Hello world!", И он называется helloworld.txt.
Я инициирую передачу с сервера с помощью следующей команды:
sx --zmodem helloworld.txt
Это побуждает сервер отправить следующий кадр ZRQINIT:
2A 2A 18 42 30 30 30 30 30 30 30 30 30 30 30 30 **.B000000000000
30 30 0D 8A 11 00.Š.
Три проблемы с этим:
- Являются ли байты заполнения (0x2A) произвольными? Почему здесь два, а в других случаях есть только один, а иногда и нет?
- В спецификации не упоминается [CR] [LF] [XON] в конце, но в статье MSDN есть. Почему это там?
- Почему [LF] имеет бит 0x80?
После этого клиент должен отправить кадр ZRINIT. Я получил это из статьи MSDN:
2A 2A 18 42 30 31 30 30 30 30 30 30 32 33 62 65 **.B0100000023be
35 30 0D 8A 50.Š
В дополнение к проблеме флага [LF] 0x80 у меня есть еще две проблемы:
- Почему [XON] не включен в этот раз?
-
CRC рассчитывается на основе двоичных данных или шестнадцатеричных данных ASCII?Если это на двоичных данных, я получаю 0x197C, и если это на шестнадцатеричных данных ASCII, я получаю 0xF775;ни то, ни другое не находится в кадре (0xBE50).(Решено; оно следует любому режиму, который вы используете. Если вы находитесь в режиме BIN или BIN32, это CRC двоичных данных. Если вы находитесь в шестнадцатеричном режиме ASCII, это CRC того, что представлено шестнадцатеричными символами ASCII.)
Сервер отвечает фреймом ZFILE:
2A 18 43 04 00 00 00 00 DD 51 A2 33 *.C.....ÝQ¢3
ХОРОШО. Это имеет смысл. Если я вычислю CRC32 из [04 00 00 00 00], я действительно получу 0x33A251DD. Но теперь у нас нет НИКАКОГО [CR] [LF] [XON] в конце. Почему это?
Сразу после этого кадра сервер также отправляет метаданные файла:
68 65 6C 6C 6F 77 6F 72 6C 64 2E 74 78 74 00 31 helloworld.txt.1
33 20 32 34 30 20 31 30 30 36 34 34 20 30 20 31 3 240 100644 0 1
20 31 33 00 18 6B 18 50 D3 0F F1 11 13..k.PÓ.ñ.
У него даже нет заголовка, он просто переходит прямо к данным. ОК, я могу жить с этим. Тем не мение:
- У нас есть наш первый загадочный кадр ZCRCW: [18 6B]. Как долго этот кадр? Где данные CRC и CRC16 или CRC32? Это не определено нигде в спецификации.
- В статье MSDN указано, что за [18 6B] должно следовать [00], но это не так.
- Тогда у нас есть кадр с неопределенным типом: [18 50 D3 0F F1 11]. Это отдельный кадр или это часть ZCRCW?
Клиент должен ответить с фреймом ZRPOS, снова взятым из статьи MSDN:
2A 2A 18 42 30 39 30 30 30 30 30 30 30 30 61 38 **.B0900000000a8
37 63 0D 8A 7c.Š
Те же проблемы, что и с кадром ZRINIT: CRC неверен, [LF] имеет установленный бит 0x80, и [XON] нет.
Сервер отвечает фреймом ZDATA:
2A 18 43 0A 00 00 00 00 BC EF 92 8C *.C.....¼ï’Œ
Те же проблемы, что и у ZFILE: с CRC все в порядке, но где же [CR] [LF] [XON]?
После этого сервер отправляет полезную нагрузку файла. Поскольку это короткий пример, он помещается в один блок (максимальный размер 1024):
48 65 6C 6C 6F 20 77 6F 72 6C 64 21 0A Hello world!.
Судя по тому, что статья упоминает, полезные нагрузки экранируются с помощью [ZDLE]. Так как же передать байт полезной нагрузки, который соответствует значению [ZDLE]? Есть ли какие-либо другие значения, подобные этому?
Сервер заканчивается этими кадрами:
18 68 05 DE 02 18 D0 .h.Þ..Ð
2A 18 43 0B 0D 00 00 00 D1 1E 98 43 *.C.....Ñ.˜C
Я полностью потерян на первом. Второй имеет такой же смысл, как и кадры ZRINIT и ZDATA.
3 ответа
Мой приятель задается вопросом, внедряешь ли ты машину времени.
Я не знаю, могу ли я ответить на все ваши вопросы - мне никогда не приходилось самому внедрять zmodem - но вот несколько ответов:
Судя по тому, что статья упоминает, полезные нагрузки экранируются с помощью [ZDLE]. Так как же передать байт полезной нагрузки, который соответствует значению [ZDLE]? Есть ли какие-либо другие значения, подобные этому?
Об этом прямо говорится в документе, на который вы ссылались в начале ваших вопросов, где говорится:
The ZDLE character is special. ZDLE represents a control sequence
of some sort. If a ZDLE character appears in binary data, it is
prefixed with ZDLE, then sent as ZDLEE.
Это постоянно относится к ZDLE-кодированию, но что это? Когда именно я использую это, и когда я не использую это?
В старые времена определенные "контрольные символы" использовались для управления каналом связи (отсюда и название). Например, отправка символов XON/XOFF может приостановить передачу. ZDLE используется для экранирования символов, которые могут быть проблематичными. Согласно спецификации, это символы, которые экранированы по умолчанию:
ZMODEM software escapes ZDLE, 020, 0220, 021, 0221, 023, and 0223.
If preceded by 0100 or 0300 (@), 015 and 0215 are also escaped to
protect the Telenet command escape CR-@-CR. The receiver ignores
021, 0221, 023, and 0223 characters in the data stream.
Я искал справочный код, но все, что я могу найти, это нечитаемые, недокументированные C-файлы начала 90-х.
Включает ли это код для пакета lrzsz? Это все еще широко доступно в большинстве дистрибутивов Linux (и удивительно удобно для передачи файлов через установленное соединение ssh).
Существует ряд других реализаций, в том числе несколько программ, перечисленных в свободном коде, включая qodem, syncterm, MBSE и другие. Я полагаю, что реализация syncterm написана как библиотека, которая может быть достаточно проста в использовании из вашего собственного кода (но я не уверен).
Вы можете найти дополнительный код, если покопаться в старых коллекциях программного обеспечения MS-DOS.
Я не могу винить тебя. Руководство пользователя не организовано в удобной для пользователя форме.
Являются ли байты заполнения (0x2A) произвольными?
Нет, со страницы 14,15:
Двоичный заголовок начинается с последовательности ZPAD, ZDLE, ZBIN.
Шестнадцатеричный заголовок начинается с последовательности ZPAD, ZPAD, ZDLE, ZHEX.
,
В спецификации не упоминается [CR] [LF] [XON] в конце, но в статье MSDN есть. Почему это там?
Страница 15
* * ZDLE B ТИП F3 / P0 F2 / P1 F1 / P2 F0 / P3 CRC-1 CRC-2 CR LF XON. Почему [LF] имеет бит 0x80?
Точно сказать не могу. Из термина Tera я получил оба управляющих символа XOR с 0x80 (8D 8A 11)
У нас есть наш первый загадочный кадр ZCRCW: [18 6B]. Как долго этот кадр? Где данные CRC и CRC16 или CRC32? Это не определено нигде в спецификации.
ZCRCW не является заголовком или типом фрейма, это больше похоже на нижний колонтитул, который сообщает получателю, что ожидать дальше. В данном случае это нижний колонтитул подпакета данных, содержащий имя файла. Это будет 32-битная контрольная сумма, потому что вы используете двоичный заголовок типа "C".
- ZDLE C ТИП F3 / P0 F2 / P1 F1 / P2 F0 / P3 CRC-1 CRC-2 CRC-3 CRC-4
,
Тогда у нас есть кадр с неопределенным типом: [18 50 D3 0F F1 11]. Это отдельный кадр или это часть ZCRCW?
Это CRC для подпакета данных ZCRCW. Это 5 байтов, потому что первый - 0x10, управляющий символ, который должен быть экранирован ZDLE. Я не уверен, что такое 0x11.
и нет [XON].
XON только для шестнадцатеричных заголовков. Вы не используете его для двоичного заголовка.
- ZDLE A ТИП F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 . Так как же передать байт полезной нагрузки, который соответствует значению [ZDLE]?
18 58 (АКА ЗДЛЕЕ)
18 68 05 DE 02 18 D0
Это нижний колонтитул подфрейма данных. Следующие 5 байтов являются CRC (последний байт кодируется в ZDLE)
ZDLE + ZBIN (0x18 0x41) означает, что кадр CRC-CCITT (XMODEM 16) с двоичными данными. ZDLE + ZHEX (0x18 0x42) означает CRC-CCITT(XMODEM 16) с данными HEX.
Данные HEX сложны, так как поначалу некоторые люди их не понимают. Каждые два байта символы ASCII представляют один байт в двоичном формате. Например, 0x30 0x45 0x41 0x32 означает 0x30 0x45, 0x41 0x32 или в ASCII 0 EA 2, затем 0x0E, 0xA2. Они расширяют двоичные два полубайта до ASCII-представления. Я нашел в нескольких регистраторах данных, что некоторые устройства используют строчные буквы для представления A~F (a~f) в HEX, это не имеет значения, но на них вы не найдете 0x30 0x45 0x41 0x32 (0EA2), а 0x30 0x65 0x61 0x32 (0ea2), это ничего не меняет, просто сначала немного сбивает с толку.
И да, CRC16 для ZBIN или ZHEX — это CRC-CCITT(XMODEM). ZDLE ZBIN32 (0x18 0x43) или ZDLE ZBINR32 (0x18 0x44) используют вычисление CRC-32.
Обратите внимание, что ZDLE и следующий за ним байт исключаются из вычисления CRC.
Я копаюсь в ZMODEM, так как мне нужно «поговорить» с дверными панелями некоторых лифтов, чтобы сразу запрограммировать новый набор параметров, вместо того, чтобы использовать их программное обеспечение для изменения атрибута за атрибутом. Этот «разговор» может быть на скамейке вместо того, чтобы сидеть над крышей кабины лифта с ноутбуком. Эти платы используют ZMODEM, но, поскольку у меня нет ожидаемого формата пакетов, плата по-прежнему отклоняет передачу моего файла. Платы посылают 0x2a 0x2A 0x18 0x42 0x30 0x31 0x30(x6) + crc, Терминал Tera, передающий файл в ZMODEM, отправляет на плату 0x2A 0x2A 0x18 0x42 0x30 0x30 ... +CRC, не знаю, почему это 00 или 01 после 0x4B означает. ПК отправляет это, а также имя файла и некоторые атрибуты файла. Плата через несколько секунд отвечает "Файл не получен"...