How do I decod node-hid data buffer from a&d scale - node.js

I have an A&D scale that I monitoring input from using node-hid. I am successfully reading the input, but I can't figure out how to decode the binary data. Any help is appreciated.
This is the code I am using:
var HID = require('node-hid');
var devices = HID.devices();
var device = new HID.HID('USB_0dbc_0005_14400000');
device.on("data", function(data){
console.log(data);
});
And this is what gets spat out when the scale is at zero.
<Buffer 00 00 53 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 57 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 62 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 62 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 62 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 62 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 62 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 63 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 62 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 62 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 58 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 53 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>

I ended up just writing the buffer up on my whiteboard and thinking freely. I found some patterns in the data and wrote code for decoding and parsing the scale data. The code is included below for anyone that might need a push in the right direction.
"use strict";
var HID = require('node-hid');
var device = new HID.HID('USB_0dbc_0005_14400000');
var weight = []
var count = 0
module.exports.show_devices = function(){
console.log(devices);
}
module.exports.start_logging = function(){
device.on("data", function(data){
var bad_array = [
'\u0000S\u0000\u0000',
'\u0000W\u0000\u0000',
]
if (count < 20 && count % 2 == 0 && !contains(bad_array, data.toString('utf16le'))){
weight.push(key[data.toString('utf16le')])
}
if(count == 19){
display_weight()
}
if(count == 23){
count = -1
weight = []
}
count++
});
}
function display_weight(){
console.log(weight.join(''));
}
function contains(a, obj){
for(var i = 0; i < a.length; i++){
if(a[i] === obj){
return true;
}
}
return false;
}
var key = {
"\u0000Y\u0000\u0000" : "1",
"\u0000Z\u0000\u0000" : "2",
"\u0000[\u0000\u0000" : "3",
"\u0000\\\u0000\u0000" : "4",
"\u0000]\u0000\u0000" : "5",
"\u0000^\u0000\u0000" : "6",
"\u0000_\u0000\u0000" : "7",
"\u0000`\u0000\u0000" : "8",
"\u0000a\u0000\u0000" : "9",
"\u0000b\u0000\u0000" : "0",
"\u0000c\u0000\u0000" : "."
}

Related

node-ffi OUT parameter with type of Struct Pointer cannot receive back values from DLL call

