LINUX.ORG.RU

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

 ,


17

19

Попытался запустить 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/

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


Предлагаю не возится с оборудованием, создятлы которого зажали спецификацию, а создавать этому оборудованию антирекламу.

wfrr ★★☆ ()

Очень хорошо, что про мой принтер даже здесь не забывают.

Похоже, большая часть работы уже проделана. Могу быть тестером. Помочь могу только этим, так как в написании драйверов не силен.

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

Я совершенно с этим согласен. Тем более, что оборудование дрянное - в LBP-2900 стоит оптика и часть механики, идентичная устаревшему HP LJ-1100, а электроника хуже (упрощен процессор).

Тем не менее, linuxprinting.org причисляет CAPT к наиболее востребованным для разработки драйверам - Canon явно не собирается отказываться от этого протокола и продолжает клепать на нем принтеры. Необходимость драйвера под 2900 у меня лично возникла потому, что из-за него не удается перевести на Linux работающий под Windows XP компьютер. Весь нужный софт есть, все работает - кроме принтера. Покупать новый принтер, разумеется, не хочется (хотя рассматриваю и этот вариант). Поэтому считаю, что Reverse Engineering сделать все же надо - хотя бы такой, чтобы принтер из состояния «кирпич» перешел в состояние «кое-как печатает». Это поможет миллионам пользователей.

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

Проделана большая работа, но не сделано главное. Неизвестен формат передачи изображений.

Вы можете помочь еще кое-чем. А именно, сбором данных для расшифровки протокола. Это просто, но нужна винда. Возьмите SnoopyPro или другой сниффер протокола USB. Возьмите Paint (именно Paint, чтобы печатал пиксел к пикселу - это важно). Нарисуйте картинку: черный пиксел в углу, остальное белое. Распечатайте, в сниффере найдите пакет, начинающися с «A0 C0» и запишите в файл его, а также все последующие пакеты вплоть до начинающегося с «A4 C0». На файле напишите, что это был один пиксел. Повторите то же самое с другими простыми картинками - два пиксела, три пиксела, ... 16 пикселов по горизонтали, потом по вертикали, потом квадратом - пока не надоест. Попробуйте более сложные рисунки - черный-белый-черный, например. Результаты выложите куда-нибудь в инет и дайте на них ссылку здесь. По этим данным я или кто-нибудь еще попытаемся расшифровать алгоритм сжатия картинок.

Если у вас не 2900, а другой CAPT-принтер, пришлите полный снифф. Интересно посмотреть, чем же принтеры отличаются.

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

> Я видел в нете руководство для установки его в ubuntu. Даже работало.

Это была инструкция по установке проприетарного (очень отстойного и закрытого) драйвера. Я с этого и начинал. Извините, драйвер ТАКОГО каКчества меня ну никак не устраивает.

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

Спасибо большое! Если любите разгадывать головоломки - можете попытаться и расшифровать пакеты. Там надо догадаться, какой бит за что отвечает. Но я не надеюсь, что кто-то справится с этим, поэтому рассчитываю только на «сырые» данные.

Расшифровка основана на том, что на картинке меняют чуть-чуть пикселы, а потом смотрят, какие биты изменились. Про принтер известно, что скорее всего у него ровно 1 бит на пиксел, но он как-то кодирует повторы.

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

>Про принтер известно, что скорее всего у него ровно 1 бит на пиксел, но он как-то кодирует повторы.

Выложите примеры пакетов и соответствующие им картинки, попробую посмотреть, что там за алгоритм.

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

> Выложите примеры пакетов и соответствующие им картинки, попробую посмотреть, что там за алгоритм.

Собственно я и прошу, чтобы мне помогли набрать подобные примеры. Это долго. При печати большого белого поля идет длинная периодическая последовательность байтов, не содержащая 0x00 - что-то около 16 байтов в периоде. Детальнее пока не исследовал.

У принтера LBP-810 была разновидность RLE.

А что на текущий момент происходит после 0xC0A0, если лить рандомные данные?

Я пробовал лить данные, пожатые алгоритмом от LBP-810 (прежде чем посмотрел повнимательнее и понял, что алгоритм другой). Как правило, печатается нечто (полосы шума, иногда тонкие вертикальные линии). От некоторых длинных принтер зависает (видимо, если в результате распаковки данные переполняют память видеогенератора).

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

ZjStream видел, спасибо. Не очень похоже «на глазок» - хотя вероятность, что это оно же, есть. Чанки zjs не просматриваются.

Достоверно известно из Service Manual, что расжатием упакованных данных в принтере занимается ASIC, заведующая USB-портом и играющая роль моста между процессором и памятью. Управляющий процессор расшифровывает команды CAPT, но расжатием не занимается.

Yampp ()

как все это знакомо

реверс-инжиниринг формата данных принтера lbp2900-3000

в районе нового года вместе с Artificial_Thought ковыряли этот принтер, тоже было расшифровано все кроме алгоритма сжатия

всем желающим помочь расшифровать алгоритм сжатия советую пройти по ссылке

реверс-инжиниринг формата данных принтера lbp2900-3000 (комментарий)

принтер для помощи совершенно не нужен, есть бинарник, который из ps файла делает код, который нужно послать в принтер для печати, он называется captfilter, по ссылке есть инструкции по использованию, бинарник есть в пакете с проприетарным драйвером

