LINUX.ORG.RU

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

 ,


23

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)

Ответ на: комментарий от anonymous

Я еще раз повторяю, у меня принтер Canon LBP2900 работает в Линуксе так же хорошо как в Винде.

ВНИМАТЕЛЬНО ЧИТАЙТЕ ИНСТРУКЦИИ.

Сначала следуем инструкциям которые я указал в ссылке выше.

Доходим до пункта 10 и после него ОСТАНАВЛИВАЕМСЯ.

Далее идут НЕ правильные рекомендации.

«хочу работаю, хочу не работаю» происходит из-за того, что при перезагрузке Линукса автоматически НЕ загружается демон печати (ccpd-Daemon), его приходится загружать в ручную командой:

sudo /etc/init.d/ccpd start

Автор статьи ссылку которую я указал выше (и на которую официально направляют на официалном сайте убунты) для автоматической загрузки демона печати предлагает аж 2 способа, НИ ОДИН из которых не работает.

Способ 1. предлагает добавить строку:

# all users that may start ccpd as root user ALL=NOPASSWD: /etc/init.d/ccpd start

в файл /etc/sudoers ЭТО НЕ РАБОТАЕТ!

Способ 2. Далее он предлагает добавить две строки в автозапуск (Система->Параметры->Запускаемые приложения):

sudo /etc/init.d/ccpd start

sh -c «sleep 30; /usr/bin/captstatusui -P LBP2900»

ЭТО НЕ РАБОТАЕТ !

Решение проблемы как я уже говорил находится в документации к драйверу. Перед выполнением всех инструкций в документации драйвера, нужно прочитать НА ГЛАВНОЙ СТРАНИЦЕ ВСЕЙ ДОКУМЕНТАЦИИ (Introduction->Canon CAPT Printer Driver for Linux) фразу:

NOTE Before installing the printer driver, please be sure to read the following files supplied with the printer driver. File names vary according to the printer driver version you are using. LICENSE-captdrv-x.xxE.txt: User License Agreement. README-capt-x.xxE.txt: Readme file with notes and warnings concerning using the printer driver, as well as supplementary information. For detailed information about printer settings, refer to the manual supplied with the printer.

ТУТ ЖЕ ВСЕ ПОНЯТНО СКАЗАННО, перед установкой драйвера принтера, пожалуйта прочитайте следующий файлы поставляемый с драйвером принтера. LICENSE-captdrv-x.xxE.txt: User License Agreement. - дерьмо можно не читать, а вот этот файл и есть ключ к решению: README-capt-x.xxE.txt

В этом файле есть абзац:

4. Auto startup setting procedure for ccpd daemon ------------------------------- When setting the Status Monitor to start automatically, ccpd daemon must be set to start automatically as well. Set ccpd daemon to start automatically in the following procedure.

<For a distribution with a /etc/rc.local file> Log in as 'root' and add the '/etc/init.d/ccpd start' command to the /etc/rc.local file.

Ubuntu это и есть дистрибутив с файлом /etc/rc.local я запустил этот файл (sudo gedit /etc/rc.local ) и как и написанно в инструкции добавил строку /etc/init.d/ccpd start выше строки exit 0

И ВСЕ, теперь демон печати не нужно запускать в ручную, при запуске Линукса он запускается автоматически.

Не нужно добавлять строки «Запускаемые приложения», не нужно корячиться с файлом /etc/sudoers.

ВСЕ ОТЛИЧНО РАБОТАЕТ.

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

Лучше расскажи, как добиться логов от ccpd. Указание в /etc/ccpd.conf не помогает.
Как раз проблемы запустить его нет, но вот бывает он просто не работает без всякой возможности диагностики причины.

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

>хочу работаю, хочу не работаю" происходит из-за того, что при перезагрузке Линукса автоматически НЕ загружается демон печати (ccpd-Daemon), его приходится загружать в ручную командой

у меня он загружается автоматически, но это не мешает ему не работать

