Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HP Color LaserJet Enterprise MFP M578 detection during printer start up #64

Open
fabled opened this issue Mar 6, 2023 · 9 comments
Open

Comments

@fabled
Copy link

fabled commented Mar 6, 2023

Somewhat related to #32, I detected additional issues in this HP printer.

When the printer is starting up, it behaves as follows during early boot:

  • /ipp/print requests return 503 Service not ready, and sadly it is missing the last \n so ipp-usb does not see it as full request
  • /eSCL/ScannerCapabilities requests return 404 Not Found, and also miss the last \n

This results ipp-usb to reset and retry device initialization. This happens because the EsclService init times out, and the error condition in https://github.com/OpenPrinting/ipp-usb/blob/master/device.go#L120 is triggered.

Later during the startup sequence, the scanner side starts first responding with success, but IPP printer still gives 503. During this condition, ipp-usb is left in hung state. The printer is not detected, because the attribute reading aborts early in https://github.com/OpenPrinting/ipp-usb/blob/master/ipp.go#L155 when error is received. Therefor no timeout happens, and https://github.com/OpenPrinting/ipp-usb/blob/master/usbtransport.go#L550 triggers. This tries to indefinitely drain the response which never comes and the channels is left stuck. (Recovery can be done with restart ipp-usb, or disconnect/connect USB cable.)

Perhaps the device init logic could be adjusted to automatically always do timeout retry if ipp return 503 error (either directly, or via quirk).

I wonder also if the response draining could be also also adjusted to cope better with printer bugs such as this one.

@alexpevzner
Copy link
Member

Hi Timo,

Perhaps the device init logic could be adjusted to automatically always do timeout retry if ipp return 503 error (either directly, or via quirk).

Looks like it is not enough, because regardless of status, if ipp-usb can't fetch the entire response, because trailing \n is missed, it will stuck anyway.

May be, for this kind of device, it will be better to simply delay initialization after device was connected, based on quirk?

@alexpevzner
Copy link
Member

BTW, ipp-usb already has init-delay quirk, so the idea to delay initialization is simple to test...

@fabled
Copy link
Author

fabled commented Mar 18, 2023

Perhaps the device init logic could be adjusted to automatically always do timeout retry if ipp return 503 error (either directly, or via quirk).

Looks like it is not enough, because regardless of status, if ipp-usb can't fetch the entire response, because trailing \n is missed, it will stuck anyway.

As workaround, I'm using now:

--- a/device.go
+++ b/device.go
@@ -84,6 +84,10 @@ func NewDevice(desc UsbDeviceDesc) (*Device, error) {
 
        if err != nil {
                dev.Log.Error('!', "IPP: %s", err)
+               if strings.StartsWith(err.Error(), "HTTP: 503") {
+                       err = ErrInitTimedOut
+                       goto ERROR
+               }
        }
 
        log.Flush()

This works because the 503 triggers a device init retry doing a reset. Not perhaps the most elegant, but works.

In any case, not receiving the trailing \n should be eventually timed out. Seems there's too many buggy printers like that out there. Perhaps receiving few zero-length USB URBs should be sufficient for that.

May be, for this kind of device, it will be better to simply delay initialization after device was connected, based on quirk?

This is not a real option. When the device is connected via cable, and you hit power on. It takes about 1-2 minutes for the USB interface to come up, and then it takes 4-6 minutes for the IPP layers to be up. For those 4-6 minutes I see the 503 error.

On the other hand, if the printer is online, and I connect the cable, everything works immediately.

Adding a 6 minute init-delay that is needed only if the device is cold starting, does not sound feasible to me.

@alexpevzner
Copy link
Member

Adding a 6 minute init-delay that is needed only if the device is cold starting, does not sound feasible to me.

Yes, 6 minutes looks a little bit too much to wait.

If we suppress the following logic in the device.go, line 144, won't it be enough for this device:

        if len(dnssdServices) == 0 {
                err = ErrUnusable
                goto ERROR
        }

@fabled
Copy link
Author

fabled commented Mar 19, 2023

If we suppress the following logic in the device.go, line 144, won't it be enough for this device:

No. See first comment. During cold boot, there in the end will be a state that the printer query will return 503, but scanner will return 200. During this stage it will permanently detect the MFP as having scanner only and printing will not be available.

alexpevzner added a commit that referenced this issue Dec 8, 2024
Some enterprise-level HP devices, during the initialization phase
(which can last several minutes), may respond with an HTTP 503
status or similar, which is expected. However, the response body may
be truncated (typically, the terminating '\n' is lost). In such
cases, `ipp-usb` will wait indefinitely for a response to maintain
synchronization with the device.

At the same time, these devices send a zero-length UDP packet at the
end of the truncated output. If the zlp-recv-hack quirk is enabled,
when ipp-usb receives a zero-length packet from the USB followed by
a receive timeout, it interprets this combination of events as a
valid termination of the response body. It works only at the
initialization time and doesn't affect futher operations.

See discussion under #64 for details.

Related issues are #83 and #32.
alexpevzner added a commit that referenced this issue Dec 10, 2024
If this quirk is enabled, device initialization is retried in case only
part of the device's functions have been initialized (say, only the
printer or only the scanner), instead of continuing to operate with
incomplete functionality.

It can be useful if the device takes a long time to fully initialize.
During this period, some components may respond normally while others
are still initializing. For example, the device may quickly report its
scanning capabilities shortly after startup, while its printing
functionality may take several minutes to become operational.

Some enterprise-level HP printers are known to have this problem.

See #64, #83 and #32 for details.
@alexpevzner
Copy link
Member

Hi @fabled,

I've recently added the following quirks to resolve issues explained here as well as under #83 and #32:

  • init-timeout = DELAY allows to tweak initialization timeout
  • init-retry-partial = true | false. If enabled, the ipp-usb will retry initialization, if some parts of device (printer or scanner) didn't initialize properly with some erroneous HTTP status code.
  • zlp-recv-hack = true | false. If enabled, that at the initialization time zero-length packet reception followed by receive timeout will be considered as EOF, so allowing reception of responses with truncated body.

Please, test on your devices. Waiting for your feedback. If everything is OK, I will need a list of affected devices, to update quirks distributed with the ipp-usb (you can write it in a comment or send me a PR)

Hope we will be able to resolve these issues now.

@alexpevzner
Copy link
Member

Hi @fabled,

may I ask you to retest your problematic HP printers with the newly added quirks?

@fabled
Copy link
Author

fabled commented Dec 18, 2024

may I ask you to retest your problematic HP printers with the newly added quirks?

Sure. But it'll probably by early next year as I am currently on vacation and without access to the devices.

I think these quirks should be applied at least to all HP "enterprise" printers. Would it be possible to match the HTTP response Server field in quirks? Alternatively, I can see if there's a wildcarded usb device name match that works.

@alexpevzner
Copy link
Member

Hi Timo,

Thank you for your response.

OK, I will wait until early next year. I want the next release to include these quirks, tested, and proven quirks for devices you have access to.

The zlp-recv-hack is risky, it can cause loss of synchronization if used with the "wrong" device, so I don't want to blindly apply it to the wide class of hardware without explicit testing of each of affected devices. So lets be specific in choosing affected devices.

The mechanism to apply the quirk based on a Server field doesn't exist for now.

So wish you a nice vacation.

Marry Christmas and happy New Year! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants