The line of significant import in the code of the previous port:
init_and_set_protocol( handle, 19200, 8, 0, 1);
By and large, USB devices aren’t just a piece of wire you can claim then shove stuff out. There tends to be a processor of some kind and it needs configuration. Many management types will utter something like,
Let’s use USB to communicate. USB 3.0 is way faster than serial ports.
Well, that’s true. It’s also true you cannot just stuff a USB cable into 2 different USB ports on a desktop to create a loop back test. Where there is a processor there is configuration to deal with. The dark side of my mind wants to know just how many projects had a Keller MBA utter the quote from above only to have the hardware and software developers do basically what I just did. Stuff 2 USB TTL UART bridge devices into the thing and hard wire them together with a Null Modem cable.
Whatever USB communication method you get stuck with on a project, it will require you to create some form of init_and_set_protocol() because the odds of being exactly right out of the box are low.
While we are talking about things you will see a lot of and should not do, you will find dozens, perhaps hundreds of posts talk about claiming the device and showing you how to do this:
if (desc.idVendor == VENDOR_ID && desc.idProduct == PRODUCT_ID) { found = 1; break; }
I know I did it here too, but that is a really bad thing. You will note that I had 2, count them two of the exact same device. There was no realistic way to predict which would be found first. By trial and error, it turned out to always be the last one plugged in, but, that probably only holds true for the front of this machine.
printf("\nTo be sent : %s\n",my_string); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), (unsigned char *)my_string,length,&transferred,5000); // last param is timeout in ms if(e == 0 && transferred == length) { printf("\nWrite successful!"); printf("\nSent %d bytes with string: %s\n", transferred, my_string); } else { printf("\nError in write! e = %d and transferred = %d\n",e,transferred); printf("message: %s\n", libusb_strerror(e)); } int retry_count = 0; int exit_flag = 0; int rcvLength = IN_PACKET_SIZE; char current_line[2048]; unsigned char new_line[] = {'\r', '\n', 'printf("\nTo be sent : %s\n",my_string); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), (unsigned char *)my_string,length,&transferred,5000); // last param is timeout in ms if(e == 0 && transferred == length) { printf("\nWrite successful!"); printf("\nSent %d bytes with string: %s\n", transferred, my_string); } else { printf("\nError in write! e = %d and transferred = %d\n",e,transferred); printf("message: %s\n", libusb_strerror(e)); } int retry_count = 0; int exit_flag = 0; int rcvLength = IN_PACKET_SIZE; char current_line[2048]; unsigned char new_line[] = {'\r', '\n', '\0'}; unsigned char next_char[] = { ' ', '\0'}; memset(current_line, '\0', sizeof(current_line)); while( exit_flag == 0) { memset(my_string1, '\0', IN_PACKET_SIZE+1); e = libusb_bulk_transfer(handle, (BULK_EP_IN | LIBUSB_ENDPOINT_IN), (unsigned char *)my_string1,rcvLength,&received,5000); if(e == 0) { for (int i=0; i < strlen(my_string1); i++) { if (my_string1[i] == '\r') { exit_flag = check_for_exit(current_line); printf("\n"); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), new_line,2,&transferred,5000); memset(current_line, '\0', sizeof(current_line)); } else { next_char[0] = my_string1[i]; putchar(my_string1[i]); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), next_char,1,&transferred,5000); strcat(current_line, (char *)next_char); } } fflush(stdout); } else { retry_count++; printf("retry_count %d\n", retry_count); if (retry_count > 10) { printf("retry_count %d\n", retry_count); exit_flag = 1; } } }'}; unsigned char next_char[] = { ' ', 'printf("\nTo be sent : %s\n",my_string); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), (unsigned char *)my_string,length,&transferred,5000); // last param is timeout in ms if(e == 0 && transferred == length) { printf("\nWrite successful!"); printf("\nSent %d bytes with string: %s\n", transferred, my_string); } else { printf("\nError in write! e = %d and transferred = %d\n",e,transferred); printf("message: %s\n", libusb_strerror(e)); } int retry_count = 0; int exit_flag = 0; int rcvLength = IN_PACKET_SIZE; char current_line[2048]; unsigned char new_line[] = {'\r', '\n', '\0'}; unsigned char next_char[] = { ' ', '\0'}; memset(current_line, '\0', sizeof(current_line)); while( exit_flag == 0) { memset(my_string1, '\0', IN_PACKET_SIZE+1); e = libusb_bulk_transfer(handle, (BULK_EP_IN | LIBUSB_ENDPOINT_IN), (unsigned char *)my_string1,rcvLength,&received,5000); if(e == 0) { for (int i=0; i < strlen(my_string1); i++) { if (my_string1[i] == '\r') { exit_flag = check_for_exit(current_line); printf("\n"); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), new_line,2,&transferred,5000); memset(current_line, '\0', sizeof(current_line)); } else { next_char[0] = my_string1[i]; putchar(my_string1[i]); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), next_char,1,&transferred,5000); strcat(current_line, (char *)next_char); } } fflush(stdout); } else { retry_count++; printf("retry_count %d\n", retry_count); if (retry_count > 10) { printf("retry_count %d\n", retry_count); exit_flag = 1; } } }'}; memset(current_line, 'printf("\nTo be sent : %s\n",my_string); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), (unsigned char *)my_string,length,&transferred,5000); // last param is timeout in ms if(e == 0 && transferred == length) { printf("\nWrite successful!"); printf("\nSent %d bytes with string: %s\n", transferred, my_string); } else { printf("\nError in write! e = %d and transferred = %d\n",e,transferred); printf("message: %s\n", libusb_strerror(e)); } int retry_count = 0; int exit_flag = 0; int rcvLength = IN_PACKET_SIZE; char current_line[2048]; unsigned char new_line[] = {'\r', '\n', '\0'}; unsigned char next_char[] = { ' ', '\0'}; memset(current_line, '\0', sizeof(current_line)); while( exit_flag == 0) { memset(my_string1, '\0', IN_PACKET_SIZE+1); e = libusb_bulk_transfer(handle, (BULK_EP_IN | LIBUSB_ENDPOINT_IN), (unsigned char *)my_string1,rcvLength,&received,5000); if(e == 0) { for (int i=0; i < strlen(my_string1); i++) { if (my_string1[i] == '\r') { exit_flag = check_for_exit(current_line); printf("\n"); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), new_line,2,&transferred,5000); memset(current_line, '\0', sizeof(current_line)); } else { next_char[0] = my_string1[i]; putchar(my_string1[i]); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), next_char,1,&transferred,5000); strcat(current_line, (char *)next_char); } } fflush(stdout); } else { retry_count++; printf("retry_count %d\n", retry_count); if (retry_count > 10) { printf("retry_count %d\n", retry_count); exit_flag = 1; } } }', sizeof(current_line)); while( exit_flag == 0) { memset(my_string1, 'printf("\nTo be sent : %s\n",my_string); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), (unsigned char *)my_string,length,&transferred,5000); // last param is timeout in ms if(e == 0 && transferred == length) { printf("\nWrite successful!"); printf("\nSent %d bytes with string: %s\n", transferred, my_string); } else { printf("\nError in write! e = %d and transferred = %d\n",e,transferred); printf("message: %s\n", libusb_strerror(e)); } int retry_count = 0; int exit_flag = 0; int rcvLength = IN_PACKET_SIZE; char current_line[2048]; unsigned char new_line[] = {'\r', '\n', '\0'}; unsigned char next_char[] = { ' ', '\0'}; memset(current_line, '\0', sizeof(current_line)); while( exit_flag == 0) { memset(my_string1, '\0', IN_PACKET_SIZE+1); e = libusb_bulk_transfer(handle, (BULK_EP_IN | LIBUSB_ENDPOINT_IN), (unsigned char *)my_string1,rcvLength,&received,5000); if(e == 0) { for (int i=0; i < strlen(my_string1); i++) { if (my_string1[i] == '\r') { exit_flag = check_for_exit(current_line); printf("\n"); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), new_line,2,&transferred,5000); memset(current_line, '\0', sizeof(current_line)); } else { next_char[0] = my_string1[i]; putchar(my_string1[i]); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), next_char,1,&transferred,5000); strcat(current_line, (char *)next_char); } } fflush(stdout); } else { retry_count++; printf("retry_count %d\n", retry_count); if (retry_count > 10) { printf("retry_count %d\n", retry_count); exit_flag = 1; } } }', IN_PACKET_SIZE+1); e = libusb_bulk_transfer(handle, (BULK_EP_IN | LIBUSB_ENDPOINT_IN), (unsigned char *)my_string1,rcvLength,&received,5000); if(e == 0) { for (int i=0; i < strlen(my_string1); i++) { if (my_string1[i] == '\r') { exit_flag = check_for_exit(current_line); printf("\n"); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), new_line,2,&transferred,5000); memset(current_line, 'printf("\nTo be sent : %s\n",my_string); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), (unsigned char *)my_string,length,&transferred,5000); // last param is timeout in ms if(e == 0 && transferred == length) { printf("\nWrite successful!"); printf("\nSent %d bytes with string: %s\n", transferred, my_string); } else { printf("\nError in write! e = %d and transferred = %d\n",e,transferred); printf("message: %s\n", libusb_strerror(e)); } int retry_count = 0; int exit_flag = 0; int rcvLength = IN_PACKET_SIZE; char current_line[2048]; unsigned char new_line[] = {'\r', '\n', '\0'}; unsigned char next_char[] = { ' ', '\0'}; memset(current_line, '\0', sizeof(current_line)); while( exit_flag == 0) { memset(my_string1, '\0', IN_PACKET_SIZE+1); e = libusb_bulk_transfer(handle, (BULK_EP_IN | LIBUSB_ENDPOINT_IN), (unsigned char *)my_string1,rcvLength,&received,5000); if(e == 0) { for (int i=0; i < strlen(my_string1); i++) { if (my_string1[i] == '\r') { exit_flag = check_for_exit(current_line); printf("\n"); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), new_line,2,&transferred,5000); memset(current_line, '\0', sizeof(current_line)); } else { next_char[0] = my_string1[i]; putchar(my_string1[i]); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), next_char,1,&transferred,5000); strcat(current_line, (char *)next_char); } } fflush(stdout); } else { retry_count++; printf("retry_count %d\n", retry_count); if (retry_count > 10) { printf("retry_count %d\n", retry_count); exit_flag = 1; } } }', sizeof(current_line)); } else { next_char[0] = my_string1[i]; putchar(my_string1[i]); e = libusb_bulk_transfer(handle, (BULK_EP_OUT | LIBUSB_ENDPOINT_OUT), next_char,1,&transferred,5000); strcat(current_line, (char *)next_char); } } fflush(stdout); } else { retry_count++; printf("retry_count %d\n", retry_count); if (retry_count > 10) { printf("retry_count %d\n", retry_count); exit_flag = 1; } } }
The last part we need to talk about is the mental hurdle. It’s a big one. When you see the function name libusb_bulk_transfer(), mentally you expect this to operate like disk I/O. A block at a time, every time. Maybe a hole bunch of blocks, but never less than a block. Keep in mind, there is a UART involved here. Actually 2 UARTS. Also keep in mind Rollie is running with one monitor here in the Corporate Housing unit, so also burns some time switching between windows before typing.
That 5 second (5000 ms) timeout parameter, it doesn’t mean wait 5 seconds or until you are full. There is no definition of bulk. There is no physically defined transfer protocol. Software defined wouldn’t help you unless you want to split hairs about something you configure on-chip being considered software. Yes, I’m running a UART (Universal Asynchronous Receiver/Transmitter) here. By definition that transfers to and from a buffer one character at a time. The logic around a buffer is where one would have to define “bulk” and it would have to be defined in a way that libusb could make use of it. Something like the endpoint having N buffers under the hood and as soon as one had a “bulk” in it, the endpoint would point to it.
At some point during my development I did at the -std=gnu11 compiler switch. Not certain it is still required, but, wanted to be up front about that.
So, rather than mess around with C level threading, I think the next logical step is to go back to the Qt code, reducing this to a single device loopback adding a chat test and full volume loopback test. That should round this out while providing usable code to others. It will also provide a place where I can pull my code when I find myself stranded at a client site wanting to remember what I did.