Files
sibo-playground/code/inventory/SCANNER-API.md
T

5.1 KiB

Workabout MX barcode scanner — API notes (reverse-engineered)

There is no official SDK documentation for the Workabout MX integral laser scanner. The Psion SIBO C SDK and I/O Devices Reference predate the MX and describe only the older external barcode modules (wands / wand-emulation), not the integral laser. These notes are reverse-engineered from device behaviour and from the Workabout MX ROM w2mx_v7.20f_eng.bin (strings), so treat unconfirmed items as such.

Hardware

  • Integral laser scanner, Symbol engine. The demo (DEMMAN.APP) reports Type: Laser 1223 (some units 1222).
  • It is a decoded scanner: it decodes in hardware and lights a green good-read LED. It does not emit an undecoded (HHLC) signal.
  • Trigger: the keyboard scan key, which the Window Server reports as key code 368. The key alone does not fire the laser from an arbitrary app; the scanner software arms/reads the engine.

Device driver and ports

LLDEV on the device lists a logical driver wl2 (units=1). The scanner is reached through this driver. The demo's "Select Scanner" screen lets you pick both a decoder type and a port (device driver + unit letter):

  • Port device drivers offered: TTY, WLS, WL2. The MX integral laser uses WL2.
  • Units seen in the ROM: WL2:A and WL2:D.

Decoder types (from the demo, "chosen from those used in standard Workabout products"):

Decoder Meaning
Generic External non-configurable reader
Symbol1 Workabout standard scanner
Datalogic Workabout CCD
HP Workabout Wand
Symbol2 Workabout MX scanner (the integral laser)

Opening the device

VOID *h;
INT  err = p_open(&h, "WL2:D", (UINT)-1);

Observed results:

Call Result Meaning
p_open("WL2:D", -1) 0 opens — this is the integral-laser unit
p_open("WL2:A", -1) -9 (E_GEN_INUSE) in use — held by the resident scanner software
p_open("WL2:B" / ":C") (untested)

WL2 has a single unit, so only one process may hold it. WL2:A is permanently -9 even with the demo closed, indicating a resident holder; WL2:D is the unit an application opens.

The 11-byte parameter block

The scanner is configured by an eleven-byte parameter block. The application interprets these bytes and converts them into commands for the selected decoder (so the same block means different wire commands for Symbol2 vs HP, etc.):

Byte Parameter
Param0 Decode security
Param1 Code type (symbology select)
Param2 Decode options A
Param3 Decode options B
Param4 General parameters
Param5 ITF length 1
Param6 ITF length 2
Param7 Preamble
Param8 Postamble byte 1
Param9 Postamble byte 2
Param10 General decode options

The preamble/postamble bytes mean decoded output may carry configurable leading / trailing characters — parsing code must account for them.

Access model

Applications do not drive WL2 byte-by-byte themselves; they use the ROM library SCANNER.DYL (used by SCANAPP.APP and DEMMAN.APP). That library opens the port, converts the 11-byte block to decoder commands, configures and enables the engine, and returns decoded scans.

Paths that do NOT work for the integral laser

Recorded so they are not retried:

  • bar*.ldd decoders (BAREAN, BARC39, …) + BAR: device. These are software decoders for the external wand modules. Loading BAREAN.LDD and opening BAR:A/BAR:B returns -41 (E_FILE_DEVICE, "no interface found in slot") — the integral laser is not a BAR: expansion interface. BAR:D/BAR:E return -38 (E_FILE_NAME, invalid unit).
  • TTY:D serial reads. Opening TTY:D powers the laser (it fires briefly), but no decoded bytes ever arrive on the serial channel — not with default config, not after P_FSET to 9600/8/1, not with P_OBEY_DSR cleared, not with the intelligent-reader escape commands (<Esc>-y1J / <Esc>-y1K), not reading one byte at a time. The integral laser's decoded data is not on TTY:D.

Open gap (not yet solved)

Opening WL2:D succeeds, but the scanner does not start scanning on a bare open — it requires an initialisation sequence (set decoder type, write the 11-byte parameter block as decoder commands, enable the engine) before a read returns data. That sequence is the function-code / control protocol of the WL2 driver and is implemented in the binary SCANNER.DYL; it is not present in any ROM strings or in the SDK.

To close it, one of:

  1. The Workabout MX C SDK scanner header / SCANNER.DYL category definition (what SCANAPP was built against) — the clean answer.
  2. Disassembly of SCANNER.DYL / SCANAPP from the ROM to extract the WL2 init sequence — large, uncertain effort.

Error codes seen (from epocdefs.h)

Value Name Meaning
-9 E_GEN_INUSE device already open / in use
-32 E_FILE_EXIST (LDD) already loaded
-38 E_FILE_NAME invalid device name / unit
-41 E_FILE_DEVICE device / interface not present