Я - автор двух пакетов, входящих более-менее во все дистрибутивы Linux: sane-airscan и ipp-usb.

Кроме того, sane-airscan входит во все основные дистрибутивы BSD (FreeBSD, NetBSD и OpenBSD) и в ChromeOS. ipp-usb в ChromeOS не взяли потому, что он написан на Go, а у них там очень жестко с размером исполняемых файлов, вместо этого они написали свое на Rust, но предпочли бы взять моё изделие, если бы могли. Совсем недавно появился порт ipp-usb на FreeBSD, вероятно, другие BSD тоже скоро подтянутся.

Вместе эти два пакета образуют стек "бездрайверного" сканирования документов для Linux и *BSD, а в перспективе нескольких лет, когда старые сканеры, наконец, вымрут, вероятно других драйверов и не останется.

Кроме того, ipp-usb делает возможным "бездрайверную" печать на USB-устройствах.

Здесь я хочу рассказать, каково оно, быть автором популярных OpenSource пакетов. Хоть эта работа и не принесла мне особых денег (на что я, впрочем, особо и не рассчитывал), она принесла мне бесценный опыт.

В целом, я полагаю, продвижение OpenSource пакетов структурно близко к продвижению на рынок программных продуктов. Занимаясь этой деятельностью, очень хорошо начинаешь понимать разницу между (1) написать программу, которая работает для меня (2) написать программу, которую можно назвать продуктом (3) вывести продукт на рынок.

Первое занимает гораздо меньше времени, чем второе. Второе - гораздо меньше времени, чем третье.

Как все началось

Началось все довольно банально: я купил себе многофункциональный принтер со сканером, который под Linux не сканировал.

Немного осмотревшись, я узнал, что протокол моего сканера называется eSCL, что спецификация его не опубликована, но существует reverse engineering этого протокола, в целом протокол не сложный, и даже существует скрипт на Питоне, который, впрочем, с моим устройством не слишком-то работал.

Сам по себе протокол состоит из поиска устройства с помощью DNS-SD (оно же MDNS, Randezvois, Bonjour - этому протоколу повезло иметь много названий) и общения с устройством посредством сочетания HTTP с незамысловатым XML внутри.

Я посмотрел на то, что такое драйвер SANE и подумал, "тыжпрограммист", почему бы не попробовать написать драйвер самому. Задача, к тому же, выглядела совсем не сложной.

Ну и сел писать. Начиная, как положено, с системы сборки, логов, общей инфраструктуры драйвера, парсера файла конфигурации и т.п. А не с того, чтобы быстренько написать пару запросов на libcurl, а потом как-нибудь довести это до состояния, напоминающего драйвер SANE. Я ж профессиональный программист, в конце концов, а не студент 3-го курса :)

От использования libcurl, кстати, пришлось быстро отказаться. Драйвер SANE, по природе своей, это shared object, DLL-ка, которая работает в контексте приложения. Любого приложения. Например, такого большого и сложного, как Libre Office. А libcurl имеет статическое состояние, которое надо инициализировать явным запросом перед использованием и делать наоборот после. И если в контексте приложения окажется две DLL-ки, использующие libcurl, то они запросто могут подраться между собой.

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

Студентов, тем временем, взяли в проект SANE, куда я планировал попасть изначально. Очень уж в проекте SANE не хватало драйвера eSCL. А мне пришлось пробиваться.

Что такое "бездрайверное" сканирование и печать

Тут следует немного объяснить, что такое "бездрайверное" сканирование и печать (driverless), и что такое драйвер бездрайверного сканера.

Если кто помнит, раньше все принтеры были разные. И каждому требовался свой драйвер. Драйвера, естественно, были только для Windows, а пользователям других операционных систем приходилось тщательно выбирать устройство, которое будет работать под их операционной системой.

Microsoft, по-видимому, устраивала возня с вендорами аппаратуры и их драйверами, а вот фирме Apple это в какой-то момент надоело. И Apple встал в положение: принтеры с поддержкой IPP работают на маке из коробки, а для всех прочих производители вольны поставлять драйвера, если хотят, а мы тут не при чем. Если учесть избалованность пользователей мака тем, что все работает "само", их многочисленность к моменту, когда это произошло и их платежеспособность, не удивительно, что эта технология победила. И теперь более-менее все принтеры худо-бедно поддерживают IPP.

