WinApi get number of available bytes from a USB port? - c++

Is there a way to check the number of bytes available from a USB device (printer in our case)?
We're using CreateFile and ReadFile and WriteFile for IO communications with our USB device, which works. But We can't figure out how much data is available without actually doing a read. We can't use GetFileSize, as even the documentation says you can't use it for a :
"nonseeking device such as a pipe or a communications device"...
So that doesn't work. Any suggestions? Are we doing our USB I/O incorrectly? Is there a better way to Read/Write to USB?

You first need to open up the port in asynchronous mode. To do that, pass the flag FILE_FLAG_OVERLAPPED to CreateFile. Then, when you call ReadFile, pass in a pointer to an OVERLAPPED structure. This does an asynchronous read and immediately returns ERROR_IO_PENDING without blocking (or, if the OS already has the data buffered, you might get lucky and get a successful read -- be prepared to handle that case).
Once the asynchronous I/O has started, you can then periodically check if it has completed with GetOverlappedResult.
This allows you to answer the question "are X bytes of data available?" for a particular value of X (the one passed to ReadFile). 95% of the time, that's good enough, since you're looking for data in a particular format. The other 5% of the time, you'll need to add another layer of abstraction top, where you keep doing asynchronous reads and store the data in a buffer.
Note that asynchronous I/O is very tricky to get right, and there's a lot of edge cases to consider. Carefully read all of the documentation for these functions to make sure your code is correct.

Can you use C#? If so you can access the USB port using System.IO.SerialPort class, and then set up a DataReceived event handler for incoming data. There is a BytesToRead property that tells you how much data is waiting to be read.
All of this must be available in native code, if I can find it I'll edit this.
EDIT: the best I can find for native is ReadPrinter - I don't see how to check if data is there, this will block if it's not.

Related

Is it possible to wrap existing TCP/OpenSSL session with `iostream`?

I use custom code to create SSL connection over native Berkeley sockets interface. I need to wrap the resulted socket with iostream to use existing algorithms written in C++ with these sockets data.
Is there any easy way to do it without need to implement stream and streambuf from scratch?
I learned boost::iostreams and boost::asio.
I didn't find any way to wrap existing OpenSSL session with boost::asio. Or may be anyone knows how to do that?
After boost:asio I concentrated my research on boost:iostreams.
boost::iostreams looks like good idea, however, its problem is that it uses read buffering. So, if we need to read just 1 byte from SSL session, it asks the TCP device to read 4 kilobytes and results in timeout. From the other hand, when I set buffer size to 0, boost::iostreams start to call write method for each byte, so when I try to write 10 bytes to stream, it calls SSL_write 10 times. TCP device itself can not use write buffering, because there are no way to forward flush method to device, so application level protocol may expect that data is sent to another peer while the data remains in output buffer.
So, we need unbuffered read and buffered flushable write; is that possible with boost::iostreams?
I found solution myself.
First of all, it is required to mark the device as flushable. Because there are not ready-made template for such device, you have to inherit device<dual_use, Ch> and override its category with multiple inheritance:
struct category : device<dual_use, Ch>::category, flushable_tag
Now when you will call flush on stream, it will forward the call to your device.
Next step is to disable stream own buffering (i. e. call open with 2nd and 3rd parameters equal to 0).
In such configuration boost will write to device each byte of data separatelly. However, you can implement buffering on device level, and flush the buffer on flush call.

WinAPI Wait on a pipe for reading data

I am writing a program for reading from and writing to pipes.
I found out that by using PeekNamedPipe function I can get the
number of bytes which are ready to be read. But I have a question
How can I wait for coming data. Can I use WaitForSingleObject function
for waiting on a pipe to get data from other end of pipe.
regards,
You can either use Overlapped I/O, or preferably use Completion Routines.
They are both asynchronous (non-blocking), but I prefer completion routines as you register a callback that gets called when there is data to read - no need to poll for data. Check out the links and build and run through the examples. It may take a little time to understand / implement, but you will be glad you took that time to do it right when it's working well :).

How can I monitor a FIFO for read and writes?

