daily_automated
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
// NoIP client sketch for ENC28J60 based Ethernet Shield.
|
||||
// You need a free account from www.no-ip.com
|
||||
//
|
||||
// 1. On NoIP website, create a host of type DNS Host (A)
|
||||
// 2. Insert your host name in noIP_host[] variable
|
||||
// 3. Encode "username:password" in base64 using an online tool like
|
||||
// 4. Paste the encoded string in noIP_auth[] variable
|
||||
//
|
||||
// Contributed by Luca Dentella <luca@dentella.it>
|
||||
// http://www.lucadentella.it/2012/04/28/enc28j60-e-arduino-6/
|
||||
|
||||
|
||||
#include <EtherCard.h>
|
||||
|
||||
// Finite-State Machine states
|
||||
#define STATUS_IDLE 0
|
||||
#define STATUS_WAITING_FOR_PUBLIC_IP 1
|
||||
#define STATUS_NOIP_NEEDS_UPDATE 2
|
||||
#define STATUS_WAITING_FOR_NOIP 3
|
||||
#define STATUS_ERROR 99
|
||||
|
||||
// The sketch will check your public IP every CHECK_IP_INTERVAL ms,
|
||||
// and wait for REQUEST_TIMEOUT ms for a response.
|
||||
// It will retry for maximum of MAX_ATTEMPTS attemps.
|
||||
#define CHECK_IP_INTERVAL 60000
|
||||
#define REQUEST_TIMEOUT 10000
|
||||
#define MAX_ATTEMPTS 3
|
||||
|
||||
// MAC Address of Ethernet Shield
|
||||
static byte mymac[] = {0xDD,0xDD,0xDD,0x00,0x00,0x01};
|
||||
|
||||
// Insert your hostname and authentication string
|
||||
const char noIP_host[] PROGMEM = "myhost.no-ip.info";
|
||||
const char noIP_auth[] PROGMEM = "XXXXXXXXXX";
|
||||
|
||||
// Don't change these ones...
|
||||
const char getIP_web[] PROGMEM = "www.lucadentella.it";
|
||||
const char noIP_web[] PROGMEM = "dynupdate.no-ip.com";
|
||||
|
||||
// Some global variables
|
||||
byte Ethernet::buffer[700];
|
||||
byte getIP_address[IP_LEN];
|
||||
byte noIP_address[IP_LEN];
|
||||
byte actual_status;
|
||||
static byte session_id;
|
||||
static uint32_t check_ip_timer;
|
||||
static uint32_t request_timer;
|
||||
int attempt;
|
||||
Stash stash;
|
||||
|
||||
void setup () {
|
||||
|
||||
Serial.begin(57600);
|
||||
Serial.println(F("NoIP Client Demo"));
|
||||
Serial.println();
|
||||
|
||||
// Change 'SS' to your Slave Select pin, if you arn't using the default pin
|
||||
if (!ether.begin(sizeof Ethernet::buffer, mymac, SS))
|
||||
Serial.println(F( "Failed to access Ethernet controller"));
|
||||
else
|
||||
Serial.println(F("Ethernet controller initialized"));
|
||||
Serial.println();
|
||||
|
||||
if (!ether.dhcpSetup())
|
||||
Serial.println(F("Failed to get configuration from DHCP"));
|
||||
else
|
||||
Serial.println(F("DHCP configuration done"));
|
||||
|
||||
ether.printIp("IP Address:\t", ether.myip);
|
||||
ether.printIp("Netmask:\t", ether.netmask);
|
||||
ether.printIp("Gateway:\t", ether.gwip);
|
||||
Serial.println();
|
||||
|
||||
actual_status = STATUS_IDLE;
|
||||
attempt = 0;
|
||||
|
||||
// Resolve IP for getIP_web and noIP_web
|
||||
// and store them into global variables
|
||||
if (!ether.dnsLookup(getIP_web)) {
|
||||
Serial.print(F("Unable to resolve IP for "));
|
||||
SerialPrint_P(getIP_web);
|
||||
actual_status = STATUS_ERROR;
|
||||
} else {
|
||||
ether.copyIp(getIP_address, ether.hisip);
|
||||
SerialPrint_P(getIP_web);
|
||||
ether.printIp(" resolved to:\t", ether.hisip);
|
||||
}
|
||||
if (!ether.dnsLookup(noIP_web)) {
|
||||
Serial.print(F("Unable to resolve IP for "));
|
||||
SerialPrint_P(noIP_web);
|
||||
actual_status = STATUS_ERROR;
|
||||
} else {
|
||||
ether.copyIp(noIP_address, ether.hisip);
|
||||
SerialPrint_P(noIP_web);
|
||||
ether.printIp(" resolved to:\t", ether.hisip);
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
|
||||
ether.packetLoop(ether.packetReceive());
|
||||
|
||||
// FSM
|
||||
switch(actual_status) {
|
||||
|
||||
case STATUS_IDLE:
|
||||
checkPublicIP();
|
||||
break;
|
||||
case STATUS_WAITING_FOR_PUBLIC_IP:
|
||||
checkPublicIPResponse();
|
||||
break;
|
||||
case STATUS_NOIP_NEEDS_UPDATE:
|
||||
updateNoIP();
|
||||
break;
|
||||
case STATUS_WAITING_FOR_NOIP:
|
||||
checkNoIPResponse();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void checkPublicIP() {
|
||||
|
||||
if(millis() > check_ip_timer) {
|
||||
|
||||
Serial.print(F("Checking public IP... "));
|
||||
|
||||
// Create a request for GetIP service,
|
||||
// set destination IP and send request saving session_id
|
||||
Stash::prepare(PSTR("GET /demo/getip.php HTTP/1.1" "\r\n" "Host: $F" "\r\n" "\r\n"), getIP_web);
|
||||
ether.copyIp(ether.hisip, getIP_address);
|
||||
session_id = ether.tcpSend();
|
||||
|
||||
// Change FSM state, prepare for timeout and increment attempts counter
|
||||
actual_status = STATUS_WAITING_FOR_PUBLIC_IP;
|
||||
request_timer = millis() + REQUEST_TIMEOUT;
|
||||
attempt++;
|
||||
}
|
||||
}
|
||||
|
||||
void checkPublicIPResponse() {
|
||||
|
||||
String actualIp, dnsIp;
|
||||
|
||||
const char* reply = ether.tcpReply(session_id);
|
||||
|
||||
// We got a valid response
|
||||
if(reply != 0) {
|
||||
|
||||
// Parse response for public IP
|
||||
for(int i = 0; i < strlen(reply) - 189; i++) actualIp = actualIp + reply[187 + i];
|
||||
Serial.println(actualIp);
|
||||
|
||||
// If we can't resolve actual IP for our hostname on NoIP,
|
||||
// return to IDLE state and wait for the next interval
|
||||
if(!ether.dnsLookup(noIP_host)) {
|
||||
Serial.print(F("Unable to resolve actual IP for "));
|
||||
SerialPrint_P(noIP_host);
|
||||
Serial.println();
|
||||
actual_status = STATUS_IDLE;
|
||||
attempt = 0;
|
||||
check_ip_timer = millis() + CHECK_IP_INTERVAL;
|
||||
|
||||
// If we can resolve the IP for our hostname, save it in xxx.xxx.xxx.xxx form
|
||||
// and compare it with our public IP
|
||||
} else {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
dnsIp = dnsIp + String(ether.hisip[i]);
|
||||
if(i < 3) dnsIp = dnsIp + ".";
|
||||
}
|
||||
SerialPrint_P(noIP_host);
|
||||
Serial.print(F(" resolved to "));
|
||||
Serial.println(dnsIp);
|
||||
|
||||
// If they are the same, we can sit down and wait for the next interval
|
||||
if(actualIp.compareTo(dnsIp) == 0) {
|
||||
Serial.println(F("No update needed :)"));
|
||||
actual_status = STATUS_IDLE;
|
||||
attempt = 0;
|
||||
check_ip_timer = millis() + CHECK_IP_INTERVAL;
|
||||
|
||||
// Different? We'd better to update NoIP!
|
||||
} else {
|
||||
Serial.println(F("Update needed :("));
|
||||
actual_status = STATUS_NOIP_NEEDS_UPDATE;
|
||||
attempt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// No valid response? Check for timeout
|
||||
// If we've already sent a max number of requests, return to IDLE state
|
||||
// and wait for the next interval
|
||||
} else {
|
||||
if(millis() > request_timer) {
|
||||
Serial.println(F(" no response :("));
|
||||
actual_status = STATUS_IDLE;
|
||||
if(attempt == MAX_ATTEMPTS) {
|
||||
Serial.println(F("Max number of attempts reached"));
|
||||
attempt = 0;
|
||||
check_ip_timer = millis() + CHECK_IP_INTERVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateNoIP() {
|
||||
|
||||
Serial.print(F("Updating NoIP..."));
|
||||
|
||||
// Create a request for updating NoIP using NoIP API,
|
||||
// set destination IP and send request saving session_id
|
||||
Stash::prepare(PSTR("GET /nic/update?hostname=$F HTTP/1.0" "\r\n"
|
||||
"Host: $F" "\r\n"
|
||||
"Authorization: Basic $F" "\r\n"
|
||||
"User-Agent: NoIP_Client" "\r\n" "\r\n"),
|
||||
noIP_host, noIP_web, noIP_auth);
|
||||
ether.copyIp(ether.hisip, noIP_address);
|
||||
session_id = ether.tcpSend();
|
||||
|
||||
// Wait for response or timeout...
|
||||
actual_status = STATUS_WAITING_FOR_NOIP;
|
||||
request_timer = millis() + REQUEST_TIMEOUT;
|
||||
attempt++;
|
||||
}
|
||||
|
||||
void checkNoIPResponse() {
|
||||
|
||||
const char* reply = ether.tcpReply(session_id);
|
||||
boolean done;
|
||||
|
||||
// We got a valid response...
|
||||
if(reply != 0) {
|
||||
|
||||
// Parse NoIP response looking for status/error codes...
|
||||
if(strstr(reply, "good") != 0) {
|
||||
Serial.println(F(" done!"));
|
||||
done = true;
|
||||
}
|
||||
else if(strstr(reply, "nochg") != 0) {
|
||||
Serial.println(F(" no change required!"));
|
||||
done = true;
|
||||
}
|
||||
else if(strstr(reply, "nohost") != 0) Serial.println(F(" host not found :("));
|
||||
else if(strstr(reply, "badauth") != 0) Serial.println(F(" invalid username or password :("));
|
||||
else if(strstr(reply, "badagent") != 0) Serial.println(F(" agent banned :("));
|
||||
else if(strstr(reply, "!donator") != 0) Serial.println(F(" feature not available for specified username :("));
|
||||
else if(strstr(reply, "abuse") != 0) Serial.println(F(" username blocked due to abuse :("));
|
||||
else Serial.println(F(" generic error :("));
|
||||
|
||||
// Record has been updated? Ok wait for next interval...
|
||||
if(done) {
|
||||
actual_status = STATUS_IDLE;
|
||||
attempt = 0;
|
||||
check_ip_timer = millis() + CHECK_IP_INTERVAL;
|
||||
}
|
||||
|
||||
// No valid response? Check for timeout
|
||||
// If we've already sent a max number of requests, return to IDLE state
|
||||
// and wait for the next interval
|
||||
} else {
|
||||
|
||||
if(millis() > request_timer) {
|
||||
Serial.println(F("No response from NoIP"));
|
||||
if(attempt == MAX_ATTEMPTS) {
|
||||
Serial.println(F("Max number of attempts reached"));
|
||||
actual_status = STATUS_IDLE;
|
||||
attempt = 0;
|
||||
check_ip_timer = millis() + CHECK_IP_INTERVAL;
|
||||
}
|
||||
else
|
||||
actual_status = STATUS_NOIP_NEEDS_UPDATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPrint_P(const char* str PROGMEM) {
|
||||
for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.write(c);
|
||||
}
|
||||
Reference in New Issue
Block a user