Barcode scanner in OpenWrt

Who was in trade they know surely what cash register is, how much it costs and such an“indispensable” thing it is in trade.

Let’s check if it is difficult to make a cash register by ourselves. Of course we will consider only the hardware aspect of the subject without touching on the aspects of the data base for goods, debit, credit etc... As a basis we take our router again and try to connect a barcode scanner to it.

On the stage of configuration OpenWrt the following modules are to be selected:
Base system :
<*> busybox:
Linux System Utilities:
<*> lsusb
Kernel modules:
USB Support:
<M> kmod-usb-hid

Let’s install the packages:

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.

Let’s connect the barcode scanner to usb-input of the router and check the response of Linux for such turn of events ))

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

As we can see a new device named TechScan Korea has appeared with ID 04b4:0100 Cypress Semiconductor Corp.

It is also important to notice that a new device has appeared in the directory /dev:

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

A new device file has been also created in the directory /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

What comes next? As usal I tried to find something ready-to-use in Internet, but I haven’t anything worth because of don’t knowing the specific of this branch. In fact it is not so dramatic because in final result I had to write something by myself in any case. Here we write only a test program to read a barcode from the scanner.

As far as I understand the device /dev/input/event0 which was created in the directory /dev, is a input device like keyboard. Therefore we only need to read barcodes which the device /dev/input/event0 should return by data availability.

Let’s write a test program for this. We can take a ready-to-use file from here.

#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;
}

We can build it using cross-compiler. How to do this was described above.

So, let’s copy the executable file barcode to the file system and check how it works. By starting we should specify a device for data reading. After starting let’s put the barcode to the scanner and press the button. I had the following image:

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

Let’s compare these figures with the figures on the barcode and if they are the same, then:

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