The MTP Specification contains this definition of the CancelTransaction Event:
Event Code: 0x4001
Parameter 1: None
Parameter 2: None
Parameter 3: None
This event is used to initiate the cancellation of a transaction over transports which do not have their own mechanism for canceling transactions. The details of how a transaction is cancelled may be transport-specific. When an initiator or responder receives this event, it should cancel the transaction identified by the TransactionID in the event dataset. If the transaction has already completed, this event should be ignored.
After receiving a CancelTransaction event from the initiator during an object transfer, the responder should send an Transaction_Cancelled response for the transfer which was in progress.
MTP USB Transport Cancellation Behavior
Why then does an MTP/USB device send a Status_OK (0x2001) instead of Transaction_Cancelled (0x201F) response when it receives a CancelTransaction (0x4001) from the application?
The reason is that the MTP USB transport has defined how cancellation is to be implemented. As pointed out in the MTP Specification above, CancelTransaction is intended for “transports which do not have their own mechanism for canceling transactions“, and will not apply to MTP/USB devices.
Here are the MTP/USB specifications for each cancellation scenario. In the cases below, “Host” can be a PC running Windows Media Player 11, and “Device” can be a MTP music player or a PTP camera that connects to the PC through USB.
Case A. When the Host Cancels
When the device receives a cancellation request from the host, it should return Device_Busy (0x2019) for a GetDeviceStatus query. The device should then perform cancellation and clean up, and return Status_OK (0x2001) for subsequent GetDeviceStatus requests. The device should NOT send a response for the cancelled transaction through the BULK-IN pipe.
After the host receives a Status_OK response from a GetDeviceStatus query on the device, it may issue the next transaction through the BULK-OUT pipe.
Case B. When the Device Cancels
If the device wants to cancel, it should STALL both BULK-IN and BULK-OUT endpoints. When the device receives a GetDeviceStatus request from host, the device should return Transaction_Cancelled (0x201F) as the reason for the STALL, and the STALL-ed endpoint numbers.
The host may then issue the ClearFeature request to clear the STALL-ed endpoints. The device should clear, get ready for next command, and return Status_OK for next GetDeviceStatus query.
Case C. When the Host and Device Both Cancel
When the device receives a cancel request from the host while it is trying to cancel, it should clear any pending device-initiated cancellations, respond to the host with Device_Busy (0x2019) for subsequent GetDeviceStatus requests, and proceed with normal host-initiated cancellation.
When the device wants to cancel (this could be initiated by the user), it first checks if there are any pending host-initiated cancellation. If yes, the device can simply return. If not, the device should STALL the BULK endpoints.
For cancellation examples, refer to the Picture Transfer Protocol (PTP) Specification – ISO 15740 Annex D: Sections D.184.108.40.206 (for device behavior) and D.9, available on the I3A PTP website.
In addition, the PTP USB Transport specification also contains a definition for the GetDeviceStatus and further descriptions of the BULK cancellation behavior.
This posting is provided “AS IS” with no warranties, and confers no rights.