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/

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

НАУЧИ КОМПЬЮТЕР ВАРИТЬ КОФЕ

управление электрическими цепями с помощью компьютера
лучший подарок для техногика; только открытые программы
http://www.unicontrollers.com/products/unc01x

[#]  
wfrr

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

**# ()
[#]  

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

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

()
[#] Ответ на: комментарий от wfrr 10.05.2010 23:58:08  
Yampp

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

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

* ()
[#] Ответ на: комментарий от terminalem 10.05.2010 23:59:47  
Yampp

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

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

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

* ()
[#] Ответ на: комментарий от terminalem 11.05.2010 0:06:21  
Yampp

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

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

* ()
[#] Ответ на: комментарий от Yampp 11.05.2010 0:11:00  

В общем, утро вечера мудренее. Сейчас не могу разобраться.

Обязательно постараюсь помочь, так как неработающий принтер - единственное, что меня держит на windows.

()
[#] Ответ на: комментарий от terminalem 11.05.2010 0:39:24  
Yampp

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

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

* ()
[#] Ответ на: комментарий от Yampp 11.05.2010 11:58:18  

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

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

***** ()
[#] Ответ на: комментарий от dn2010 11.05.2010 12:08:53  
Yampp

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

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

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

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

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

* ()
[#] Ответ на: комментарий от dn2010 11.05.2010 17:51:45  
Yampp

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

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

* ()
[#]  
HighwayStar

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

www.linux.org.ru/forum/development/4424546

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

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

www.linux.org.ru/jump-message.jsp?msgid=4424546&cid=4431287

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

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

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

**** ()
[#] Ответ на: комментарий от dn2010 11.05.2010 17:49:35  
Yampp

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

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

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

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

* ()
[#] Ответ на: комментарий от HighwayStar 11.05.2010 17:59:26  
Yampp

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

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

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

* ()
[#]  
HighwayStar

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

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

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

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

**** ()
[#] Ответ на: комментарий от Yampp 11.05.2010 18:03:15  
Yampp

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

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

* ()
[#]  
HighwayStar

добавлю еще сюда мои исследования по поводу тога как запускать 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 11.05.2010 18:27:33  
HighwayStar

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

**** ()
[#] Ответ на: комментарий от Artificial_Thought 11.05.2010 18:50:09  
Yampp

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

* ()
[#] Ответ на: комментарий от Yampp 11.05.2010 0:04:29  
wfrr

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

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

**# ()
[#] Ответ на: комментарий от wfrr 11.05.2010 22:55:56  
kraftello

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

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

** ()
[#] Ответ на: комментарий от wfrr 11.05.2010 22:55:56  
Yampp

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

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

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

* ()
[#] Ответ на: вы поддерживаете производителя от kraftello 11.05.2010 23:09:01  
Yampp

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

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

* ()
[#] Ответ на: комментарий от Artificial_Thought 12.05.2010 15:28:34  
Yampp

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

* ()
[#] Ответ на: комментарий от Yampp 12.05.2010 16:05:40  
Yampp

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

* ()
[#]  
Mojo

Неделю назад устновил 2900 на Lucid все работает нормально, просто нужно скачивать драйвер не 1.6 и не 1.8 а самый последний 2.0

()