LINUX.ORG.RU

Canon LBP-2900 и другие CAPT-принтеры - ПИШУ ДРАЙВЕР

 ,


24

21

Попытался запустить LBP-2900 в Ubuntu. Довольно быстро выяснилось, что фирменный драйвер Canon - полный отстой, не поддерживается, и с этим надо что-то делать. Обнаружил также попытки написания энтузиастами аналогичного драйвера, но для 2900 он не работает. В связь с этим начал обратный инжениринг принтера и решил написать СОБСТВЕННЫЙ ДРАЙВЕР.

UPD: ТЕКУЩЕЕ СОСТОЯНИЕ

Исходники доступны на Github: https://github.com/agalakhov/captdriver

Чеклист к первому релизу:
[X] Передача параметров компрессии Hi-SCoA
[X] Компрессия Hi-SCoA
[X] Поддержка LBP-2900 и LBP-3000
[X] Баг «only 10 bytes»
[X] Печать многих страниц
[X] Ожидание наличия бумаги
[ ] Генерация PPD-файлов

Чеклист ко второму релизу:
[ ] Компрессия SCoA
[ ] Поддержка LBP-810 и LBP-1120

(Текст исходного верхнего поста следует)

Ищу единомышленников для Reverse Engineering протокола принтера. На сегодняшний день мне удалось полностью расшифровать протокол нижнего уровня USB и частично - протокол верхнего уровня. Мой драйвер уже может отсылать страницы на печать. ТРЕБУЕТСЯ расшифровать алгоритм сжатия пиксельных данных (он оказался отличным от алгоритма LBP-810 и, по-видимому, является какой-то модификацией ALPC-сжатия). Попытки прикрутить алгоритм от 810 привели к тому, что принтер включается и печатает, но на бумаге получаются только полосы, линии и регулярные узоры из пикселей. У меня пока нет времени на расшифровку, поэтому прошу помощи.

ОПИСАНИЕ ТОГО, ЧТО УДАЛОСЬ РАСШИФРОВАТЬ

Работать с принтером можно с помощью простого open(«/dev/usb/lp0») - libusb не требуется. Общение идет пакетами довольно простого формата. Формат пакета:

байты 1,2 - код команды - 16 бит (младший байт первый)

байты 3,4 - длина посылки (полная) - 16 бит (очевидно, меньше 4 байт не бывает)

байты с 5 - данные (опционально)

Если суммарная длина посылки превышает 4096 байт, посылка делится на части по 4096 байт.

Компьютер посылает принтеру команду. Принтер отвечает пакетом, содержащим код той же команды и минимум 2 байта данных (код возврата), всего не менее 6 байт. Эти 6 байт читают одним read(). Если длина превышает 6 байт, то затем делается read() на оставшуюся длину (она у меня никогда не превышала 4 килобайта, так что про ограничения ничего не знаю). Если не прочитать ответ принтера и продолжить посылать данные, он зависнет, и его придется выключить и включить снова.

Коды команд:

0xA1A1 - начало работы. Параметров нет (4 байта). Принтер отвечает длинной последовательностью байтов - видимо, номером модели, серийным номером, характеристиками и чем-то еще, я не разбирался.

0xA0A0 - какая-то проверка статуса? Встречается на 810, ни разу не видел на 2900. Параметров нет. Принтер отвечает длинной простышей байтов.

0xA0A8 - запрос какого-то статуса. Параметров нет. В коде возврата - явно битовые флаги.

0xA3A2 - что-то включает, меняет флаги в предыдущей команде. Параметров нет. Ответ всегда 0x0000.

0xE0A0 - проверка готовности. Если в ответе поднят бит 0x0008, то буфер принтера полон, надо ждать и не посылать больше данные.

0xA0A1 - проверка кучи вещей, в том числе наличия бумаги. Как оно работает на 2900 - не знаю.

0xA2A0 - загрузка первой магической последовательности. Параметр: магическая последовательность байтов.

0xE1A1 - загрузка второй магической последовательности.

0xE0A3, 0xE0A2, 0xE0A4 - что-то включают. Всегда идут в начале и в такой последовательности. Их отсутствие никак на печать не влияет(?). Возвращают 0, а при попытке вызвать повторно - 0x8800.

0xE0A5 - третья магическая последовательность.

0xD0A9 - загрузка магической последовательности, непосредственно предшествующая загрузке данных печати. Ответа на эту команду не дожидаются (?).

