Benutzer-Werkzeuge

Webseiten-Werkzeuge


hardware:magicolor_scan
The Scanning Protocol of the Konica Minolta 1690MF

The Scanning Protocol of the Konica Minolta 1690MF

All contents on this page were obtained through observing the communication between the Windows WIA and TWAIN drivers (using the standard windows scanning wizzart) and the multi-function printer connected on the LAN (using wireshark). The purpose is solely for documentational purposes, so that I will be able to write a proper SANE backend to support this device. I do not have any access to any internal documentation of the device or protocol :( I also did not disassemble the windows driver, just looked at the commands sent over the local network.

Scanner hardware details

The protocol described in this document is used at least by the following devices (other devices might use the same protocol, but I have not had access to any of them):

The following values need to be hardcoded in the driver, There is no command to retrieve those values from the scanner!

type value used for
optical resolution 600dpi top/left/width/height of scan area
color depth 1/8bit calculation of parameter of 0x03 08 command
ADF present

The commands

The scanner uses a binary protocol and reacts to 03 xx xx commands, which might have additional arguments. Each command sent to the scanner has a fixed size (LAN: 64 bytes, USB: 72 bytes), which is padded with 00 if the command does not use arguments of the full length.

General structure of commands:

  • Byte 1: 03 for scanner commands, 04 for LAN communication wrapper (1 byte)
  • Byte 2: The actual command (1 byte)
  • Bytes 3-6: Length n of first argument (4 bytes in little endian!)
  • Bytes 7-(n+6): First argument (n bytes)
  • Byte2 (n+7)-(n+10): (Optional) Length m of second argument (4 bytes in little endian!)
  • Bytes (n+11)-…: (Optional) Second argument (m bytes)
  • 4 Bytes: 00 00 00 00 - End of command

Known 03 scanner commands:

Command meaning
03 08 Start scan
03 09 Poll for error
03 0a Stop scan / cleanup
03 0b Query image parameters
03 0c Scan settings
03 0d Get status
03 0e Read data
03 0f Unknown (Get buttons?)
03 12 End of scan

Difference between USB and LAN packets sent to scanner:

  • LAN packets: exactly 64 bytes, command starts at first byte
    • The first 2 bytes of the 64-byte block indicate the command
    • Remaining bytes are optionally used for arguments to the command
  • USB packets: always 72 bytes, command starts at the 25-th byte!
    • The first 24 bytes are mostly 00 (byte 17, i.e. 0x10, is typically 01) FIXME
    • Bytes 25/26 indicate the command
    • Remaining bytes are optionally used for arguments to the command

Typically, only 3/8/16/20 bytes will be used for the command, the remaining bytes of the 64/72 byte blocks are padded with 0x00.

NOTE: The padded bytes to fill the 64/72-byte blocks are truncated in all commands and sniffs below.

Communication wrapper

  • USB: No communication wrapper, only 03 xx xx commands; basically polling for status with 03 09 01 until the scan is initiated.
  • LAN: General communication wrapper (using 04 xx xx commands, which have no fixed data size):
<= 04 00 00       (Some HELO/READY message)
=> 04 01 00 89 20 (Greeting by computer)
<= 04 02 00       (ACK by scanner)
[Lots of ''03 xx xx'' commands by computer, response data by scanner]
=> 04 03 00       (BYE)

USB communication

The device uses endpoint #3 (0x03, OUT) for requests sent to the scanner and endpoint #5 (0x85, IN as bit #7 determines IN/OUT of the endpoint as seen from the host=computer) for data sent by the scanner.

Each command sent to the scanner on endpoint 0x03 is answered on endpoint 0x03 by „00 00 00 00 00 00 00 00“. Similarly, when reading data from endpoint 0x85, the computer first sends „00 00 00 00 00 00 00 00“ to the scanner on endpoing 0x85, after which the data is received. This is the general way USB data transfers work. See for example http://wiki.wireshark.org/USB:

For each captured 'packet' (URB, using the USB terminology) the kernel (and thus libpcap) provides two 'events':

  • a 'submit', issued when the USB data transfer begins
  • a 'completion' or an 'error', issed after the data transfer completion.

The USB data is present only in one of two events associated with an URB. If the transfer direction is from the host to the device, the data is present in the 'submit' event, otherwise the data is present in the 'completion' event. The amount of data effectively present into the event can be less than the amount of data effectively exchanged.

The completion event for transfers to the scanner and the submit event for transfers from the scanner are always '00 00 00 00 00 00 00 00' and will be neglected in all data sniffs below. The events containing the data seem to have an 8-byte header, too, which is also always null, i.e. '00 00 00 00 00 00 00 00'.

LAN communication (''04'' commands)

The network functionality uses TCP port 4567 on the scanner.

When talking to a network-attached device, the communication is established by special 04 … commands. If they are successfull, then the usual 03 commands are used for the actual scanner commands. At the end of a session, 04 commands are again used to close the session.

These commands are only used when the scanner is connected via the LAN (not via USB). The data length is not padded and is 3 (or 5) bytes exactly, with no further trailing 00.

Dir. Cmd Arguments Description
04 00 Status Welcome message by scanner, Status: 00=OK, 01=BUSY
04 01 00 USB-ID Response by Computer, USB-ID in little endian (e.g. 89 20 for the magicolor 1690MF with USB-ID 132b:2089)
04 02 ACK Acknowledgement by scanner, ACK=00 for OK, ACK=01 for NOT OK (e.g. invalid USB-ID sent in 04 01 command)
04 03 00 BYE command sent by the computer to the scanner

All commands with arguments and responses

03 08: Start scan with given parameters

03 08 (Bytes 1-2) Initiate the scan with given parameters
    04 00 00 00 (Bytes 3-6) Length arg1 (4 bytes)
       Bytes 1-4 (7-10) arg1: Expected return data size: Lines*BytesPerLine (see below)
    01 00 00 00 (Bytes 11-14) Length arg2 (1 byte)
       Byte 1 (15) Unknown FIXME
Response: NONE

Notes for data size (bytes 7-10):

  • Lines: Value from Bits 3-4 of the 03 0b return value
  • BytesPerLine: image pixels per line (bits 1-2 of the 03 0b call) * depth/8 * colors

Typical call:

    03 08 04 00 00 00 00 6e  10 00 01 00 00 00 00 ...

03 09: Poll for error

03 09 (Bytes 1-2) Poll for error
    01 00 00 00 (Bytes 3-6) Length arg1 (1 bytes)
       Byte 1 (7) arg1: Unused? Always 00
Response:
       Byte 1 Error code
00 … OK
01 … error (feeder, etc)
02 … Printer open (front or top door, not ADF!)
03 … already locked (already scanning, web frontend, communication error occured and waiting for button press etc.)
USB: 00 00 00 00 00 00 00 00 for OK

Typical call:

   03 09 01 00 ...
        01

03 0a: Cancel scan

03 0a (Bytes 1-2) Cancel a scan
    00 00 00 00 (Bytes 3-6) Length arg1 (0 bytes)
Response: NONE

Typical call:

   03 0a 00 00 00 00 ...

This command is sent when either the scan was cancelled manually (i.e. the cancel button in the frontend was pressed), or to reset the printer when an error occured (like a paper jam).

03 0b: Query image parameters

03 0b (Bytes 1-2) Query image parameters
    08 00 00 00 (Bytes 3-6) Length arg1 (8 bytes)
       Bytes 1-8 (7-14) arg1: Unused? Always 00 FIXME
Response:
       Byte 1-2 #pixels returned per line(*), padding to multiples of 512 bytes is included, little endian
       Byte 3-4 #lines returned; y-extent*resolution/600dpi, little endian
       Byte 5-6 image pixel per line; x-extent*resolution/600dpi, little endian
       Byte 7-8 image lines, typically same as byte 3-4

(*) E.g. in B/W a value of 0x1000 means 4096 pixel = 512 bytes at 1 bit depth. In Grayscale a value of 0x0200 means 512 pixel = 512 bytes at 8 bith depth, 0x0600 means 1536 pixel(=bytes). In Color a value of 0x0a00 means 2560 pixel (i.e. 2560 bytes per color channel at 8 bith depth).

Only the number of pixels given in bytes 5-6 is really used, the remaining pixels returned by the scanner appear to be random memory dump data (i.e. some intermediate data from internal image processing, without any useful purpose).

Typical call:

   03 0b 08 00 00 00 00 00 00 00 00 00 00 00 ...
        00 10 e5 06 e4 04 e5 06

03 0c: Settings for the scan

03 0c (Bytes 1-2) Set scan options
    11 00 00 00 (Bytes 3-6) Length arg1 (17 bytes)
       Byte 1 (7) Resolution: (00=150dpi, 01=300dpi, 02=600dpi), 1200dpi/2400dpi not supported (also uses 02)
       Byte 2 (8) Color type: (00=B/W, 02=Grayscale, 03=Color)
       Byte 3 (9) Brightness: 05=0, 01=-127, 09=+127
       Byte 4 (10) Unknown. Always 'ff' FIXME
       Byte 5-6 (11-12) x-Start, little endian, pixel in optical resolution(=600dpi)
       Byte 7-8 (13-14) y-Start, little endian, pixel in optical resolution(=600dpi)
       Byte 9-10 (15-16) x-Extent, little endian, pixel in optical resolution(=600dpi) (1)
       Byte 11-12 (17-18) y-Extent, little endian, pixel in optical resolution(=600dpi) (1)
       Byte 13 (19) Source (00 is flatbed, 01 is ADF)
       Bytes 14-17 (20-23) Unknown. Always 00 00 00 00 ? FIXME
Response: NONE

(1) The x-/y-Extents are given in 600dpi (i.e. optical resolution), but with some additional padding. For example, A4 (21×29.7cm) would be 4960,63×7015,75 pixel, but the actual extent sent to the scanner is 5008×7060. The values are not padded to some multiple of 8, 16 or so! Some reference values:

Format real size real pixel sent pixel difference
A4 X 21cm 4960.63 5008 (0x1390) +47.37
Y 29.7cm 7015.75 7060 (0x1b94) +44.25
A6 X 10.5cm 2480.31 2528 (0x09e0) +47.69
Y 14.85cm 3507.87 3544 (0x0dd8) +36.13
FBF X 5112 (0x13f8)
Y 8412 (0x20dc)

Typical call:

   03 0c 11 00 00 00 00 00  05 ff 00 00 00 00 f8 13  dc 20 00 00 00 00 00

03 0d: Get status?

03 0d (Bytes 1-2) Get status?
    0b 00 00 00 (Bytes 3-6) Length arg1 (11 bytes)
       Bytes 1-11 (7-18) arg1: Unused? Always 00
Response:
       Byte 1 Unknown, LAN: always ff, USB: 00
       Byte 2 ADF status (00=no doc loaded, 01=doc loaded)
       Byte 3-11 Unknown, always 00? FIXME

Typical call:

   03 0d 0b 00 00 00 00 00  00 00 00 00 00 00 00 00  00
        ff 00 00 00 00 00 00 00  00 00 00

Typical response:

  LAN: ff 00 00 00 00 00 00 00  00 00 00
  USB: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   00 02 00
  
  

03 0e: Read scanned data

03 0b (Bytes 1-2) Read scanned data
    04 00 00 00 (Bytes 3-6) Length arg1 (4 bytes)
       Bytes 1-4 (7-10) arg1: length of requested data chunk in bytes (should be a multiple of bytes_per_line, typically 0xf000 or 0xfa00 or 0xfe00, i.e. 0xef00=61184 bytes, last request will be shorter)
Response:
       Bytes 1-… Scanned data (format see below)

Typical call:

   03 0e 04 00 00 00 00 fe  00 00
       [0xFE00 bytes of scan data sent to computer]
       

03 0f: Unknown

FIXME

03 0f (Bytes 1-2) Unknown
    01 00 00 00 (Bytes 3-6) Length arg1 (1 bytes)
       Byte 1 (7) arg1: Unused? Always 00
Response:
       Byte 1 Unknown, always 00

Typical call:

   03 0f 01 00 00 00 00
       00

Ilia Sotnikov: function is „Get buttons“

03 12: Unknown

FIXME

03 12 (Bytes 1-2) Unknown
    0b 00 00 00 (Bytes 3-6) Length arg1 (11 bytes)
       Bytes 1-11 (7-17) arg1: Unused? Always 00
Response:
       Bytes 1-11 Unknown, always 00?

Typical call:

   03 12 0b 00 00 00 00 00  00 00 00 00 00 00 00 00  00
       00 00 00 00 00 00 00 00  00 00 00

Typical response:

   LAN: 00 00 00 00 00 00 00 00  00 00 00
   USB: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   00 02 00

Further commands, not (yet?) found with the 1690MF

Ilia Sotnikov has decoded the USB data flow of the BizHub 162/132 and DiMage 1611 devices, which are B/W only and USB only.

03 10: Set button wait

FIXME

03 10 (Bytes 1-2) Set button wait
    0? 00 00 00 (Bytes 3-6) Length arg1 (? bytes)
       Bytes 7-? arg1: ?
Response: ?

Sequence of commands of a typical communication (Pseudo-code)

'⇒' indicates data/command sent to scanner, '⇐' indicated data returned by the scanner (request data packet omitted here!):

Handshake / Opening connection

FIXME

Scanning operation

FIXME

Error handling

FIXME

LAN: Device and capabilities detection via SNMP

The Windows installer apparently employs SNMP to detect network-connected devices. An SNMP broadcast is sent to the address 255.255.255.255, and if SNMP is enabled on the scanner, it will respond properly.

Interesting OIDs (used by the windows driver to detect the device):

  • 1.3.6.1.2.1.1.1.0 (SNMPv2-MIB::sysDescr.0) = STRING: KONICA MINOLTA magicolor 1690MF
  • 1.3.6.1.2.1.1.2.0 (SNMPv2-MIB::sysObjectID.0) = OID: SNMPv2-SMI::enterprises.18334.1.1.1.1.1.23.1.1
  • 1.3.6.1.2.1.2.2.1.6.1 (IF-MIB::ifPhysAddress.1) = STRING: 0:20:6b:cc:6:77

All SNMP OIDs supported by the device

Image format returned by the scanner

The data format is fairly simple: Simply one pixel after each other, one line after each other (without any newline indicators).

There is no image header returned. All image size information must be used from the 03 0b request call for pixels_per_line and from the argument passed to the 03 08 start scan command for the BytesPerLine value.

The only pitfall is that each line always uses a multiple of 512 bytes (the exact number of data pixels per line is returned in the 03 08 call and needs to be uses, as there is no other obvious way to calculate the value), so some additional bytes are added to pad each line to such a multiple. When passing on the image data to a scanning frontend, one needs to make sure these additional padding pixels are ignored. The following image shows an example of the whole FBF area and the actuall image sent by the scanner (where each line uses at least 512 bytes). Most of the image data sent by the scanner must be ignored:

Sample scan

The scanned FBF area is only a small part of the whole image returned from the scanner. The extensions of the scanned area (framed in red) and the whole returned area are both returned by the ''03 0b'' command.

Black & White, Lineart

The image data for 1-bit B/W is simply a bit-by-bit representation of the scanned data, i.e. 8 pixels per byte, one byte after the other. Each line uses exactly BytesPerLine bytes (i.e. a multiple of 512 bytes!), where only the first PixelsPerLine bits are used, the rest can and should be ignored.

Grayscale

The image data for 8-bit Grayscale is simply a byte-by-byte representation of the scanned data, i.e. 1 pixel per byte, one byte after the other. Each line uses exactly BytesPerLine bytes (i.e. a multiple of 512 bytes!), where only the first PixelsPerLine bytes are used, the rest can and should be ignored.

Color

The format of color scans is the same as for Grayscale images, with the only difference that the R/G/B scan data is returned one line after the other (each of them is padded as described above!). So the individual values for the RGB bytes of one pixel are actually scan_pixels_per_line apart in the returned data.

Open questions

  • Are the padding bytes useful in any way?

Example communications

hardware/magicolor_scan.txt · Zuletzt geändert: 2013/03/13 10:42 (Externe Bearbeitung)