BLE on ESP32 packet Errorchecking - error-handling

when transmit data from esp32 to an esp32,does the BLE's libary contain errorchecking? AKA resending packets? uses Ack-Naks? error correction also?
Thanks

There is error checking.
You can check if a write was successful.
A Ble packet consist of:
Preamble: RF synchronization sequence.
Access address: 32 bits, advertising or data access addresses (it is
used to identify the communication).
Header: its content depends on the packet type (advertising or data
packet).
Length: Length of the data payload(When encryption is used, the
message integrity code (MIC) at the end of the packet is 4 bytes, so
this leads to 251 bytes as actual maximum available payload size.
Checksum: CRC.
There is no error correction or resending of packets, unless you implement it yourself.
So,if a write was not successful you can resend a packet.

Related

boost asio ; short read in udp; How to read each udp packet seperately

I am writing a program for receiving udp multicast packet. I came across short read. Is that applicable to udp? How do I ensure that I read one packet at a time? Is that possible?
My packet has a fixed size header followed by a variable length body.
https://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/overview/core/streams.html#:~:text=When%20a%20short%20read%20or,write()%20and%20async_write()%20.
"I came across short read"
What does that mean? You mean you "heard about it"? Or received the error?
Is that applicable to udp?
No. UDP is connectionless and DATAGRAM.
How do I ensure that I read one packet at a time?
That's how UDP works.
Is that possible?
Something else is not possible, although you can set flags that allow an incomplete datagram when the supplied buffer is too small to receive the complete datagram.
My packet has a fixed size header followed by a variable length body.
SUMMARY
The title of the page you linked was Streams, Short Reads and Short Writes. Your sockets are UDP, that is, not streams.

Calculate OPUS packet length

I have a simple application where I send OPUS packets from one client to other say A to B.
A reads one packet from a OPUS file, and send to B.
Again after 20ms or 30ms reads one more packet and send to B, so on..
Till now I was using RTP over UDP, so on receiving side at B, when I receive the packet, I receive complete packet. After receiving complete packet I write to a new file.
This works fine.
Now I am planning to support RTP over TCP.
A will read a complete packet from OPUS file and send to B.
When packet is received at B, it may be received as a single packet or multiple packet (tcp behaviour). My requirement is, I should buffer the data till I receive complete packet. Once I receive complete packet, I will write it to a file.
Now my question is, how do I determine the length of OPUS packet at B while I receiving, so that I can buffer it.
Do not want to use libopus etc if somehow I can avoid it. If by any means from received data, can I find out length of packet?
TCP is a stream protocol. You have two primary choices: add a length word (16 bits is enough) before each Opus packet (read length, then read packet, dealing with buffering (wait to get enough bytes for the read), or pad every Opus packet to a specific size. Opus doesn't use fixed-size packets; they depend on the content and the bitrate and quality settings.

USB CDC Bulk IN Endpoint Freeze

I am using LPC2368 to communicate with PC using USB CDC.
When PC sends the command to LPC over Bulk Out End Point 2,LPC2368 recives 4104 bytes from UART which is sent to PC over USB CDC Bulk IN Endpoint 2.
At PC,this data is considered to be coming form virtual com port,enabling me to see the data (sent to PC) over hypertermial.
There are some commands to which response is less than 64bytes.
After sending command to get these 4104bytes,the 4014 bytes are successfully received from UART and sent in for loop(for in bulk transmission only 64 bytes can be sent in one go) to PC.
Now,if any command be sent after receiving the 4104 bytes,no response is seen.Only,after sending command twice I get response.
Can anyone guide to resolve this behavior of USB?
for in bulk transmission only 64 bytes can be sent in one go
Yes, and the connection will "hang" if your last transaction is exactly 64 bytes long. Reason is little known feature of bulk pipes that treats back-to-back 64 byte (max packet size) transactions as as single larger transaction. Any packet smaller than max packet size will finish a transaction.
A fix is simple: If you have no more bytes to transmit after a 64 byte packet, just transmit a zero packet. Yes, that is a packet containing no data bytes.
Most USB2UART example codes do not implement this fix, because the UART is usually not fast enough to fill the fifo to 64 bytes in the first place.

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.

When do USB Hosts require a zero-length IN packet at the end of a Control Read Transfer?

I am writing code for a USB device. Suppose the USB host starts a control read transfer to read some data from the device, and the amount of data requested (wLength in the Setup Packet) is a multiple of the Endpoint 0 max packet size. Then after the host has received all the data (in the form of several IN transactions with maximum-sized data packets), will it initiate another IN transaction to see if there is more data even though there can't be more?
Here's an example sequence of events that I am wondering about:
USB enumeration process: max packet size on endpoint 0 is reported to be 64.
SETUP-DATA-ACK transaction starts a control read transfer, wLength = 128.
IN-DATA-ACK transaction delivers first 64 bytes of data to host.
IN-DATA-ACK transaction delivers last 64 bytes of data to host.
IN-DATA-ACK with zero-length DATA packet? Does this transaction ever happen?
OUT-DATA-ACK transaction completes Status Phase of the transfer; transfer is over.
I tested this on my computer (Windows Vista, if it matters) and the answer was no: the host was smart enough to know that no more data can be received from the device, even though all the packets sent by the device were full (maximum size allowed on Endpoint 0). I'm wondering if there are any hosts that are not smart enough, and will try to perform another IN transaction and expect to receive a zero-length data packet.
I think I read the relevant parts of the USB 2.0 and USB 3.0 specifications from usb.org but I did not find this issue addressed. I would appreciate it if someone can point me to the right section in either of those documents.
I know that a zero-length packet can be necessary if the device chooses to send less data than the host requested in wLength.
I know that I could make my code flexible enough to handle either case, but I'm hoping I don't have to.
Thanks to anyone who can answer this question!
Read carefully USB specification:
The Data stage of a control transfer from an endpoint to the host is complete when the endpoint does one of
the following:
Has transferred exactly the amount of data specified during the Setup stage
Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet
So, in your case, when wLength == transfer size, answer is NO, you don't need ZLP.
In case wLength > transfer size, and (transfer size % ep0 size) == 0 answer is YES, you need ZLP.
In general, USB uses a less-than-max-length packet to demarcate an end-of-transfer. So in the case of a transfer which is an integer multiple of max-packet-length, a ZLP is used for demarcation.
You see this in bulk pipes a lot. For example, if you have a 4096 byte transfer, that will be broken down into an integer number of max-length packets plus one zero-length-packet. If the SW driver has a big enough receive buffer set up, higher-level SW receives the entire transfer at once, when the ZLP occurs.
Control transfers are a special case because they have the wLength field, so ZLP isn't strictly necessary.
But I'd strongly suggest SW be flexible to both, as you may see variations with different USB host silicon or low-level HCD drivers.
I would like to expand on MBR's answer. The USB specification 2.0, in section 5.5.3, says:
The Data stage of a control transfer from an endpoint to the host is
complete when the endpoint does one of the following:
Has transferred exactly the amount of data specified during the Setup stage
Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet
When a Data stage is complete, the Host Controller advances to the
Status stage instead of continuing on with another data transaction.
If the Host Controller does not advance to the Status stage when the
Data stage is complete, the endpoint halts the pipe as was outlined in
Section 5.3.2. If a larger-than-expected data payload is received from
the endpoint, the IRP for the control transfer will be
aborted/retired.
I added emphasis to one of the sentences in that quote because it seems to specifically say what the device should do: it should "halt" the pipe if the host tries to continue the data phase after it was done, and it is done if all the requested data has been transmitted (i.e. the number of bytes transferred is greater than or equal to wLength). I think halting refers to sending a STALL packet.
In other words, the device does not need a zero-length packet in this situation and in fact the USB specification says it should not provide one.
You don't have to. (*)
The whole point of wLength is to tell the host the maximum number of bytes it should attempt to read (but it might read less !)
(*) I have seen devices that crash when IN/OUT requests were made at incorrect time during control transfers (when debugging our host solution). So any host doing what you are worried about, would of killed those devices and is hopefully not in the market.