1/* sane - Scanner Access Now Easy.
2
3   pieusb_scancmd.c
4
5   Copyright (C) 2012-2015 Jan Vleeshouwers, Michael Rickmann, Klaus Kaempf
6
7   This file is part of the SANE package.
8
9   This program is free software; you can redistribute it and/or
10   modify it under the terms of the GNU General Public License as
11   published by the Free Software Foundation; either version 2 of the
12   License, or (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
22   As a special exception, the authors of SANE give permission for
23   additional uses of the libraries contained in this release of SANE.
24
25   The exception is that, if you link a SANE library with other files
26   to produce an executable, this does not by itself cause the
27   resulting executable to be covered by the GNU General Public
28   License.  Your use of that executable is in no way restricted on
29   account of linking the SANE library code into it.
30
31   This exception does not, however, invalidate any other reasons why
32   the executable file might be covered by the GNU General Public
33   License.
34
35   If you submit changes to SANE to the maintainers to be included in
36   a subsequent release, you agree by submitting the changes that
37   those changes may be distributed with this exception intact.
38
39   If you write modifications of your own for SANE, it is your choice
40   whether to permit this exception to apply to your modifications.
41   If you do not wish that, delete this exception notice.  */
42
43/* =========================================================================
44 *
45 * Pieusb scanner commands
46 *
47 * Each scanner command has its own function.
48 * See the sort description preceding each function.
49 *
50 * ========================================================================= */
51
52#define DEBUG_DECLARE_ONLY
53
54#include "pieusb.h"
55#include "pieusb_scancmd.h"
56#include "pieusb_usb.h"
57
58#ifdef HAVE_ALLOCA_H
59#include <alloca.h>
60#endif
61
62#include <time.h> /* for time() */
63
64static void _prep_scsi_cmd(SANE_Byte* command_bytes, SANE_Byte command, SANE_Word size);
65
66/* =========================================================================
67 *
68 * Pieusb utility functions
69 *
70 * ========================================================================= */
71
72/*
73 * Get the unsigned char value in the array at given offset
74 */
75static SANE_Byte
76_get_byte(SANE_Byte* array, SANE_Byte offset) {
77    return *(array+offset);
78}
79
80/*
81 * Set the array at given offset to the given unsigned char value
82 */
83static void
84_set_byte(SANE_Byte val, SANE_Byte* array, SANE_Byte offset) {
85    *(array+offset) = val;
86}
87
88
89/*
90 * Get the unsigned short value in the array at given offset.
91 * All data in structures is little-endian, so the LSB comes first
92 * SANE_Int is 4 bytes, but that is not a problem.
93 */
94static SANE_Int
95_get_short(SANE_Byte* array, SANE_Byte offset) {
96    SANE_Int i = *(array+offset+1);
97    i <<= 8;
98    i += *(array+offset);
99    return i;
100}
101
102
103/*
104 * Put the bytes of a short int value into an unsigned char array
105 * All data in structures is little-endian, so start with LSB
106 */
107static void
108_set_short(SANE_Word val, SANE_Byte* array, SANE_Byte offset) {
109    *(array+offset) = val & 0xFF;
110    *(array+offset+1) = (val>>8) & 0xFF;
111}
112
113
114/*
115 * Get the signed int value in the array at given offset.
116 * All data in structures is little-endian, so the LSB comes first
117 */
118static SANE_Int
119_get_int(SANE_Byte* array, SANE_Byte offset) {
120    SANE_Int i = *(array+offset+3);
121    i <<= 8;
122    i += *(array+offset+2);
123    i <<= 8;
124    i += *(array+offset+1);
125    i <<= 8;
126    i += *(array+offset);
127    return i;
128}
129
130#if 0 /* unused */
131/*
132 * Put the bytes of a signed int value into an unsigned char array
133 * All data in structures is little-endian, so start with LSB
134 */
135static void
136_set_int(SANE_Word val, SANE_Byte* array, SANE_Byte offset) {
137    *(array+offset) = val & 0xFF;
138    *(array+offset+1) = (val>>8) & 0xFF;
139    *(array+offset+2) = (val>>16) & 0xFF;
140    *(array+offset+3) = (val>>24) & 0xFF;
141}
142#endif
143
144/*
145 * Copy count unsigned char values from src to dst
146 */
147static void
148_copy_bytes(SANE_Byte* dst, SANE_Byte* src, SANE_Byte count) {
149    SANE_Byte k;
150    for (k=0; k<count; k++) {
151        *dst++ = *src++;
152    }
153}
154
155
156/*
157 * Get count unsigned short values in the array at given offset.
158 * All data in structures is little-endian, so the MSB comes first.
159 * SANE_Word is 4 bytes, but that is not a problem.
160 */
161static void
162_get_shorts(SANE_Word* dst, SANE_Byte* src, SANE_Byte count) {
163    SANE_Byte k;
164    for (k=0; k<count; k++) {
165        *dst = *(src+2*k+1);
166        *dst <<= 8;
167        *dst++ += *(src+2*k);
168    }
169}
170
171/*
172 * Copy an unsigned short array of given size
173 * All data in structures is little-endian, so start with MSB of each short.
174 * SANE_Word is 4 bytes, but that is not a problem. All MSB 2 bytes are ignored.
175 */
176static void
177_set_shorts(SANE_Word* src, SANE_Byte* dst, SANE_Byte count) {
178    SANE_Byte k;
179    for (k=0; k<count; k++) {
180        *(dst+2*k) = *src & 0xFF;
181        *(dst+2*k+1) = ((*src++)>>8) & 0xFF;
182    }
183}
184
185
186/**
187 * Perform a TEST UNIT READY (SCSI command code 0x00)
188 * Returns status->pieusb_status:
189 * - PIEUSB_STATUS_GOOD if device is ready
190 * - PIEUSB_STATUS_DEVICE_BUSY if device is still busy after timeout
191 * - other SANE status code if TEST UNIT READY failed or if it returned
192 *   CHECK CONDITION and REQUEST SENSE failed
193 *
194 * @param device_number Device number
195 * @return Pieusb_Command_Status SANE_STATUS_GOOD if ready, SANE_STATUS_DEVICE_BUSY if not
196 */
197void
198sanei_pieusb_cmd_test_unit_ready(SANE_Int device_number, struct Pieusb_Command_Status *status)
199{
200    SANE_Byte command[SCSI_COMMAND_LEN];
201
202    DBG (DBG_info_scan, "sanei_pieusb_cmd_test_unit_ready()\n");
203
204    _prep_scsi_cmd (command, SCSI_TEST_UNIT_READY, 0);
205
206    status->pieusb_status = sanei_pieusb_command (device_number, command, NULL, 0);
207
208    DBG (DBG_info_scan, "sanei_pieusb_cmd_test_unit_ready() return status = %s\n",
209         sane_strstatus (sanei_pieusb_convert_status (status->pieusb_status)));
210}
211
212/**
213 * slide action
214 * @param action  SLIDE_NEXT, SLIDE_PREV, SLIDE_INIT, SLIDE_RELOAD
215 * @return Pieusb_Command_Status
216 */
217
218void
219sanei_pieusb_cmd_slide(SANE_Int device_number, slide_action action, struct Pieusb_Command_Status *status)
220{
221    SANE_Byte command[SCSI_COMMAND_LEN];
222#define SLIDE_DATA_SIZE 4
223    SANE_Byte data[SLIDE_DATA_SIZE];
224
225    DBG (DBG_info_scan, "sanei_pieusb_cmd_slide(0x%02x)\n", action);
226
227    _prep_scsi_cmd(command, SCSI_SLIDE, SLIDE_DATA_SIZE);
228    memset(data, '\0', SLIDE_DATA_SIZE);
229    data[0] = action;
230    data[1] = 0x01;
231
232    status->pieusb_status = sanei_pieusb_command(device_number, command, data, SLIDE_DATA_SIZE);
233#undef SLIDE_DATA_SIZE
234}
235
236/**
237 * Perform a REQUEST SENSE (SCSI command code 0x03)
238 * Returns status->pieusb_status:
239 * - PIEUSB_STATUS_GOOD is the command executes OK
240 * - other SANE status code if REQUEST SENSE fails
241 * The sense fields in status are always 0. A REQUEST SENSE is not repeated if
242 * the device returns PIEUSB_STATUS_DEVICE_BUSY.
243 *
244 * @param device_number Device number
245 * @param sense Sense data
246 * @param status Command result status
247 * @see struct Pieusb_Sense
248 */
249void
250sanei_pieusb_cmd_get_sense(SANE_Int device_number, struct Pieusb_Sense* sense, struct Pieusb_Command_Status *status, PIEUSB_Status *ret)
251{
252    SANE_Byte command[SCSI_COMMAND_LEN];
253#define DATA_SIZE 14
254    SANE_Int size = DATA_SIZE;
255    SANE_Byte data[DATA_SIZE];
256    PIEUSB_Status st;
257  SANE_Char* sd;
258
259    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_sense()\n");
260
261    _prep_scsi_cmd(command, SCSI_REQUEST_SENSE, size);
262
263    memset(data, '\0', size);
264    st = sanei_pieusb_command(device_number, command, data, size);
265    if (st != PIEUSB_STATUS_GOOD) {
266      status->pieusb_status = st;
267      /*FIXME*/
268        return;
269    }
270
271    /* Decode data received */
272    sense->errorCode = _get_byte (data, 0);
273    sense->segment = _get_byte (data, 1);
274    sense->senseKey = _get_byte (data, 2);
275    _copy_bytes (sense->info, data+3, 4);
276    sense->addLength = _get_byte (data, 7);
277    _copy_bytes (sense->cmdInfo, data+8, 4);
278    sense->senseCode = _get_byte (data, 12);
279    sense->senseQualifier = _get_byte (data, 13);
280    status->pieusb_status = PIEUSB_STATUS_GOOD;
281#undef DATA_SIZE
282  DBG (DBG_info_scan, "\tsense details:\n");
283  DBG (DBG_info_scan, "\t\terror......... : 0x%02x\n", sense->errorCode);
284  DBG (DBG_info_scan, "\t\tsegment....... : %d\n", sense->segment);
285  DBG (DBG_info_scan, "\t\tsenseKey...... : 0x%02x\n", sense->senseKey);
286  DBG (DBG_info_scan, "\t\tinfo.......... : %02x %02x %02x %02x\n", sense->info[0], sense->info[1], sense->info[2], sense->info[3]);
287  DBG (DBG_info_scan, "\t\taddLength..... : %d\n", sense->addLength);
288  DBG (DBG_info_scan, "\t\tcmdInfo....... : %02x %02x %02x %02x\n", sense->cmdInfo[0], sense->cmdInfo[1], sense->cmdInfo[2], sense->cmdInfo[3]);
289  DBG (DBG_info_scan, "\t\tsenseCode..... : 0x%02x\n", sense->senseCode);
290  DBG (DBG_info_scan, "\t\tsenseQualifier : 0x%02x\n", sense->senseQualifier);
291  sd = sanei_pieusb_decode_sense (sense, ret?ret:&st);
292  DBG (DBG_info_scan, "\tsense: %s\n", sd);
293  free(sd);
294}
295
296/**
297 * Read the scan frame with the specified index. This requires two
298 * commands, one to ask the device to prepare the pattern, and one to read it.
299 *
300 * @param device_number Device number
301 * @param frame Scan frame
302 * @return Pieusb_Command_Status
303 * @see Pieusb_Scan_Frame
304 */
305void
306sanei_pieusb_cmd_get_scan_frame(SANE_Int device_number, SANE_Int index, struct Pieusb_Scan_Frame* frame, struct Pieusb_Command_Status *status)
307{
308    SANE_Byte command[SCSI_COMMAND_LEN];
309#define FRAME_SIZE 256 /* Assumed maximum frame size */
310    SANE_Int size = FRAME_SIZE;
311    SANE_Byte data[FRAME_SIZE];
312    PIEUSB_Status st;
313
314    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_scan_frame()\n");
315
316    /* Ask scanner to prepare the scan frame with the given index. Only SCSI_COMMAND_LEN bytes of data. */
317    _prep_scsi_cmd (command, SCSI_WRITE, SCSI_COMMAND_LEN);
318    memset (data, '\0', SCSI_COMMAND_LEN);
319    data[0] = SCSI_SCAN_FRAME | 0x80; /* set bit 7 means prepare read */
320    data[4] = index;
321
322    st = sanei_pieusb_command (device_number, command, data, SCSI_COMMAND_LEN);
323    if (st != PIEUSB_STATUS_GOOD) {
324      status->pieusb_status = st;
325      /* FIXME */
326        return;
327    }
328
329    /* Read scan frame */
330    _prep_scsi_cmd (command, SCSI_READ, size);
331
332    memset(data, '\0', size);
333    status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
334
335    /* Decode data */
336    frame->index = _get_byte (data, 4);
337    frame->x0 = _get_short (data, 6);
338    frame->y0 = _get_short (data, 8);
339    frame->x1 = _get_short (data, 10);
340    frame->y1 = _get_short (data, 12);
341
342    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_scan_frame() set:\n");
343    DBG (DBG_info_scan, " x0,y0 = %d,%d\n", frame->x0, frame->y0);
344    DBG (DBG_info_scan, " x1,y1 = %d,%d\n", frame->x1, frame->y1);
345    DBG (DBG_info_scan, " index = %d\n", frame->index);
346#undef FRAME_SIZE
347}
348
349/**
350 * command 17 - unknown
351 */
352
353void
354sanei_pieusb_cmd_17(SANE_Int device_number, SANE_Int value, struct Pieusb_Command_Status *status)
355{
356    SANE_Byte command[SCSI_COMMAND_LEN];
357#define CMD_17_SIZE 6
358    SANE_Byte data[CMD_17_SIZE];
359
360    DBG (DBG_info_scan, "sanei_pieusb_cmd_17(%d)\n", value);
361
362    _prep_scsi_cmd (command, SCSI_WRITE, CMD_17_SIZE);
363    memset (data, '\0', CMD_17_SIZE);
364    _set_short (SCSI_CMD_17, data, 0);
365    _set_short (2, data, 2);
366    _set_short (value, data, 4);
367
368    status->pieusb_status = sanei_pieusb_command (device_number, command, data, CMD_17_SIZE);
369#undef CMD_17_SIZE
370    if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
371      DBG (DBG_info_scan, "sanei_pieusb_cmd_17 failed: 0x%02x\n", status->pieusb_status);
372      return;
373    }
374}
375
376/**
377 * Read the shading data parameters. This requires two
378 * commands, one to ask the device to prepare the value, and one to read it.
379 *
380 * @param device_number Device number
381 * @param shading Shading data parameters
382 * @return Pieusb_Command_Status
383 * @see Pieusb_Shading_Parameters
384 */
385void
386sanei_pieusb_cmd_get_shading_parms(SANE_Int device_number, struct Pieusb_Shading_Parameters_Info* shading, struct Pieusb_Command_Status *status)
387{
388    SANE_Byte command[SCSI_COMMAND_LEN];
389#define SHADING_SIZE 32
390#define PREP_READ_SIZE 6
391    SANE_Int size = SHADING_SIZE;
392    SANE_Byte data[SHADING_SIZE];
393    int k;
394
395    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_shading_parms()\n");
396
397    /* Ask scanner to prepare the scan frame with the given index. Only SCSI_COMMAND_LEN bytes of data. */
398    _prep_scsi_cmd (command, SCSI_WRITE, SCSI_COMMAND_LEN);
399    memset (data, '\0', PREP_READ_SIZE);
400    data[0] = SCSI_CALIBRATION_INFO | 0x80; /* set bit 7 means prepare read */
401
402    status->pieusb_status = sanei_pieusb_command (device_number, command, data, PREP_READ_SIZE);
403    if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
404      return;
405    }
406
407    /* Read shading parameters */
408    _prep_scsi_cmd(command, SCSI_READ, size);
409
410    memset (data, '\0', size);
411    status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
412    if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
413      return;
414    }
415
416    /* Decode data [32 bytes]
417       0: 95 00 type
418       2: 1c 00 payload len
419       4: 04    entries
420       5: 06    entry size
421       6: 04 00 ?
422       8: 00 10 10 14 1a 1d type send recv nlines pixPerLine(2bytes)
423      14: 08 10 10 14 1a 1d
424      20: 10 10 10 14 1a 1d
425      26: 20 10 10 14 1a 1d
426     */
427    for (k = 0; k < data[4]; k++) {
428        shading[k].type = _get_byte (data, 8 + data[5]*k);
429        shading[k].sendBits = _get_byte (data, 9 + data[5]*k);
430        shading[k].recieveBits = _get_byte (data, 10 + data[5]*k);
431        shading[k].nLines = _get_byte (data, 11 + data[5]*k);
432        shading[k].pixelsPerLine = _get_short (data, 12 + data[5]*k);
433    }
434#undef PREP_READ_SIZE
435#undef SHADING_SIZE
436}
437
438/**
439 * Read scanned data from the scanner memory into a byte array. The lines
440 * argument specifies how many lines will be read, the size argument specifies
441 * the total amount of bytes in these lines. Use sanei_pieusb_cmd_get_parameters() to
442 * determine the current line size and the number of available lines.\n
443 * If there is scanned data available, it should be read. Waiting too long
444 * causes the scan to stop, probably because a buffer is filled to its limits
445 * (if so, it is approximately 2Mb in size). I haven't tried what happens if you
446 * start reading after a stop. Reading to fast causes the scanner to return
447 * a busy status, which is not a problem.
448 * This is a SCSI READ command (code 0x08). It is distinguished from the other
449 * READ commands by the context in which it is issued: see sanei_pieusb_cmd_start_scan().
450 *
451 * @param device_number
452 * @param data
453 * @param lines
454 * @param size
455 * @return Pieusb_Command_Status
456 */
457void
458sanei_pieusb_cmd_get_scanned_lines(SANE_Int device_number, SANE_Byte* data, SANE_Int lines, SANE_Int size, struct Pieusb_Command_Status *status)
459{
460    SANE_Byte command[SCSI_COMMAND_LEN];
461
462    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_scanned_lines(): %d lines (%d bytes)\n", lines, size);
463
464    _prep_scsi_cmd (command, SCSI_READ, lines);
465    memset (data, '\0', size);
466
467    status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
468}
469
470/**
471 * Set the scan frame with the given index to the frame. The command is a SCSI
472 * WRITE command (code SCSI_WRITE, write code SCSI_SCAN_FRAME).
473 *
474 * @param device_number Device number
475 * @param index Frame index (0-7)
476 * @param frame Scan frame
477 * @return Pieusb_Command_Status
478 * @see Pieusb_Scan_Frame
479 */
480void
481sanei_pieusb_cmd_set_scan_frame(SANE_Int device_number, SANE_Int index, struct Pieusb_Scan_Frame* frame, struct Pieusb_Command_Status *status)
482{
483    SANE_Byte command[SCSI_COMMAND_LEN];
484#define FRAME_SIZE 14
485    SANE_Int size = FRAME_SIZE;
486    SANE_Byte data[FRAME_SIZE];
487
488    DBG (DBG_info_scan, "sanei_pieusb_cmd_set_scan_frame()\n");
489
490    _prep_scsi_cmd(command, SCSI_WRITE, size);
491
492    DBG (DBG_info_scan, " x0,y0 = %d,%d\n", frame->x0, frame->y0);
493    DBG (DBG_info_scan, " x1,y1 = %d,%d\n", frame->x1, frame->y1);
494    DBG (DBG_info_scan, " index = %d\n", index);
495
496    /* Code data */
497    memset (data, '\0', size);
498    _set_short (SCSI_SCAN_FRAME, data, 0);
499    _set_short (size-4, data, 2); /* size: one frame, 5 shorts */
500    _set_short (index, data, 4);
501    _set_short (frame->x0, data, 6);
502    _set_short (frame->y0, data, 8);
503    _set_short (frame->x1, data, 10);
504    _set_short (frame->y1, data, 12);
505
506    status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
507#undef FRAME_SIZE
508}
509
510/**
511 * Set the relative exposure time to the given values. Only the first
512 * Pieusb_Exposure_Time_Color is used. The command is a SCSI
513 * WRITE command (code SCSI_WRITE, write code SCSI_EXPOSURE).
514 *
515 * @param device_number Device number
516 * @param time Relative exposure time
517 * @return Pieusb_Command_Status
518 * @see Pieusb_Exposure_Time
519 */
520void
521sanei_pieusb_cmd_set_exposure_time(SANE_Int device_number, struct Pieusb_Exposure_Time* time, struct Pieusb_Command_Status *status)
522{
523    SANE_Byte command[SCSI_COMMAND_LEN];
524#define EXPOSURE_DATA_SIZE 8
525    SANE_Byte data[EXPOSURE_DATA_SIZE];
526    struct Pieusb_Exposure_Time_Color *exptime;
527    int i;
528
529    DBG (DBG_info_scan, "sanei_pieusb_cmd_set_exposure_time()\n");
530
531    for (i = 0; i < 3; ++i) { /* R, G, B */
532      _prep_scsi_cmd (command, SCSI_WRITE, EXPOSURE_DATA_SIZE);
533      memset (data, '\0', EXPOSURE_DATA_SIZE);
534      exptime = &(time->color[i]);
535      _set_short (SCSI_EXPOSURE, data, 0);
536      _set_short (EXPOSURE_DATA_SIZE-4, data, 2); /* short: RGB, short: value */
537      _set_short (exptime->filter, data, 4);      /* 1: neutral, 2: R, 4: G, 8: B */
538      _set_short (exptime->value, data, 6);
539      status->pieusb_status = sanei_pieusb_command (device_number, command, data, EXPOSURE_DATA_SIZE);
540      if (status->pieusb_status != PIEUSB_STATUS_GOOD)
541	break;
542    }
543
544#undef EXPOSURE_DATA_SIZE
545}
546
547/**
548 * Set the highlight and shadow levels to the given values. Only the first
549 * Pieusb_Highlight_Shadow_Color is used. The command is a SCSI
550 * WRITE command (code SCSI_WRITE, write code SCSI_HIGHLIGHT_SHADOW).
551 *
552 * @param device_number Device number
553 * @param hgltshdw highlight and shadow level
554 * @return Pieusb_Command_Status
555 * @see Pieusb_Highlight_Shadow
556 */
557void
558sanei_pieusb_cmd_set_highlight_shadow(SANE_Int device_number, struct Pieusb_Highlight_Shadow* hgltshdw, struct Pieusb_Command_Status *status)
559{
560    SANE_Byte command[SCSI_COMMAND_LEN];
561#define HIGHLIGHT_SHADOW_SIZE 8
562    SANE_Byte data[HIGHLIGHT_SHADOW_SIZE];
563    struct Pieusb_Highlight_Shadow_Color *color;
564    int i;
565
566    DBG (DBG_info_scan, "sanei_pieusb_cmd_set_highlight_shadow()\n");
567
568    for (i = 0; i < 3; ++i) { /* R, G, B */
569      _prep_scsi_cmd (command, SCSI_WRITE, HIGHLIGHT_SHADOW_SIZE);
570      memset (data, '\0', HIGHLIGHT_SHADOW_SIZE);
571      color = &(hgltshdw->color[i]);
572      _set_short (SCSI_HIGHLIGHT_SHADOW, data, 0);
573      _set_short (HIGHLIGHT_SHADOW_SIZE-4, data, 2); /* short: RGB, short: value */
574      _set_short (color->filter, data, 4);      /* 1: neutral, 2: R, 4: G, 8: B */
575      _set_short (color->value, data, 6);
576      status->pieusb_status = sanei_pieusb_command (device_number, command, data, HIGHLIGHT_SHADOW_SIZE);
577      if (status->pieusb_status != PIEUSB_STATUS_GOOD)
578	break;
579    }
580
581#undef HIGHLIGHT_SHADOW_SIZE
582}
583
584/* SCSI PARAM, code 0x0F */
585/**
586 * Get the parameters of an executed scan, such as width, lines and bytes, which
587 * are needed to calculate the parameters of the READ-commands which read the
588 * actual scan data.
589 *
590 * @param device_number Device number
591 * @param parameters Scan parameters
592 * @return Pieusb_Command_Status
593 * @see Pieusb_Scan_Parameters
594 */
595void
596sanei_pieusb_cmd_get_parameters(SANE_Int device_number, struct Pieusb_Scan_Parameters* parameters, struct Pieusb_Command_Status *status)
597{
598    SANE_Byte command[SCSI_COMMAND_LEN];
599#define PARAMETER_SIZE 18
600    SANE_Int size = PARAMETER_SIZE;
601    SANE_Byte data[PARAMETER_SIZE];
602
603    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_parameters()\n");
604
605    _prep_scsi_cmd (command, SCSI_PARAM, size);
606    memset (data, '\0', size);
607
608    status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
609    if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
610        return;
611    }
612
613    /* cyberview:
614     * 0: e6 02       width 0x2e6 - 742
615     * 2: e0 02       lines 0x2e0 - 736
616     * 4: e6 02       bytes 0x2e6 - 742
617     * 6: 08          filterOffeset1 8
618     * 7: 08          filterOffset2  8
619     * 8: c9 1c 00 00 period         7369
620     * c: 00 00       scsi transfer rate
621     * e: d7 00       available lines 215
622     * 10:00 00
623     */
624    /* Decode data received */
625    parameters->width = _get_short(data, 0);
626    parameters->lines = _get_short(data, 2);
627    parameters->bytes = _get_short(data, 4);
628    parameters->filterOffset1 = _get_byte(data, 6);
629    parameters->filterOffset2 = _get_byte(data, 7);
630    parameters->period = _get_int(data, 8); /* unused */
631    parameters->scsiTransferRate = _get_short(data, 12); /* unused */
632    parameters->availableLines = _get_short(data, 14);
633
634    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_parameters() read:\n");
635    DBG (DBG_info_scan, " width = %d\n", parameters->width);
636    DBG (DBG_info_scan, " lines = %d\n", parameters->lines);
637    DBG (DBG_info_scan, " bytes = %d\n", parameters->bytes);
638    DBG (DBG_info_scan, " offset1 = %d\n", parameters->filterOffset1);
639    DBG (DBG_info_scan, " offset2 = %d\n", parameters->filterOffset2);
640    DBG (DBG_info_scan, " available lines = %d\n", parameters->availableLines);
641#undef PARAMETER_SIZE
642}
643
644/**
645 * Read INQUIRY block from device (SCSI command code 0x12). This block contains
646 * information about the properties of the scanner.
647 * Returns status->pieusb_status:
648 * - PIEUSB_STATUS_GOOD if the INQUIRY command succeeded
649 * - PIEUSB_STATUS_DEVICE_BUSY if device is busy after repeat retries
650 * - other SANE status code if INQUIRY failed or if it returned CHECK CONDITION
651 *   and REQUEST SENSE failed
652 *
653 * @param device_number Device number
654 * @param data Input or output data buffer
655 * @param size Size of the data buffer
656 * @return Pieusb_Command_Status
657 * @see Pieusb_Scanner_Properties
658 */
659void
660sanei_pieusb_cmd_inquiry(SANE_Int device_number, struct Pieusb_Scanner_Properties* inq, SANE_Byte size, struct Pieusb_Command_Status *status)
661{
662    SANE_Byte command[SCSI_COMMAND_LEN];
663#define INQUIRY_SIZE 256
664    SANE_Byte data[INQUIRY_SIZE];
665    int k;
666
667    DBG (DBG_info_scan, "sanei_pieusb_cmd_inquiry()\n");
668
669    _prep_scsi_cmd (command, SCSI_INQUIRY, size);
670    memset (data, '\0', INQUIRY_SIZE); /* size may be less than INQUIRY_SIZE, so prevent returning noise */
671
672    status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
673    if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
674        return;
675    }
676
677    /* Decode data received */
678    inq->deviceType = _get_byte(data, 0);
679    inq->additionalLength = _get_byte(data, 4);
680    _copy_bytes((SANE_Byte*)(inq->vendor), data+8, 8); /* Note: not 0-terminated */
681    _copy_bytes((SANE_Byte*)(inq->product), data+16, 16); /* Note: not 0-terminated */
682    _copy_bytes((SANE_Byte*)(inq->productRevision), data+32, 4); /* Note: not 0-terminated */
683    /* 1st Vendor-specific block, 20 bytes, see pie_get_inquiry_values(), partially: */
684    inq->maxResolutionX = _get_short(data, 36);
685    inq->maxResolutionY = _get_short(data, 38);
686    inq->maxScanWidth = _get_short(data, 40);
687    inq->maxScanHeight = _get_short(data, 42);
688    inq->filters = _get_byte(data, 44);
689    inq->colorDepths = _get_byte(data, 45);
690    inq->colorFormat = _get_byte(data, 46);
691    inq->imageFormat = _get_byte(data, 48);
692    inq->scanCapability = _get_byte(data, 49);
693    inq->optionalDevices = _get_byte(data, 50);
694    inq->enhancements = _get_byte(data, 51);
695    inq->gammaBits = _get_byte(data, 52);
696    inq->lastFilter = _get_byte(data, 53);
697    inq->previewScanResolution = _get_short(data, 54);
698    /* 2nd vendor specific block (36 bytes at offset 96) */
699    _copy_bytes((SANE_Byte*)(inq->firmwareVersion), data+96, 4); inq->firmwareVersion[4]=0x00;
700    inq->halftones = _get_byte(data, 100);
701    inq->minumumHighlight = _get_byte(data, 101);
702    inq->maximumShadow = _get_byte(data, 102);
703    inq->calibrationEquation = _get_byte(data, 103);
704    inq->maximumExposure = _get_short(data ,104);
705    inq->minimumExposure = _get_short(data ,106);
706    inq->x0 = _get_short(data, 108);
707    inq->y0 = _get_short(data, 110);
708    inq->x1 = _get_short(data, 112);
709    inq->y1 = _get_short(data, 114);
710    inq->model = _get_short(data, 116);
711    _copy_bytes((SANE_Byte*)(inq->production), data+120, 4);
712    _copy_bytes((SANE_Byte*)(inq->timestamp), data+124, 20);
713    _copy_bytes((SANE_Byte*)(inq->signature), data+144, 40);
714    /* remove newline in signature */
715    for (k=0; k<40; k++) if (inq->signature[k]==0x0a || inq->signature[k]==0x0d) inq->signature[k]=' ';
716#undef INQUIRY_SIZE
717}
718
719/**
720 * Set scan mode parameters, such as resolution, colors to scan, color depth,
721 * color format, and a couple of scan quality settings (sharpen, skip
722 * calibration, fast infrared). It performs the SCSI-command MODE SELECT,
723 * code 0x15.
724 *
725 * @param device_number Device number
726 * @param mode Mode parameters
727 * @return Pieusb_Command_Status
728 * @see Pieusb_Mode
729 */
730void
731sanei_pieusb_cmd_set_mode(SANE_Int device_number, struct Pieusb_Mode* mode, struct Pieusb_Command_Status *status)
732{
733    SANE_Byte command[SCSI_COMMAND_LEN];
734#define MODE_SIZE 16
735    SANE_Int size = MODE_SIZE;
736    SANE_Byte data[MODE_SIZE];
737    SANE_Byte quality;
738
739    DBG (DBG_info_scan, "sanei_pieusb_cmd_set_mode()\n");
740
741    _prep_scsi_cmd(command, SCSI_MODE_SELECT, size);
742
743    DBG (DBG_info_scan, "sanei_pieusb_cmd_set_mode() set:\n");
744    DBG (DBG_info_scan, " resolution = %d\n", mode->resolution);
745    DBG (DBG_info_scan, " passes = %02x\n", mode->passes);
746    DBG (DBG_info_scan, " depth = %02x\n", mode->colorDepth);
747    DBG (DBG_info_scan, " color format = %02x\n", mode->colorFormat);
748    DBG (DBG_info_scan, " sharpen = %d\n", mode->sharpen);
749    DBG (DBG_info_scan, " skip calibration = %d\n", mode->skipShadingAnalysis);
750    DBG (DBG_info_scan, " fast infrared = %d\n", mode->fastInfrared);
751    DBG (DBG_info_scan, " halftone pattern = %d\n", mode->halftonePattern);
752    DBG (DBG_info_scan, " line threshold = %d\n", mode->lineThreshold);
753
754    /* Code data */
755    /* cyberview
756     * 00 0f entries
757     * f4 01 resolution 500
758     * 80    RGB (90: RGBI)
759     * 04    color depth (4: 8 bit, 20: 16 bit)
760     * 04    color format
761     * 00
762     * 01    byte order
763     * 08    quality bitmask: 80=fast infrared, 08=skip shading analysis, 02=sharpen
764     * 00 00
765     * 00    halftone pattern
766     * 80    line threshold
767     * 10 00
768     *
769     * pieusb
770     * 0: 00 0f
771     * 2: e8 03 resolution 1000
772     * 4: 80    passes
773     * 5: 04    color depth
774     * 6: 04    color format
775     * 7: 00
776     * 8: 01    byte order
777     * 9: 02    quality bitmask: sharpen
778     * a: 00 00
779     * c: 00    halftone pattern
780     * d: 7f    line threshold
781     * e: 00 00
782     */
783    memset (data, '\0', size);
784    _set_byte (size-1, data, 1);
785    _set_short (mode->resolution, data, 2);
786    _set_byte (mode->passes, data, 4);
787    _set_byte (mode->colorDepth, data, 5);
788    _set_byte (mode->colorFormat, data, 6);
789    _set_byte (mode->byteOrder, data, 8);
790    quality = 0x00;
791    if (mode->sharpen) quality |= 0x02;
792    if (mode->skipShadingAnalysis) quality |= 0x08;
793    if (mode->fastInfrared) quality |= 0x80;
794    _set_byte (quality, data, 9);
795    _set_byte (mode->halftonePattern, data, 12);
796    _set_byte (mode->lineThreshold, data, 13);
797    _set_byte (0x10, data, 14); /* ? */
798
799    status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
800#undef MODE_SIZE
801}
802
803/* SCSI COPY, code 0x18 */
804/**
805 * Get the currently used CCD-mask, which defines which pixels have been used in
806 * the scan, and which allows to relate scan data to shading data. A mask is a
807 * 5340 byte array which consists only contains the values 0x00 and 0x70. A
808 * value of 0x00 indicates the pixel is used, a value of 0x70 that it is not.\n
809 * The number of 0x00 bytes equals the number of pixels on a line.\n
810 * The mask begins with a number of 0x70 bytes equal to the scan frame x0-value
811 * divided by 2.\n
812 * The SCSI-command COPY (code 0x18) is used for function.
813 *
814 * @param device_number Device number
815 * @param mask
816 * @return Pieusb_Command_Status
817 */
818void
819sanei_pieusb_cmd_get_ccd_mask(SANE_Int device_number, SANE_Byte* mask, SANE_Int mask_size, struct Pieusb_Command_Status *status)
820{
821    SANE_Byte command[SCSI_COMMAND_LEN];
822
823    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_ccd_mask()\n");
824
825    _prep_scsi_cmd (command, SCSI_COPY, mask_size);
826
827    memset (mask, '\0', mask_size);
828    status->pieusb_status = sanei_pieusb_command (device_number, command, mask, mask_size);
829}
830
831/**
832 * Get scan mode parameters, such as resolution, colors to scan, color depth,
833 * color format, and a couple of scan quality settings (sharpen, skip
834 * calibration, fast infrared). It performs the SCSI-command MODE SELECT,
835 * code 0x1A.
836 *
837 * @param device_number Device number
838 * @param mode Mode parameters
839 * @return Pieusb_Command_Status
840 * @see Pieusb_Mode
841 */
842void
843sanei_pieusb_cmd_get_mode(SANE_Int device_number, struct Pieusb_Mode* mode, struct Pieusb_Command_Status *status)
844{
845    SANE_Byte command[SCSI_COMMAND_LEN];
846#define MODE_SIZE 16
847    SANE_Int size = MODE_SIZE;
848    SANE_Byte data[MODE_SIZE];
849    SANE_Byte quality;
850
851    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_mode()\n");
852
853    _prep_scsi_cmd (command, SCSI_MODE_SENSE, size);
854    memset (data, '\0', size);
855
856    status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
857    if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
858        return;
859    }
860
861    /* Decode data received */
862    mode->resolution = _get_short (data, 2);
863    mode->passes = _get_byte (data, 4);
864    mode->colorDepth = _get_byte (data, 5);
865    mode->colorFormat = _get_byte (data, 6);
866    mode->byteOrder = _get_byte (data, 8);
867    quality = _get_byte (data, 9);
868    mode->sharpen = (quality |= 0x02) ? SANE_TRUE : SANE_FALSE;
869    mode->skipShadingAnalysis = (quality |= 0x08) ? SANE_TRUE : SANE_FALSE;
870    mode->fastInfrared = (quality |= 0x80) ? SANE_TRUE : SANE_FALSE;
871    mode->halftonePattern = _get_byte (data, 12);
872    mode->lineThreshold = _get_byte (data, 13);
873
874    DBG (DBG_info_scan, "cmdGetMode():\n");
875    DBG (DBG_info_scan, " resolution = %d\n", mode->resolution);
876    DBG (DBG_info_scan, " passes = %02x\n", mode->passes);
877    DBG (DBG_info_scan, " depth = %02x\n", mode->colorDepth);
878    DBG (DBG_info_scan, " color format = %02x\n", mode->colorFormat);
879    DBG (DBG_info_scan, " sharpen = %d\n", mode->sharpen);
880    DBG (DBG_info_scan, " skip calibration = %d\n", mode->skipShadingAnalysis);
881    DBG (DBG_info_scan, " fast infrared = %d\n", mode->fastInfrared);
882    DBG (DBG_info_scan, " halftone pattern = %d\n", mode->halftonePattern);
883    DBG (DBG_info_scan, " line threshold = %d\n", mode->lineThreshold);
884#undef MODE_SIZE
885}
886
887/**
888 * Start a scan (SCSI SCAN command, code 0x1B, size byte = 0x01).\n
889 * There are four phases in a scan process. During each phase a limited number of
890 * commands is available. The phases are:\n
891 * 1. Calibration phase: make previously collected shading correction data available\n
892 * 2. Line-by-line scan & read phase\n
893 * 3. Output CCD-mask phase\n
894 * 4. Scan and output scan data phase\n
895 *
896 * The calibration phase is skipped if Pieusb_Mode.skipCalibration is set. If
897 * the scanner determines a calibration is necessary, a CHECK CONDIDITION response
898 * is returned. Available command during this phase:\n
899 * 1. sanei_pieusb_cmd_test_unit_ready()\n
900 * 2. sanei_pieusb_cmd_get_scanned_lines(): read shading correction lines\n
901 * 3. sanei_pieusb_cmd_stop_scan: abort scanning process\n
902 * 4. sanei_pieusb_cmd_get_gain_offset() : the settings are generated during the initialisation of this phase, so they are current\n
903 * 5. cmdSetSettings(): settings take effect in the next scan phase\n\n
904 * The line-by-line phase is only entered if Pieusb_Mode.div_10[0] bit 5 is
905 * set. It is not implemented.\n\n
906 * In the CCD-mask output phase the CCD-mask is read. Available command during this phase:\n
907 * 1. sanei_pieusb_cmd_test_unit_ready()\n
908 * 2. sanei_pieusb_cmd_get_ccd_mask()\n
909 * 3. sanei_pieusb_cmd_stop_scan: abort scanning process\n\n
910 * In the 'scan and output scan data' phase, the slide is scanned while data is
911 * read in the mean time. Available command during this phase:\n
912 * 1. sanei_pieusb_cmd_test_unit_ready()\n
913 * 2. sanei_pieusb_cmd_get_scanned_lines()\n
914 * 2. sanei_pieusb_cmd_get_parameters()\n
915 * 4. sanei_pieusb_cmd_stop_scan: abort scanning process\n
916 *
917 * @param device_number Device number
918 * @return Pieusb_Command_Status
919 */
920void
921sanei_pieusb_cmd_start_scan(SANE_Int device_number, struct Pieusb_Command_Status *status)
922{
923    SANE_Byte command[SCSI_COMMAND_LEN];
924
925    DBG (DBG_info_scan, "sanei_pieusb_cmd_start_scan()\n");
926
927    _prep_scsi_cmd (command, SCSI_SCAN, 1);
928
929    status->pieusb_status = sanei_pieusb_command (device_number, command, NULL, 0);
930}
931
932/**
933 * Stop a scan started with sanei_pieusb_cmd_start_scan(). It issues a SCSI SCAN command,
934 * code 0x1B, with size byte = 0x00.
935 *
936 * @param device_number Device number
937 * @return Pieusb_Command_Status
938 */
939void
940sanei_pieusb_cmd_stop_scan(SANE_Int device_number, struct Pieusb_Command_Status *status)
941{
942    SANE_Byte command[SCSI_COMMAND_LEN];
943
944    DBG (DBG_info_scan, "sanei_pieusb_cmd_stop_scan()\n");
945
946    _prep_scsi_cmd (command, SCSI_SCAN, 0);
947
948    status->pieusb_status = sanei_pieusb_command (device_number, command, NULL, 0);
949}
950
951/**
952 * Set scan head to a specific position, depending on the value for mode:\n
953 * mode = 1: Returns the scan head to the resting position, after a short move
954 * forward. If this command is left out between two scans, the second scan is
955 * up-down-mirrored, and scanning starts where the proevious scan stopped.\n
956 * mode = 2: Resets the scan head an then moves it forward depending on 'size',
957 * but it is a bit unpredictable to what position. The scanner may attempt to
958 * move the head past its physical end position. The mode is not implemented.\n
959 * mode = 3: This command positions the scan head to the start of the slide.\n
960 * mode = 4 or 5: The command forwards (4) or retreats (5) the scan head the
961 * given amount of steps (in size).\n
962 * The SCSI code is 0xD2, there is no related command name.
963 *
964 * @param device_number Device number
965 * @param mode
966 * @param size
967 * @return Pieusb_Command_Status
968 */
969void
970sanei_pieusb_cmd_set_scan_head(SANE_Int device_number, SANE_Int mode, SANE_Int steps, struct Pieusb_Command_Status *status)
971{
972    SANE_Byte command[SCSI_COMMAND_LEN];
973#define SCAN_HEAD_SIZE 4
974    SANE_Int size = SCAN_HEAD_SIZE;
975    SANE_Byte data[SCAN_HEAD_SIZE];
976
977    DBG (DBG_info_scan, "sanei_pieusb_cmd_set_scan_head()\n");
978
979    _prep_scsi_cmd (command, SCSI_SET_SCAN_HEAD, size);
980
981    /* Code data */
982    memset (data, '\0', size);
983    switch (mode) {
984        case 1:
985            data[0] = 2;
986            break;
987        case 2:
988            DBG (DBG_error, "sanei_pieusb_cmd_set_scan_head() mode 2 unreliable, possibly dangerous\n");
989            status->pieusb_status = PIEUSB_STATUS_INVAL;
990            return;
991        case 3:
992            data[0] = 8;
993            break;
994        case 4:
995            data[0] = 0; /* forward */
996            data[2] = (steps>>8) & 0xFF;
997            data[3] = steps & 0xFF;
998            break;
999        case 5:
1000            data[0] = 1; /* backward */
1001            data[2] = (steps>>8) & 0xFF;
1002            data[3] = steps & 0xFF;
1003            break;
1004    }
1005
1006    status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
1007#undef SCAN_HEAD_SIZE
1008}
1009
1010/**
1011 * Get internal scanner settings which have resulted from an auto-calibration
1012 * procedure. This procedure only runs when calibrating (Scan phase 1), so the
1013 * data returned are relatively static.\n
1014 * The SCSI code is 0xD7, there is no related command name.
1015 *
1016 * @param device_number Device number
1017 * @param settings Settings for gain and offset for the four colors RGBI
1018 * @return Pieusb_Command_Status
1019 * @see Pieusb_Settings
1020 */
1021void
1022sanei_pieusb_cmd_get_gain_offset(SANE_Int device_number, struct Pieusb_Settings* settings, struct Pieusb_Command_Status *status)
1023{
1024    SANE_Byte command[SCSI_COMMAND_LEN];
1025#define GAIN_OFFSET_SIZE 103
1026    SANE_Int size = GAIN_OFFSET_SIZE;
1027    SANE_Byte data[GAIN_OFFSET_SIZE];
1028    int k;
1029    SANE_Byte val[3];
1030
1031    DBG (DBG_info_scan, "sanei_pieusb_cmd_get_gain_offset()\n");
1032
1033    _prep_scsi_cmd (command, SCSI_READ_GAIN_OFFSET, size);
1034
1035    memset (data, '\0', size);
1036    status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
1037    if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
1038        return;
1039    }
1040
1041    /* Decode data received */
1042    _get_shorts (settings->saturationLevel, data+54, 3);
1043    _get_shorts (settings->exposureTime, data+60, 3);
1044    _copy_bytes (val, data+66, 3);
1045    for (k = 0; k < 3; k++) settings->offset[k] = val[k];
1046    _copy_bytes (val, data+72, 3);
1047    for (k = 0; k < 3; k++) settings->gain[k] = val[k];
1048    settings->light = _get_byte (data, 75);
1049    settings->exposureTime[3] = _get_short (data, 98);
1050    settings->offset[3] = _get_byte (data, 100);
1051    settings->gain[3] = _get_byte (data, 102);
1052
1053    DBG (DBG_info, "sanei_pieusb_cmd_get_gain_offset() set:\n");
1054    DBG (DBG_info, " saturationlevels = %d-%d-%d\n", settings->saturationLevel[0], settings->saturationLevel[1], settings->saturationLevel[2]);
1055    DBG (DBG_info, " ---\n");
1056    DBG (DBG_info, " exposure times = %d-%d-%d-%d\n", settings->exposureTime[0], settings->exposureTime[1], settings->exposureTime[2], settings->exposureTime[3]);
1057    DBG (DBG_info, " gain = %d-%d-%d-%d\n", settings->gain[0], settings->gain[1], settings->gain[2], settings->gain[3]);
1058    DBG (DBG_info, " offset = %d-%d-%d-%d\n", settings->offset[0], settings->offset[1], settings->offset[2], settings->offset[3]);
1059    DBG (DBG_info, " light = %02x\n", settings->light);
1060    DBG (DBG_info, " double times = %02x\n", settings->doubleTimes);
1061    DBG (DBG_info, " extra entries = %02x\n", settings->extraEntries);
1062#undef GAIN_OFFSET_SIZE
1063}
1064
1065
1066/**
1067 * Set internal scanner settings such as gain and offset.\n
1068 * There are two effective moments for this command:\n
1069 * 1. For a scan without calibration phase: before the sanei_pieusb_cmd_start_scan() command;
1070 * 2. For a sccan with calibration phase: before (or during) reading the shading reference data.
1071 * The SCSI code is 0xDC, there is no related command name.
1072 *
1073 * @param device_number Device number
1074 * @param settings Settings for gain and offset for the four colors RGBI
1075 * @return Pieusb_Command_Status
1076 * @see Pieusb_Settings
1077 */
1078void
1079sanei_pieusb_cmd_set_gain_offset(SANE_Int device_number, struct Pieusb_Settings* settings, struct Pieusb_Command_Status *status)
1080{
1081    SANE_Byte command[SCSI_COMMAND_LEN];
1082#define GAIN_OFFSET_SIZE 29
1083    SANE_Int size = GAIN_OFFSET_SIZE;
1084    SANE_Byte data[GAIN_OFFSET_SIZE];
1085    int k;
1086    SANE_Byte val[3];
1087
1088    DBG (DBG_info_scan, "sanei_pieusb_cmd_set_gain_offset()\n");
1089
1090    _prep_scsi_cmd (command, SCSI_WRITE_GAIN_OFFSET, size);
1091
1092    DBG (DBG_info, "sanei_pieusb_cmd_set_gain_offset() set:\n");
1093    DBG (DBG_info, " exposure times = %d-%d-%d-%d\n", settings->exposureTime[0], settings->exposureTime[1], settings->exposureTime[2], settings->exposureTime[3]);
1094    DBG (DBG_info, " gain = %d-%d-%d-%d\n", settings->gain[0], settings->gain[1], settings->gain[2], settings->gain[3]);
1095    DBG (DBG_info, " offset = %d-%d-%d-%d\n", settings->offset[0], settings->offset[1], settings->offset[2], settings->offset[3]);
1096    DBG (DBG_info, " light = %02x\n", settings->light);
1097    DBG (DBG_info, " double times = %02x\n", settings->doubleTimes);
1098    DBG (DBG_info, " extra entries = %02x\n", settings->extraEntries);
1099
1100    /* Code data */
1101    memset (data, '\0', size);
1102    _set_shorts (settings->exposureTime, data, 3);
1103    for (k = 0; k < 3; k++) {
1104      val[k] = settings->offset[k];
1105    }
1106    _copy_bytes (data + 6, val, 3);
1107    for (k = 0; k < 3; k++) {
1108      val[k] = settings->gain[k];
1109    }
1110    _copy_bytes (data + 12, val, 3);
1111    _set_byte (settings->light, data, 15);
1112    _set_byte (settings->extraEntries, data, 16);
1113    _set_byte (settings->doubleTimes, data, 17);
1114    _set_short (settings->exposureTime[3], data, 18);
1115    _set_byte (settings->offset[3], data, 20);
1116    _set_byte (settings->gain[3], data, 22);
1117    /*
1118     * pieusb-get_gain_offset:
1119     *  00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1120     *  00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1121     *  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1122     *  00000030: a9 00 88 00 b1 00 00 00 00 00 00 00 04 10 04 10 )...1...........
1123     *  00000040: 04 10 53 4f 6e 00 00 00 2e 21 21 05 04 10 df 2d ..SOn....!!..._-
1124     *  00000050: a3 5c e7 f2 a1 2c b3 c4 42 df 32 42 eb 82 8e e0 #\gr!,3DB_2Bk..`
1125     *  00000060: 87 be 04 10 4f 00 2c                            .>..O.,
1126     *
1127     * cyberview:
1128     * 00000000: 65 22  57 18  19 19 - exposure time RGB
1129     * 00000006: 51 4e 6a - offset RGB
1130     * 00000009: 00 00 00
1131     * 0000000c: 21 21 21 - gain RGB
1132     * 0000000f: 05 - light
1133     * 00000010: 01 - extra entries
1134     * 00000011: 00 - double times
1135     * 00000012: 04 10 - exposure time I
1136     * 00000014: 4e 00 - offset I
1137     * 00000016: 2a - gain I
1138     * 00000017: 00 00 00 00 00 00
1139     *
1140     * pieusb:
1141     * 00000000: 04 10  04 10  04 10 - exposure time RGB
1142     * 00000006: 53 4f 6e - offset RGB
1143     * 00000009: 00 00 00
1144     * 0000000c: 2e 21 21 - gain RGB
1145     * 0000000f: 05 - light
1146     * 00000010: 00 - extra entries
1147     * 00000011: 00 - double times
1148     * 00000012: 04 10 - exposure time I
1149     * 00000014: 4f 00 - offset I
1150     * 00000016: 2c    - gain I
1151     * 00000017: 00 00 00 00 00 00
1152     */
1153
1154    status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
1155#undef GAIN_OFFSET_SIZE
1156}
1157
1158/**
1159 * Get scanner state information: button pushed,
1160 * warming up, scanning.
1161 *
1162 * @param device_number Device number
1163 * @param state State information
1164 * @return Pieusb_Command_Status
1165 */
1166void
1167sanei_pieusb_cmd_read_state(SANE_Int device_number, struct Pieusb_Scanner_State* state, struct Pieusb_Command_Status *status)
1168{
1169    SANE_Byte command[SCSI_COMMAND_LEN];
1170#define GET_STATE_SIZE 12
1171    SANE_Byte data[GET_STATE_SIZE];
1172    SANE_Int size = GET_STATE_SIZE;
1173
1174    /* Execute READ STATUS command */
1175    DBG (DBG_info_scan, "sanei_pieusb_cmd_read_state()\n");
1176
1177    _prep_scsi_cmd (command, SCSI_READ_STATE, size);
1178
1179    memset (data, '\0', size);
1180    status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
1181
1182    if (status->pieusb_status == PIEUSB_STATUS_WARMING_UP
1183        || status->pieusb_status == PIEUSB_STATUS_DEVICE_BUSY) {
1184      data[5] = 1;
1185      status->pieusb_status = PIEUSB_STATUS_GOOD;
1186    }
1187    /* Decode data received */
1188    state->buttonPushed = _get_byte(data, 0);
1189    state->warmingUp = _get_byte(data, 5);
1190    state->scanning = _get_byte(data, 6);
1191/*    state->busy = _get_byte(data, 8); */
1192    DBG (DBG_info_scan, "sanei_pieusb_cmd_read_state(): button %d, warmingUp %d, scanning %d, busy? %d\n", state->buttonPushed, state->warmingUp, state->scanning, _get_byte(data, 8));
1193#undef GET_STATE_SIZE
1194}
1195
1196/**
1197 * Prepare SCSI_COMMAND_LEN-byte command array with command code and size value
1198 *
1199 * @param command
1200 * @param code
1201 * @param size
1202 */
1203static void
1204_prep_scsi_cmd(SANE_Byte* command, SANE_Byte code, SANE_Word size)
1205{
1206    memset(command, '\0', SCSI_COMMAND_LEN);
1207    command[0] = code;
1208    command[3] = (size>>8) & 0xFF; /* lsb first */
1209    command[4] = size & 0xFF;
1210}
1211