Сканер штрих-кодов в OpenWrt

Те, кто занимался торговлей, наверняка знают, что такое кассовый аппарат, сколько он стоит и какая это «незаменимая» вещь в торговле.

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

На этапе конфигурации OpenWrt нужно отметить следующие модули:
Base system :
<*> busybox:
Linux System Utilities:
<*> lsusb
Kernel modules:
USB Support:
<M> kmod-usb-hid

Устанавливаем пакеты:

root@OpenWrt:/# opkg install kmod-usb-hid
Installing kmod-usb-hid (2.6.36.2-1) to root...
Downloading ftp://ftp:ftp@192.168.0.9/kmod-usb-hid_2.6.36.2-1_brcm47xx.ipk.
Installing kmod-hid (2.6.36.2-1) to root...
Downloading ftp://ftp:ftp@192.168.0.9/kmod-hid_2.6.36.2-1_brcm47xx.ipk.
Installing kmod-input-core (2.6.36.2-1) to root...
Downloading ftp://ftp:ftp@192.168.0.9/kmod-input-core_2.6.36.2-1_brcm47xx.ipk.
Installing kmod-input-evdev (2.6.36.2-1) to root...
Downloading ftp://ftp:ftp@192.168.0.9/kmod-input-evdev_2.6.36.2-1_brcm47xx.ipk.
Configuring kmod-input-core.
Configuring kmod-hid.
Configuring kmod-input-evdev.
Configuring kmod-usb-hid.

Подключаем сканер штрих-кодов к usb-входу роутера и посмотрим реакцию Linux на такой поворот событий ))

root@OpenWrt:/# dmesg
usb 1-1.3: new low speed USB device using ohci_hcd and address 5
input: TechScan Korea DG Dashuo USB-V4.0 as /devices/ssb0:1/usb1/1-1/1-1.3/1-1.3:1.0/input/input1
generic-usb 0003:04B4:0100.0002: input: USB HID v1.00 Keyboard [TechScan Korea DG Dashuo USB-V4.0 ] on usb-ssb0:1-1.3/input0

root@OpenWrt:/# lsusb
Bus 001 Device 001: ID 1d6b:0001
Bus 002 Device 001: ID 1d6b:0002
Bus 001 Device 002: ID 0a05:7211
Bus 001 Device 003: ID 0951:1603
Bus 001 Device 004: ID 04b4:0100

Как видно, обнаружилось новое устройство TechScan Korea с ID 04b4:0100 Cypress Semiconductor Corp.

Также важно заметить, что в директории /dev создалось новое устройство:

root@OpenWrt:/# ls -l /dev/input/
crw-r--r-- 1 root root 13, 64 Jan 1 00:01 event0

А также создался файл устройства в директории /proc:

root@OpenWrt:/# cat /proc/bus/input/devices
I: Bus=0003 Vendor=04b4 Product=0100 Version=0100
N: Name="TechScan Korea DG Dashuo USB-V4.0 "
P: Phys=usb-ssb0:1-1.3/input0
S: Sysfs=/devices/ssb0:1/usb1/1-1/1-1.3/1-1.3:1.0/input/input2
U: Uniq=
H: Handlers=event0
B: EV=120013
B: KEY=e080ffdf 1cfffff ffffffff fffffffe
B: MSC=10
B: LED=1f

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

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

Напишем тестовую программку, которая именно это и делает. Готовый файл можно взять отсюда.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>

#define KEY_PRESS 1
#define KEY_KEEPING_PRESSED 2

int main (int argc, char *argv[])
{
struct input_event ev[64];
int fd, rd,size = sizeof (struct input_event);
char name[256] = "Unknown",i;
char *device = NULL;
char decode_scancode[]={0,0,1,2,3,4,5,6,7,8,9,0};

if (argv[1] == NULL){
printf("Please enter path to device\n");
return 1;
}

if ((getuid ()) != 0)
printf ("You must be as root for correct work!\n");

if (argc > 1)
device = argv[1];

if ((fd = open (device, O_RDONLY)) == -1){
printf ("Open error of device %s\n", device);
return 1;
}

ioctl (fd, EVIOCGNAME (sizeof (name)), name);
printf ("Reading From : %s (%s)\n", device, name);

while (1){
if ((rd = read (fd, ev, size * 64)) < size){
perror ("Read error");
return 1;
}

for (i=0; i< ((int)(rd/size)); i++) {
if (ev[i].type == EV_KEY) {
if ((ev[i].value == KEY_PRESS) || (ev[i].value == KEY_KEEPING_PRESSED)) {
if (ev[i].code < 12) {
printf ("%d", (decode_scancode[ev[i].code]));
}
else if (ev[i].code == 28) {
printf ("\n");
}
}
}
}
}

return 0;
}

Собрать её надо, используя кросс-компилятор. Как это сделать, было рассказано раньше.

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

root@OpenWrt:/# /home/barcode /dev/input/event0
Reading From : /dev/input/event0 (TechScan Korea DG Dashuo USB-V4.0 )
4810151007577
4600717035256
2000061957969

Осталось сравнить эти цифры с теми, что на самом штрих-коде, и если они совпадают, то тогда:

Usb cканер штрихкода