Finding available keyboards on linux - keyboard

I want to bind to the hidraw of any plugged in keyboard. In order to do that I need to find all input devices that are actually keyboards.
I have done some research and want to share some of my findings to get some inputs around that subject.
I can get a list of usb devices using lsusb -v.
There I can find keyboards by interface class
Bus 001 Device 002: ID 17ef:6099 Lenovo Lenovo Traditional USB Keyboard
Device Descriptor:
...
idVendor 0x17ef Lenovo
idProduct 0x6099
...
Configuration Descriptor:
...
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 0
that would be one way to locate keyboards and then use idVendor and idProduct to find the correlating device, but I felt like looking for another generic approach that is not limited to usb devices

By iterating through sys/class/input/inputN/capabilities/key I can get devices that have key events and check for the proper mapping.
The mapping correlates with the definition in /usr/include/linux/input-event-codes.h.
So in the above mentioned case key contains 1000000000007 ff9f207ac14057ff ff980000000007ff febeffdfffefffff fffffffffffffffe
the blocks are each 16 hex values so one block contains 8 bytes or 64 bits, with the least significant to the right. The first block only contains 13 hey values or 52 bits. A total of 52 + 64 + 64 + 64 = 244 bits.
start | end | bits
----- | --- | -------------------------------------------------------------------------------
243 | 192 | 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111
191 | 128 | 1111 1111 1001 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 1111 1111
1111 1111 1001 1111 0010 0000 0111 1010 1100 0001 0100 0000 0101 0111 1111 1111
127 | 64 | 1111 1110 1011 1110 1111 1111 1101 1111 1111 1111 1110 1111 1111 1111 1111 1111
63 | 0 | 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110
This means that in my example all keys from bit 1 to bit 138 are defined but
0 ... KEY_RESERVED
84 ... (undefined)
101 ... KEY_LINEFEED
112 ... KEY_MACRO
118 ... KEY_KPPLUSMINUS
120 ... KEY_SCALE
and for the rest we have
140 ... KEY_CALC
142 ... KEY_SLEEP
150 ... KEY_WWW
152 ... KEY_COFFEE
158 ... KEY_BACK
159 ... KEY_FORWARD
161 ... KEY_EJECTCD
163 ... KEY_NEXTSONG
164 ... KEY_PLAYPAUSE
165 ... KEY_PREVIOUSSONG
166 ... KEY_STOPCD
173 ... KEY_REFRESH
176 ... KEY_EDIT
177 ... KEY_SCROLLUP
178 ... KEY_SCROLLDOWN
179 ... KEY_KPLEFTPAREN
180 ... KEY_KPRIGHTPAREN
183 ... KEY_F13
184 ... KEY_F14
185 ... KEY_F15
186 ... KEY_F16
187 ... KEY_F18
188 ... KEY_F19
189 ... KEY_F19
190 ... KEY_F20
191 ... KEY_F21
When I want to check if the keyboard supports the keys I need, like a-z would be
16 ... KEY_Q
...
25 ... KEY_P
30 ... KEY_A
...
38 ... KEY_L
44 ... KEY_Z
...
50 ... KEY_M
0111 1111 0000 0111 1111 1100 0011 1111 1111 0000 0000 0000 0000 => 7f07fc3ff0000
all that needs to be checked is if the last block validates fffffffffffffffe & 7f07fc3ff0000 == 7f07fc3ff0000
in bash i used this snippet to get the last part of each key capability, make sure it is interpreted as hex and test if the bitwise-and matches
ls -d1 /sys/class/input/input*/capabilities/key | while read dev; do KEY="$(cat $dev | rev | cut -d ' ' -f 1 | rev)"; [ $(( (0x$KEY & 0x7f07fc3ff0000) == 0x7f07fc3ff0000 )) == 1 ] && echo $dev ; done

Related

imagemagick gm node buffer file conversion

I'm currently using ImageMagick and gm to process images from a buffer. My problem is that I cannot control what file types are put in the buffer but wish to have everything turned to jpg.
Not sure how to do that using the buffer since I'm not giving it an output file path with extension.
gm(buf).command('convert').in('-auto-orient','-resize','500x','-quality','92','-strip','-quality','100','jpg').toBuffer((err, buffer) => err ? reject(err) : resolve(buffer));
I don't know anything about the node.js bindings of ImageMagick or GraphicsMagick, but I do know that if you do this in Terminal, you will force a JPEG output, so maybe you can adapt that...
# Make a 1x1 black image and write to stdout as JPEG. Dump result with 'xxd'
gm convert xc:black jpg:- | xxd
00000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0048 ......JFIF.....H
00000010: 0048 0000 ffdb 0043 0008 0606 0706 0508 .H.....C........
00000020: 0707 0709 0908 0a0c 140d 0c0b 0b0c 1912 ................
00000030: 130f 141d 1a1f 1e1d 1a1c 1c20 242e 2720 ........... $.'
00000040: 222c 231c 1c28 3729 2c30 3134 3434 1f27 ",#..(7),01444.'
00000050: 393d 3832 3c2e 3334 32ff c000 0b08 0001 9=82<.342.......
00000060: 0001 0101 1100 ffc4 0014 0001 0000 0000 ................
00000070: 0000 0000 0000 0000 0000 0008 ffc4 0014 ................
00000080: 1001 0000 0000 0000 0000 0000 0000 0000 ................
00000090: 0000 ffda 0008 0101 0000 3f00 3fbf ffd9 ..........?.?...
It is just the same with ImageMagick and, say, PNG output:
magick xc:black png:-

`tcpdump` shows different length for the same ARP packet

I'm running tcpdump in two identical Linux machines with this command:
tcpdump -i enp0s8 -nn -XX -vvv
During an ARP request in the sender machine I see:
20:03:29.113813 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.1 tell 10.0.0.2, length 28
0x0000: 0800 27bb f251 0800 27cf ce8e 0806 0001 ..'..Q..'.......
0x0010: 0800 0604 0001 0800 27cf ce8e 0a00 0002 ........'.......
0x0020: 0000 0000 0000 0a00 0001 ..........
but in the destination machine:
20:03:29.114928 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.1 tell 10.0.0.2, length 46
0x0000: 0800 27bb f251 0800 27cf ce8e 0806 0001 ..'..Q..'.......
0x0010: 0800 0604 0001 0800 27cf ce8e 0a00 0002 ........'.......
0x0020: 0000 0000 0000 0a00 0001 0000 0000 0000 ................
0x0030: 0000 0000 0000 0000 0000 0000 ............
Why the packet is zerofilled reaching a length of 46?
The ARP message itself is 28 bytes long, exactly as you indicated. Now, with correct Ethernet implementations, the outgoing frame has to be padded to be at least 64 bytes long. There are some quirks about this, however - the device that originated this ARP message may itself be capable of sending it in an untagged frame or in 802.1Q-tagged frame. The tag size is always accounted towards the total frame size, resulting in different paddings:

Why isn't "1010 0000" a valid BCD representation?

I came across this in the book "Programming the Z80", it was an exercise question that wasn't answered.
Because you're trying to represent decimal values with binary numbers. You can only use representations of numbers between 0 and 9.
Valid BCD 4-bit chunks:
0000 - 0
0001 - 1
0010 - 2
0011 - 3
0100 - 4
0101 - 5
0110 - 6
0111 - 7
1000 - 8
1001 - 9
Invalid BCD 4-bit chunks:
1010 - 10
1011 - 11
1100 - 12
1101 - 13
1110 - 14
1111 - 15
Examples:
0101 0011 - 53
1001 0111 - 97
1000 1001 0100 - 894
1010 0000 - (10)0 // We can't represent 10 in a single decimal digit
The values 10 to 15 would be valid in a BCH (binary coded hexadecimal) context. The previous invalid example would result in something like this:
1010 0000 - A0