Это называется "бездрайверная" печать - в том смысле, что не драйвер подстраивается под устройство, а устройство подстраивается под драйвер, который реализует один, универсальный, протокол.

Потом Apple то же самое проделали со сканерами. По-ихнему это называется Bonjour Scanning, который является частью неопубликованного Bonjour Printing 1.4 (выдается только под NDA, мне не дали, но я особо и не просил), неофициально называется Apple Airscan (по аналогии с Airprint - более ранним названием Bonjour Printing) в более узких кругах известно под названием eSCL. Автором самого протокола, по-видимому, является HP, но это не точно.

Сейчас еще не все сканеры поддерживают eSCL, но дело туда явно идет.

Поскольку HTTP подразумевает сеть, а бывают устройства без сети, а только с USB, то с этим тоже надо что-то делать. В результате организация, занимающая стандартизацией USB, изобрела протокол под названием IPP over USB, который вернее надо было назвать HTTP over USB, потому что он этим и является: прям в USB endpoint отправляется HTTP-запрос, а на него обратно приходит HTTP-ответ, и так работает все HTTP-ное: печать, через IPP, который пользуется HTTP-транспортом, сканирование, через eSCL и даже веб-консоль принтера через него тоже удивительным образом работает.

И там все тоже не совсем просто, потому, что HTTP, в общем-то, рассчитан на TCP. А TCP-соединение можно в любой момент закрыть, и сервер все поймет правильно, что клиент не заинтересован в продолжении запроса. А в USB никакой индикации того, что клиент отвалился, не предусмотрено, поэтому если уж клиент начал посылать запрос, то запрос надо дослать до конца и вычитать ответ. Иначе кусок недопосланного запроса или кусок недополученного ответа застрянет в USB-буферах, и синхронизация между хостом и устройством будет потеряна. И ее не так-то просто потом восстановить. На USB-reset, например, разные устройства реагируют по-разному...

Продолжение истории про sane-airscan

И вот в какой-то момент мой драйвер дошел до состояния, когда его было не стыдно показать людям (я из тех людей, кто не любит показывать или анонсировать недоделанную работу).

Ну и я, весь такой наивный, зафайлил в sane-backends багу #202 с предложением sane-escl выкинуть, а вместо него вставить моё изделие.

Что тут началось...

Главный мейнтейнер проекта SANE спросил ребят, которые написали sane-escl, что они думают о моем поделии. Ну они понятно что сказали, что думают (у них, к тому же, тестовая база была из десятка разных устройств, а у меня из одного. Ну и они нашли, конечно, в своей тестовой базе несовместимые устройства, и только о них и написали). В итоге случилась война за рынок сбыта, результатом которой явилось следующее:

  1. sane-airscan не вошел в дистрибутив SANE. Сначала не брали, я потом я уж и сам не захотел

  2. в sane-airscan появилась поддержка еще одного "бездрайверного" протокола, WSD от Microsoft.

  3. sane-airscan вошел во все дистрибутивы Linux

  4. sane-escl входит в состав SANE, но в большинстве дистрибутивов запрещен

Эх, был бы я политиком потоньше, предложил бы не заменить одно на другое, а положить вместе. Глядишь бы, WSD писать не пришлось :)

В конечном итоге, то, что мой проект существует отдельно от SANE для меня хорошо. И цикл релизов у меня свой, как мне удобно, и вся слава достается мне :)

Последствием неудачной попытки войти в состав SANE стало то, что sane-airscan вышел под SANE-овской лицензией (GPL с исключениями, фактически - LGPL). Я не люблю эту лицензию, считаю ее слишком жадной, и если бы не оглядывался на SANE, использовал бы 2-clause BSD.

Пользователи, правда, выиграли. Как потом выяснилось, примерно 1/3 устройств, на которые я получил ответ от пользователей (а у меня нет своей тестовой базы, вся отладка по переписке) поддерживают только WSD, но не eSCL

Сколько у меня в итоге пользователей? Я не знаю. В списке сейчас 170 устройств. За каждым стоит какая-то история. По большей части люди приходят сказать, что у них какая-то проблема. Многие проблемы разрешались без моего участия, мне только сообщали, что очередное устройство заработало. Некоторые пользователи приходили просто поблагодарить. Кое-кто даже присылал PR со своим устройством, добавленным в список - я никогда не отказывал им в merge.

Думаю, что количество пользователей, которые просто молча пользуются, не подозревая о моем существовании, измеряется тысячами. Возможно, десятками тысяч. Как это узнать, мне неизвестно.

Продвижение

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

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

Для этого в природе существует openSUSE Build Service, который, на удивление, умеет собирать пакеты под кучу дистрибутивов, а не только под SUSE. Но разобраться в нем нелегко, документация у него довольно своеобразная. Но зато потом все работает, и не надо учить пользователей собирать программы.

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

Первым дистрибутивом, который принял мой драйвер в свой состав, был Arch. Потом подтянулись Ubuntu, Debian и Fedora. Потом оно пошло как-то само.

Российские дистрибутивы (Alt и Astra) подтянулись очень поздно, с большой задержкой по сравнению с их западными коллегами. За другими я не следил и не в курсе, что там делается.

Интересно, что в Ubuntu новые пакеты попадают через Debian. Они там активно взаимодействуют между собой, и Ubuntu очень предпочитает основываться на Debian-овской кодовой базе. Минуя Debian, пакет попадет в Ubuntu только в том случае, если Убунте очень хочется этот пакет у себя иметь, а Дебиану почему-то очень не хочется.

Интересна так же разница в подходах. Debian/Ubuntu сделали очень дотошный code review глазами, Fedora прогнали через статический анализатор. Остальные дистрибутивы не заморачивались, и брали, как есть.

Так же стоит отметить, что такой контроль есть только при первоначальном включении пакета в дистрибутив. Потом мои патчи никто уже особо и не смотрел - разве что из любопытства.

Отладка по переписке

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

При этом следует отметить, что идея писать в логи вообще всё подряд, иногда по пять раз одно и то же (потому, что на разных уровнях), она такая себе. Такие логи очень трудно читать, они сбивают с толку избытком ненужных подробностей.

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

Сам по себе многолетний опыт отладки по логам, а не отладчиком, приводит к формированию особого стиля организации кода. Стараешься основные сюжетные линии развивать, по возможности, просто и прямолинейно. Иначе потом очень сложно разобраться. Я считаю, что это существенно улучшает и структурирует код.

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

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

В итоге было принято решение параллельно .log-файлу писать еще и .tar-файл, складывая туда полученные изображения и ответы, которые мне не удалось расшифровать. У .tar-а очень простой формат, и генерировать его прямо из программы совсем несложно. Фактически, .tar - это последовательность файлов, в которой на каждый файл пишется несложный заголовок, а потом идет тело файла.

С какими проблемами приходилось иметь дело

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

Устройства enterprise класса ничуть не менее глючны, чем бюджетные устройства потребительского сектора. Более того, они еще умеют засыпать и по полминуты просыпаться, ведя себя в полусонном состоянии странным образом, и это приходится учитывать.

Некоторые устройства от HP хотят зачем-то, чтобы в HTTP-запросе, в поле Host: было написано localhost. А иначе не работают. Что это, наивная защита от доступа из сети? Непонятно. Как я догадался, что они этого хотят? Не знаю, интуиция сработала. Но как-то вот догадался.

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

Благодаря этому в моем драйвере корректно работает cancel.

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

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

Недавно мне попалось устройство, которое анонсировало поддержку PNG, но фактически присылало JPG. Пришлось сделать автодетект формата по сигнатуре файла.

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

Поддержка WSD

Я долго колебался, стоит ли с этим связываться. Но хотелось иметь неоспоримое конкурентное преимущество перед sane-escl

Microsoft, как известно, это своя особая вселенная, наполненная своими звездами и планетами, на них проживает свое особое человечество. И все сетевые протоколы у них тоже свои.

Идея бездрайверной печати и сканирования не прошла мимо них, но сделали они все по-своему.

Это называется, WSD. Web Services for Devices. WS-Print и WS-Scan. При чем тут Web, не вполне понятно, никто не собирается свой родной принтер в Интернет выставлять, он там долго не проживет. Но Microsoft, зачем-то, провели WSD как стандарты W3C. Причем есть два диалекта: один, который описан на MSDN-е, а другой - в W3C-ных стандартах. Они как бы одинаковые, но URL-и, которые обозначают XML-ные namespaces - разные. Мой принтер понимает оба варианта, другие не проверял. Но реализовывать, разумеется, лучше тот вариант, который в Windows. Понятно, что производители принтеров ни с каким другим никогда не тестировали свои изделия.

