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 
64 static 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  */
75 static SANE_Byte
_get_byte(SANE_Byte* array, SANE_Byte offset)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  */
83 static void
_set_byte(SANE_Byte val, SANE_Byte* array, SANE_Byte offset)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  */
94 static SANE_Int
_get_short(SANE_Byte* array, SANE_Byte offset)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  */
107 static void
_set_short(SANE_Word val, SANE_Byte* array, SANE_Byte offset)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  */
118 static SANE_Int
_get_int(SANE_Byte* array, SANE_Byte offset)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  */
135 static 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  */
147 static void
_copy_bytes(SANE_Byte* dst, SANE_Byte* src, SANE_Byte count)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  */
161 static void
_get_shorts(SANE_Word* dst, SANE_Byte* src, SANE_Byte count)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  */
176 static void
_set_shorts(SANE_Word* src, SANE_Byte* dst, SANE_Byte count)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  */
197 void
sanei_pieusb_cmd_test_unit_ready(SANE_Int device_number, struct Pieusb_Command_Status *status)198 sanei_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 
218 void
sanei_pieusb_cmd_slide(SANE_Int device_number, slide_action action, struct Pieusb_Command_Status *status)219 sanei_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  */
249 void
sanei_pieusb_cmd_get_sense(SANE_Int device_number, struct Pieusb_Sense* sense, struct Pieusb_Command_Status *status, PIEUSB_Status *ret)250 sanei_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  */
305 void
sanei_pieusb_cmd_get_scan_frame(SANE_Int device_number, SANE_Int index, struct Pieusb_Scan_Frame* frame, struct Pieusb_Command_Status *status)306 sanei_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 
353 void
sanei_pieusb_cmd_17(SANE_Int device_number, SANE_Int value, struct Pieusb_Command_Status *status)354 sanei_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  */
385 void
sanei_pieusb_cmd_get_shading_parms(SANE_Int device_number, struct Pieusb_Shading_Parameters_Info* shading, struct Pieusb_Command_Status *status)386 sanei_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  */
457 void
sanei_pieusb_cmd_get_scanned_lines(SANE_Int device_number, SANE_Byte* data, SANE_Int lines, SANE_Int size, struct Pieusb_Command_Status *status)458 sanei_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  */
480 void
sanei_pieusb_cmd_set_scan_frame(SANE_Int device_number, SANE_Int index, struct Pieusb_Scan_Frame* frame, struct Pieusb_Command_Status *status)481 sanei_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  */
520 void
sanei_pieusb_cmd_set_exposure_time(SANE_Int device_number, struct Pieusb_Exposure_Time* time, struct Pieusb_Command_Status *status)521 sanei_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  */
557 void
sanei_pieusb_cmd_set_highlight_shadow(SANE_Int device_number, struct Pieusb_Highlight_Shadow* hgltshdw, struct Pieusb_Command_Status *status)558 sanei_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  */
595 void
sanei_pieusb_cmd_get_parameters(SANE_Int device_number, struct Pieusb_Scan_Parameters* parameters, struct Pieusb_Command_Status *status)596 sanei_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  */
659 void
sanei_pieusb_cmd_inquiry(SANE_Int device_number, struct Pieusb_Scanner_Properties* inq, SANE_Byte size, struct Pieusb_Command_Status *status)660 sanei_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  */
730 void
sanei_pieusb_cmd_set_mode(SANE_Int device_number, struct Pieusb_Mode* mode, struct Pieusb_Command_Status *status)731 sanei_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  */
818 void
sanei_pieusb_cmd_get_ccd_mask(SANE_Int device_number, SANE_Byte* mask, SANE_Int mask_size, struct Pieusb_Command_Status *status)819 sanei_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  */
842 void
sanei_pieusb_cmd_get_mode(SANE_Int device_number, struct Pieusb_Mode* mode, struct Pieusb_Command_Status *status)843 sanei_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  */
920 void
sanei_pieusb_cmd_start_scan(SANE_Int device_number, struct Pieusb_Command_Status *status)921 sanei_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  */
939 void
sanei_pieusb_cmd_stop_scan(SANE_Int device_number, struct Pieusb_Command_Status *status)940 sanei_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  */
969 void
sanei_pieusb_cmd_set_scan_head(SANE_Int device_number, SANE_Int mode, SANE_Int steps, struct Pieusb_Command_Status *status)970 sanei_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  */
1021 void
sanei_pieusb_cmd_get_gain_offset(SANE_Int device_number, struct Pieusb_Settings* settings, struct Pieusb_Command_Status *status)1022 sanei_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  */
1078 void
sanei_pieusb_cmd_set_gain_offset(SANE_Int device_number, struct Pieusb_Settings* settings, struct Pieusb_Command_Status *status)1079 sanei_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  */
1166 void
sanei_pieusb_cmd_read_state(SANE_Int device_number, struct Pieusb_Scanner_State* state, struct Pieusb_Command_Status *status)1167 sanei_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  */
1203 static void
_prep_scsi_cmd(SANE_Byte* command, SANE_Byte code, SANE_Word size)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