I would like to send a second time (to a different address) an UDP frame already sent once. Here are the details : I fill the W5100 buffer (ethernet shield of my Arduino UNO), then send it with the instruction UDP.endPacket(). Everything goes well ! But now I want to send again this content of the W5100 UDP buffer (which has not changed) to another IP address; is it possible ?
the UDP.beginPacket instruction which allows to set a new IP address "erase" the content of the W5100 buffer (or resets is internal frame length counetr to zero). How can I send another time this existing buffer to another address, keeping is content ?
I use 3 instructions :
Udp.beginPacket (IP adress, Port); to set remote Ip address, Port, and initialize the send buffer length
UDP.write (myBuffer, length) to fill the W5100 send buffer
Udp.endPacket(); to send the UDP frame over the internet.
Is there another instruction (or method) that would allows to send to another IP address this existing W5100buffer ?
thanks in advance !
thanks bruggi !
"myBuffer" is in the memory of the arduino and is only a few characters long, it is used to fill (in several times) the transmission buffer of the W5100 of the ethernet shield (I do it like that not to use 1,4K of RAM memory of the arduino).
So the buffer of 1,4 kbytes that I want to send a second time is in the W5100, but the instruction to change the remote IP address initializes the content of this buffer (that I wanted to send a second time).
yes, I am sure that I need to send the same UDP frame several times, to at least 3 computers all 300 km apart, with different network addresses (e.g. 22.147.110.12, 11.148.63.55, 148.222.23.16, and so on)
does the Broadcast function allow this ?
You could probably add a new function to the EthernetUDP class that allows you to resend the last packet to a new address. this would have to be something that either you maintain for yourself or that you can convince others it is a worthwhile extension. It appears that EthernetUDP.beginPacket sets _offset to zero and this could be changed in your new function so that you had a function such as
i
int EthernetUDP::beginPacket(IPAddress ip, uint16_t port, bool resend)
{
if (!resend) _offset = 0;
//Serial.printf("UDP beginPacket\n");
return Ethernet.socketStartUDP(sockindex, rawIPAddress(ip), port);
}
I have not checked that this would work, and certainly have not tested it! It is just an idea that might help you.
countrypaul, it's the way ! I have to find where is this internal index of the W5100 which defines the size of the buffer.
If someone has an idea?
drmpf, I read the .ino program of "Cheap NMEA/AIS Hub 1".
I'm not sure I understand the broadcast function: it allows to send to several receivers in the same network, but not to several different network-addresses, right?
In this case, the broadcast function would not allow me to send to multiple IP addresses, right?
I think what you are asking for is in W5100Class::init(void) to be found in w5100.cpp. By default it appears to set the WS5100 buffer size to 2048 bytes - though be careful about changing it as I recall someone previously trying without success but I do not recall why.
Broadcast UDP will normally not be sent out onto the Internet by your router even if the EthernetUDP supports it. I am unsure whether multicast is supported, or whether that is permitted via the router onto the Internet.
Here is my in-expert understanding of the situation.
Check out Understanding IP Multicasting
The Cheap NMEA/AIS Hub uses a multicast address. (230.1.1.1)
Your receiver subscribes to this address to receive msgs. The IP (network) of the receiver does not come into it at this level so hosts on multiple networks can receive from the 230.1.1.1 host.
However there needs to be a router path between the receiving host and the multicaster.
So the trick in your case is to create a path between the routers for the multicast msg
Mulitcast UDP msgs are forwarded by routers.
To get though the router you need to set a 'hop count' ttl higher than 1 virtual int beginPacketMulticast(IPAddress multicastAddress, uint16_t port, IPAddress interfaceAddress, int ttl = 1);
see Using Multicast (Programming Interfaces Guide)
Messages with ttl > 1 on arrival at a router have the ttl decremented and forwarded.
BUT be careful you can easily crash a network with flooding udp messages with high ttls. I worked on a system that used upd for the 'initial' broadcast of data and a stress tester had a ttl setting of 10 suddenly we were getting support calls saying the system was 'down'. All the routers were choking in the blast of the testers udp packets. Typically you only need about 20 hops to get around the world.
So long story short for destination IPs 22.147.110.12, 11.148.63.55, 148.222.23.16 they need to subscribe to the sending UDP ip and port AND the ttl of the multicast message needs to be high enough to get through the intervening routers AND the routers configured to bridge between the networks AND not to block the multicast msgs.
One way to set this up would be to multi-home the host on those three network. (The host is the bridge)
OR the three receiving hosts can multi-home on the sender's network
thanks bruggi, drmpf!
countrypaul: "By default, it looks like the WS5100 buffer size is 2048 bytes - but be careful not to change it, as I remember someone tried it before without success, but I can't remember why."
I'll keep you posted. I've dug into the EthernetUDP.cpp, socket.cpp and WS5100.cpp sources of the WS5100 associated library
With the technical doc of WS5100 (pdf easily accessible), we find the registers which are interesting (of which those to fix the size of the buffer, 2048 by default, but modifiable). Unfortunately, the 2 registers which are used as pointers on the emission buffer have a very strange operation. In fact, they are not pointers themselves, I suspect that they are intermediate registers, which influence the real internal pointers, but not with the freedom we need.
They are 16-bit counters in freewheel, they only increase as you write in the WS5100. They are virtual pointers, you have to correct them to find the real address in the range of 2048 bytes, with in addition the offset of what you have already written in the emission buffer to take into account. Wait, it's not finished ! you can write in these virtual pointers, but if you read them again, you get the value '0x0000'... it's only after the command to send the UDP frame that these virtual registers are refreshed, and display the starting address of the future frame in the send buffer. This buffer is thus a rotating buffer, it is necessary to take into account the passage of the 2048 bytes border. The solution I was looking for was, after sending the frame, to decrement one of the 2 virtual pointers, to make the WS5100 believe that it had something to send. Impossible to decrement this virtual pointer, it refuses to move backwards! Grrrrr