commit 02c3e5619f24abf0a675836c94b8db6ca4bf6f25 Author: s3lph Date: Mon Nov 25 23:10:11 2024 +0100 feat: first version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..99831c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +honeywell-config diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f97c93a --- /dev/null +++ b/LICENSE @@ -0,0 +1,16 @@ +Copyright 2024 s3lph + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1345548 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ + +.PHONY: clean + +honeywell-config: + gcc -lusb-1.0 -o honeywell-config honeywell-config.c + +clean: + rm honeywell-config diff --git a/README.md b/README.md new file mode 100644 index 0000000..7b5a2e6 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# Honeywell Barcode Reader Config Tool + +## What? + +A Linux tool for configuring Honeywell barcode scanners via USB. + +## Why? + +I had obtained a used Honeywell Hyperion 1300G scanner, however it was locked down and secured with a password, and the password was unknown. +There is a Windows-only configuration tool from Honeywell called "EZconfig" with which the barcode scanners can be configured via USB, even when locked down. +To not rely on a Windows VM for configuring the scanner, I sniffed the USB traffic using Wireshark and extracted the relevant messages, and wrapped them in this tool. + +## Usage + +First of all, compile the program using `make`. It depends only on `libusb-1.0`. + +The configuration strings need to be provided as command line arguments. You can provide multiple: + +``` +./honeywell-config [... ] +``` + +In general, please refer to your scanner's manual for configuration strings. + +Here are some examples: + +### Factory Reset + +``` +./honeywell-config DEFOVR. DEFALT. +``` + +### Switch Operation Mode + +USBHID: + +``` +./honeywell-config PAP131. +``` + +Keyboard: + +``` +./honeywell-config PAP124. +``` + +### Add Prefix to Output + +The following adds the string `FCKAFD ` (ASCII hex `46 43 4B 41 46 44 20`) in front of every scanned barcode: + +``` +./honeywell-config PREBK246434B41464420. +``` + +Note how this behaves differently from if you were to configure the scanner in-band via scanning config barcodes. +There you would scan a lot of individual codes from the manual: + +1. `PREBK2.` +1. `K4K.` +1. `K6K.` +1. ... +1. `K2K.` +1. `K0K.` +1. `MNUSAV.` + +On the USB config interface, all of that goes into a single string instead. + +## Adapting for Other Scanners + +The tool currently has hardcoded USB vendor/product IDs for a Honeywell Hyperion 1300G in Keyboard or USBHID modes. +If you have a different Honeywell scanner, and the tool doesn't find it, you can try making this tool work for it: +1. Obtain the USB vendor and product IDs for your scanner, e.g. through `lsusb`. +1. Replace the VID/PID in the following line of code in `honeywell-config.c`: + + ```c + libusb_device_handle *devh = libusb_open_device_with_vid_pid(ctx, 0x0c2e, 0x0b07); + ``` +1. Recompile the tool with `make clean; make` + +## License + +MIT License + diff --git a/honeywell-config.c b/honeywell-config.c new file mode 100644 index 0000000..5c90f2d --- /dev/null +++ b/honeywell-config.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Template for control messages, obtained through packet capture +unsigned char *CMD = "\xfd\x00\x16M\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + + +int main(int argc, char **argv) { + uint8_t cmd[64]; + memcpy(cmd, CMD, 64); + struct usbdevfs_ioctl command; + libusb_context *ctx = NULL; + + // + // Find and open the device + // + libusb_init(&ctx); + if (!ctx) { + perror("failed to initialize libusb"); + return 1; + } + + libusb_device_handle *devh = libusb_open_device_with_vid_pid(ctx, 0x0c2e, 0x0b07); + if (!devh) { + devh = libusb_open_device_with_vid_pid(ctx, 0x0c2e, 0x0b01); + if (!devh) { + perror("failed to open device"); + return 1; + } + } + libusb_device *dev = libusb_get_device(devh); + if (!dev) { + perror("failed to get device info"); + return 1; + } + + // + // Disconnect usbhid driver from both device interfaces + // + char usbdevfs[32]; + snprintf(usbdevfs, 32, "/dev/bus/usb/%03d/%03d", libusb_get_bus_number(dev), libusb_get_device_address(dev)); + // usbdevfs/ioctl inspired from + // https://www.linuxquestions.org/questions/linux-hardware-18/how-to-unclaim-usb-device-558138/#post3406986 + int fd = open(usbdevfs,O_RDWR); + if (fd < 1) { + perror("failed to open usbdevfs file"); + return 1; + } + for (uint8_t i = 0; i < 2; ++i) { + command.ifno = i; + command.ioctl_code = USBDEVFS_DISCONNECT; + command.data = NULL; + int ret = ioctl(fd, USBDEVFS_IOCTL, &command); + if (ret < 0) { + perror("failed to unclaim USB interface from usbhid"); + } + } + + // + // Prepare and send a message on the control channel for each config argument + // + for (int i = 1; i < argc; ++i) { + memset(cmd+5, 0, 59); + cmd[1] = strlen(argv[i])+3; + memcpy(cmd+5, argv[i], strlen(argv[i])); + libusb_control_transfer(devh, 0x21, 0x09, 0x02fd, 1, cmd, 64, 0); + } + + // + // Cleanup + // + libusb_release_interface(devh, 1); + libusb_close(devh); + libusb_exit(ctx); +} diff --git a/pcap/honeywellusbreset.pcapng b/pcap/honeywellusbreset.pcapng new file mode 100644 index 0000000..0f95945 Binary files /dev/null and b/pcap/honeywellusbreset.pcapng differ