Get a substring from a file shell script [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
i need get a substring from a file shell script
i need a little help with this shell script. I have a variable, represents a IP/TCP header. I need filter a traffic capture by the header selected.
> var=ttl 128 (only TTL=128)
>
> tcpdump -Xvv -n -i eth0 -c 300 > capture.txt 2>/dev/null
>
I'm trying using grep command, but only have the line with ttl 128, don't the ip source and destination
> grep -i "$var" capture.txt > resultGrep.txt
The result of the tcpdump command is some like this
15:29:18.164566 IP (tos 0x0, ttl 1, id 2394, offset 0, flags [none], proto UDP (17), length 125)
10.0.0.155.58363 > 239.255.255.254.1900: UDP, length 97
0x0000: 4600 0024 0000 0000 0102 3ad3 0a00 0000 F..$......:.....
0x0010: e000 0001 9404 0000 1101 ebfe 0000 0000 ................
0x0020: 0300 0000 0000 0000 0000 0000 0000 ..............
15:29:18.164566 IP (tos 0x0, ttl 128, id 2394, offset 0, flags [none], proto UDP (17), length 125)
10.0.0.131.58363 > 239.255.255.250.1900: UDP, length 97
0x0000: 4600 0024 0000 0000 0102 3ad3 0a00 0000 F..$......:.....
0x0010: e000 0001 9404 0000 1101 ebfe 0000 0000 ................
0x0020: 0300 0000 0000 0000 0000 0000 0000 ..............
15:29:18.164566 IP (tos 0x0, ttl 64, id 2394, offset 0, flags [none], proto UDP (17), length 125)
10.0.0.147.58363 > 239.255.255.255.1900: UDP, length 97
0x0000: 4600 0024 0000 0000 0102 3ad3 0a00 0000 F..$......:.....
0x0010: e000 0001 9404 0000 1101 ebfe 0000 0000 ................
0x0020: 0300 0000 0000 0000 0000 0000 0000 ..............
I need have ip address source and ip address destination from packets with ttl 128 header, in the example the output result must be
10.0.0.131.58363 > 239.255.255.250.1900
If your grep supports displaying a context -A, you can try
grep -A 1 -e 'ttl 128' capture.txt | grep '^ ' | cut -d: -f1
The first grep shows all lines with ttl 128 plus one following line. The second grep filters the lines starting with blanks. The final cut selects everything before the first :.

Checksum/CRC calculation

I am decoding a message sent by an wireless outdoor weather station. I have figured out what most of the protocol means except haven't been able to determine how to calculate the checksum. Here is what I've found so far:
0100 0111 0110 0000 0111 0100 0011 0010 1110 0110
|----|---------|--------------|---------|---------|
start id temp humidity checksum?
So in the above example the temperature was 11.6 degrees and 50% humidity. The "id" field changes to a "random" value when I replace the batteries in the outdoor transmitter. The last 8 bits only change when the id/temp/humidity changes so I'm fairly certain those are the checksum/crc bits.
Here are a bunch of different transmissions:
0100 1110 0101 0000 1001 0010 0011 0011 1010 0001
0100 1110 0101 0000 1001 0010 0011 0100 0011 0110
0100 0111 0110 0000 1001 0010 0011 0100 0110 1100
0100 0111 0110 0000 1001 0010 0011 0101 0101 1101
0100 0111 0110 0000 1001 0100 0011 0101 0000 0111
0100 0111 0110 0000 1001 0101 0011 0110 1010 0000
0100 0111 0110 0000 1001 1000 0011 0111 1101 0001
0100 0111 0110 0000 1010 1000 0011 0111 0110 0011
0100 0111 0110 0000 1010 1001 0011 0111 1001 0111
0100 0111 0110 0000 1010 1010 0011 0111 1011 1010
0100 0111 0110 0000 0111 0100 0011 0010 1110 0110
0100 0111 0110 0000 0111 0101 0011 0010 0001 0010
0100 0111 0110 0000 0111 0110 0011 0010 0011 1111
I'm not familiar with checksum/crc techniques, can anyone see what might be being used here or point me in a direction for how to determine this?
Seriously, your best bet is probably to go to the weather station and look at the manufacturer and model number, then either plug that into Google or send email to the manufacturer asking how the checksum is calculated.
If they baulk at releasing the information, tell them you're evaluating a solution and you may make a decision to buy ten to a hundred of their devices based on how easy it is to write software for it (information requests aren't delivered under oath and social engineering is still usually the easiest way to get at information you wouldn't normally get to see).
Hacked OK. Here's the C# code to generate the 5-th byte out of the previous 4 bytes.
/// <summary>A variant of CRC-8</summary>
/// <param name="data">Pass here the first 4 bytes of data, e.g. { 0x4E 0x50 0x92 0x33 }</param>
/// <returns>The computed SRC value, e.g. 0xA1 for the data specified above.</returns>
static byte src8( byte[] data )
{
byte res = 0;
foreach( byte b in data )
{
byte val = b;
for( int i = 0; i < 8; i++ )
{
byte tmp = (byte)( ( res ^ val ) & 0x80 );
res <<= 1;
if( 0 != tmp )
res ^= 0x31;
val <<= 1;
}
}
return res;
}

Resources