это проприетарное говно почему-то не может определить включен ли в данный момент принтер, и при его отключенее один из процессов ccpd начинает жрать 100CPU, включение принтера не помогает. помогает лишь убивание всех относящихся к «драйверу» процессов и запуск всего заново

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

> Инстукция по установке:

Я прошу БОЛЬШЕ НЕ ПРЕДЛАГАТЬ установку проприетарных дров. В частности, я хочу установить драйвер принтера на плату с процессором ARM S3C2440. Не объясните ли вы, где взять драйвер под ARM?

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

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

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

УРА! Сжал большой рандомный битмэп, сжал его же инвертированный, результаты поксорил. Получил важные результаты!

XOR от начала таких данных выглядит так:

00001111 11110000 11111111 00001111 11110000 11111111 и т.д.

То есть, четыре бита совпадают, 8 разных, 4 совпадают, 8 разных. Связи между битами и исходным файлом пока не увидел.

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

Более того, сжатые рандомные данные выглядят так:

1001xxxx xxxx1110 xxxxxxxx 1001xxxx xxxx1110 xxxxxxxx

На входе подавалось: DD 8E B6 AF... На выходе получилось: *A 2* 2F *9 B* DE *2 6* 92 *1...

Связи пока не вижу.

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

Расшифровка удалась. Все данные XOR 0x43, и под этим XOR упаковка по байтам/тетрадам. Тетрада D означает, что далее следует неупакованный байт. Остальные означают повтор.

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

Итак, более полное описание - то, что понял пока что.

Поток битовый. Поксорен на 0x43. Дальнейшее описание относится к данным под XOR. Биты читаются слева направо, как на экране - от старшего бита к младшему, по порядку байтов в потоке.

1101: далее следуют 8 бит картинки 101111: повторить последний байт 1110-01-1: повторить последний байт 2 раза 1110-01-0: три раза Далее следует достаточно очевидный код Левенштейна 2-го порядка: 1110-10-11: четыре 1110-10-10: пять 1110-10-01: шесть 1110-10-00: семь 1110-110-111: восемь 1110-110-110: девять ... 1110-110-000 1110-1110-1111 .... 1110-1110-0000 1110-11110-11111 ... 1110-11110-00000 1110-111110-111111 ... 1110-111110-000000: 127 раз После 127 начинается уже другой код.

Это то ли RLE, то ли LZ77, частный случай которого похож на RLE. Разбираюсь дальше.

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

Расшифровал до 256. Повтор 128 байт обозначается 1111110000 , после чего используются несколько странные коды:

1110-111111 - NOP (ничего не повторять)
1110-00 - повторить еще 1 раз
1110-01-1 - еще 2 раза
Далее код тот же самый, по 1110-111110-000000 включительно.

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

Удалось расшифровать значительное количество кодов. Слишком много, чтобы писать сюда. Есть некоторые неясности с кодированием повторов строк. Желающим помочь в расшифровке пришлю свои рабочие файлы.

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

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

в закодированном виде закодированные данные сразу идут, если в исходном рисунке они в начале самой верхней строчки?

может на sourceforge или pastebin зальешь, и может в жабере в конфе обсудить соображения?

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

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

На sourceforge в проекте foo2capt есть файлик notes.txt - это результаты расшифровки. В SVN.

В который жаббер идти?

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

Не скажите, уважаемый. Струйники с раздельными чернилницами у них очень даже ничего — подержал отмену пять секунд и он уже печатает «кончившейся» чернильницей, несмотря на то что она чипованая и есть оптический сенсор наличия чернил.

Разумеется покупать лазерный Canon это простите ССЗБ. Лазерные принтеры бывают только Xerox.

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

Информации о протоколе принтера накоплено достаточно для получения работающего прототипа драйвера. Прототип будет написан в эти или в следующие выходные. Ожидается поддержка LBP-2900 и, возможно, некоторых других подобных USB-принтеров Canon.

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

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

Удалось напечатать первый тест. Однако не удается напечатать изображение выше одной полоски в 104 пикселя, а при попытке печати более двух полос принтер зависает. Также принтер требует перезагрузки после печати каждого листа. Исходники доступны в SVN.

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

> вечером попробую собрать и что-то напечатать

Там в главном файле (foo2capt.c) находятся циклы по строкам, пикселам и ограничитель по полоскам (band). Судя по всему, после каждых 104 (?) строк в поток надо вставлять какую-то фигню, которая разделяет полоски. Иначе принтер печатает только первую полоску, а потом может зависнуть. Но надо сказать, ПЕРВУЮ полоску печатает он правильно :)

И еще я что-то делаю не так на уровне команд CAPT, потому что после печати первой страницы принтер надо выключить и снова включить.

Если при сборке попросит программу grc, надо просто убрать COLORIZER из Makefile. Для сборки нужна библиотека netpbm.

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

собрла, потестировал.

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

> a1 a1 04 00 < a1 a1 38 00 00 0b < 31 2a 01 01 f0 ff 40 00 04 00 41 00 01 00 d0 02 00 00 6f 08 00 00 e4 0d 00 00 00 00 00 00 fa 02 00 00 f6 04 00 00 28 3c 32 32 58 02 58 02 15 03 02 00

a2 a3 04 00

< a2 a3 06 00 00 00

a0 a2 0c 00

< a0 a2 08 00 00 00 < 02 00

a1 e1 7a 00

< a1 e1 06 00 90 00

a5 e0 14 00

< a5 e0 06 00 00 00 Ошибка сегментирования

сейчас попробую выттащить те последовательности что получались у меня в дампах и подстваить

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

форматирование


./foo2capt < test.pbm 
> a1 a1 04 00
< a1 a1 38 00 00 0b
< 31 2a 01 01 f0 ff 40 00 04 00 41 00 01 00 d0 02 00 00 6f 08 00 00 e4 0d 00 00 00 00 00 00 fa 02 00 00 f6 04 00 00 28 3c 32 32 58 02 58 02 15 03 02 00
> a2 a3 04 00
< a2 a3 06 00 00 00
> a0 a2 0c 00
< a0 a2 08 00 00 00
< 02 00
> a1 e1 7a 00
< a1 e1 06 00 90 00
> a5 e0 14 00
< a5 e0 06 00 00 00
Ошибка сегментирования
HighwayStar ★★★★★
()
Ответ на: комментарий от Yampp

у меня банально зависает

./foo2capt <~/a.pbm
> a1 a1 04 00
< a1 a1 38 00 00 0b
< 30 2a 01 01 f0 ff 40 00 04 00 40 00 01 00 48 03 00 00 6f 08 00 00 e4 0d 00 00 00 00 00 00 fa 02 00 00 f6 04 00 00 28 3c 32 32 58 02 58 02 15 03 02 00
> a2 a3 04 00
< a2 a3 06 00 00 00
> a0 a2 0c 00
< a0 a2 08 00 00 00
< 01 00
> a1 e1 66 00
< a1 e1 06 00 90 00
> a5 e0 14 00
< a5 e0 06 00 00 00
> a9 d0 44 00
band size = 8168
> a0 c0 ec 1f
^C
принтер — LBP3000

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

при сегфолте получается следующий бактрейс

#0  0xb7fae769 in pnm_readpaminit () from /usr/lib/libnetpbm.so.10
#1  0x08048adc in pnm_allocpamrow ()
#2  0xb7e55440 in ?? () from /lib/libc.so.6
#3  0xb7d0face in __libc_start_main () from /lib/libc.so.6
#4  0x08048991 in pnm_allocpamrow ()

видимо у меня неправильный файл pbm, как его правильно заготовить?

я сейчас просто в гипме создал файл 4958x7017 и сохранил как pbm

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