по теме готов протестировать любой код, в наличии принтер LBP2900

2ТС попробуй использовать captfilter и напиши инструкцию на своем сайте, если кто заинтересуется чтобы тоже мог поковырять его, в этом бинарнике код для всех кеноновских принтеров

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

> Попробуйте следующую картинку нарисовать и кинуть на печать:

Предлагаю хитрее.

00000000 00000000 01010101
01010101 00000000 00100100
00100100 00000000 00010001
00010001 00000000 10101010
10101010 00000000 11111111
11111111 00000000 11111111

Доберусь до принтера - сделаю. (Если раньше другие не сделают).

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

> есть бинарник, который из ps файла делает код, который нужно послать в принтер для печати, он называется captfilter

Вау, вот это новость. Вот спасибо-то. Странно, что тема не нагуглилась...

captfilter долбать - это совсем не то, что принтер :) Это в миллион раз легче. Это же методы криптоанализа применить можно!!! Как же я его проспал-то... Ведь искал в бинарном драйвере подобную штуку, специально искал - и проглядел... Балда я...

Yampp ()

чем могу поделиться из исследований алгоритма сжатия - смотрел частотные таблицы для разных документов закодированных в capt, так вот для небольшого квадрата примерно 6x6 в частотной таблице порядка 10 уникальных байт всего используется, а при усложнении документа уникальных байт становится гораздо больше, и при очень сложном документе - разнообразные линии в разные стороны - используются все 256 байт, примерно с одинаковой частотой

так же интересное чтиво есть вот тут

http://sourceforge.net/projects/splix/files/doc/1.0/specs-en.pdf/download

это спецификации языка Samsung Printer Language, различные источники говорят что capt это вариации на тему SPL,только немного «улучшенного»

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

> различные источники говорят что capt это вариации на тему SPL

Похоже, что CAPT - это набор команд принтера, а сжатие называется «SCoA» или «Hi-SCoA». То есть, ломаем мы SCoA.

Yampp ()

добавлю еще сюда мои исследования по поводу тога как запускать captfilter без принтера:

после подачи документа на печать, он преобразуется в ps стандартными методами cups, а затем в pgmraw командой

/usr/bin/gs -r600 -q -dNOPROMPT -dSAFER -sDEVICE=pgmraw -sOutputFile=-

что дает на стандартом выходе pgmraw файл. он то и кодируется посредством captfilter:

captfilter --CNTblHalftone=3 --CNTblModel=1 --PageSize=Letter --MediaType=PlainPaper --InputSlot=0 --Collate=False --Resolution=600 --CNTonerSaving=False --CNTblHalftone=30 --CNTblHalftone=31

при запуске вручную последние два аргумента вызывали segfault, их можно убрать

pgmwar файл подавать нужно на стандартный вход или как аргумент, результат забирать со стандартного вывода

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

в бинарнике генерируемом прогоном captfilter быйты от начала до 0x000000d0 это параметры страницы или что-то вроде того, отсылаемые принтеру до начала печати, а начиная с 0x000000d0 уже готовые данные закодированные чудопротоколом

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

Я знаю о существовании двух или трех. В большее число версий я не верю, поскольку разжатие осуществляет ASIC, который вряд ли разный в разных моделях, ибо разработка дорого стоит.

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

Необходимость драйвера под 2900 у меня лично возникла потому, что из-за него не удается перевести на Linux работающий под Windows XP компьютер. Весь нужный софт есть, все работает - кроме принтера. Покупать новый принтер, разумеется, не хочется

Аналогично, но принтер стоит чуть дороже комплекта фирменных катриджей, кроме того пользуясь сим говном вы поддерживаете производителя, а тем более разрабатывая для него драйвера.

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

вы поддерживаете производителя

Навряд ли. Кто столкнулся с кэноном хоть раз, создаст антирекламу. И отсоветует всем вокруг (аналогичная ситуация с lbp1120 на работе). Кстати, и под мастдайку дровишки у него кривые.

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

> а тем более разрабатывая для него драйвера.

А я и не хочу делать хороший драйвер. Драйвер будет уровня «кое-как работает - ну и ладно».

По поводу алгоритма сжатия: я осознал, что на самом деле полная расшифровка алгоритма не нужна. Достаточно будет научиться писать байты без сжатия - да, печатать будет медленно, но печатать будет. Сойдет. Если будет надо - кто-нибудь улучшит.

Yampp ()
Ответ на: вы поддерживаете производителя от kraftello

> Кстати, и под мастдайку дровишки у него кривые.

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

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

Для подавляющего большинства алгоритмов сжатия, подобных RLE и LZ, можно поступить как с «псевдо-GIF»: всегда записывать байт или бит как «ранее не встречавшийся, без повторов». Есть исключения, но они крайне редки.

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

Итак, что удалось выяснить.Существуют 4 типа принтеров и 2 алгоритма сжатия. (Переключаются параметром CNTblModel у captfilter). Тип 0 - это LBP-810, его алгоритм сжатия известен. Типы 1, 2 и 3 используют один и тот же алгоритм сжатия, но дают файлы разного размера; вероятно, это черно-белый, оттенки серого и цветной соответственно (хотя я этого не проверял).

Yampp ()