Hi,
I have a project making a ENTTECproUSB compatible device running on a Linux Box to play with LEDDimmer controls via RDM.
With my workstation an Intel XEON I had little trouble getting the Discovery work reliable but with my Lenovo have the device connected to USB it failed very badly. All kind of Checksum errors happens. I dug deep and found the problem in the common/io/Descriptor.cpp exactly in the Receiver function.
There are two improvements I have done.
- Populate a EAGAIN error to inform the upper stack about a "do it again kernel wasn't ready"
- Add an ipctl() to read if they're the amount of data available we want to read and if not wait and check again (exhaust wait time 110ms)
Below the snippet with some other improvements not show here fix the checksum errors and problems with discovery and all RDM SET/GET entirely.
I have sometime in the coming days and will file a pull request.
Regards
Chris
uint32_t available;
uint8_t loop=10;
int fd = ReadDescriptor();
wait_loop:
ret = ioctl(fd, FIONREAD, &available);
if (available < size) {
usleep(100);
loop--;
if (loop>0)
goto wait_loop;
}
ret = read(ReadDescriptor(), data, size - data_read);
if (ret<0) {
if (errno == EAGAIN || errno == EWOULDBLOCK)
return -EAGAIN;
if (errno != EINTR) {
OLA_WARN << "read failed, " << strerror(errno);
return -1;
}
return ret;
}
else if (ret == 0) {
return 0;
}
data_read += ret;
data += data_read;
}
#endif // _WIN32
return 0;
Hi,
I have a project making a ENTTECproUSB compatible device running on a Linux Box to play with LEDDimmer controls via RDM.
With my workstation an Intel XEON I had little trouble getting the Discovery work reliable but with my Lenovo have the device connected to USB it failed very badly. All kind of Checksum errors happens. I dug deep and found the problem in the common/io/Descriptor.cpp exactly in the Receiver function.
There are two improvements I have done.
Below the snippet with some other improvements not show here fix the checksum errors and problems with discovery and all RDM SET/GET entirely.
I have sometime in the coming days and will file a pull request.
Regards
Chris
uint32_t available;
uint8_t loop=10;
int fd = ReadDescriptor();
wait_loop:
ret = ioctl(fd, FIONREAD, &available);
if (available < size) {
usleep(100);
loop--;
if (loop>0)
goto wait_loop;
}
ret = read(ReadDescriptor(), data, size - data_read);
if (ret<0) {
if (errno == EAGAIN || errno == EWOULDBLOCK)
return -EAGAIN;
if (errno != EINTR) {
OLA_WARN << "read failed, " << strerror(errno);
return -1;
}
return ret;
}
else if (ret == 0) {
return 0;
}
data_read += ret;
data += data_read;
}
#endif // _WIN32
return 0;