zlp-send quirk should default to true (and perhaps be removed)
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 停滞
- 技術スタック
- go
- 領域
- embedded-iot
調査の方向性
まずリポジトリ内で zlp-send の設定と USB bulk-transfer の処理箇所を特定し、次にその設定が基盤となる転送レイヤーにどのように渡されるかを確認します。デフォルトで有効にすること、または quirk を削除することによって既存の動作が維持されるかを判断し、デフォルトを変更する前に、関連するテストやデバイスレベルのチェックを特定します。
索引モデルが issue の本文から書いたものです。
説明
The USB ZLP (Zero Length Packet) with Bulk Transfers seems to have been widely misunderstood. Especially because OSes need to offer low-level driver implementation APIs that have the ability to omit sending it. But the ZLP really needs to be generated in various conditions or things will break or have delays in randomly seeming manner.
USB 2.0 specification section 5.8.3 Bulk Transfer Packet Size Constraints says the following:
A bulk transfer is complete when the endpoint does one of the following:
•Has transferred exactly the amount of data expected
•Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet
When a bulk transfer is complete, the Host Controller retires the current IRP and advances to the next IRP. If a data payload is received that is larger than expected, all pending bulk IRPs for that endpoint will be aborted/retired.
In addition to the above, the host controller offers an IRP level timeout after which the IRP times out. The application may then choose to consider the timeout as a success or an error (e.g. based on the data received).
On Bulk endpoints the transfer typically maps to a read or write operation - also typically on application level a full APDU (e.g. HTTP request) does not need to happen within a single transfer, but it can span multiple transfer. That is, you can write multiple times (do multiple transfers) and the other side then on application level determines based on content when the APDU/HTTP request is complete.
The significant thing is that if the final transfer is a multiple of the USB maximum packet size and the ZLP is not sent, the transfer is not considered complete. While some USB stacks might still handle it. The USB specification is clear that the IRP is not complete, and the application will not see it. And this is a host controller (not OS) related feature. (Think of transfer complete as "flush the buffers from host controller to OS/application".) Without ZLP when needed, the IRP will typically timeout at some point and then it is completely up to the device if it proceeds handling at as valid data, or generating a timeout error. I've seen some USB-IPP devices where this actually depends on what type of request was being made. Other side effects are that print jobs do not print immediately (if any of the IPP requests suffer for this, the timeout needs happen - typically several seconds).
The other problem is that when streaming large amounts of print data, we might end up sending huge transfer sizes. That is we send full USB packets continuously for a long time. The USB specification says that the data payload is larger than expected, all pending bulk IRPs will be aborted/retired. Now some printers handle this fine, but I've seen devices that crash (though this should really be fixed on the device to). USB-IPP does not state maximum transfer size, but the Appendix C there suggests that typically large requests are split to multiple transfers. There is not requirement on boundaries, alignment other matters. When reading IPP-USB the transfers just map to read/write.
I personally think that libusb should have inverted the flag. Most users typically want ZLPs to be automatically generated or things will break in strange ways randomly and depending on device. LIBUSB_TRANSFER_ADD_ZERO_PACKET should really be LIBUSB_TRANSFER_NO_ZERO_PACKET. And have ZLP generation on by default.
But given the following facts on not generating ZLPs:
- is against the "spirit" of USB 5.8.3 and IPP-USB
- will cause random timeouts which different devices handle differently (some work but with additional delay causing perf issues, some error out)
- may cause other compatibility issues during streaming of large print data
I strongly recommend to enable zlp-send by default, or even just removing the quirk.
Thank you for considering.
PS. Perhaps this will also explain more about the received ZLPs. Normally the OS will drain these from received data. But applications can observe them if a they issue bulk read, and the peripheral sends no data (ZLP) as a response. Typically this means the buffers are flushed from the peripheral and no data is pending. But depending on the internal implementation of a peripheral this might be just an implementation quirk. In other cases it can actually mean what it should: there is no more data going to be available. So its always safe to ignore ZLPs, and typically it should be used to indicate that the upper protocol layer should now look into what is happening.
- 主要言語
- Go
- スター
- 211
- フォーク
- 35
- 平均マージ
- 5時間 47分
- マージ済み PR(30日)
- 1
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
OpenPrinting/ipp-usb のほかの issue
-
難易度 5/5 1週間以上 初心者へのやさしさ 20/100
OpenPrinting/ipp-usb#142 · コメント 2 件 ·
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
OpenPrinting/ipp-usb#136 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 32/100
OpenPrinting/ipp-usb#123 · コメント 10 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 42/100
OpenPrinting/ipp-usb#122 · コメント 1 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
OpenPrinting/ipp-usb#116 · コメント 2 件 ·
OpenPrinting/ipp-usb の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
limitlessprojects/Go-Hybrid#3342 ·
メンテナーはふだん 1 日以内に返信
-
status/ready type/bug
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
buildpacks/pack#2733 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
kind/bug needs-priority needs-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
konveyor/tackle2-hub#1166 · コメント 1 件 ·
メンテナーはふだん 4 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
router-for-me/CLIProxyAPI#7209 ·
メンテナーはふだん 1 日以内に返信