WSD - это целый собственный мир. У них даже поиск устройств в сети не на основе DNS-SD, а свой собственный. На основе XML-ек, которые рассылаются UDP-мультикастами.

И в отличии от DNS-SD, готовой такой службы в Linux не было, пришлось ее самому, прям в драйвере, написать.

В конечном итоге, как выяснилось, примерно 1/3 устройств, которые понимают WSD, при этом не понимают eSCL. Так что оно того стоило, многим людям я открыл в Linux поддержку для их устройств. Хотя в более долгой перспективе, WSD, вероятно, умирающий протокол. Для печати он никогда особо и не использовался, потому что был IPP, для сканирования в Windows 11, говорят, наконец добавили eSCL-клиента. Так что у производителей оборудования особой мотивации поддерживать WSD вроде как не осталось. Ну может разве только на каком-то очень крутом enterprise-рынке, ориентированном на экосистему Microsoft...

Device discovery

Про это стоит сказать еще пару слов.

Представьте себе, ваше устройство поддерживает IPv4 и IPv6, HTTP и HTTPS, eSCL и WSD. Да еще и подключено по WiFi и проводами. В результате, вы найдете его в сети... 16 раз, во всех возможных сочетаниях.

Вываливать всё найденное на голову бедному пользователю - пусть студенты так делают. Это не наш метод.

В результате, примерно 1/4 кодовой базы sane-airscan - это сведение вместе всех вариантов, в каком виде может быть найдено одно и то же устройство. Тот факт, что DNS-SD и WSD пользуются совершенно разными пространствами имен, совсем не упрощает этой задачи.

Кроме того, DNS-SD, фактически, читает список уже найденных устройств из кеша демона Avahi. А вот WS-Discovery приходится все делать самому, на старте драйвера. И чтобы все это работало надежно, недостаточно один раз послать мультикастный запрос, немного подождать ответов и на этом успокоиться. Приходится сканировать несколько секунд - я рискнул поставить это время в 2.5 секунды. Но даже это слишком долго.

Поэтому пришлось изобрести хитрый алгоритм: если все устройства, которые найдены, как IPP-принтеры (по DNS-SD) откликнулись или как WSD-устройства, или как eSCL-сканеры, дальше можно поиск не продолжать. Я рассчитываю на то, что чистых сетевых сканеров, без принтерской части, в природе встречается мало, а сканеры, объединенные с принтерами, откликаются на протокол IPP, потому, что он все же основной для печати. В большинстве случаев этот алгоритм существенно сокращает время поиска. Теоретически, в некоторых случаях он может находить устройство нестабильно, и для борьбы с этим его можно выключить через настройки драйвера, перейдя на прямолинейное полное сканирование. Но никто пока не жаловался...

ipp-usb

Изначально я не собирался его писать. Более того, я даже не подозревал о существовании такого протокола.

Первым человеком, который написал bug report на sane-airscan был Till Kamppeter - человек, который отвечает за систему печати в Linux вообще и в Ubuntu в частности.

Till - потрясающий совершенно инженер, работать с ним одно удовольствие. При удаленной отладке он с полуслова понимает, чего я от него жду, и делает ровно то, что надо - как если бы я сам сидел с другого конца, только лучше. Очень и очень редко выпадает удовольствие поработать с таким человеком.

Принтер, которым он располагал, был тоже совершенно потрясающим. Недорогой какой-то HP, в котором были реализованы все интересные протоколы. Кажется, это замечательное устройство собрало в себе если не все, то уж по крайней мере 90% багов прошивок. Если что-то работало на принтере Till-а, ну, я был почти уверен, что оно и на других устройствах заработает.

В какой-то момент Till спросил, а почему sane-escl работает на его принтере через USB, а мой драйвер - нет.

Собственно, ipp-usb был ответом на вопрос. До него в Linux был ippusbxd - демон, который просто принимал TCP-соединения и релеил их в USB. Я не собирался туда лезть, но вот пришлось.

У меня тогда не было IPP over USB устройства (вернее, не было кабеля, который втыкается в принтер. Они там не такие, как все, а с квадратным разъемом). Поэтому отлаживаться пришлось с Till-ом по переписке.

