Last active
February 28, 2020 04:47
-
-
Save tresf/6251ed49f7cc124c387dfe58548d8f22 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Code backup 2020-02-27 | |
// Fongwah UHF Reader WRD-130-U1 | |
// QZ Tray 2.1.0 | |
// Work in progress, not yet functional | |
function scanRFID() { | |
let vid = "0x0e6a"; | |
let pid = "0x0317"; | |
let usage = "0x0c"; | |
// Toggle automatic scanning option | |
var autoScan = false; | |
var scanTime = 0x01; // x10ms (ignored if autoScan is off) | |
var sameCard = 0x01; // x100mx (ignored if autoScan is off) | |
// Toggle keyboard emulation | |
var kbdEmu = false; | |
// Configure read sensitivity | |
var dBm = -2; | |
// Frequency range | |
var range = { | |
us: 0x31, // 902-928 Mhz | |
tw: 0x32, // 922-928 Mhz | |
cn: 0x33, // 920-925 Mhz | |
cn2: 0x34, // 840-845 Mhz | |
eu: 0x35, // 865-868 Mhz | |
jp: 0x36, // 916-921 Mhz | |
kr: 0x37, // 917-921 Mhz | |
vn: 0x38, // 918-923 Mhz | |
eu2: 0x39, // 916-920 Mhz | |
in: 0x41 // 865-867 Mhz | |
} | |
var devRange = range.us; | |
qz.hid.claimDevice({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage, | |
}).then(function() { | |
// Set jurisdicational radio frequency mode (e.g. FCC complaince) | |
return qz.hid.sendData({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage, | |
endpoint: 0x08, | |
data: [0x02, 0x41, 0x4E, 0x35, 0x2C, 0x30, devRange] | |
}); | |
}).then(function() { | |
// Set USB mode options (for toggling on/off keyboard emulation) | |
return qz.hid.sendData({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage, | |
endpoint: 0x08, | |
data: [0x02, 0x92, 0x00, 0x02, kbdEmu ? 0x01 : 0x00, 0x05] | |
}); | |
}).then(function() { | |
// Set auto-read options (for toggling on/off auto-scan feature) | |
console.log("Setting auto read to ", autoScan); | |
return qz.hid.sendData({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage, | |
endpoint: 0x08, | |
data: [0x02, 0x92, 0x02, 0x04, autoScan ? 0xC3 : 0x43, scanTime, sameCard, 0x00 ] | |
}); | |
}).then(function() { | |
// | |
// FIXME: This isn't working | |
// | |
// Set distance/sensitivy option | |
// - Valid range: -2dBm - 27dBm | |
// -2dBm = 0x30 0x30 | |
// 27dBm = 0x31 0x44 | |
// Calculate bits (most significant, least significant) | |
// **WARNING** Magic counting to follow: | |
// 1. MSB incriments when LSB hits 0x46 hex | |
// 2. Counting is done using decimal, BUT... | |
// 3. Decimal is strangly passed in hex format | |
var msb = parseInt(30 + Math.floor(((dBm + 2) + 30)/46), 16); | |
var lsb = parseInt(30 + ((dBm + 2) % 46), 16); | |
console.log("Setting power level to", dBm + "dBm = ", "MSB:", "0x" + msb.toString(16), "LSB:", "0x" + lsb.toString(16)); | |
return qz.hid.sendData({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage, | |
endpoint: 0x08, | |
data: [0x02, 0x41, 0x4E, 0x31, 0x2C, msb, lsb] | |
}) | |
}).then(function() { | |
// Blink lights and beeper | |
console.log("Beeping and blinking light...") | |
return qz.hid.sendData({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage, | |
endpoint: 0x04, // Note: Beep uses a different endpoint | |
data: [0x02, 0x91, 0x09, 0x32], | |
}); | |
}).then(function() { | |
// read current etag | |
console.log("Asking to read eTag") | |
return qz.hid.sendData({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage, | |
endpoint: 0x08, | |
data: [0x02, 0x41, 0x52, 0x31, 0x2C, 0x32, 0x2C, 0x34], | |
}); | |
}).then(function() { | |
// repeat read a few times to ensure we get the latest values | |
var chain = []; | |
for(var i = 0; i < 5; i++) { | |
var link = function() { | |
return qz.hid.readData({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage, | |
responseSize: 32 | |
}).then(function(read) { | |
console.log(read); | |
parseHex(read); | |
return new Promise(resolve => setTimeout(resolve, 500)); | |
}); | |
}; | |
chain.push(link); | |
} | |
//build and execute the promise loop | |
var firstLink = Promise.resolve(); | |
var lastLink = null; | |
chain.reduce(function(sequence, link) { | |
lastLink = sequence.then(link); | |
return lastLink; | |
}, firstLink); | |
//cleanup device | |
lastLink.then(function() { | |
qz.hid.releaseDevice({ | |
vendorId: vid, | |
productId: pid, | |
usagePage: usage | |
}); | |
}).catch(function(err) { | |
console.error(err); | |
}); | |
}).catch(function(e) { | |
console.error(e); | |
}); | |
} | |
// | |
// FIXME: This isn't working | |
// | |
function parseHex(data) { | |
var parsed = ""; | |
for(var i in data) parsed += String.fromCharCode(parseInt(data[i], 16)); | |
var start = parsed.indexOf("R"); | |
var length = 24; | |
if(start == 4 && parsed.length - (start + 1) >= length) { | |
console.log(parsed.substring(start + 1, start + 1 + length)); | |
} else { | |
console.warn("Couldn't parse data as RFID tag", parsed); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment