LINUX.ORG.RU
 
Yampp

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


0

5

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

Ищу единомышленников для 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/

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


[#] Ответ на: комментарий от Artificial_Thought 10.11.2010 21:53:26  

Что-то я окончательно в 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 10.11.2010 23:21:23  
Yampp

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

* ()
[#] Ответ на: комментарий от Yampp 10.11.2010 23:26:18  
Yampp

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

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

* ()
[#] Ответ на: комментарий от Yampp 10.11.2010 23:27:50  
BigL

При попытке собрать в убунте 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

()
[#] Ответ на: комментарий от HighwayStar 11.11.2010 10:13:41  
BigL

Смысл в том, что если я сделаю make install куда он все установит и как мне потом удалить если не будет работать? Может есть более правильное и элегантное решение?

()
[#] Ответ на: комментарий от BigL 11.11.2010 10:41:28  
Yampp

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

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

* ()
[#] Ответ на: комментарий от Yampp 11.11.2010 11:19:05  
BigL

Спасибо за совет. Вот что в итоге у меня получается: 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 11.11.2010 11:31:46  
Yampp

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

* ()
[#] Ответ на: комментарий от Yampp 11.11.2010 11:50:55  
BigL

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

()
[#] Ответ на: комментарий от BigL 11.11.2010 11:56:01  
Yampp

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

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

* ()
[#] Ответ на: комментарий от BigL 11.11.2010 12:18:22  

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

* ()
[#] Ответ на: комментарий от Artificial_Thought 11.11.2010 12:41:55  
Yampp

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

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

* ()
[#]  
HighwayStar

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

http://rghost.ru/3226988

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

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

**** ()
[#] Ответ на: комментарий от HighwayStar 12.11.2010 2:22:54  
HighwayStar

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

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

**** ()
[#] Ответ на: комментарий от HighwayStar 12.11.2010 2:55:41  
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-х страниц, в последовательности, в какой они записаны в логе

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

**** ()
[#] Ответ на: комментарий от Yampp 12.11.2010 21:33:21  
Yampp

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

* ()
[#] Ответ на: комментарий от Yampp 13.11.2010 21:02:28  
Yampp

В общем, там HighwayStar несколько неправильно проанализировал, а я не проверил. Протокол другим оказался. Теперь должно все работать.

* ()
[#]  

LBP 3200

./rastertocapt < test.pbm DEBUG2: > a1 a1 04 00 DEBUG2: < a1 a1 14 00 00 03 DEBUG2: > a8 a0 04 00 И тут виснет. Бумага находится в дополнительном отверстии для подачи.

anonymous ()
[#]  

LBP 3200

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

anonymous ()