Reporting Status Results for Control Transfers - usb

Consider section 8.5.3.1 of USB 2.0 specification:
Control write transfers return status information in the data phase of the Status stage transaction.
For control writes, the host sends an IN token to the control pipe to initiate the Status stage. The function
responds with either a handshake or a zero-length data packet to indicate its current status.
In IN transactions handshake is done by host, not device!
Question is: how device can send handshake for an IN transaction?

In IN transactions handshake is done by host, not device!
I believe there is some misunderstanding.
Device sends NAK/STALL during handshake phase of IN transaction(control write) if there is no data packet during status stage.
If there is a data packet from function corresponding to the IN token, the function expects ACK handshake from host after sending the data packet.
Data packets during status stages are Zero Length Packets.
This is the illustration of scenario in the question:
See also link in comments.

Related

What happens to client message if Server does not exist in UDP Socket programming?

I ran the client.java only when I filled the form and pressed send button, it was jammed and I could not do anything.
Is there any explanation for this?
enter image description here
TLDR; the User Datagram Protocol (UDP) is "fire-and-forget".
Unreliable – When a UDP message is sent, it cannot be known if it will reach its destination; it could get lost along the way. There is no concept of acknowledgment, retransmission, or timeout.
So if a UDP message is sent and nobody listens then the packet is just dropped. (UDP packets can also be silently dropped due to other network issues/congestion.)
While there could be a prior-error such as resolving the IP for the server (eg. an invalid hostname) or attempting to use an invalid IP, once the UDP packet is out the door, it's out the door and is considered "successfully sent".
Now, if a program is waiting on a response that never comes (ie. the server is down or packet was "otherwise lost") then that could be .. problematic.
That is, this code which requires a UDP response message to continue would "hang":
sendUDPToServerThatNeverResponds();
// There is no guarantee the server will get the UDP message,
// much less that it will send a reply or the reply will get back
// to the client..
waitForUDPReplyFromServerThatWillNeverCome();
Since UDP has no reliability guarantee or retry mechanism, this must be handled in code. For example, in the above maybe the code would wait for 1 second and retry sending a packet, and after 5 seconds of no responses it would report an error to the client.
sendUDPToServerThatMayOrMayNotRespond();
while (i++ < 5) {
reply = waitForUDPReplyForOneSecond();
if (reply)
break;
}
if (reply)
doSomethingAwesome();
else
showErrorToUser();
Of course, "just using TCP" can often make these sorts of tasks simpler due to the stream and reliability characteristics that the Transmission Control Protoocol (TCP) provides. For example, the pseudo-code above is not very robust as the client must also be prepared to handle latent/slow UDP packet arrival from previous requests.
(Also, given the current "screenshot", the code might be as flawed as while(true) {} - make sure to provide an SSCCE and relevant code with questions.)

USB interrupt endpoint is unidirectional?

On reading about usb protocol in
http://www.beyondlogic.org/usbnutshell/usb4.shtml
It is said that interrupt endpoint is unidirectional and periodic.
Yet, I see in the description for IN interrupt endpoint, that host initiate the IN token and then data packet is send from device to host.
"If an interrupt has been queued by the device, the function will send
a data packet containing data relevant to the interrupt when it
receives the IN Token."
So, If the data packet is sent on this IN endpoint from device to host, doesn't it mean that the same endpoint is used both the transmit and receive ?
I believe the terminology "unidirectional" is meant for only data and not for token and handshake packets. So "IN" endpoint is for reading data and "OUT" endpoint is for writing data. That's why its called unidirectional.
But control endpoint is bidirectional because you can read or write data using the control endpoint. Check the standard USB commands like "Get Descriptor" and "Set Descriptor".

USB - doubts about protocol

I'm currently studying how USB works. I read, that there are transactions, which are build from smaller pieces - packets. I read about all kinds of packets.
I can't understand one thing. As the book says - every transaction consists of 3 packets: token, data and hanshake.
The way I understand my book is depicted in the schema below.
In my opinion:
I think the first transaction should contain only token IN and data packet, but no hanshake packet (handshake for what?).
I think, that response should only contain ACK hanshake packet (that the data is written properly to the device).
Please, help me understand it in a proper way.
Best regards,
Tom.
A transaction is a series of one or more packets.
A typical IN transaction with no data looks like this:
The host sends an IN token.
The device sends a NAK handshake packet, which means it doesn't have any data to send.
A typical IN transaction with data looks like this:
The host sends an IN token.
The device sends a DATA0 or DATA1 packet with data.
The host sends an ACK handshake.
A typical OUT transaction looks like this:
The host sends an OUT token.
The host sends a DATA0 or DATA1 packet with data.
The device sends a NAK or ACK handshake depending on whether it accepted the data.
Note that I am just talking about full-speed (12 Mbps) USB 2.0 devices, and things can get a bit more complicated for the higher-speed devices.
Note that any of these packets could be lost due to noise issues. The USB specification specifically accounts for this, ensuring that packet loss doesn't result in incorrect operation of the device or host.

UDP transmit performance

I have an application that transmits some data in a loop.
Underlying protocol is UDP on WinSock. If I don't add sleep(1ms) after each transmit operation most of the data is not sent (or wireshark can not capture it) Have you experienced such a behavour that UDP does not handle repetitive sending in a loop ?
Regards
Tugrul
First thing you should check the return values when you send data to check if data is successfully sent or not.
Second thing, This can happen internal buffer of UDP cannot accommodate more data because previous data is yet not transmitted. So the simplest solution is that each time before send the data you should check if your UDP socket is writable or not. You can do it by calling "select" or "poll" on that UDP socket.

Dealing with sendto failure for UDP socket

If sendto fails according to the manpage
"On success, these calls return the number of characters sent. On error, -1 is returned, and errno is set appropriately."
I know that with TCP that is definately the case and you should really attempt to send the remaining data as pointed out in Beej's guide to network programming.
However, partially sending a UDP packet makes no sense to me, and this comment seems to imply it.
If the message is too long to pass atomically through the underlying protocol, the error EMSGSIZE is returned, and the message
is not transmitted.
Can someone confirm for me that if I call sendto (or send) with a UDP packet that if it actually doesn't fit in the outbound buffer then I'll get -1 returned with errno set to EMSGSIZE and no partial send as with a stream (TCP) socket?
There is no hidden meaning, the function just returns the count of bytes sent. It is a standard pattern for Unix APIs. Datagrams are all or nothing delivery, receipt is more complicated if the network caused fragmentation to occur but generally the stack hides all the details and presents each complete packet as it is reconstructed.
EMSGSIZE indicates that "the socket requires that the message be sent atomically, but the size of the message to be sent makes this impossible" (see man sendto).
However, the outbound buffer being full isn't necessarily the reason - Linux (for instance) apparently won't fragment UDP packets by default (see man udp).