#include <EEPROM.h>
#include <Arduino.h>PHYEEPROM
#include <EtherCard.h>
#include <MemoryFree.h>
#include <Time.h>
#define VERSION "WOWlanCloud 20140104-0800"
// min/maj, cmd
#define URL "/index.php?action=get&id=zorglub"
#define WEBSITE "wolpobox.logsm.net"
#define PERIODEMS 5000
#define WOLLISTENPORT 9
#define WOLTARGETPORT 9
#define WOLOUTPORT 100
// EEPROM map
#define RESET 0
#define PHYEEPROM 1
#define IPEEPROM 8
#define NAMEEEPROM 11
#define EEPROMUSED 30
//
#define true 1
#define false 0
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x00,0x16,0xA5,0x76,0x19,0x3A };
int DEBUG=false; // true for debugging
int TRACE=true; //some progree info.
int CLOUD=false;
int SERVER=true;
int PROXY=true;
int DALLAS=false; // real clock & memory
#define LBUF 400
char website[] PROGMEM = WEBSITE;
//char url[] PROGMEM = URL;
static byte lowip= 255; // left part by Dhcp 255 if no!
static byte unb ; // for ucase
static uint32_t timer;
static byte broadcast[4] = {255,255,255,255} ; //{255,255,255,255};
static int n=0; // count http requests
static int ok=true; // global abandon
static int lenquoi;
static int termine; // 1 when found
static int eq;
static int iii;
static int pv;
static int ipv;
// byte mac[6] ;
byte key[10];
char magic[102];
char alphabet[17] /*PROGMEM*/ ="0123456789ABCDEF";
char hexamac[100]="";
char mailto[100]="";
byte Ethernet::buffer[LBUF]; //??????
BufferFiller bfill; //???????
static int udpon=0;
void prtoptions(){
Serial.print("Options: Debug, Trace, Cloud, Server, Proxy:");
Serial.print (DEBUG);
Serial.print (TRACE);
Serial.print (CLOUD);
Serial.print (SERVER);
Serial.println (PROXY);
Serial.print("freeMemory()=");
Serial.println(freeMemory());
}
void prttime(){
time_t t=now();
Serial.print(t);
Serial.print (">>");
Serial.print(year(t));
Serial.print("/");
Serial.print(month(t)); // The month now (1-12)
Serial.print("/");
Serial.print(day(t)); // The day now (1-31)
Serial.print("-");
Serial.print(hour(t)); // The hour now (0-23)
Serial.print(":");
Serial.print(minute(t)); // The minute now (0-59)
Serial.print(":");
Serial.print(second(t)); // The second now (0-59)
Serial.println("");
}
void blink(int led, int secondes, int on, int off){
iii=secondes*1000;
while (iii>0){
digitalWrite(led, 0); // turn the LED on (HIGH is the voltage level)
delay(on); // wait for a second
digitalWrite(led, 1); // turn the LED off by making the voltage LOW
delay(off); // wait for a second
iii=iii-on-off;
}
}
void raz(){
Serial.println("EEPROM Reeseted!");
for (iii=0;iii<EEPROMUSED;iii++) EEPROM.write(iii,0);
}
void chkhardreset(){
int rc;M
rc=1+EEPROM.read(RESET);
EEPROM.write(RESET,rc);
if (rc>=4) raz();
if (rc==1) blinMk(13,10,100,900); else blink(13,10,900,100);
EEPROM.write(RESET,0);
}
void setup () {
Serial.begin(9600);
Serial.println("andiamo, waitting 10\" for hard reset!");
chkhardreset();
prttime();
// check EEprom for mc address
termine=false;
for (iii=1;iii<6;iii=iii+1) if (EEPROM.read(PHYEEPROM+iii)!=255) termine=true;
if (!termine){
Serial.println("no previous PHY in EEPROM, added");
for (iii=0;iii<6;iii=iii+1) EEPROM.write(PHYEEPROM+iii, mymac[iii]);
}
// for (iii=0;iii<6;iii=iii+1) mymac[iii]=EEPROM.read(PHYEEPROM+iii);
for (iii=0;iii<6;iii=iii+1) {
Serial.print(alphabet[mymac[iii]/16]);
Serial.print(alphabet[mymac[iii]%16]);
Serial.print(":");
}
Serial.println(" <---- MAC used");
Serial.println(VERSION);
prtoptions();
Serial.print("Ethernet Controller: ");
if (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0) {
ok=false;
Serial.println( "Access Failed.");
} else Serial.println("Ok.");
// ether.staticSetup(myip);
if (ok) {
Serial.print("Dhcp: ");
if (!ether.dhcpSetup()) {
Serial.println("failed.");
// setting fixed ip
ether.myip[0]=192;
ether.myip[1]=168;
ether.myip[2]=100;
ether.myip[3]=1;
} else Serial.println("Ok.");
}
if (ok){
if (lowip<255) ether.myip[3]=lowip;
ether.printIp("IP: ", ether.myip);
ether.printIp("GW: ", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
if (CLOUD){
if (!ether.dnsLookup(website)) {
Serial.println("DNS failed");
ok=false;
}
if (ok) {
ether.printIp("SRV: ", ether.hisip);
}
}
}
//register udpSerialPrint() to port 1337
if (ok && PROXY) {
ether.udpServerListenOnPort(&udpReceivedCallback, WOLLISTENPORT);
Serial.print("listen wol on UDP port: ");
Serial.println(WOLLISTENPORT);
}
}
// return used part
word getvalue(word off,word len,char retour[],int lenret,char pin[]){
lenquoi=strlen(pin);
termine=false; // true whenpin found
iii=off-1;
/*
Serial.print(pin);Serial.print(" ");
Serial.print(off);Serial.print(" ");
Serial.print(len);Serial.print(" ");
Serial.println("<---pin off len");
*/
while (!termine) {
eq=0;
iii=iii+1;
if (iii==len) {
//termine=true;
// start pin not found
// Serial.println("pas trouve initiale en bour");
retour[0]=0;
return len;
}
while (!termine && Ethernet::buffer [iii+eq]==pin[eq]){
// Serial.print (pin[eq]);
// Serial.println("trouve une ettre");
eq=eq+1;
if (eq>=lenquoi ) termine=true;
// pin not found
if (iii+eq>len) {
retour[0]=0;
return len;
}
}
}
// Serial.println("");
// get value
termine=false;
ipv=0;
// Serial.println("trouve pin ");
//Serial.print("reponse=");
while (!termine && iii+eq+1+ipv<len && ipv<lenret ) {
retour[ipv]=Ethernet::buffer [iii+eq+ipv];
if (retour[ipv]==';') {
// Serial.println("ok ; final ");
retour[ipv]=0;
termine=true;
}
ipv=ipv+1;
}
if (!termine) {
// Serial.println ("no colon found");
// ok=false;
retour[0]=0;
return len;
}
return iii+eq+ipv;
}
/*
void doopt (char* cmd,int target, int v){
if (strcmp(hexamac,cmd)==0 ) target=v;
}
*/
void option(int v){
// prtoptions();
if (strcmp(hexamac,"DEBUG")==0 ) DEBUG=v;
// doopt("DEBUG",DEBUG,v);
if (strcmp(hexamac,"TRACE")==0 ) TRACE=v;
if (strcmp(hexamac,"CLOUD") ==0) CLOUD=v;
if (strcmp(hexamac,"PROXY" )==0) PROXY=v;
if (strcmp(hexamac,"SERVER")==0 ) SERVER=v;
if (TRACE) prtoptions();
}
void ucase(word off,word len){
// search for pin:
for (iii=off;iii<len;iii=iii+1){
unb= Ethernet::buffer [iii];
if (unb>96 && unb <=96+26) Ethernet::buffer [iii]=unb-32;
}
//Serial.println("up");
// keep options
word start;
hexamac[0]='.';
hexamac[1]=0;
start=off;
while (strlen(hexamac)>0) {
start=getvalue(start,len,hexamac,100,"SET:");
if (strlen(hexamac)>0) option(true) ; // optionis in hexamac
}
hexamac[0]='.';
hexamac[1]=0;
start=off;
while (strlen(hexamac)>0) {
start=getvalue(start,len,hexamac,100,"CLR:");
if (strlen(hexamac)!=0) option(false) ; // optionis in hexamac
}
start=getvalue(off,len,hexamac,100,"MAILTO:");
if (strlen(hexamac)>0) {
memcpy(hexamac,mailto,strlen(hexamac));
Serial.print ("mailto:");
Serial.println(mailto);
}
start=getvalue(off,len,hexamac,100,"TIME:");
if (strlen(hexamac)>0) {
uint32_t tt= atol(hexamac);
setTime(tt);
// Serial.println(tt);
// Serial.println(now());
prttime();
}
start=getvalue(off,len,hexamac,100,"PHY:");
if (strlen(hexamac)>0) {
// 12 to 6
if (h2d(hexamac[1])%2==1) {
Serial.println("rejected");
} else {
for (iii=0;iii<6;iii=iii+1) {
int v=h2d(hexamac[2*iii])*16+h2d(hexamac[2*iii+1]);
int w=PHYEEPROM+iii;
EEPROM.write(w, v );
}
Serial.print("verif:");
for (iii=0;iii<6;iii=iii+1) {
// byte b=
Serial.print(EEPROM.read(PHYEEPROM+iii));
Serial.print("=");
}
Serial.println("");
}
}
hexamac[0]='.';
hexamac[1]=0;
start=off;
while (strlen(hexamac)>0) {
start=getvalue(start,len,hexamac,100,"PIN:");
if (strlen(hexamac)>0) {
if (TRACE) Serial.println(hexamac);
char* sep=strchr(hexamac,':');
if (TRACE) {
Serial.print("arg:");
Serial.print (sep-hexamac);
}
hexamac[sep-hexamac]=0;
if (TRACE) {
Serial.print("pin:");
Serial.print (sep-hexamac);
}
if (TRACE) {
Serial.print("val:");
Serial.println (sep);
}
}
}
}
// called when the client request is complete
static void my_callback (byte status, word off, word len) {
if (DEBUG) Serial.println(">>>");
Ethernet::buffer[len] = 0;
if (DEBUG) for (int j=off;j<len;j=j+1) Serial.print((char ) Ethernet::buffer[j]);
// check print full packet
ucase(off,len);
getvalue(off,len,hexamac,100,"MAC:");
if (strlen(hexamac)==0) return;
getvalue(off,len,hexamac,100,"IP:");
getvalue(off,len,hexamac,100,"ID:");
getvalue(off,len,hexamac,100,"TOKEN:");
getvalue(off,len,hexamac,100,"MAC:");
if (TRACE) {
Serial.print("Cloud: mac:");
Serial.println(hexamac);
}
buildmagic();
if (termine) sendmagic(magic,102);
}
//callback that echo received packet (magic!)
void udpReceivedCallback(word port, byte ip[4], const char *data, word len) {
if (!udpon) { // protect again re-entrance'
udpon=true;
if (DEBUG){
Serial.println(" Raw: ");
Serial.println(data);
}
if (TRACE) Serial.println ("udp packet forwarded as broadcast");
sendmagic((char *) data,len);
if (DEBUG) Serial.println(" done");
udpon=false;
}
}
static word hP(int ok) {
n=n+1; // compte les appels à 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>Po server</title>"
"<h1>$D$D:$D$D:$D$D</h1> n= $D ok=$D"),
h/10, h%10, m/10, m%10, s/10, s%10,n,ok); //???????
return bfill.position(); //???????
}
int h2d(char h){
char* ih= strchr(alphabet,h);
char* i0= strchr(alphabet,'0');
int ici=ih-i0;
if (ici>15) ici=ici-6;
return ici;
}
void buildmagic (){
termine=false;
if (strlen(hexamac)!=12) return;
if (DEBUG) Serial.print("build magic mac:");
termine=true;
for (iii=0;iii<12;iii++) {
char unc=hexamac[iii];
Serial.print(unc);
if (unc<'0' || unc>'F' || (unc>'9' && unc<'A')) termine=false;
}
if (!termine) return;
for (int repe=0;repe<6;repe=repe+1) magic[repe]=255;
for (iii=0;iii<6;iii=iii+1){
magic[iii]=h2d(hexamac[2*iii])*16+h2d(hexamac[2*iii+1]);
for (int repe=1;repe<16;repe=repe+1){
magic[6+6*repe+iii]=magic[6+iii];
}
}
}
void sendmagic(char* magic,int len){
ether.sendUdp(magic, len, WOLOUTPORT, broadcast, WOLTARGETPORT);
}
void loop () {
if (ok==1 && PROXY) {
// nothing
}
if (CLOUD) ether.packetLoop(ether.packetReceive());
if (ok==1 && CLOUD) {
if (millis() > timer) {
timer = millis() + PERIODEMS;
ether.browseUrl(PSTR(URL) , "", website, my_callback);
} // timer
} // end cloud
if (ok==1 && SERVER){
word len = ether.packetReceive();
word pos = ether.packetLoop(len);
if (pos>0) {// check if valid tcp data is received
if (DEBUG){
Serial.print("received http ");
Serial.print(pos);
Serial.print(" len ");
Serial.println(len);
Serial.println("---------------------");
for (iii=pos;iii<len;iii=iii+1) Serial.print((char)Ethernet::buffer [iii]);// search for pin:
Serial.println("");
Serial.println("---------------------");
}
ucase(pos,len);
if (DEBUG) Serial.println("received http");
getvalue(pos,len,hexamac,100,"MAC:");
if (TRACE) {
Serial.print(hexamac);
Serial.println("<----server http");
}
if (strlen(hexamac)>0) buildmagic();
ether.httpServerReply(hP(termine)); // send web page data
if (termine) {
sendmagic(magic,102);
if (TRACE) Serial.println("Sent.");
}
}
}
}