Vault 7: Projects
This publication series is about specific projects related to the Vault 7 main publication.
The firmware should never call both USBDeferINDataStage() and USBDeferOUTDataStage() during the same control
transfer. These functions are mutually exclusive (a control transfer with data stage can never contain both IN and OUT data
packets during the data stage).
Preconditions
Before calling USBDeferINDataStage(), the firmware should first verify that the control transfer has a data stage, and that it
is of type device-to-host (IN).
Function
void USBDeferINDataStage(void);
1.4.1.1.1.6 USBDeferOUTDataStage Function
This function will cause the USB hardware to continuously NAK the OUT data packets sent from the host, during the data
stage of a device to host control transfer. This allows the firmware more time to prepare the RAM buffer that will eventually
be used to receive the data from the host. This is also useful, if the firmware wishes to receive the OUT data in a different
context than what the USBDeviceTasks() function executes at.
Calling this function (macro) will assert ownership of the currently pending control transfer. Therefore, the USB stack will not
STALL when it reaches the data stage of the control transfer, even if the firmware has not (yet) called the USBEP0Receive()
API function. However, the application firware must still (eventually, once it is ready) call one of the aforementioned API
function.
Example Usage:
1. Host sends a SETUP packet to the device, requesting a host to device control transfer, with data stage (OUT data
packets).
2. USBDeviceTasks() executes, and then calls the USBCBCheckOtherReq() callback event handler. The
USBCBCheckOtherReq() calls the application specific/device class specific handler that detects the type of control
transfer.
3. If the firmware needs more time before it wishes to receive the first OUT data packet, or, if the firmware wishes to process
the command in a different context, then it may call USBDeferOUTDataStage(), in the context of the
USBCBCheckOtherReq() handler function.
4. If the firmware called USBDeferOUTDataStage() in step #3 above, then the hardware will NAK the OUT data packets
sent by the host, for the OUT data stage.
5. Once the firmware is ready, it should then call USBEP0Receive(), to prepare the USB stack to receive the OUT data from
the host, and to write it to the user specified buffer.
6. The firmware should now call USBCtrlEPAllowDataStage(). This will allow the data stage to complete. Once all OUT data
has been received, the user callback function (provided by the function pointer provided when calling USBEP0Receive())
will get called.
7. Once all data has been received from the host, the status stage (a 0-byte IN packet) will complete automatically
(assuming the firmware did not call USBDeferStatusStage() during step #3).
File
usb_device.h
Syntax
void USBDeferOUTDataStage();
Remarks
Section 9.2.6 of the official USB 2.0 specifications indicates that the USB device must be able to receive all bytes and
complete the control transfer within a maximum of 5 seconds.
If the firmware calls USBDeferOUTDataStage(), it must eventually call USBEP0Receive(), and then call
USBCtrlEPAllowDataStage(). If it does not do this, the control transfer will never be able to complete. This will break the
1.4 Library Interface MLA - USB Library Help Device/Peripheral
42
Protego_Release_01_05-Related-OEM-Documentation-MLA_v2013_12_20-help_mla_usb.pdf