[sane-standard] preliminary protocol doc

Henning Meier-Geinitz henning@meier-geinitz.de
Mon, 18 Oct 2004 20:21:59 +0200


Hi,

Some comments. Mostly by reading the standard and the code. I haven't
tested anything so I may be wrong.

On Fri, Oct 15, 2004 at 03:47:21PM +0200, Johannes Berg wrote:
> In the sane network protocol, an array is represented by the length of the array
> following the items.

"... followed by ...". The length is a SANE_Word.

> A pointer is represented by a single word that is 0 if the pointer is NULL,
> or non-zero otherwise. Then follow the items the struct that the pointer
> points to contains.

"The pointer is followed by the items ..."

> A string is transferred as an array of its bytes,

SANE_Chars actually (doesn't matter as of now but you never know...)

> unless the protocol is in ASCII mode.

As far as I understand the standard there is no ascii protocol. I know
codec_ascii but it's not in the standard and practically only used for
saving frontend options.

> The transferred data does not include the trailing 0.

It does! ("The trailing NUL byte is considered part of the array").

> === SANE_NET_AUTHORIZE ===
> This message is used to send authorization tokens for a given resource.
> ==== request ====
>  * resource (string)
>  * username (string)
>  * password (string)
> 
> ==== reply ====
>  * a single 0 word if no protocol errors occurred

There is one word of reply but it's value doesn't matter.

> === SANE_NET_GET_DEVICES ===
> This message causes the network daemon to enumerate all devices it can
> access.

enumerate?

> ==== request ====
>  nothing but the procedure code
> 
> ==== reply ====
>  TODO 

*((* SANE_Device)[])

I hope I got the brackets right :-)

> === SANE_NET_OPEN ===
> ==== request ====
>  * the device name (may not contain a colon)

The SANE device name can contain a colon (e.g. test:001).

> ==== reply ====
>  * status (word)
>  * handle (word)
>  * resource to authorize (string)
>  
> Here, if you give a NULL device name, the two following things are possible:

1. saned crashes (if an older version is used) :-)
2. you get SANE_STATUS_INVAL

Your points are about an empty string, not a NULL string:

>  1. handle is 0 and the resource is NULL, then status contains an error code from sane_get_devices

Not really. If status is not 0, handle and resource are undefined. The
net backend doesn't check the status before looking at resource but it
should IMHO.

>  2. no devices exist, and the status is SANE_STATUS_INVAL

3. authorization is needed for the first device (or more exactly, the
   backend of that device) and so status 0 and resource = backend name
   is returned

4. No authorization is needed and the handle of the first device is
   returned (SANE_NET_OPEN succeeded).

> After these replies or if you do not give a NULL device name, the protocol proceeds with
> authorization to the resource "saned" (see SANE_NET_AUTHORIZE).

As far as I can see resource name is the backend name of the first
device. "saned" is only used as the name of the file that contains
passwords (saned.users).

> If authorization fails, the reply's status is set to SANE_STATUS_ACCESS_DENIED, otherwise
> the device is opened and the result of that is sent in the status field. An additional
> status is possible, SANE_STATUS_NO_MEM, if a handle could not be allocated, otherwise
> the handle field is set to the device handle, which is needed in further operations.
> 
> 
> === SANE_NET_CLOSE ===
> ==== request ====
>  * handle (word)
>  
> ==== reply ====
>  * a zero word

The value doesn't matter.

> === SANE_NET_GET_OPTION_DESCRIPTORS ===
> ==== request ====
>  * handle (word)
>  
> ==== reply ====
>  * the status code (word)

A struct consisting of
  SANE_Word num_options;
and  

>  * an array of pointers to a SANE_Option_Descriptor struct which contains (in the given order):

[...]

> === SANE_NET_CONTROL_OPTION ===
> ==== request ====
>  * handle (word)
>  * option (word)
>  * action (word)
>  * if action != SANE_ACTION_SET_AUTO (or the wire protocol version is < 3) then the following fields follow:

Practically speaking, you are right. The excemption for
SANE_ACTION_SET_AUTO is not in the standard, however (as far as I can
see).


> ==== reply ====
>  * status (word)
>  * info (word)
>  * value_type (word)
>  * value_size (word)
>  * value (data)
>  * resource to authorize (string)
> 
> Authentication may need to occurr, in that case all fields but the resource to authorize
> are set to 0.

They can be any value (undefined).

> Otherwise, the reply contains the result of sane_control_option.

If the status isn't 0, all other values are undefined. That's a
contradiction to the authorization stuff IMHO. Do I have to check
status or resource first?

> === SANE_NET_START ===
> ==== request ====
>  * handle
>  
> ==== reply ====
>  * status (word)
>  * port (word)
>  * byte order (word, 0x1234 for little, 0x4321 for big endian)
>  * resource to authorize
>  
> Again, authorization may be required in which case everything but the resource to authorize
> is set to 0.

(everything else is undefined, see above)

> After the status returned is SANE_STATUS_GOOD, the server starts listening
> on the port given in the port field. The client must then connect to that port
> (the server blocks until that has happened). The client must not send any data
> to the data connection, that connection is only for receiving data (like FTP).

With FTP you can send data :-)

Bye,
  Henning