EtherCard Library, for a html webserver

Im using the EtherCard library. I need to build a small webserver to show some data, arduino received via serial interface.
I could run this example sketch:

#include <EtherCard.h>

// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x00,0x14,0xA5,0x76,0x19,0x3A  };
static byte myip[] = { 192,168,1,7 };

byte Ethernet::buffer[500];      //??????
BufferFiller bfill;                     //???????

void setup () {
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println( "Failed to access Ethernet controller");
  ether.staticSetup(myip);
}

static word homePage() {
  long t = millis() / 1000;
  word h = t / 3600;
  byte m = (t / 60) % 60;
  byte s = t % 60;
  bfill = ether.tcpOffset();                         //???????
  bfill.emit_p(PSTR(                                 //???????
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<meta http-equiv='refresh' content='1'/>"
    "<title>RBBB server</title>" 
    "<h1>$D$D:$D$D:$D$D</h1>"),
      h/10, h%10, m/10, m%10, s/10, s%10);                //???????
  return bfill.position();                                           //???????
}

void loop () {
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if (pos)  // check if valid tcp data is received
    ether.httpServerReply(homePage()); // send web page data
}

Now I need to modify this to achieve my task, so please help me to understand the codes I marked with ??? above…

Thanx…

Basically its declaring the packet buffer in the Ethernet library (so you can control how big), instantiating a BufferFiller object to do the filling of the buffer, then interacting with the ether object to get packets and know where to fill the response into a TCP packet. Its not very robust code, note (not even checking the request is on the right port or is HTTP!)

The buffer filler reports back a position at the end of homePage() to be passed back to the ether object so it knows how big packet to send down the wire.

thanx alot for your answer,.. you said this is not a robust code. But actually I'm going to send some data collected with XBee, and finally connect this server to internet to monitor the data remotely. So i realy need a robust code. Can you help me write a robust code.. what are the things I should concern?..any example?

and I hope to do port forwarding to this arduino server. so I need to be able to check a custom port with this code, am I correct? how can I do so?..

In that example, it is going to send an HTTP response back to ANY TCP request on ANY port. Advantage: Simpler for beginners. Disadvantage: Not very robust!

Lately, I have been using uIP for ENC28J60 networking. It has the exact opposite tradeoffs. It can do pretty much anything. But it has a level of complexity that typically requires a few years of programming to understand.

uIP is neatly packaged up as NanodeUIP, and there are many examples in the library, including a multi-function web server. Also covered this web server in my blog: Control and Monitor Arduino Over the Web Using ENC28J60.

I hope to enable access to this server via Internet. But as I'm having an ADSL connection with dynamic IP, I hope to use a DDNS service, and configure my router to update my ip and also do port forwarding with a custom port. cant i achieve my task with this library?..

phantom89: I hope to enable access to this server via Internet. But as I'm having an ADSL connection with dynamic IP, I hope to use a DDNS service, and configure my router to update my ip and also do port forwarding with a custom port. cant i achieve my task with this library?..

Of those things, which specifically need to be done by the Arduino?

Router should b configured for both DDNS and pprt forwarding. I still haven't studied much about port forwarding. But I dont think fpr port forwarding, it matters what the arduino code does.am i right? but I got confused with what you said about the robustness of this code and http requests. could you please explain me that alittle more..?

phantom89: Router should b configured for both DDNS and pprt forwarding. I still haven't studied much about port forwarding. But I dont think fpr port forwarding, it matters what the arduino code does.am i right? but I got confused with what you said about the robustness of this code and http requests. could you please explain me that alittle more..?

Really, you shouldn't need anything on Arduino if your router is doing the forwarding. Shouldn't even need a custom port. The router should be able to listen on like 8080 and forward to 80 on the arduino.

The example is not robust because, among other thIngs it responds to any protocol on any port. So an FTP connection request would get this http response too.

ya,I understan now. could you pleas help me correct those things in my server please..its a great help.. and thanx alot you for your help so far.. :)

can I make this server only listen to a predefined port?

@phantom89,

Did you manage to get further with EtherCard and your duino ?

To your last question the easy answer is "yes", but how to get there is a bit complex for me too.

@maniacbug,

Fully agree that the uIP is much "better", but there are many posts in forums stating that there is a big problem with it: it is so big there is barely any space left to put your logic in the 32k Flash.

So I decided to go EtherCard as well. When you look at the EtherCard.cpp, it looks like you can do a lot with it, but unfortunately there is close to zero documentation. Could anyone provide some ?

#include <EtherCard.h>

#define STATIC 1 // set to 1 to disable DHCP (adjust myip/gwip values below)

#if STATIC
// ethernet interface ip address
static byte myip = { 192,168,2,15 };
// gateway ip address
static byte gwip = { 192,168,2,1 };
#endif

// ethernet mac address - must be unique on your network
static byte mymac = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[500]; // tcp/ip send and receive buffer

BufferFiller bfill; //???
const char page PROGMEM =
“HTTP/1.0 503 Service Unavailable\r\n”
“Content-Type: text/html\r\n”
“Retry-After: 600\r\n”
“\r\n”
“”
“”
“Rain Home Automation”
“”
“”

This service is currently unavailable



"The main server is currently off-line.
"
“Please try again later.”


“”
“”
;

void setup(){
Serial.begin(57600);
Serial.println("\n[backSoon]");

if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( “Failed to access Ethernet controller”);
#if STATIC
ether.staticSetup(myip, gwip);
#else
if (!ether.dhcpSetup())
Serial.println(“DHCP failed”);
#endif

ether.printIp("IP: ", ether.myip);
ether.printIp("GW: ", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
}

void loop(){
word len = ether.packetReceive();
word pos = ether.packetLoop(len);

if (pos) // check if valid tcp data is received
ether.httpServerReply(homePage()); // send web page data

}
static word homePage() {
long t = millis() / 1000;
word h = t / 3600;
byte m = (t / 60) % 60;
byte s = t % 60;
bfill = ether.tcpOffset(); //???
bfill.emit_p(PSTR( //???
“HTTP/1.0 200 OK\r\n”
“Content-Type: text/html\r\n”
“Pragma: no-cache\r\n”
“\r\n”
“”
“RBBB server”

$D$D:$D$D:$D$D

”),
h/10, h%10, m/10, m%10, s/10, s%10); //???
return bfill.position(); //???
}