Reading the data from ethernet interface

Hi all,

I am a newbie. I have been programming in C but never used to socket/ioctl or accessing devices.

Here is my question.

I have to read data from my ethernet interface en0. I expect packets which give me the speed of motor. I have to store these values in a buffer.

I have to read the the interface every 1 second.

I have thought of the following.

Please help me out:

I set interupt which calls my read function. This function should access en0.

Do I use sockets? Should I open a socket to connect to en0 and then simply read this into my buffer?

Should I handle the packet for the data I want?
Should I do a TCP or IP socket? Ultimately I have to extract the velocity value. Does this mean I have to do some packet handling or are there some OS level handlers that I should use?

Where can I find more information on all this? I read a socket tutorial but there is nothing on packet handling.

I think what you mean is that you expect a data packet over ethernet every second. There are different strategies for doing this depending on the applications needs. Here are a few.

  1. In a loop call read(). The thread will block until the data arrives and you can process it then.

  2. Create a special thread that just calls read in a loop. When it gets the data, it has to transfer the data to another thread or process. With QNX you can have the thread send a message. Alternatively, you can pass the data in a buffer using a mutex or condvar for synchronization.

  3. Use select, it will wait on multiple input events, such as data from a socket, or input from a keyboard.

Whether or not you use sockets depends on what is on the other end sending the data. The two high level protocols are TCP/IP and TCP/UDP. The latter seems more appropriate in your case. If the other end is just flinging an IP packet at you, you will need to look into the raw packet interface.

By the way, this not a QNX specific question. You might more info posting in TCP/IP related site/forum.

Unless the poster is not clearly specifying the question. Perhaps the device sending the update is not using IP. In that case they may need to use the bpf interface (which while it exists on netbsd, is certainly fair game as a question in an OS specific forum).

Hi all,

I have followed the ideas of maschoen and have laid an outline program:

  1. I have a main function that creates 2 threads. A writer(WHICH SHOULD READ FROM en0 AND THEN WRITE TO A RING BUFFER) and a Reader thread which READS OUT OF RING BUFFER…this thread should act like a server thread that should be called by any client application wanting to read the ring buffer

2)The writer thread actually calls a function which reads the en0. Here is where I have some issues… Should I have as rgallen suggests a bpf interface that captures ethernet packets or should I go for TCP sock? The bottomline is, I have to simulate receiving some speed values of motor at my en0. I am not sure of any format :frowning: What could be the easiest?
Also the thread ‘writer’ should read this en0 at say every second and write to ring buffer(hence the writer thread does a read and write so to say!!)
One more issue is, at the moment I have the read interface thread as part of my function call for the writer thread. This read interface function should then call a filling up ring buffer function…This seems a long wind… Do you have better ideas? Am I missing something here?

If this is just a simulation, then by all means use IP (UDP or TCP) as it will be the easiest. BPF is only necessary if you are talking to a real device that doesn’t use IP framing.

I’m not sure why you are using the term “server” here. If there really are clients, other processes that want to get and process the input, then they do not “call” the thread. They send a message. The receiving thread would then wait for data in the ring buffer using a condvar. When it finds the data it would reply. If it is possible for multiple clients, then the resource manager would need to be multi-threaded.

On the other hand, if these “clients” are just other threads in the same process that consume the data in the ring buffer, you just need the mutexes and condvars.

Uhhh, no. You have two threads. One reads from en0 and puts the data in your ring buffer. The other waits for data in the ring buffer and removes it when it appears.
[/quote]

I would write a resource manager that would be supply the data that is in the ring buffer to any client that wants it. This resource manager would have a “motor” thread that would be responsible for getting the data from the network ( TCP/IP ) and put it in the ring buffer. You can replace the “motor” thread by a thread that simulated data or that inject it via a TCP/IP link in effect simulating the actual device.

How you will read data off the network depends on what type of communication the devices supports, hopefully it is TCP or UDP.

Yes maschoen, I am sorry for not being clear. I did mean that the client applications would use message passing for using buffer values.
@ Mario, I will look up how to write resource manager also.

If I dont have sockets or bpf, how else can I read my eth0 interface…??

This is a weird statement, QNX comes with socket support and bpf support, you cannot not have them.

Socket should be the way to go, if you device is not using TCP or UDP then it is a VERY weird device.

Socket or bpf are the clean way of doing it and you shouldn’t really be looking at anything else.

I wouldn’t say that. I have seen lots of devices (with ethernet) that aren’t IP based. Admittedly not many newly designed devices though.

I was reading more on sockets…I have stuck to them for now. Just some confirmations. I open a socket with AF_NET for domain with SOCK_DGRM as socket type(essentially UDP). I dont use SOCK_RAW as I dont want to wrap and unwrap headers which I think is already done by the kernel in case of DGRM and STREAM.
After this I bind to the en0 interface after defining the sockaddr_in structure. The tutorial says:" if I use a buffer ‘big enough’(which is not quite concrete) to hold the bytes, the read() returns the bytes read from en0 and this would essentially mean ONE PACKET"( and this is just the payload isn’t it??)…Essentially I was asked to stick to 4 bytes for the speed value which would mean int type. So I can have an int array ring buffer which should accomodate some 60 values (assuming I store data of the last one minute only in my ring buffer, reading new values from en0 every one sec)… But I am not sure what these bytes that read() returns includes? Can somebody clarify.

You need to read a book on TCP/IP and really get a bigger picture to make an informed decision.

Unless you have control over what the “motor” thingy sends, you are a slave to it, you cannot chose between UDP or TCP you have to comply with whatever the “motor” sends.

But to answer your question, if you use UDP then yes if the read is big enough you will have the complete packet. The buffer returned by read() will be just the payload, all of the IP/UDP stuff will be stripped for you. Same as if you do a read() on a file, you wouln’t expect read to return metadata, inodes etc ;-)

Ninja,

Not necessarily. Read can definitely return more than 1 Packet. In practice though you will most likely only read one packet.

The way you end up reading more than 1 packet is:

  1. Your app is calling read() slower than packets are arriving so that data is buffering in IP stack (not likely in your case if the device is only sending one packet per second)
  2. The number of bytes you request from read() is more than the size of a single packet (by packet I mean payload of the packet) AND there is more than 1 packet worth of data queued up.

Now if you know the device is always sending exactly 4 bytes then you can ensure you only read 1 packet at a time by just requesting 4 bytes. Then regardless of how much data is queued up you’ll only read 1 packet.

Correct.

As you surmrised, read() only returns the payload (4 bytes in your case).

You mention doing a read() once per second. Is this device a polled device where you send a packet to request data or does the device send data on it’s own without any prompting requried from you? If the device sends data on it’s own you’ll want to make sure that the speed with which you read() is the speed that the device sends (so if it sends data 10x a second you better be prepared to read 10x a second otherwise lots of data will buffer up and you’ll end up way out of sync)

Tim

Thanks a lot Tim. I got this working!