Hello,
I'm actually working on an ARP like table :
The thing is quite simple :
- Passively listen to trafic to detect who is active on the network
- Emit data to specific active node
I didn't found satisfying function in Ethernet library : they require a connection, that is not exactly a passive listening of the network ^^
So I found a raw ethernet method directly coming from the W5100 controller.
This work fine alone.
Then for the emitting part I decided to directly use the UDP sending method proposed in the Ethernet library, it is quite simple and avoid me to manually define MAC CRC, IP header CRC, and other painfull stuf like ARP resolution...
This UDP sending method works also fine alone.
The problem occurs when the two methods/functions are used in the same sketch.
Here is the debug example I use :
#include <SPI.h> // needed for Ethernet library communication with the W5100 (Arduino ver>0018)
#include <Ethernet.h>
#include <utility/w5100.h>
#include <EthernetUdp.h>
// our listening socket that will be opened in RAW mode
SOCKET s;
//socket raw IP
//SOCKET t;
byte rbuf[1500+14]; // receive buffer
int rbuflen; // length of data to receive
/*
byte sbuf[1500+14]; // send buffer
int sbuflen = 64; // length of data to send
*/
int i;
byte IP_source[] = {192, 168, 1, 177};
byte MAC_source[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
unsigned int local_port = 27225;
byte IP_dest[] = {192, 168, 1, 180};
unsigned int remote_port = 27226; // local port to listen on
byte data = 255;
EthernetUDP Udp;
void setup() {
// initialize the w5100 chip and open a RAW socket
W5100.init();
//open the RAW_ethernet listening socket
W5100.writeSnMR(s, SnMR::MACRAW);
W5100.execCmdSn(s, Sock_OPEN);
//open the RAW_IP listening socket
/*
W5100.writeSnMR(t, SnMR::IPRAW);
W5100.execCmdSn(t, Sock_OPEN);
*/
//open udp socket
Ethernet.begin(MAC_source,IP_source);
Udp.begin(local_port);
//init of serial line (feedback)
Serial.begin(9600);
}
void loop() {
Serial.println("test");
// check if we have received something
rbuflen = W5100.getRXReceivedSize(s);
//Detection of incoming packet
if (rbuflen>0) {
// receive packet
W5100.recv_data_processing(s, rbuf, rbuflen);
W5100.execCmdSn(s, Sock_RECV);
Serial.println("frame captured");
Serial.println("dest MAC addresse");
// offset 2 ... because the first two bytes in 'rbuf' contain the packet length
for (i=2; i<6; i=i+1)
{
Serial.println(rbuf[i]);
}
Serial.println("Dest MAC addresse");
for (i=8; i<14; i=i+1)
{
Serial.println(rbuf[i]);
}
Serial.println("Type");
for (i=14; i<16; i=i+1)
{
Serial.println(rbuf[i]);
}
Serial.println("Identifiant IP");
for (i=18; i<20; i=i+1)
{
Serial.println(rbuf[i]);
}
Serial.println("IP src");
for (i=28; i<32; i=i+1)
{
Serial.println(rbuf[i]);
}
Serial.println("IP dest");
for (i=32; i<36; i=i+1)
{
Serial.println(rbuf[i]);
}
}
}
As you can see I don't even send effectively frame, I just opened both sockets.
At the begining of the loop, if put a little test print to check if the program is running.
So in this example, with both sockets opened, nothing appears on the serial line.
If i go backward and comment the opening of the udp socket
//open udp socket
//Ethernet.begin(MAC_source,IP_source);
//Udp.begin(local_port);
Then the serial line gets active and start printing the "test" message.
The problem also occurs if I open a RAW ethernet socket and a RAW IP socket throught W5100 methods...
(you can test it with the quoted init methods)
The questions are :
Is that normal doctor ?
What is the problem ?
Is there a way to create two different socket operating at different layers ?
Somebody advised me to close the first listening socket before opening the socket used for emission, but I fear that the setup is only runned once and that a closed socket cannot be reopened in another cycle of the loop ...
I may be not very clear, so do not hesitate to ask for more accurate description of the problem :*