How should one monitor data that went through a FIFO ? Simply open and keep watching doesn't work, since if the monitor reads all bytes, the actual program that needs data will fail to receive the data.
I am not sure what kind of FIFO you have there (pipe? socket? maybe you should elaborate more on your question in general), but the only case where I know about forward-reading is with sockets.
You can use recv() with the flag MSG_PEEK with the following effect:
This flag causes the receive operation to return data from the
beginning of the receive queue without removing that data from the
queue. Thus, a subsequent receive call will return the same data.
You can implement IPC with sockets, too (unix(7)), so you might want to add them to your project (if you are using linux/unix). If you want to know how to use sockets then you should read the man page: socket(2) and socket(7) or in case of Windows, recv() and socket().
You might also want to try to use 2 FIFO's, one to your monitor and the other one from your monitor to your actual program. Then you simply read all incoming data with your monitor and filter the relevant parts and write them directly to your actual program. This might come in handy if you have multiple receivers inside your actual programs and want to split up the incoming data.
If you simply want to know whether there is data to read, you can use select(2) or pselect(2) or maybe poll(2), or select()
You should use one of the following system calls:
select()- source: man -s 2 select
pselect()- source: man -s 2 pselect
select() and pselect() allow a program to monitor multiple
file
descriptors, waiting until one or more of the file descriptors become
"ready" for some class of I/O operation (e.g., input possible). A file
descriptor is considered ready if it is possible to perform the corre-
sponding I/O operation (e.g., read(2)) without blocking.
Note they are all I/O blocking calls.
ppoll()- man -s 2 ppoll
poll()- man -s 2 poll
Also read the difference between the both set of system calls: http://www.unixguide.net/network/socketfaq/2.14.shtml
And using pselect or ppoll is always better than select and poll for safer uses.

mkfifo Alternative

I have a process that continuously needs to write information. Furthermore, there is a second process which sometimes connects to the "information channel" of the writing process and should read the information that are written since it's connected. This process might also deconnect and reconnect several times again.
I am currently realizing this with a named pipe, by using mkfifo() in my c++ program. Unfortunately if I call open() on this fifo it blocks until a process opens the fifo for reading. This is quite normal for named pipes, but I need this open command to be non-blocking.
Do you know an alternative to mkfifo in this case?
Heinrich
You could use Unix-domain sockets, or regular TCP sockets on loopback interface.
You can use shared memory or mmap. It should contain offset to the oldest data, and the block of memory for data
fifo is limited to 64k (depends on distribution and some settings).
I finally used the unix message queue, Reader and Writer can.be started totally independet and everything can be performed non blocking

Setting a timeout on ifstream in C++?

We're trying to read data from 2 usb mice connected to a linux box (this data is used for odometry/localization on a robot). So we need to continuously read from each mouse how much it moved. The problem is that when a mouse is not moving, it doesn't send any data, so the file stream from which we get the data blocks execution and therefore the program can't do the odometry calculations (which involve time measurement for speed).
Is there a way to set a timeout on the input stream (we're using ifstream in C++ and read from /dev/input/mouse), so that we're able to know when the mouse doesn't move, instead of waiting for an event to be received? Or do we need to mess up with threads (arggh...)? Any other suggestions are welcome!
Thanks in advance!
A common way to read from multiple file descriptors in linux is to use select(). I suggest starting with the manpage. The basic system flow is as follows:
1) Initialize devices
2) Obtain list of device file descriptors
3) Setup the time out
4) Call select with file descriptors and timeout as parameters - it will block until there is data on one of the file descriptors or the time out is reached
5) Determine why select returned and act accordingly (i.e. call read() on the file descriptor that has data). You may need to internally buffer the result of read until an entire data gram is obtained.
6) loop back to 4.
This can become your programs main loop. If you already have a different main loop you, can run the above without looping, but your will need to insure that the function is called frequently enough such that you do not lose data on the serial ports. You should also insure that your update rate (i.e. 1/timeout) is fast enough for your primary task.
Select can operate on any file descriptor such network sockets and anything else that exposes an interface through a file descriptor.
What you're looking for would be an asynchronous way to read from ifstream, like socket communication. The only thing that could help would be the readsome function, perhaps it returns if no data is available, but I doubt this helps.
Using threads would be the best way to handle this.
Take a look at the boost Asio library. This might help you deal with the threading suggested by schnaeder.
No, there is no such method. You'll have to wait for an event, or create a custom Timer class and wait for a timeout to repoll, or use threads.