C Data Structure:
typedef struct dpfpdd_dev_info {
unsigned int size;
char name[MAX_DEVICE_NAME_LENGTH];
DPFPDD_HW_DESCR descr;
DPFPDD_HW_ID id;
DPFPDD_HW_VERSION ver;
DPFPDD_HW_MODALITY modality;
DPFPDD_HW_TECHNOLOGY technology;
} DPFPDD_DEV_INFO;
typedef struct dpfpdd_hw_descr {
char vendor_name[MAX_STR_LENGTH];
char product_name[MAX_STR_LENGTH];
char serial_num[MAX_STR_LENGTH];
} DPFPDD_HW_DESCR;
typedef struct dpfpdd_hw_id {
unsigned short vendor_id;
unsigned short product_id;
} DPFPDD_HW_ID;
typedef struct dpfpdd_hw_version {
DPFPDD_VER_INFO hw_ver;
DPFPDD_VER_INFO fw_ver;
unsigned short bcd_rev;
} DPFPDD_HW_VERSION;
typedef struct dpfpdd_ver_info {
int major;
int minor;
int maintenance;
} DPFPDD_VER_INFO;
typedef unsigned int DPFPDD_HW_MODALITY;
typedef unsigned int DPFPDD_HW_TECHNOLOGY;
Emulated JS code of the C code above:
const ref = require('ref');
const StructType = require('ref-struct');
const FixedBuffer = require('./FixedBuffer'); // from https://gist.github.com/TooTallNate/80ac2d94b950216a2705
const DPFPDD_DEV_INFO = StructType({
size: ref.types.uint,
name: FixedBuffer(MAX_DEVICE_NAME_LENGTH, 'utf-8'),
descr: DPFPDD_HW_DESCR,
id: DPFPDD_HW_ID,
ver: DPFPDD_HW_VERSION,
modality: DPFPDD_HW_MODALITY,
technology: DPFPDD_HW_TECHNOLOGY
});
const DPFPDD_HW_DESCR = StructType({
vendor_name: FixedBuffer(MAX_STR_LENGTH, 'utf-8'),
product_name: FixedBuffer(MAX_STR_LENGTH, 'utf-8'),
serial_num: FixedBuffer(MAX_STR_LENGTH, 'utf-8')
});
const DPFPDD_HW_ID = StructType({
vendor_id: ref.types.ushort,
product_id: ref.types.ushort
});
const DPFPDD_HW_VERSION = StructType({
hw_ver: DPFPDD_VER_INFO,
fw_ver: DPFPDD_VER_INFO,
bcd_rev: ref.types.ushort
});
const DPFPDD_VER_INFO = StructType({
major: ref.types.int,
minor: ref.types.int,
maintenance: ref.types.int
});
const DPFPDD_HW_MODALITY = ref.types.uint;
const DPFPDD_HW_TECHNOLOGY = ref.types.uint;
DLL API:
int DPAPICALL dpfpdd_query_devices (unsigned int *dev_cnt, DPFPDD_DEV_INFO *dev_infos)
node-ffi code of the DLL API above:
const lib = ffi.Library('theDLL'), {
'dpfpdd_init': [ 'int', [] ],
'dpfpdd_query_devices': [ 'int', [ ref.refType('uint'), ref.refType(DPFPDD_DEV_INFO) ] ]
});
ffi function invocation in node:
lib.dpfpdd_init();
let deviceEntries = ref.alloc('uint');
let deviceInfo = ref.alloc(DPFPDD_DEV_INFO);
lib.dpfpdd_query_devices(deviceEntries, deviceInfo);
console.log(deviceInfo.deref());
The console log would return something like this:
{ size: 0,
name: <Buffer#0x019572AC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >,
descr: { vendor_name: <Buffer#0x019576AC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >,
product_name: <Buffer#0x0195772C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >,
serial_num: <Buffer#0x019577AC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >,
'ref.buffer': <Buffer#0x019576AC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... > },
id: { vendor_id: 0,
product_id: 0,
'ref.buffer': <Buffer#0x0195782C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> },
ver: { hw_ver: { major: 0,
minor: 0,
maintenance: 0,
'ref.buffer': <Buffer#0x01957830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> },
fw_ver: { major: 0,
minor: 0,
maintenance: 0,
'ref.buffer': <Buffer#0x0195783C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> },
bcd_rev: 0,
'ref.buffer': <Buffer#0x01957830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> },
modality: 0,
technology: 0,
'ref.buffer': <Buffer#0x019572A8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... > }
From all the Buffer type logs it seems like I'm receiving back no values at all from my OUT StructType parameter. I have no Idea why this is happening. I'm very new to using node-ffi and node-ref. I managed to get to communicate to another USB device but data structures are much simpler, no nested struct and array types. But this one I cannot get to work. Anyone enlighten me to what with what I'm doing wrong?

why output of lscpi is inconsistent with respect to BAR

Below is my output of lspci -xxxx -vvvv -nn
00:02.0 VGA compatible controller [0300]: InnoTek Systemberatung GmbH VirtualBox Graphics Adapter [80ee:beef] (prog-if 00 [VGA controller])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 18
Region 0: Memory at e0000000 (32-bit, prefetchable) [size=64M]
Expansion ROM at <unassigned> [disabled]
Kernel driver in use: vboxvideo
00: ee 80 ef be 07 00 00 00 00 00 00 03 00 00 00 00
10: 08 00 00 e0 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 0b 01 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Specifically I want to ask about the following lines:
Region 0: Memory at e0000000 (32-bit, prefetchable) [size=64M]
and
10: 08 00 00 e0 00 00 00 00 00 00 00 00 00 00 00 00
Based on this (look at section 12.1.3) the value of BAR0 should be e0000008 and not e0000000, i.e. the last byte should be 08 and not 00, like it says in the description of Region 0. Why is it this way? What am I missing?
The low 4 bits are not actually part of the address. That particular bit (bit #3 with value 0x08) is the bit that marks the region as prefetchable. See https://en.wikipedia.org/wiki/PCI_configuration_space#Bus_enumeration or http://wiki.osdev.org/PCI#Base_Address_Registers or just do a web search for "PCI configuration space header"

Do modern operating systems ignore LBA/CHS information in the MBR boot sector?

I've wiped all the CHS/LBA information and bootcode on a spare flash drive leaving only the bare sector count information:
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 ff |................|
000001c0 ff ff 0c ff ff ff 00 08 00 00 00 f8 d4 01 00 00 |................|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
Leaving only this:
80 ff ff ff 0c ff ff ff 00 08 00 00 00 f8 d4 01
The first flag saying it is bootable, the 4th that it is FAT32, and the last 2, 4 byte values the sector start and count in Big-endian. The FF's are CHS/LBA info I set all to FF
And, the disk still works fine. Partition shows up, I can mount it, read from it, write etc.
I'm on Linux. How does Windows handle the LBA/CHS info? Is CHS/LBA irrelevant in this day and age?

JPEG EOF vs EOI marker

The JPEG file signature states that the JPEG EOI (End of Image) marker is given by the final FF D9. However I very occasionally come across JPEGs that also have a small amount of data following this EOI (in this example 02 24 ...):
FF D8 FF E1
...
...
FF D9
02 24 02 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 00 00 00 00 00 00 00 00 00 00 00 00 27 10 00 00 00 00 00 00 00 00 27 10 00 00 00 00 27 10 00 00 27 10 00 00 00 00 00 00 00 00 27 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 58 53 21 00 1E 5D 32 00 00 00 00
Does the JPEG standard allow for data following the EOI marker or is this additional binary data corruption?
If this is not corruption what information is encoded in these final bytes?
The JPEG standard only defines a JPEG data stream. That is what goes between the SOI and EOI markets. Anything outside that is outside JPEG.
JPEG does not define a file format so technically there is nothing wrong with having extra data at the begin or the end. However, most decoders will puke if you have extra data before the SOI marker.

hexadecimal string to wireshark pcap

I have a hex string which I want to convert into a Wireshark pcap. Wireshark accepts a hex dump in the following format:
0000 00 00 00 00 00 aa 00 00 00 00 00 01 88 47 00 3e
0010 80 0a 00 00 d1 0a 10 00 89 02 20 01 05 46 00 00
0020 00 01 00 02 04 03 6d 64 31 02 03 6d 61 57 00 00
0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0060 00 00 00 00 00
I have the following stream:
0000000000AA0000000000018847003E800A0000D10A100089022001054600000001000204036D643102036D615700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
I have been experimenting with od -Ax -tc1 -v command in linux but can not seem to get the correct output. Does anyone know how this can be done?
First put the hex stream into a text file "a.txt",
0000000000AA0000000000018847003E800A0000D10A100089022001054600000001000204036D643102036D615700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
then convert the text file into a binary file:
xxd -r -p a.txt a.bin
using od and text2pcap to convert the binary file to a pcap file.
od -Ax -tx1 -v a.bin | text2pcap - a.pcap
You can use the following script. This is just a workaround. od and hexdump will interpret 0 as the character '0', and use the byte 48, so you may not get proper output. The script reads two chars for 16 times, and offset is incremented accordingly. Pretty simple to understand I guess:)
#!/bin/bash
off=0
while [ 1 ]
do
printf "%04x " $off
for ((i=0;i<16;i++))
do
read -n 2 a
[ $? -ne 0 ] && echo && exit
echo -n "$a "
done
echo
off=`expr $off + 16`
done <test
where test is the file that holds the stream. I got the following output for your input.
0000 00 00 00 00 00 AA 00 00 00 00 00 01 88 47 00 3E
0010 80 0A 00 00 D1 0A 10 00 89 02 20 01 05 46 00 00
0020 00 01 00 02 04 03 6D 64 31 02 03 6D 61 57 00 00
0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0060 00 00 00 00 00

Resources