0xC0A0 - Главная Команда. Загружает в принтер сжатое изображение или его часть. Ответа принтера нет.

0xC0A4 - Конец Загрузки. Выдается сразу после 0xC0A0.

0xE0A7 - Включение Печати. Когда принтер подтвердит готовность после загрузки, выдают эту команду, и принтер начинает печатать. Параметр: 16-битное число 0x0001 (видимо, означающее «включить»).

Дополнительная информация - в исходниках драйвера http://www.boichat.ch/nicolas/capt/

Исходники того, что написал на данный момент, могу прислать.



Последнее исправление: cetjs2 (всего исправлений: 5)
Ответ на: комментарий от Artificial_Thought

Что-то я окончательно в ppd накосячил, теперь вообще не печатает из купса.

/bin/bash: /usr/local/bin/rastertocapt: Permission denied
$ ls /usr/local/bin/rastertocapt -lh
-rwxr-xr-x 1 root root 14K 2010-11-11 00:04 /usr/local/bin/rastertocapt

Artificial_Thought ★★★★
()
Ответ на: комментарий от Artificial_Thought

Входной растр подается уже порезанным на страницы - формат pbm так умеет, просто cat несколько файлов pbm вместе (или вывод gs это автоматом даст). Проблема в другом. Там в captmain.c есть цикл по страницам, он в конце вызывает printer_end_page() из print.c. Так вот, в printer_end_page надо добавить корректный поллинг состояния принтера и ожидание завершения печати страницы, а потом, кажется, еще какие-то команды подтверждения. Без этого работать не будет.

Yampp
() автор топика
Ответ на: комментарий от Yampp

> Чуть раньше в этом треде хайвейстар выкладывал то, что я нашёл по этой теме в январе.

Вроде бы это уже в коде реализовано. Похоже, надо снова за снифферы браться... Я, к сожалению, пока не могу этого сделать - винды нету, проприетарный драйвер не пашет в принципе (коркается).

Yampp
() автор топика
Ответ на: комментарий от Yampp

При попытке собрать в убунте 10.10 выдает следующее: root@DELL:~/svn# make deps hiscoa.c deps byteutil.c deps bitstream.c deps error.c deps captdrv.c deps captio.c deps captmagic.c deps print.c deps captmain.c captmain.c:11: fatal error: pam.h: Нет такого файла или каталога compilation terminated. deps captmain.c captmain.c:11: fatal error: pam.h: Нет такого файла или каталога compilation terminated. gcc captmain.c captmain.c:11: fatal error: pam.h: Нет такого файла или каталога compilation terminated. make: *** [captmain.o] Ошибка 1

BigL
()
Ответ на: комментарий от BigL

Достаточно сделать dh_make, после чего образуется директория debian. После этого проверить файл debian/rules и собрать пакет: fakeroot debian/rules binary.

Что касается этого драйвера, то он ставит ровно 1 файл в /usr/local/bin. Оформлять его в виде пакета пока рано - слишком сырой.

Yampp
() автор топика
Ответ на: комментарий от Yampp

Спасибо за совет. Вот что в итоге у меня получается: root@DELL:/usr/local/bin# ./rastertocapt DEBUG2: > a1 a1 04 00 DEBUG2: < a1 a1 40 00 00 0b DEBUG2: > a8 a0 04 00 DEBUG2: < a8 a0 3c 00 31 8e DEBUG: unexpected 8e31 != 8a31 DEBUG2: > a2 a3 04 00 DEBUG2: < a2 a3 06 00 00 00 DEBUG2: > a0 a2 0c 00 DEBUG2: +p 8 DEBUG2: < a0 a2 08 00 00 00 DEBUG2: > a1 e1 7a 00 DEBUG2: +p 118 DEBUG2: < a1 e1 06 00 00 00 DEBUG2: > a3 e0 04 00 DEBUG2: < a3 e0 06 00 00 00 DEBUG2: > a2 e0 04 00 DEBUG2: < a2 e0 06 00 00 00 DEBUG2: > a4 e0 04 00 DEBUG2: < a4 e0 06 00 00 00 DEBUG2: > a5 e0 14 00 DEBUG2: +p 16 DEBUG2: < a5 e0 06 00 00 00

Дальше ничего не происходит. Пробовал ставить testppd с ним принтер не хочет ничего печатать.

BigL
()
Ответ на: комментарий от BigL

