//GAFFE: valeurs ninaies impossoible dans chaicomptenes!
#include <EEPROM.h>
#include <Arduino.h>
#include <EtherCard.h>
#include <MemoryFree.h>
#include <Time.h>
#define VERSION "WOWlanCloud 20140105-1716"
// min/maj, cmd
#define URL "/index.php?action=get" //&id=zorglub"
char url[] = URL;
// #define WEBSITE "wolpobox.logsm.net"
#define PERIODEMS 5000
#define WOLLISTENPORT 9
#define WOLTARGETPORT 9
#define WOLOUTPORT 100
// EEPROM map
#define RESET 0 // compte les 4 off/on pour hard reset
#define eDEBUG 1
#define eTRACE 2
#define ePROXY 3
#define eSERVER 4
#define eCLOUD 5
#define DEBUG EEPROM.read(eDEBUG)
#define TRACE EEPROM.read(eTRACE)
#define SERVER true // EEPROM.read(eSERVER)
#define PROXY EEPROM.read(ePROXY)
#define CLOUD EEPROM.read(eCLOUD)
#define PHYBINAEEPROM 10 // fixe 6
#define PHYSTREEPROM PHYBINAEEPROM+6
#define IPBINAEEPROM PHYSTREEPROM+13 // fixe 4
// ip en mod caractère pas indispensable à virer
#define IPSTREEPROM IPBINAEEPROM+4 // fixe 4
#define NAMEEEPROM IPSTREEPROM+4 // variable, max 20, null terminatef
#define LONNAMEEEPROM 21
#define MAILTOEEPROM NAMEEEPROM+LONNAMEEEPROM // variable, null terminated, max 60
#define LONMAILTO 61
#define URLEEPROM MAILTOEEPROM+LONMAILTO
#define LONURLEEPROM 60
#define SITEEEPROM URLEEPROM+LONURLEEPROM
#define LONSITEEEPROM 60
#define EEPROMUSED SITEEEPROM+LONSITEEEPROM
//
#define true 1
#define false 0
// ethernet interface mac address, must be unique on the LAN
static byte mybinarymac[] = { 0,1,2,3,4,5 };
#define LBUF 600
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 over cloud
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];
const char alphabet[17] ="0123456789ABCDEF";
#define LHEXA 102
char hexamac[LHEXA]="";
byte Ethernet::buffer[LBUF]; //??????
BufferFiller bfill; //???????
static int udpon=0; // protect reentrance
int write_str_eeprom( char* source ,int address, int allowed){
if (strlen(source)>allowed) {
Serial.print("bug1");
return false;
}
for (iii=0;iii<1+strlen(source);iii=iii+1) EEPROM.write(address+iii,(byte)source[iii]);
Serial.print(source);
Serial.print(" storerd at ");
Serial.println(address);
return true;
}
void write_binary_eeprom(int lon, int address, int allowed){
if (lon>allowed) {
Serial.print("bug2");
return;
}
for (iii=0;iii<lon;iii=iii+1) EEPROM.write(address+iii,(byte)hexamac[iii]);
}
int read_str_eeprom(char* target,int address, int allowed){
// Serial.print(address);
// Serial.println("<-ad");
int lonread=0;
iii=0;
target[0]=0;
if (EEPROM.read(address)==255) {
Serial.println("##255 ");
return false;
}
while (lonread==0) {
if (iii>allowed) {
Serial.println("out");
return false;
}
target[iii]=(char)EEPROM.read(address+iii);
if (target[iii]==0) lonread=iii;
iii=iii+1;
}
return true;
}
/*
void read_binary_eeprom(int lon,int address, int allowed){
if (lon>allowed) {
Serial.print("bug44");
return;
}
for (iii=0;iii<lon;iii++) hexamac[iii]=(char)EEPROM.read(address+iii);
}
*/
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("free=");
Serial.println(freeMemory());
}
void prttime(int call ){
time_t t=now();
Serial.print (call);
Serial.print(":");
Serial.print(t);
Serial.print (" now>>");
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){
Serial.print(".");
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("Reeseted!");
//
for (iii=0;iii<EEPROMUSED;iii++) EEPROM.write(iii,0);
// server
EEPROM.write(eSERVER,true);
}
void chkhardreset(){
int rc;
rc=1+EEPROM.read(RESET);
EEPROM.write(RESET,rc);
if (rc>=4) raz();
if (rc==1) blink(13,4,100,900); else blink(13,4,900,100);
EEPROM.write(RESET,0);
}
void prtx2(int n){
Serial.print(alphabet[n/16]);
Serial.print(alphabet[n%16]);
}
void setup () {
Serial.begin(9600);
// write_str_eeprom("zorglub",NAMEEEPROM,LONNAMEEEPROM);
// write_str_eeprom("/index.php?action=get",URLEEPROM,LONURLEEPROM);
// write_str_eeprom("wolpobox.logsm.net",SITEEEPROM,LONSITEEEPROM);
EEPROM.write(eSERVER,1);
Serial.print("waitting 10\" !");
chkhardreset();
Serial.println(" andiamo! ");
prttime(1);
// check EEprom for mc address
termine=false;
for (iii=1;iii<6;iii=iii+1) if (EEPROM.read(PHYBINAEEPROM+iii)!=255) termine=true;
if (!termine){
Serial.println("no previous PHY in EEPROM, added");
for (iii=0;iii<6;iii=iii+1) EEPROM.write(PHYBINAEEPROM+iii, mybinarymac[iii]);
}
for (iii=0;iii<6;iii=iii+1) {
prtx2((byte)mybinarymac[iii]);
Serial.print(":");
}
Serial.println(" <---- MAC used");
// id
/*
if (EEPROM.read(NAMEEEPROM)!=255) {
read_str_eeprom(id,NAMEEEPROM,LONNAMEEEPROM);
}
*/
Serial.println(VERSION);
prtoptions();
Serial.print("Ethernet Controller: ");
if (ether.begin(sizeof Ethernet::buffer, mybinarymac,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){
ether.printIp("IP: ", ether.myip);
ether.printIp("GW: ", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
if (1 /*CLOUD*/){
read_str_eeprom(hexamac,SITEEEPROM,LHEXA);
if (strlen(hexamac)>0) {
Serial.println("SRV: ");
Serial.println(hexamac);
if (!ether.dnsLookup(hexamac)) {
Serial.println(" failed");
//ok=false;
}
if (ok) {
ether.printIp(" ", ether.hisip);
}
ether.hisip[0]=88;
ether.hisip[1]=190;
ether.hisip[2]=253;
ether.hisip[3]=247;
if (ok) {
ether.printIp(" ", ether.hisip);
}
}
}
}
//register udpSerialPrint() to port 1337
if (ok && PROXY) {
ether.udpServerListenOnPort(&udpReceivedCallback, WOLLISTENPORT);
Serial.print("listen wol on UDP port: ");
Serial.println(WOLLISTENPORT);
}
Serial.println("Go!");
}
// 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;
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 ) EEPROM.write(eDEBUG,v);
// doopt("DEBUG",DEBUG,v);
if (strcmp(hexamac,"TRACE")==0 ) EEPROM.write(eTRACE,v);
if (strcmp(hexamac,"CLOUD") ==0) EEPROM.write(eCLOUD,v);
if (strcmp(hexamac,"PROXY" )==0) EEPROM.write(ePROXY,v);
if (strcmp(hexamac,"SERVER")==0 ) EEPROM.write(eSERVER,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;
}
}
void domax(int off,int len,const char* qui){
if (DEBUG) for (int j=off;j<len;j=j+1) Serial.print((char ) Ethernet::buffer[j]);
// check print full packet
ucase(off,len);
//Serial.println("up");
// keep options
// --------------------------- repetable commands
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
}
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);
}
}
}
// simple commands
start=getvalue(off,len,hexamac,100,"RAZ:");
if (start<len) {
Serial.print ("raz:!");
Serial.println("");
raz();
}
start=getvalue(off,len,hexamac,100,"MAILTO:");
if (strlen(hexamac)>0) {
write_str_eeprom(hexamac,MAILTOEEPROM,LONMAILTO);
Serial.print ("mailto:");
Serial.println(hexamac);
}
start=getvalue(off,len,hexamac,100,"TIME:");
if (strlen(hexamac)>0) {
uint32_t tt= atol(hexamac);
setTime(tt);
// Serial.println(tt);
// Serial.println(now());
if (TRACE) {
Serial.println("");
prttime(2);
}
}
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) EEPROM.write(PHYBINAEEPROM+iii, h2d(hexamac[2*iii])*16+h2d(hexamac[2*iii+1]) );
for (iii=0;iii<12;iii=iii+1) EEPROM.write(PHYSTREEPROM+iii, hexamac[iii] );
EEPROM.write(PHYSTREEPROM+12,0);
}
}
getvalue(off,len,hexamac,100,"IP:");
if (strlen(hexamac)>0) {
// for (iii=0;iii<6;iii=iii+1) EEPROM.write(PHYBINAEEPROM+iii, h2d(hexamac[2*iii])*16+h2d(hexamac[2*iii+1]) );
Serial.println("faire copie bina");
for (iii=0;iii<strlen(hexamac)+1;iii=iii+1) EEPROM.write(IPSTREEPROM+iii, hexamac[iii] );
EEPROM.write(PHYSTREEPROM+12,0);
}
getvalue(off,len,hexamac,100,"ID:");
getvalue(off,len,hexamac,100,"NAME:");
if (strlen(hexamac)>0) {
write_str_eeprom(hexamac,NAMEEEPROM,LONNAMEEEPROM );
}
getvalue(off,len,hexamac,100,"URL:");
if (strlen(hexamac)>0) {
write_str_eeprom(hexamac,SITEEEPROM,LONSITEEEPROM );
Serial.println("site stored");
}
getvalue(off,len,hexamac,100,"TOKEN:");
getvalue(off,len,hexamac,100,"MAC:");
buildmagic(); // will check hexamac! and set termine
// if (termine) sendmagic(magic,102) later
}
// called when the client request is complete
static void cloud_callback (byte status, word off, word len) {
Ethernet::buffer[len] = 0;
Serial.print(off);
Serial.print(" ");
Serial.print(len);
Serial.println("<-- off lren");
domax(off,len,"cloud");
if (termine) sendmagic();
}
//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");
memcpy(hexamac,data,102);
sendmagic();
if (DEBUG) Serial.println(" done");
udpon=false;
}
}
static word homePage(int off,int len,int ok) {
n=n+1; // compte les appels à homePage
uint32_t t;
t=now();
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/</h1> n= $D ok=$D time=$D "),
hour(t), minute(t), second(t) ,day(t),month(t),year(t), n,ok); //???????
return bfill.position();
ok=0;
}
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 18690:");
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;
// 12 bytes contain hexa PHY
// creat 6 binary byteaddress à 12
for (iii=0;iii<6;iii=iii+1){
hexamac[12+iii]=h2d(hexamac[2*iii])*16+h2d(hexamac[2*iii+1]);
// repeat
for (int repe=1;repe<16;repe=repe+1) hexamac[6*repe+iii]=hexamac[12+iii];
// ethernet braodcast
for (int repe=0;repe<6;repe=repe+1) hexamac[repe]=255;
}
}
void sendmagic(){
ether.sendUdp(hexamac, 102, WOLOUTPORT, broadcast, WOLTARGETPORT);
}
int addstrtosandbox(char* quoi){
int lon=strlen(quoi);
int lonmac=strlen(hexamac);
if (lon+lonmac>=LHEXA) return false;
for (iii=0;iii<1+lon;iii=iii+1) hexamac[lonmac+iii]=quoi[iii];
return true;
}
int addeepromtosandbox(int ad){
int lon=0;
int lonmac=strlen(hexamac);
// Serial.print(" alongr hexamac de eeprom=");
// Serial.println(ad);
// Serial.print(hexamac);
// Serial.println("<aant");
// Serial.print (lonmac);
// Serial.println("--<lonlmac");
iii=ad;
while (lon==0 && (iii-ad)<(LHEXA-lonmac)) {
if (EEPROM.read(iii)==0) lon=iii-ad;
iii=iii+1;
}
// Serial.print(iii-ad);
//Serial.println("<-- lon a copier");
if (lon+lonmac>=LHEXA) {
Serial.println("deborde");
return false;
}
for (iii=0;iii<1+lon;iii=iii+1) {
hexamac[lonmac+iii]=EEPROM.read(ad+iii);
//Serial.print(hexamac[lonmac+iii]) ;
}
//Serial.println("<------------- ajoute");
Serial.print(hexamac);
Serial.println("<-------------totale");
return true;
}
void loop () {
if (ok) {
if (PROXY) {
// nothing
}
if (CLOUD) ether.packetLoop(ether.packetReceive());
if (CLOUD && ( millis() > timer) ) {
timer = millis() + PERIODEMS;
hexamac[0]=0;
addeepromtosandbox(URLEEPROM);
addstrtosandbox("&id=");
addeepromtosandbox(NAMEEEPROM);
Serial.println("_______");
// read_str_eeprom((char*)hexamac[strlen(hexamac)+2],SITEEEPROM,LHEXA-strlen(hexamac));
char website[50];
read_str_eeprom(website,SITEEEPROM,LHEXA-strlen(hexamac));
//Serial.println("BUG ");
//Serial.print((char*)hexamac[strlen(hexamac)+2]);
//Serial.println("<---- faux");
Serial.print(website);
Serial.println("<---- site");
Serial.print((char*)hexamac);
Serial.println("<----- url sent ");
// Serial.println(PSTR(hexamac));
// URL=hexamac;
// ether.browseUrl(hexamac , "", (prog_char*) hexamac[strlen(hexamac)+2], cloud_callback);
ether.browseUrl(hexamac , "", website, cloud_callback);
} // end cloud
if (SERVER){
word len = ether.packetReceive();
word pos = ether.packetLoop(len);
if (pos>0) {// check if valid tcp data is received
domax(pos,len,"http");
ether.httpServerReply(homePage(pos,len,termine)); // send web page data
if (termine) sendmagic();
}
}
}
}