И еще я что-то делаю не так на уровне команд CAPT, потому что после печати первой страницы принтер надо выключить и снова включить.

надо по идее как-то составить список всех встречающихся команд capt и записать назначение тех что известны, а остальные потом разьирать опытным путем

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

HighwayStar ★★★★★
()

запишу еще сюда найденное в логах linux-talks за январь чтобы не потерять:

[10:42:11] <Artificial Thought> > 00000000: a0 e0 04 00
< 00000000: a0 e0 0c 00 10 88
< 00000000: 00 00 0f 00 00 00
[10:42:23] <Artificial Thought> highwaystar, запиши, что ожидание бумаги выглядит так
...

[10:44:20] <Artificial Thought> а
> a0 e0 04 00
< 00000000: a0 e0 0c 00 10 8b
< 00000000: 00 00 0f 00 00 00
[10:44:29] <Artificial Thought> это когда кнопку нажал
HighwayStar ★★★★★
()
Ответ на: комментарий от HighwayStar

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

0xa9 0xe0 0x06 0x00 0x02 0x00

и тут же каким-то образом задается номер текущей страницы или что-то в этом роде.

фрагмент логов l-t за 9 января:

[08:53:36] <highwaystar> ога, печатетает только один раз
[08:53:40] <highwaystar> второй раз не хочет
[08:53:43] <highwaystar> завис
[08:53:50] <highwaystar> и не отвечает судя по выводу программки
[08:54:05] <Artificial Thought> значит \xa9\xe0\x06\x00\x02\x00 сбрасывает принтер

....

[08:57:11] <highwaystar> точно с xa9\xe0\x06\x00\x02\x00 печатет потом сколкьо угодно
[08:58:02] <highwaystar> кстати да \xa9\xe0\x06\x00\x02\x00 вроде по одному разу во всех лога
[08:58:09] <highwaystar> надо и все обрезать до него
[08:59:10] <highwaystar> Artificial Thought: там кстати помоему чем адальше печатешь тем код сбрса другой
[08:59:17] <highwaystar> у меня в логах идет \xa9\xe0\x06\x00\x02\x00
[08:59:22] <highwaystar> потом \xa9\xe0\x06\x00\x03\x00
[08:59:28] <highwaystar> в следующем уже \xa9\xe0\x06\x00\x04\x00
[08:59:40] <Artificial Thought> инкрементится
[08:59:43] <highwaystar> потом 5
[08:59:56] <highwaystar> наверное для ачала можно нулем сбрасыаать
[09:00:14] <highwaystar> может это нужно для того чтобы он знал сколько уже страниц отпечатал

HighwayStar ★★★★★
()

Интересно, что-нибудь получилось? Если получится, то напишете главной а релизе драйверов. Хотя у меня нет данного принтера, но всё же интересно: удастся ЛОРовцам раскусить или нет, да и многим людям может пригодится.

Root-msk ★★★★★
()
Ответ на: комментарий от lem8r

captfiler без исходников, но есть исходники на pstocapt, pstocapt2, pstocapt3. вы их смотрели?

там нет ничего интересного, эти три файла нужны для передачи задания из купса в ccpd

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

> Кто столкнулся с кэноном хоть раз, создаст антирекламу. И отсоветует всем вокруг

А вот мне Canon'ы (недорогие струйники) нравятся... И если честно, я не понимаю Вашей ненависти. М.б. Вам стоит попробовать Epson, дабы понять, что Canon не так уж и плох

bellato
()

re re re

В программировании я полный и когда прочел этот пост аж запекло у нутрях 2 года уже вынужден просить сына отпечатать любую бумаженцию в винде.
Надеюсь и жду т.к. в видююю я ни ногой!

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

А я, что дебоширил? Или те хочется хоть что-нибудь сказать? Как говорят в братской Украине «Або нэ мовчакы» то бишь «Лишь бы не молчать»?

Правильно «абы нэ мовчкы». :)

nanoo_linux
()