enc28J60 e Arduino (17)

luca 19 dicembre 2013 8

In alcuni tutorial precedenti, avete già imparato a realizzare semplici pagine web per comandare a distanza led, relay… oggi vi mostrerò come rendere queste pagine sicure grazie ad una password.

Form web

La pagina web pubblicata da Arduino contiene una semplice form, composta da due pulsanti e da un campo di input per la password:

Alla pressione del pulsante, viene inviato ad Arduino un comando POST contenente – oltre ad informazioni del browser – i dati della form:

Dallo screenshot si può notare come i dati siano concatenati dal carattere & e il valore del campo password sia specificato dopo l’etichetta pwd=.

Sketch

Il codice in esecuzione su Arduino (lo trovate nel repository Github), alla ricezione di una nuova richiesta, esegue le seguenti operazioni:

  • verifica se la richiesta è di tipo POST
  • in questo caso, estrae dalla richiesta il valore della password e la confronta con quella memorizzata
  • se la password è corretta, estrae dalla richiesta il pulsante (ON|OFF) premuto
  • modifica lo stato dell’uscita
  • restituisce la pagina HTML

Vediamolo nel dettaglio:

char* led_password = "SesamE";

la password è inserita hardcoded nello sketch, di default sarà SesamE

pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, LOW);
led_status = false;

all’interno del setup() avviene l’inizializzazione del PIN e dello stato dell’uscita (di default spenta)

if(strstr((char *)Ethernet::buffer + pos, "POST /") != 0) {

lo sketch verifica – tramite la funzione strstr() – se il pacchetto ricevuto contiene il comando POST /

char* password_position = strstr((char *)Ethernet::buffer + pos, "&pwd=");
if(password_position != 0) {
  strcpy(password, password_position + 5);
  if(strcmp(password, led_password) == 0) Serial.println("Valid password :)");

lo sketch cerca la stringa &pwd= nel pacchetto; se la trova estrae la password e la memorizza nella variabile password. Le due password sono quindi confrontate

if(strstr((char *)Ethernet::buffer + pos, "OFF=") != 0) {
digitalWrite(led_pin, LOW);
led_status = false;

se la password è corretta e il pacchetto contiene il comando OFF=, l’uscita viene spenta. Lo stesso controllo avviene per il comando ON=

if(led_status == true) bfill.emit_p(PSTR(
[...]

infine viene generata la pagina HTML, resa dinamica da due if:

  • in base allo stato dell’uscita, uno dei due pulsanti viene disabilitato (aggiungendo l’attributo disabled)
  • se la password non è corretta, viene visualizzato un messaggio di errore

Funzionamento

Ecco due screenshot relativi all’inserimento di una password valida e una sbagliata:

8 Comments »

  1. nasim 20 dicembre 2013 at 10:43 - Reply

    hi …
    i just want to simulate …
    how i get enc28j60 mac address for proteus simulation..

    • luca 23 dicembre 2013 at 08:41 - Reply

      Hi Nasim,

      I never used Proteus but the MAC I think you can use the same mac address I use in my sketches… while the IP address must belong to the same network (simulated one?) you’re using.

  2. jmv 23 gennaio 2014 at 17:26 - Reply

    hi, luca, great site!.
    how I send a TCP packet to a client tcp.
    I intend to make a Modbus server.
    sorry bad english.
    thanks.

    • luca 27 gennaio 2014 at 22:14 - Reply

      Hi Jonas,

      mmm are you asking how to send a tcp packet to a server? give a look to my examples, basically you have to “create” the packet in a Stash object and send to the server using the tcpSend() method.

  3. Tony 22 febbraio 2014 at 16:57 - Reply

    Hi Luca

    how to keep password remember? each time i press the button, the password cleared and i have to enter again and again to control the LED

    • luca 2 marzo 2014 at 13:44 - Reply

      Hi Tony

      you can include the password in the html page:

      if(password_valid == true) bfill.emit_p(PSTR("

      "), password);

  4. Tunir Saha 8 marzo 2014 at 08:04 - Reply

    [backSoon]
    DHCP failed
    IP: 0.0.0.0
    GW: 0.0.0.0
    DNS: 0.0.0.0

    Sir any explanation for this ? I don’t know how to figure this out.

    • luca 15 marzo 2014 at 10:45 - Reply

      Hi Tunir,

      it seems Arduino can’t obtain an IP address from your DHCP: have you a DHCP server in your network?

Leave A Response »