I am capturing IEEE802.11 packets with the pcap library. As yet i used pcap_loop and a callback function for receiving and then processing the packets. But now I have switch the wifi channel the device is listening on periodically. Unfortunately, pcap_loop is blocking so I can't call my function using a timeout.
Then I read about pcap_dispatch, but I don't really know how that should work asynchronous, because doing something like
while(1) {
int cnt = pcap_dispatch(handle, -1, callback, null);
}
wouldn't solve a thing.
So can anyone explain to me how to make pcap capture packets asynchronous / event based or in other words how to solve my dilemma?
To quote the pcap_get_selectable_fd() man page (this is the version from the trunk):
DESCRIPTION
pcap_get_selectable_fd() returns, on UNIX, a file descriptor number for
a file descriptor on which one can do a select() or poll() to wait for
it to be possible to read packets without blocking, if such a descrip‐
tor exists, or −1, if no such descriptor exists. Some network devices
opened with pcap_create() and pcap_activate(), or with
pcap_open_live(), do not support select() or poll() (for example, regu‐
lar network devices on FreeBSD 4.3 and 4.4, and Endace DAG devices), so
−1 is returned for those devices.
Note that in:
FreeBSD prior to FreeBSD 4.6;
NetBSD prior to NetBSD 3.0;
OpenBSD prior to OpenBSD 2.4;
Mac OS X prior to Mac OS X 10.7;
select() and poll() do not work correctly on BPF devices;
pcap_get_selectable_fd() will return a file descriptor on most of those
versions (the exceptions being FreeBSD 4.3 and 4.4), but a simple
select() or poll() will not indicate that the descriptor is readable
until a full buffer’s worth of packets is received, even if the read
timeout expires before then. To work around this, an application that
uses select() or poll() to wait for packets to arrive must put the
pcap_t in non‐blocking mode, and must arrange that the select() or
poll() have a timeout less than or equal to the read timeout, and must
try to read packets after that timeout expires, regardless of whether
select() or poll() indicated that the file descriptor for the pcap_t is
ready to be read or not. (That workaround will not work in FreeBSD 4.3
and later; however, in FreeBSD 4.6 and later, select() and poll() work
correctly on BPF devices, so the workaround isn’t necessary, although
it does no harm.)
Note also that poll() doesn’t work on character special files, includ‐
ing BPF devices, in Mac OS X 10.4 and 10.5, so, while select() can be
used on the descriptor returned by pcap_get_selectable_fd(), poll()
cannot be used on it those versions of Mac OS X. Kqueues also don’t
work on that descriptor. poll(), but not kqueues, work on that
descriptor in Mac OS X releases prior to 10.4; poll() and kqueues work
on that descriptor in Mac OS X 10.6 and later.
pcap_get_selectable_fd() is not available on Windows.
In addition, the workaround won't work on Mac OS X 10.6, due to a bug in 10.6's BPF (introduced as part of a fix to another bug); the workaround will work on 10.7 and later, but isn't necessary.
So you could make it event-based if you have a select()/poll()/epoll()/kqueue/etc.-based event loop - add the descriptor you get from pcap_get_selectable_fd() as one of the file descriptors selected on in that event loop.
Related
I am designing the software controlling several serial ports, operating system is OpenWrt. The device application is running in is single core ARM9 # 450 MHz. Protocol for serial ports is Modbus.
The problem is with Modbus slave implementation. I designed it in real-time manner, looping reading data from serial port (port is open in non-blocking mode with 0 characters to wait for and no timeouts). The sequence/data stream timeout is about 4 milliseconds # 9600/8/N/1 (3.5 characters as advised). Timeout is checked if application does not see anything in the buffer, therefore if application is slower that incoming stream of characters, timeouts mechanism will not take place - until all characters are removed from the buffer and bus is quiet.
But I see that CPU switches between threads and this thread is missed for about 40-60 milliseconds, which is a lot to measure timeouts. While I guess serial port buffer still receives the data (how long this buffer is?), I am unable to assess how much time passed between chars, and may treat next message as continuation of previous and miss Modbus request targeted for my device.
Therefore, I guess, something must be redesigned (for the slave - master is different story). First idea coming to my mind is to forget about timeouts, and just parse the incoming data after being synchronized with the whole stream (by finding initial timeout). However, there're several problems - I must know everything about all types of Modbus messages to parse them correctly and find out their ends and where next message starts, and I do not see the way how to differentiate Modbus request with Modbus response from the device. If developers of the Modbus protocol would put special bit in command field identifying if message is request or response... but it is not the case, and I do not see the right way to identify if message I am getting is request or response without getting following bytes and checking CRC16 at would-be byte counts, it will cost time while I am getting bytes, and may miss window for the response to request targeted for me.
Another idea would be using blocking method with VTIME timeout setting, but this value may be set to tenths of seconds only (therefore minimal is 100 ms), and this is too much given another +50 ms for possible CPU switching between threads, I think something like timeout of 10 ms is needed here. It is a good question if VTIME is hardware time, or software/driver also subject to CPU thread interruptions; and the size of FIFO in the chip/driver how many bytes it can accumulate.
Any help/idea/advice will be greatly appreciated.
Update per #sawdust comments:
non-blocking use has really appeared not a good way because I do not poll hardware, I poll software, and the whole design is again subject to CPU switching and execution scheduling;
"using the built-in event-based blocking mode" would work in blocking mode if I would be able to configure UART timeout (VTIME) in 100 us periods, plus if again I would be sure I am not interrupted during the executing - only then I will be able to have timing properly, and restart reading in time to get next character's timing assessed properly.
Background:
I use UART for communication between two devices (with different OSs, one with Linux and one with Windows). I have an application on Windows, as master (sending commands) and an application in Linux as acting and responding application. It will do corresponding operations and give response.
Windows app: Application will send a command and wait for the response. If Linux has not responded within some (say, 10 seconds), come out of wait, notifying the user a timeout error, (and send the next command by user).
Linux app: Application will wait for the command. Process it (say, for 5 seconds max), and then send response to Windows.
Problem: If due to any error/issue, Linux responds after Windows app's timeout (say, 15 seconds), Windows application has already aborted the command thinking it's timed out, and sent the next command. The response of first command is being treated as response for current one, which is not correct.
Solution: I thought of appending the command byte as first byte in Linux response to check/verify in Windows application (that whether the response is for current command or not) and ignore if invalid. But this too has limitations that, if both the commands are same, there will be a mismatch again.
What other logic I can implement to solve this?
I have an embedded linux project where I want to use multi-touch with Qt.
I've been looking at qTUIO ( https://github.com/x29a/qTUIO ) and it looks great.
I cross-compiled the qTUIO library and deployed to the board.
I also cross-compiled and deployed the requirements for the TUIO 'server':
http://bitmath.org/code/mtdev/
http://liblo.sourceforge.net/
http://repo.or.cz/w/mtdev2tuio.git
On the board I fired up the 'server':
./mtdev2tuio /dev/input/touchscreen osc.udp://127.0.0.1:3333/
Sending OSC/TUIO packets to osc.udp://127.0.0.1:3333/
Just to make sure that it was reading the input device I also did the following and saw the 'failure in name resolution' when I moved my finger on the touchscreen:
./mtdev2tuio /dev/input/touchscreen osc.udp://localhost:3333/
Sending OSC/TUIO packets to osc.udp://localhost:3333/
...
OSC error -3: Temporary failure in name resolution
OSC error -3: Temporary failure in name resolution
OSC error -3: Temporary failure in name resolution
OSC error -3: Temporary failure in name resolution
OSC error -3: Temporary failure in name resolution
...
I then ran the qTUIO version of the 'pinchzoom' example on the board and it is running like below with this output:
# ./pinchzoom -qws
graphicsview initialized
listening to TUIO messages on UDP port 3333
So I have a server claiming to be interpreting my touches and sending them UDP to port 3333, and the qt application claiming to be reading those TUIO events and passing them to Qt. When I touch the screen nothing happens. Does anybody have ideas on this?
can you actually fire up a network logger (like tcpdump, Wireshark) and see, if OSC packets actually get sent from your server?
The error
OSC error -3: Temporary failure in name resolution
looks like an issue on your server side, so to eliminate the client as an error source, choose a serve (tracker) different then yours. http://tuio.org/?software features a good overview, if you happen to have an Android Fon around, try http://code.google.com/p/tuiodroid/ to simulate OSC packets.
Now to the client. qTUIO is actually far from done, so there is a good chance, that it is the culprit. A good way to test, if packets are received and forwarded correctly is to look at the overloaded event() method in your code, and see, if it triggers and if yes, with which type. I can only tell you, that it worked okay with a CCV 1.4 as tracker. Also, use the paint example if possible, as it practically translates the touchevents to paintevents, less magic that could go wrong.
Working in an embedded field just adds another special flavour to error sources. Do you maybe have endianess problems? Timing issues?
Can you provide more info on which versions of libs, OS, hardware, etc. you are using?
I will gladly update this post to provide a real solution, once its clear, what component causes the error. Good luck!
I have an app that is connected to the balance through the serial port. The balance is quite large and pressing the PRINT button is not an option. So my app asks the balance to print programmatically upon a certain user action. The balance interface allows it, and defines a print command. All works for awhile. Then after weighting few items, the balance starts outputing the previous weight....I am buffled at this point since there are few commands defined and there is not too many options to what can be done. I am already flushing out the OUT buffer after each time. So I don't know why it keeps giving me the old value.
Here is my code:
if (askedToPrint)
{
_sp.DiscardOutBuffer();
//ask the balance to print
_sp.Write("P\r\n");
}
_sp - is a SerialPort object
I am using WinCE 6.0 and Compact Framework 2.0/C#
if you are reading data from serial port using Readline() or Read() then there is a possibility that balance have sent multiple packets queued. So before reading you have to discard already pending packets. other way around is before writing request to print use ReadExisting() method to read all available data. So after sending command if your balance still sending old packets then there might be a problem with balance.
I have an application that consists of two processes (let's call them A and B), connected to each other through Unix domain sockets. Most of the time it works fine, but some users report the following behavior:
A sends a request to B. This works. A now starts reading the reply from B.
B sends a reply to A. The corresponding write() call returns an EPIPE error, and as a result B close() the socket. However, A did not close() the socket, nor did it crash.
A's read() call returns 0, indicating end-of-file. A thinks that B prematurely closed the connection.
Users have also reported variations of this behavior, e.g.:
A sends a request to B. This works partially, but before the entire request is sent A's write() call returns EPIPE, and as a result A close() the socket. However B did not close() the socket, nor did it crash.
B reads a partial request and then suddenly gets an EOF.
The problem is I cannot reproduce this behavior locally at all. I've tried OS X and Linux. The users are on a variety of systems, mostly OS X and Linux.
Things that I've already tried and considered:
Double close() bugs (close() is called twice on the same file descriptor): probably not as that would result in EBADF errors, but I haven't seen them.
Increasing the maximum file descriptor limit. One user reported that this worked for him, the rest reported that it did not.
What else can possibly cause behavior like this? I know for certain that neither A nor B close() the socket prematurely, and I know for certain that neither of them have crashed because both A and B were able to report the error. It is as if the kernel suddenly decided to pull the plug from the socket for some reason.
Perhaps you could try strace as described in: http://modperlbook.org/html/6-9-1-Detecting-Aborted-Connections.html
I assume that your problem is related to the one described here: http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable
Unfortunately I'm having a similar problem myself but couldn't manage to get it fixed with the given advices. However, perhaps that SO_LINGER thing works for you.
shutdown()
may have been called on one of the
socket endpoints.
If either side may fork and execute a
child process, ensure that the
FD_CLOEXEC
(close-on-exec) flag is set on the
socket file descriptor if you did not
intend for it to be inherited by the
child. Otherwise the child process
could (accidentally or otherwise) be
manipulating your socket connection.
I would also check that there's no sneaky firewall in the middle. It's possible an intermediate forwarding node on the route sends an RST. The best way to track that down is of course the packet sniffer (or its GUI cousin.)