Выглядело так, словно иногда ответ на HTTP-запрос приходил в обрезанном виде. Сначала я подумал, ippusbxd глючит. Все-таки, он многопоточный, по потоку на TCP-соединение, и написан очень по-простому. Мог бы и запутаться среди своих потоков. Внимательно его вычитал всего. Ну нет явных ошибок, хоть ты тресни.

Потом меня осенило, что возможно, кусок предыдущего ответа остается в буфере самого USB. И что возможно это происходит потому, что sane-airscan в некоторых случаях не заморачивался дочитывать ответ до конца, а просто бросал соединение, когда ему уже все было понятно.

Я быстренько, буквально за несколько часов, написал на Go и отладил с Till-овской помощью прототип HTTP-to-USB proxy, который всегда доводил HTTP-транзакцию до конца, если уж начал, независимо от заинтересованности клиента в продолжении.

И все прям заработало: sane-airscan, печать, веб-консоль, которая через ippusbxd вообще никогда не работала и никто не знал, почему.

А вот чтобы этот работающий прототип превратился в подобие продукта, ушел месяц. За это время мне пришлось:

  • сделать анонс устройства через DNS-SD. Для этого пришлось научиться извлекать параметры устройства через IPP для принтерной части и через eSCL для сканерной части. А для этого пришлось написать клиентскую библиотеку IPP, потому что готовой работающей для Go, к моему удивлению, не нашлось, а которая была, падала в панику, а чтобы ее починить, надо было разобраться в протоколе, а в протоколе разобраться было проще всего, написав свою реализацию, которая не падает в панику, а раз уж я ее написал (что заняло, впрочем, два дня всего), то уже имеющуюся чинить не захотелось

  • отказаться от http.Client, потому что он в Go, в основном, автоматический менеджер HTTP-соединений, а мне в этом месте совершенно не хотелось никакого автоматизма, а хотелось иметь полный контроль над происходящим

  • отказаться от готового Go-ной обертки над libusb и приладиться к libusb напрямую через cgo, потому, что появились какие-то другие глючные устройства, и хотелось быть к железу поближе, чтобы сподручнее было с ними разбираться

  • сделать логи с авторотацией

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

  • сделать запуск демоном из systemd и без

  • написать man-page

И вот когда все это было сделано, из работающего прототипа получился продукт, и это заняло месяц (вспомним, что прототип был написан за несколько часов). А вот чтобы уже вполне работающий и оформленный продукт попал в основные дистрибутивы, прошло еще несколько месяцев, порядка года - это при том, что Till мне изрядно помогал в организационном плане.

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

С Google на равных

Обычно мы, программисты, общаемся с Google на собеседованиях или поступаем туда на работу или что-то в этом роде.

Как автор опенсорсных проектов, в которых Google был заинтересован, я общался с Google, как две равные сущности.

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

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

Они хвастались, что перепишут ipp-usb за пару недель на Си (на Go они взять в ChromeOs не могли, из-за размера), но не смогли, и приходили ныть, что не смогли. Намекали, что может я возьмусь, но денег не предлагали, и я не взялся. Потом переписали на Rust-е, это у них получилось. Потому, что для Rust-а есть нормальный HTTP в библиотеке, а для Си нету. А написать руками у них не хватило пороху а у меня - мотивации.

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

Как не сломать программу, которой пользуются тысячи человек

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

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

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

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

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

OpenSource под санкциями

На удивление, ничего не изменилось. Отношение зарубежных коллег и пользователей осталось прежним. Меня один раз спросили, нет ли у меня проблем с доступом и не надо ли чем помочь, и на этом все. Больше темы политики никто не касался. Хорошо, что в мире остались еще какие-то области, куда тревожные политические вопросы пока не просочились. И хорошо, что программное обеспечение остается достоянием человечества, а не одного какого-то народа. По крайней мере, то, которое с открытыми текстами.

Стоило ли оно потраченного времени?

На мой взгляд - да.

На человека с двумя успешными проектами, пусть и достаточно нишевыми, по-другому смотрят на собеседовании.

Сам по себе опыт самостоятельного ведения проектов, когда всё сам, а не тикеты в TFS-е закрываешь по команде менеджера - он совершенно ни с чем не сравнимый и очень полезный. Приучает к самостоятельности, к планированию, к разумному целеположению и т.п. Учит не разбрасываться силами, у меня же не бесконечное количество ресурсов, а денег мне сама по себе эта деятельность не приносит.

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

