[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