Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Simple web server for Nanode v5 that also provides Wake-On-LAN broadcast on network segment in response to a HTTP request. This provides a route-able way to start a server on another network segment.
// Simple web server for Nanode v5 that also provides Wake-On-LAN broadcast on
// network segment in response to a HTTP request. This provides a route-able
// way to start a server on another network segment.
// 2012-01-07 <matthew@densons.org> http://opensource.org/licenses/mit-license.php
#include <EtherCard.h>
#include <NanodeUNIO.h>
// ethernet mac address - must be unique on your network
static byte mymac[6];
// ethernet mac address - to wake
static byte wakemac[] = { 0x00,0x11,0x43,0xfd,0x68,0xc1 };
static BufferFiller bfill; // used as cursor while filling the buffer
byte Ethernet::buffer[700]; // tcp/ip send and receive buffer
// this buffer will be used to construct a collectd UDP packet
static byte udpBuf [102];
char page[] PROGMEM =
"<html>"
"<head><title>"
"Service Temporarily Unavailable"
"</title></head>"
"<body>"
"<h3>This service is currently unavailable</h3>"
"<p><em>"
"The main server is currently off-line.<br />"
"Please try again later."
"</em></p>"
"</body>"
"</html>"
;
void setup(){
NanodeUNIO unio(NANODE_MAC_DEVICE);
if (!unio.read(mymac,NANODE_MAC_ADDRESS,6))
Serial.println("MAC failed");
ether.begin(sizeof Ethernet::buffer, mymac);
ether.dhcpSetup();
}
char okHeader[] PROGMEM =
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n"
"Pragma: no-cache\r\n"
;
static void homePage (BufferFiller& buf) {
buf.emit_p(PSTR("$F\r\n$F"), okHeader, page);
}
static void wakeServer () {
static byte destIp[] = { 255,255,255,255 }; // broadcast on local segment
byte loc = 0;
for (byte j = 0; j<6; j++, loc++) {
udpBuf[loc] = 0xFF;
}
for (byte i = 0; i<16; i++) {
for (byte j = 0; j<6; j++, loc++) {
udpBuf[loc] = wakemac[j];
}
}
ether.sendUdp ((char*) udpBuf, 102, 23456, destIp, 7);
}
void loop(){
boolean wake=false;
// DHCP expiration is a bit brutal, because all other ethernet activity and
// incoming packets will be ignored until a new lease has been acquired
if (ether.dhcpExpired())
ether.dhcpSetup();
// wait for an incoming TCP packet, but ignore its contents
word len = ether.packetReceive();
word pos = ether.packetLoop(len);
// check if valid tcp data is received
if (pos) {
bfill = ether.tcpOffset();
char* data = (char *) Ethernet::buffer + pos;
// receive buf hasn't been clobbered by reply yet
if (strncmp("GET / ", data, 6) == 0)
homePage(bfill);
else if (strncmp("GET /w", data, 6) == 0) {
wake=true;
bfill.emit_p(PSTR(
"$F\r\n"
"<h1>Woke Server</h1>"), okHeader);
} else
bfill.emit_p(PSTR(
"HTTP/1.0 401 Unauthorized\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<h1>401 Unauthorized</h1>"));
ether.httpServerReply(bfill.position()); // send web page data
if (wake) wakeServer();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment