[sane-devel] backend coding overview

Bertrik Sikken bertrik@zonnet.nl
Sun, 05 Sep 2004 15:38:53 +0200


Mbosowo I Sampson wrote:
> I'm interested in writing a back end for the 3970. I've been reading 
> specs, looking at other back ends, trying to get familiar with sane, 
> etc... Its all a little daunting. I feel as though I know more than I 
> did a few days ago, but not nearly enough to even begin to know where to 
> start. I think what I'm looking for here is a general overview of how 
> sane interacts with a USB scanner.  I feel like I can't see the forest 
> because I'm preoccupied with studying the composition of bark on each 
> tree. Once I have the conceptual part down, I think all the details will 
> fall into place as I continue reading the documentation.
> 
> What I'm asking for is a break down of the steps involved for a scan to 
> be made. I'm trying to conceptualize how libusb, the driver I will 
> write, the front end, and the chip set all interact together to execute 
> a successful scan. Doesn't have to be in minute detail, but some detail 
> is always good.

I can tell you a little about how the niash backend was developed.
This may not be the best example, but the process worked quite well
in the end.

First of all, a very important piece of documentation is obviously
the SANE API spec, which is at
http://www.sane-project.org/html/
especially read chapter 4 and look at the diagram in section 4.4

When support for niash chipset scanners was first developed, I
started out with a simple testtool. The testtool can be executed
independently of sane and makes everything a little simpler when
the development is in the experimental phase.
The testttool has the following layered structure:

1 cmd line interface
2 scanner core functionality
3 scanner device interface using libusb

(layer 1 calls functions in layer 2 and possibly layer 3,
  layer 2 calls functions in layer 3)

The cmd line interface (1) parses any arguments and then makes calls
to the scanner core layer to do stuff like turn the lamp on or off,
scan a strip or get scanner status information.
The scanner device interface (3) abstracts some basic scanner data
transfer functions. In my case, the scanner basically had only 4
types of transfers (which each consisted of 1 or more USB transfers):
* sending control data to the scanner, e.g. writing a register to
set the scan resolution and set scan area limits.
* reading control data from the scanner, e.g. reading a register to
get the scanner chipset version, the status of the scanner lamp
(on/off) and scanner head position.
* sending bulk data to the scanner, like calibration tables,
gamma correction tables and stepper motor tables, etc.
* reading bulk data from the scanner, i.e. the actual image data.
The middle layer, the scanner core functionality layer (2) contains
the code to write all scanner settings in the proper order and with
the proper data to start a scan with specific settings.

When the testtool more-or-less worked, I built a SANE backend by
replacing the cmd line interface (1) with a SANE API interface.
Also I copied the scanner device interface (3) and modified it to
use sanei_usb instead of libusb.
This results in the following structure:

1 SANE API backend interface
2 scanner core functionality
3 scanner device interface using sanei_usb

I ripped the SANE API interface (1) from the sm3600 backend by stripping
out all device dependent stuff from sm3600.c (and renaming it). This 
results in a kind of dummy backend that is not actually able to scan
but does present a SANE frontend with all of the basic device settings
(like scan resolution, scan area, etc.) Once you have the backend
compiling and recognised by a sane frontend, you can 'connect' the
sane_init, sane_open, sane_start, sane_read (etc) functions to the
scanner core functionality layer.
The scanner core functionality layer (2) stays exactly the same.
The scanner device interface (3) needs only a little modification,
because the sanei_usb interface is already quite similar to the libusb
interface.

If you have any USB logs, just post a link to the list and we can
have a look at them (and perhaps see a pattern).

Hope this helps,
Bertrik