Мы переключаемся на систему, в которой нашим грузоотправителям необходимо наносить штрих-коды с нашими идентификаторами статей на продукты, которые они отправляют впредь. Наше руководство готово предоставить им принтеры этикеток Brother TD-4100N при условии, что они не будут использовать его для других целей, кроме печати наших штрих-кодов, и теперь мне поручено программировать интерфейс, позволяющий им печатать наши штрих-коды.
Их основная компетенция, однако, заключается в управлении отгрузкой, а не в администрировании ИТ, и поэтому я должен держать вещи простыми и независимыми от платформы - или, по крайней мере, настолько независимыми от платформы, насколько это возможно. Идея в том, чтобы подключить один из этих принтеров через Ethernet без какой-либо настройки - настолько просто, насколько это возможно. Нет драйверов, нет ничего, держите это просто, глупо. Порт Ethernet и сокеты - все, что я хочу использовать. И с этой конкретной моделью, имеющей порт Ethernet и принимающей коды ESC / P, что не должно быть так сложно, верно?
Проведя неделю на одном тестовом компьютере, я узнал достаточно о кодах ESC / P и фирменных расширениях Brother (по крайней мере, так они утверждают), чтобы написать небольшую структуру на C. Печать штрих-кодов в требуемом формате ( Code128) сама по себе не представляет проблемы, но бухгалтерия вокруг этого делает; Сейчас я в своем третьем руководстве, в котором утверждается, что простая отправка команды "\ x1B \ x69 \ x53" (ESC i S) должна привести к тому, что принтер отправит мне 32-байтовую запись своего текущего состояния, но для некоторых причина, по которой принтер просто не хочет присылать мне, как он делает:
char buffer_send[] = "x1B\x69\x53";
send(sock_jet,buffer_send,sizeof(buffer_send) - 1,0);
char buffer[32];
memset(buffer,0,sizeof(buffer));
recv(sock_jet,buffer,sizeof(buffer),0);
fprintf
(
stderr,
"%02x%02x%02x%02x%02x%02x%02x%02x\n",
buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7]
);
fprintf
(
stderr,
"%02x%02x%02x%02x%02x%02x%02x%02x\n",
buffer[8],buffer[9],buffer[10],buffer[11],buffer[12],buffer[13],buffer[14],buffer[15]
);
fprintf
(
stderr,
"%02x%02x%02x%02x%02x%02x%02x%02x\n",
buffer[16],buffer[17],buffer[18],buffer[19],buffer[20],buffer[21],buffer[22],buffer[23]
);
fprintf
(
stderr,
"%02x%02x%02x%02x%02x%02x%02x%02x\n",
buffer[24],buffer[25],buffer[26],buffer[27],buffer[28],buffer[29],buffer[30],buffer[31]
);
Этот код просто останавливается на некоторое время, пока не истечет время ожидания или что-то еще, и recv
не записывает данные в мой буфер:
0000000000000000
0000000000000000
0000000000000000
0000000000000000
И я, видимо, не единственный с такой проблемой. Этот Ruby пакет Python (https://pypi.org/project/brotherprint/#files) утверждает, что он специально предназначен для принтеров Brother, но я никогда не вижу, чтобы они получали какие-либо данные (по крайней мере brotherprint/brotherprint.py
). На самом деле я даже не видеть их написание "получить" правильно.
На SO ( работающем принтере с программированием php-сокета ) кто-то пытался сделать то же самое в PHP, который я пытаюсь сделать в C - , и у них была точно такая же проблема, как и у меня имея, при этом принтер отказывается предоставлять им данные о состоянии . Похоже, что решение заключается в переключении с порта 9100 на порт 515 и использовании другого протокола, и хотя я видел, что порт 515 открыт на принтере, я никогда не видел никаких выходных данных с этого принтера, на бумага или на розетке. На этом этапе я бы обратился в службу поддержки Brother, но у меня уже есть еще один открытый билет, потому что другой их принтер действительно испытывает серьезные проблемы с отправкой отчетов о состоянии обратно в CUPS.
Я попытался добавить NUL-байт в конце своей полезной нагрузки, на случай, если принтер ожидает подачи страницы, но это тоже не сработало. Опять же: печать штрих-кодов до чертовски полезной вещи, так что IP, порт и соединение работают по крайней мере в некоторой степени - но получение отчета о состоянии - нет.
strace
из моей программы:
connect(3, {sa_family=AF_INET, sin_port=htons(9100), sin_addr=inet_addr("192.168.XXX.XXX")}, 16) = 0
sendto(3, "\33iS", 3, 0, NULL, 0) = 3
recvfrom(3, <blocks here for minutes> "", 32, 0, NULL, NULL) = 0
write(2, "0000000000000000\n", 170000000000000000
) = 17
write(2, "0000000000000000\n", 170000000000000000
) = 17
write(2, "0000000000000000\n", 170000000000000000
) = 17
write(2, "0000000000000000\n", 170000000000000000
) = 17
close(3)
И основное руководство, которое я использую: https://download.brother.com/welcome/docp000579/cv_td4000_eng_escp_120.pdf (поиск "ESC i S").