Опыт продвижения на рынок - это то, с чем программисты вообще редко сталкиваются. За них это обычно делает работодатель. Свой собственный опыт избавляет от многих иллюзий. Например, становится понятно, что компания делает для меня, а не только, что я делаю для компании. Начинаешь понимать (не в теории, а на опыте), что написание работающего, отлаженного, проверенного кода - это очень сильно меньше, чем половина работы по созданию продукта. Большую часть времени занимает вовсе даже не багфиксинг, как иногда любят говорить, а вот создание тех самых мелочей, которые, в совокупности, и отличают прототип от продукта, и которые, каждая сама по себе, кажутся не очень обязательными и не очень объемными, но вместе набегает, как надо. Очень много времени занимает само по себе продвижение. Даже не усилий, а именно времени, никому неизвестный продукт никому и не нужен, а известность нарастает весьма неторопливо - даже если сама по себе программа хороша.

Комментарии (52)


  1. horon
    29.07.2023 10:28
    +17

    Спасибо тебе за драйвер, юзаю.


    1. apevzner Автор
      29.07.2023 10:28
      +11

      И тебе спасибо на добром слове!


    1. 0xd34df00d
      29.07.2023 10:28
      +1

      Поддерживаю спасибо. Не так давно купил новое МФУ и заодно заметил в репах sane-airscan, поставил — и все просто работает! Сканирование работает, автоподатчик работает, выбор области работает, и все само. Прямо будующее.


      ОП, спасибо тебе.


      1. apevzner Автор
        29.07.2023 10:28

        Спасибо на добром слове!

        А это что за дистрибутив такой, что sane-airscan надо отдельно ставить? Обычно он ставится автоматически...


        1. 0xd34df00d
          29.07.2023 10:28

          Gentoo.


  1. sshmakov
    29.07.2023 10:28
    +4

    Не практикуете автотесты с эмуляторами устройств?


    1. apevzner Автор
      29.07.2023 10:28
      +1

      Нет, очень трудоёмко

      Гугловцы вроде делают что-то подобное (https://chromium.googlesource.com/chromiumos/third_party/virtual-usb-printer/) для ChromeOS-а. Но судя потому, что мне они особо ни на что не жаловались, существенных проблем они таким образом не накопали


  1. xsevenbeta
    29.07.2023 10:28
    +5

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


  1. victor_1212
    29.07.2023 10:28
    +3

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


    1. apevzner Автор
      29.07.2023 10:28
      +10

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


      1. victor_1212
        29.07.2023 10:28
        +1

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

        ps

        все из личного опыта, типа 50+ лет в программировании


        1. apevzner Автор
          29.07.2023 10:28
          +1

          Интересно, а сколько Вам лет, если у Вас 50+ лет опыта?

          У меня 35+, и я совсем уже не мальчик (и не девочка)...


          1. victor_1212
            29.07.2023 10:28

            70+, из них 30+ работы в us, в том числе digital, ciena и пр.


      1. saipr
        29.07.2023 10:28
        +7

        Да, свою работу надо уважать. Вы меня вдохновили. Теперь постараюсь на вашем опыте и что-то свое нанести в opensource.

        P. S. Сам стиль написания статьи просто супер, читается как захватывающий роман или детектив. Подумайте и над этим. Спасибо. Настроение подняли. И солнце за окном больничной палаты.


        1. Serge78rus
          29.07.2023 10:28


          Здоровья Вам! Это самый необходимый для работы ресурс.


        1. apevzner Автор
          29.07.2023 10:28

          Спасибо на добром слове. Выздоравливайте!


  1. korvint
    29.07.2023 10:28

    Прошу прощения за глупый вопрос. Но сам собираюсь в проект Open Source, и мучает неопределенность. Суть вопроса - никто не пытался у Вас украсть исходники и выдать их за свои? Физлица или юрлица. Не слышали ли Вы про такие истории с Open Source?


    1. apevzner Автор
      29.07.2023 10:28
      +26

      Я как-то спокойно к этому отношусь. Ну украдут и украдут - им же потом и поддерживать украденное :)


      1. gluck59
        29.07.2023 10:28

        Может быть именно поэтому в релизы просачивается "оно работает но мы не знаем почему"?


        1. apevzner Автор
          29.07.2023 10:28

          От использования чужих исходников?


          1. gluck59
            29.07.2023 10:28

            Ну да... "смогли украсть — могите и поддерживать"...


            1. apevzner Автор
              29.07.2023 10:28
              +2

              Я думаю, дело не в этом

              Очень трудно сказать менеджеру, что у меня всё работает, тесты проходит, но я не доконца пока понимаю, как мне это удалось. И хотелось бы потратить еще недельку, чтобы разобраться.

              И сулит неприятности


  1. dyadyaSerezha
    29.07.2023 10:28
    +1

    Все же интересно, можно ли как-то это монетизировать? Были ли предложения от крутых фирм перейти к ним?


    1. apevzner Автор
      29.07.2023 10:28
      +3

      Это прокачивает всякие полезные скилзы. Скилзы, разумеется, в конечном итоге можно монетизировать


  1. ildarin
    29.07.2023 10:28
    +7

    Ничо не понял, но очень плюс поставил. Не шарю за драйверы на Unix, но опенсорс - уважаю.


    1. apevzner Автор
      29.07.2023 10:28
      +19

      Ну, значит буду ходить загадочно оплюсованным :)


  1. TotalAMD
    29.07.2023 10:28
    +2

    Начиная, как положено, с системы сборки, логов, общей инфраструктуры драйвера, парсера файла конфигурации и т.п.

    А у вас есть где-то описание, где вы этому всему научились?


    1. apevzner Автор
      29.07.2023 10:28
      +8

      Я как-то даже не знаю, что сказать

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


  1. Tattobu
    29.07.2023 10:28
    +1

    Большое спасибо за ваш проект. Удачи вам и терпения


  1. ProMix
    29.07.2023 10:28
    +4

    Не думали над системой тестов на пользовательском оборудовании? По типу "вот вам скрипт, он сам скачает последнюю версию и прогонит по тестам, потом вернёт всё как было, а вам глубочайшая благодарность от сообщества"?


    1. DungeonLords
      29.07.2023 10:28

      Я думаю среди пользователей хабра как раз можно поискать желающих! Я бы взялся


    1. apevzner Автор
      29.07.2023 10:28

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

      Дело такое, достаточно хлопотное.

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


  1. kay
    29.07.2023 10:28
    +1

    Спасибо за утилиту. Использую её для добавления WiFi в свой USB HP принтер через Raspberry Pi.

    На USB-reset, например, разные устройства реагируют по-разному...

    Увы у меня печать с CUPS не идёт, скажем, совсем. Возможно вся проблема в этих буферах... Пока приходится кидать нужное для печати на Android телефон, а оттуда уже печать идет без проблем.


    1. apevzner Автор
      29.07.2023 10:28

      А не пробовали в CUPS баги файлить?

      Там ребята сидят довольно вменяемые, и обычно на баги реагируют

      Вряд ли тут дело в USB-буферах. ipp-usb, все же, с этим делом радикально разобрался. Скорее всего, дело где-то вокруг PPD. Иногда помогает вытащить PPD из проприетарного драйвера и подсунуть его CUPS-у.


  1. N-Cube
    29.07.2023 10:28

    Для разработчиков опен сорс может быть полезно еще написать (электронную) книгу про свой проект - амазон и прочие онлайн буксторы отлично индексируются, да и многие пользователи узнают о новом софте вовсе не на гитхабе или на форумах. Ну и ссылаться будет на что - одно дело, код на гитхабе, другое - книга. Насколько знаю, из России опубликоваться можно, только денег вывести не дадут (если вообще будет что выводить).


  1. quaer
    29.07.2023 10:28
    +1

    Скажите, пожалуйста, как выбираются имена для пакетов и утилит? Вот например ваши называются sane-airscan и ipp-usb. Как можно догадаться об их назначении? Читая эти названия ничего не понятно. Но ведь вы же вряд ли называется функцию в своём коде только вам понятными или просто красивыми словами или сочетаниями букв?


    1. apevzner Автор
      29.07.2023 10:28

      Ну в общем, для тех, кто в курсе терминологии в предметной области, эти названия вполне говорящие. Что до "обычного пользователя", я не знаю. Они, на самом деле, все разные, эти обычные пользователи. Многие очень квалифицированны, а многие - не очень

      А как могли бы звучать более узнаваемые названия?


      1. quaer
        29.07.2023 10:28

        printer_usb_driver, scanner_usb_driver. Это же предельно странно, когда чтобы найти нужную утилиту на компе надо гуглить, чтобы узнать, как она может называться.


        1. apevzner Автор
          29.07.2023 10:28
          +1

          Да, но...

          printer_usb_driver, но ведь (1) ipp-usb работает не только с принтерами, но и со сканерами (2) существуют другие протоколы печать через USB, со своими драйверами

          scanner_usb_driver, но sane-airscan, в первую очередь, работает с сетевыми устройствами. А в сочетании с ipp-usb - еще и с USB-ными

          Технологии сейчас сложны и разнообразны. Привязываться к "простым" признакам (печать + USB) - не дает однозначности. А привязываться к названиям протоколов - не понятно пользователям, которые не в курсе про протоколы

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


          1. quaer
            29.07.2023 10:28
            +1

            А как вы внутри объекты и функции называете? Вряд ли ведь словами sane, insane и подобными?

            Впрочем, это был более общий вопрос, связанный с весьма странными названиями пакетов/утилит.


            1. apevzner Автор
              29.07.2023 10:28

              А как вы внутри объекты и функции называете?

              Ну это же open source. Если интересно, можете на исходники сами посмотреть :)


        1. Gendenig
          29.07.2023 10:28

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

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

          А вот разработчики не могут. Что для вас printer_driver для другого xerox_utils_base.


          1. quaer
            29.07.2023 10:28

            Что printer_driver, что xerox_utils_base - это более внятно, чем sane-airscan, например, или встречающиеся названия других пакетов.


  1. grwprwn
    29.07.2023 10:28
    +1

    спасибо за разработку и статью, было очень интересно почитать и наверняка пользовался Вашим продуктом!


  1. grwprwn
    29.07.2023 10:28

    спасибо за разработку и статью, было очень интересно почитать и наверняка пользовался Вашим продуктом!


  1. grwprwn
    29.07.2023 10:28

    спасибо за разработку и статью, было очень интересно почитать и наверняка пользовался Вашим продуктом!


  1. Zeusina
    29.07.2023 10:28

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


    1. apevzner Автор
      29.07.2023 10:28

      Сейчас пошли довольно забавные времена. Трудно даже сказать, с чем больше шансов нарваться на негативный опыт, с Linux или Windows.

      Железо стало очень сложным и разнообразным. У меня в "зоне ответственности" два очень похожих ноута, мой собственный, с линухом, и ноут жены, с вендой

      В моём работает вообще все, но пришлось немного сунуть туда-сюда пальцы. У жены очень плохо работает засыпание при закрытии крышки (часто не засыпает, а зависает, устраивая при этом большую нагрузку на CPU). И куда сунуть пальцы, непонятно


  1. Morgan_iv
    29.07.2023 10:28

     ~  apt list --installed | grep sane
    # ...
    sane-airscan/jammy,now 0.99.27-1build1 amd64 [installed]
    # ...
    

    Вот и я, оказывается, пользуюсь, большое спасибо за работу!


  1. amberovsky
    29.07.2023 10:28

    У вас случайно нет инсайдов из индустрии на тему можно ли ждать кооперации производителей принтеров и сканеров и наконец- то придти к какому-то нормальному безглючному стандарту?


    1. apevzner Автор
      29.07.2023 10:28

      Консенсус заключается в следующем:

      • DNS-SD используется, как протокол для автоматического поиска устройств в сети

      • IPP используется, как протокол для печати

      • IPP over USB используется для USB-устройств, превращая их в псевдосетевые

      • eSCL используется, как протокол для сканирования

      Первые три пункта называются IPP everywhere: https://www.pwg.org/ipp/everywhere.html
      Спецификация eSCL опубликована Mopria alliance: https://mopria.org/mopria-escl-specification
      В терминологии Apple все это вместе называется Bonjour Printing

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


  1. rutexd
    29.07.2023 10:28
    +1

    Крайне интересно почитать о подобном опыте!

    С вашим драйвером наверняка не сталкивался, с печатью и сканерами дел почти не имею, однако если будет нужда - обязательно поставлю!

    Труд титанический проделан и страшно представить сколько нервотрепа ушло... Низкий поклон вам.