То есть принтер подвисает после команды A5 E0 ? Важная информация, спасибо. Это какая модель принтера? Можете прислать *.usblog, снятые SnoopyPro в Windows в момент печати тестовой страницы?

Yampp
() автор топика
Ответ на: комментарий от Yampp

Вообще принтер ничего не распечатал и даже не шолохнулся. То что я запостил выше появилось в результате запуска под рутом того самого единственного файла :) А принтер Canon LBP3300. Если по подробнее объясните как все дело проделать в винде - помогу обязательно.

BigL
()
Ответ на: комментарий от BigL

По логу видно, что принтер завис даже до начала передачи данных печати. A5 E0 - одна из команд инициализации, причем неизвестного назначения - чего-то там грузит в принтер, и известно только, что без нее не работает.

Как анализировать в винде. Качаем SnoopyPro, там в меню нажимаем «unpack drivers» и «install service», в списке устройств (если списка не видно - жмем F2) выбираем принтер и «install» на него сниффер. Открываем новый снифф и печатаем что-нибудь, желательно документ из 2 страничек. (секретное не печатайте, лог будет в инете опубликован :) . Появится лог всякой двоички - его надо будет сохранить в *.usblog и прислать.

Yampp
() автор топика
Ответ на: комментарий от BigL

запакуй в tar и положи на omloader 2Yampp На моём LBP3000 некоторые документы, особенно в которыхе сть горизонтальные/вертикальные линии (таблицы например) не печататет полностью, режет одну четвёртую картинки снизу

Artificial_Thought ★★★★
()
Ответ на: комментарий от Artificial_Thought

На 2900 такой проблемы нет. Возможно, на 3000 надо отсылать данные меньшими порциями (if, строка 24 print.c).

Присылать можно на любой файлообменник, на почту agalakhov собака gmail com. Активным разработчикам даю доступ на SVN на запись (говорите логин sourceforge).

Yampp
() автор топика

логи снятые в винде при печати 2,3 и 4 страниц на LBP2900

http://rghost.ru/3226988

что видно сразу: страницы загружаются по одной, и после каждой следует команда 0xC0A4 - Конец Загрузки, после чего сразу же идет следующая страница

команда 0xE0A9 про которою я писал ранее, когда делал патч для нормальной печати несколько раз подряд, как казалось идет не после каждой страницы, а вовсе после всех страниц, с аргументом, равным числу напечатанных страниц, правда при печати двух страниц аргумент почему-то равен 1

HighwayStar ★★★★★
()
Ответ на: комментарий от HighwayStar

для печати каждой из страниц идет команда 0xE0A7 - Включение Печати с аргументом - номером страницы, для первой 1, для 2й 2 и тд.

при нормальном ходе событий принтер отвечает на эти команды кодом 0

HighwayStar ★★★★★
()
Ответ на: комментарий от HighwayStar

между командами печати 0xE0A7 идут долгие проверки статуса принтера командой 0xE0A0

судя по всему до тех пор, пока принтер не ответит что страница номер N напечатана, такие ответы выглядят так

    00000000: 00 00 0f 00 00 00 84 00 80 00 00 00 02 00 01 00
    00000010: 00 00 00 00 00 00 57 00 00 00 03 00 00 00 00 04
    00000020: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000030: 00 00
    00000000: 00 00 0f 00 00 00 84 00 80 00 00 00 03 00 02 00
    00000010: 01 00 01 00 00 00 57 00 00 00 03 00 00 00 00 04
    00000020: 03 00 00 00 00 00 03 00 00 00 01 00 00 00 00 00
    00000030: 00 00

приведены куски из лога печати 3-х страниц, в последовательности, в какой они записаны в логе

тут очевидно, последняя пара байт в первой строке показывает номер напечатанной страницы, а предпоследняя номер следующей(?). После начала печати последней страницы подобная проверка статуса больше не делается

HighwayStar ★★★★★
()
Ответ на: комментарий от Yampp

Посмотрел на сегфолт. Это внутри libpbm. Чем-то ей входной файл не нравится, а может тому, как я ее вызываю. В любом случае скоро эту часть кода выпилю совсем.

Yampp
() автор топика

LBP 3200

Касательно этого принтера. Могу отснифить всё, что пожелаете. Где-то тут был маунал, но я потерял его из вида. Лучше будет, если в первом сообщении отписать как снифить, каким ПО, какие данные подавать на вход (ссылки на файлы). Все необходимые отчёты вышлю на мыло.

anonymous
()