alexpevzner / sane-airscan

Scanner Access Now Easy - universal driver for eSCL (Apple AirScan) and WSD
Other
278 stars 39 forks source link

sane_start() returns an error on HP Laser MFP 135WR #332

Closed vklachkov closed 6 months ago

vklachkov commented 6 months ago

I was experimenting with the SANE API and found that sane-airscan returns an error when calling sane_start() twice.

I wrote a small program which scans as scanimage tool. The SANE API calls were like this:

It works, but scan was very slow. In the documentation, in the code flow section, says that I can scan again without reopening the device:

Code flow

I added a second sane_start() call and now the calls were like this:

And the second call of sane_start() returned INVAL. The documentation says that INVAL means that "scan cannot be started with the current set of options". But if I re-open the device, scanning proceeds without problems.

To check, I changed airscan:e0:HP_Laser_MFP_135wr to v4l:/dev/video0 and scanning occurs without problems, without re-opening the device.

sane-airscan config ``` $ sudo cat /etc/sane.d/airscan.conf ``` ```config [devices] "HP_Laser_MFP_135wr" = https://192.168.1.121:443/eSCL [options] discovery = disable [debug] #trace = ~/airscan/trace #enable = true ```

If necessary, I can provide any logs and help with debugging.

alexpevzner commented 6 months ago

@zgdump,

Once sane_start is called, you MUST call sane_read in loop until EOF or an error. In the log that you provided, I don't see it to be done. Without it, sane-airscan will consider scan to be in progress and will not allow to call sane_start second time until first scan job is finished.

Calling sane_cancel is not enough to finish the job. It only attempts to interrupt on device scan job being executed, but you need to finish the job "logically" by calling sane_read anyway.

This is not something special to sane-airscan, other drivers behave the same way

vklachkov commented 6 months ago

@alexpevzner

I figured out the problem. I called sane_read() until the buffer was full and then call sane_read() again with maxlen=0 and sane_read() returned GOOD and *len=0, instead of EOF. As soon as I set maxlen to 1, sane_read() immediately returned EOF, the error went away and everything started working as it should... I'm surprised that V4L worked without errors.

Thanks for the sane_cancel() explanation, I thought this call actually stops the scan and allows sane_start() to be called again.

alexpevzner commented 6 months ago

I'm surprised that V4L worked without errors.

I think its a corner case. If maxlen == 0, both behaviours looks correct.

I thought this call actually stops the scan and allows sane_start() to be called again.

sane_cancel() can be called even from signal handler (for example, scanimage calls it if you press Ctrl-C), so there is not too much things that it actually can do

P.S. I probably can close this issue or convert it into discussion?

vklachkov commented 6 months ago

@alexpevzner

Please move this issue into discussions. There is no bug, "delo bylo ne v bobine".

Last question, if it's not too difficult. How to properly scan via SANE, via sane_read? Any pitfalls or tips? Or I just need to remember about maxlen > 0? After our discussion, I looked at the simple-scan source code and saw that it reads pixels by scanlines and it confused me.