AnsweredAssumed Answered

How to NAK an HID report request

Question asked by Gareth McCaughan on Jul 26, 2017
Latest reply on Jul 27, 2017 by Gareth McCaughan

Background: I'm using a KL26 MCU, and I'm still on version 1.3.0 of the KSDK. (But an answer that begins "First, move to a more recent SDK version" is better than none at all :-).) I'm making a USB HID device. It runs at the hilariously-misnamed "full speed".


Under some circumstances (more details available on request, but I don't think they're important) I would like my device to respond to get/set-report requests with a NAK, so that the host will retry a little later.


I haven't found anything in the documentation indicating how to do this (nor anything indicating that it's impossible).


My report-processing code is called from the HID class-specific callback, so in outline it looks like this:

uint8_t class_callback(uint8_t request, uint16_t value,                        uint8_t ** pData, uint32_t * pSize, void * arg) {   uint8_t lvalue = value & 0xFF;   switch (request) {     case USB_HID_GET_REPORT_REQUEST:       // write report into buffer       *pData = &buffer;       *pSize = /* size of report */;       return USB_OK;     case USB_HID_SET_REPORT_REQUEST:       // parse report and do whatever's necessary       return USB_OK;     // other cases   } }

In particular, I am not explicitly calling USB_Class_HID_Send_Data (nor USB_Class_Send_Data, nor usb_device_send_data, nor anything else that sends data explicitly). There's a thread elsewhere in the NXP Community where someone asks a question similar to mine and the answer is to refrain from calling the data-sending function; but that doesn't seem applicable here.


Is there anything I can do that will make the host get a NAK in response to its request? For instance, will setting *pSize = 0 do that, or will it simply produce a report of length zero, or is its effect undefined and not-to-be-relied-on?


Looking briefly at the USB stack source code, it looks to me -- but it's fairly complicated and I haven't spent long trying to disentangle it -- as if the return value from the class-specific callback is completely ignored. (I wondered about returning USBERR_DEVICE_BUSY or something, but it doesn't seem as if that will help.)


I can do some experiments with a USB analyser, but for obvious reasons I would prefer my code to be based on something more solid than "I tried this and it seemed to work" :-).