hardware:magicolor_scan
no way to compare when less than two revisions
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
— | hardware:magicolor_scan [2013/03/13 10:42] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== 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): | ||
+ | * [[http:// | ||
+ | |||
+ | 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/ | ||
+ | | color depth | 1/8bit | calculation of parameter of 0x03 08 command | | ||
+ | | ADF | present | | | ||
+ | |||
+ | ===== The commands ===== | ||
+ | |||
+ | The scanner uses a binary protocol and reacts to '' | ||
+ | |||
+ | < | ||
+ | * Byte 1: '' | ||
+ | * 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): | ||
+ | * Bytes (n+11)-...: (Optional) Second argument (m bytes) | ||
+ | * ... | ||
+ | * 4 Bytes: 00 00 00 00 - End of command | ||
+ | |||
+ | Known '' | ||
+ | ^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 | | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | * 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 '' | ||
+ | * 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 '' | ||
+ | </ | ||
+ | |||
+ | 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 '' | ||
+ | |||
+ | * LAN: General communication wrapper (using '' | ||
+ | |||
+ | <= 04 00 00 (Some HELO/READY message) | ||
+ | => 04 01 00 89 20 (Greeting by computer) | ||
+ | <= 04 02 00 (ACK by scanner) | ||
+ | [Lots of '' | ||
+ | => 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:// | ||
+ | < | ||
+ | For each captured ' | ||
+ | * a ' | ||
+ | * a ' | ||
+ | |||
+ | 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 ' | ||
+ | </ | ||
+ | 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 ('' | ||
+ | |||
+ | The network functionality uses TCP port 4567 on the scanner. | ||
+ | |||
+ | When talking to a network-attached device, the communication is established by special '' | ||
+ | |||
+ | 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 '' | ||
+ | * **BytesPerLine**: | ||
+ | |||
+ | 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 | | ||
+ | | | | | '' | ||
+ | | | | | '' | ||
+ | | | | | '' | ||
+ | | | | | '' | ||
+ | | | | | USB: '' | ||
+ | |||
+ | 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/ | ||
+ | |\ \ \ |\ \ \ | Byte 5-6 | image pixel per line; x-extent*resolution/ | ||
+ | |\ \ \ |\ \ \ | Byte 7-8 | image lines, typically same as byte 3-4 | | ||
+ | |||
+ | (*) E.g. in B/W a value of '' | ||
+ | In Grayscale a value of '' | ||
+ | In Color a value of '' | ||
+ | |||
+ | 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/ | ||
+ | |\ \ \ |\ \ \ | Byte 2 (8) | Color type: (00=B/W, 02=Grayscale, | ||
+ | |\ \ \ |\ \ \ | Byte 3 (9) | Brightness: '' | ||
+ | |\ \ \ |\ \ \ | Byte 4 (10) | Unknown. Always ' | ||
+ | |\ \ \ |\ \ \ | 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 ('' | ||
+ | |\ \ \ |\ \ \ | Bytes 14-17 (20-23) | Unknown. Always 00 00 00 00 ? FIXME | | ||
+ | ^ Response: NONE^^^^ | ||
+ | |||
+ | (1) The x-/ | ||
+ | |||
+ | ^ Format | ||
+ | | A4 | ||
+ | | | ||
+ | | A6 | ||
+ | | | ||
+ | | FBF | X | | ||
+ | | | ||
+ | |||
+ | 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, | ||
+ | ^ Response: ^^^^ | ||
+ | |\ \ \ |\ \ \ | Bytes 1-... | Scanned data ([[hardware: | ||
+ | |||
+ | Typical call: | ||
+ | 03 0e 04 00 00 00 00 fe 00 00 | ||
+ | | ||
+ | |||
+ | |||
+ | ==== 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 '' | ||
+ | |||
+ | 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) ===== | ||
+ | |||
+ | ' | ||
+ | |||
+ | === 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, | ||
+ | |||
+ | Interesting OIDs (used by the windows driver to detect the device): | ||
+ | * 1.3.6.1.2.1.1.1.0 (SNMPv2-MIB:: | ||
+ | * 1.3.6.1.2.1.1.2.0 (SNMPv2-MIB:: | ||
+ | * 1.3.6.1.2.1.2.2.1.6.1 (IF-MIB:: | ||
+ | |||
+ | [[: | ||
+ | |||
+ | ===== 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 '' | ||
+ | |||
+ | 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 '' | ||
+ | |||
+ | <box 700px orange round> | ||
+ | {{: | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== 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 '' | ||
+ | |||
+ | ==== 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 '' | ||
+ | ==== 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: | ||
+ | * [[hardware: | ||
+ | * [[hardware: |
hardware/magicolor_scan.txt · Zuletzt geändert: 2013/03/13 10:42 von 127.0.0.1