if(!strstr(buffer, "Authorization: Basic TVBPQToyMDE0")){ //MPOA 2014
sprintf(httpHeader,"HTTP/1.1 401 Authorization Required \r\nContent-Type: text\r\nWWW-Authenticate: Basic realm='Login required!'\r\n\r\n");
client.send(httpHeader,strlen(httpHeader)); //Odeslání výzvy k přihlášení
sprintf(httpHeader, "\r\n\t\r\n\t\tError \r\n\t\r\n\t\r\n\t\t401 Unauthorised.
\r\n\t\r\n");
client.send(httpHeader,strlen(httpHeader)); //Formát stránky s chybovým hlášením
client.close();
}
==== metoda POST ====
Přesto že předat těch několik parametrů není problém skrze URL, tedy metodou GET, ale výsledek není zrovna lahodivý oku,
proto byla implementována podpora metody POST. Obsluha je ve výsledku velice jednoduchá (ale ladění zabralo jeden celý den).
Data se posílají dvěma pakety (i když i přes WireShark to lze jen těžko poznat). První obsahuje identifikační hlavičku s identifikátorem metody, prohlížeče klienta, autorizačních ůdajů apod.
V druhém paketu se nacházejí samotná data a je nutné jej příjmout až v samotném průběhu zpracování metody POST,
jinak by do toho kecal autorizační algoritmus a ani selektor metod by si s tím nevěděl rady.
} //konec metody GET
else if (!strncmp(buffer, "POST ", 5)) { //ověření, že se jedná o POST data
int n = client.receive(buffer, sizeof(buffer)); //příjem dalšího paketu se samotnými daty
... //následuje zpracování přijatých dat
==== vykreslení webové stránky ====
Dekódování přijatých dat je věc hraní si s řetězci a následnými převody, ale toho je internet plný a o radu v případě problému není nouze.
Zde tedy pár řádku k nahlédnutí jak vypadá generátor webové stránky uvnitř procesoru.
void display_page(void){
sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n");
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\r\n\t\tK64F HTTP RGB controller \r\n\t\t\r\n\t\r\n\t\r\n\t\tK64F RGB on-line controller
");
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\r\n\t\t\t\r\n\t\t\t\tRGB controls & status \r\n\t\t\t\tSW2 status \r\n\t\t\t\tSW3 status \r\n\t\t\t \r\n\t\t\t\r\n\t\t\t\t ");
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\t\t ",r_col, g_col, b_col);
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\t\t ",s2_col);
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\t\t ",s3_col);
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\t \r\n\t\t
\r\n\t\r\n");
client.send(httpHeader,strlen(httpHeader));
}
a zde výsledek, který už umí přechroustat snad každý prohlížeč:
K64F HTTP RGB controller
K64F RGB on-line controller
RGB controls & status
SW2 status
SW3 status
a zde ještě výsledek, který je mezi lidmi oblíbenější:
{{ 2014:mbed-http:webpage.png |Obrázek výsledné webové stránky}}
Přes tuto stránku je možné zapínat a vypínat jednotlivé barvy RGB LED a hned vidět i výsledek bez nutnosti být zrovna u desky.
Výsledná barevná kombinace je spočítaná ze všech tří složek a kdyby se aplikace poupravila tak, že samostatné vlákno by simulovalo PWM modulaci,
pořád by přibližně odpovídala barva na webové stránce barvě na LED.
Je to možné velice snadno ověřit na [[http://www.quackit.com/css/css_color_codes.cfm|paletě webových barev]].
Na stránce se dále zobrazují dva jakoby bargrafy simulující klasické tlačítka (v horní poloze neaktivní).
Pro větší pohodlí a uživatelský komfort se stránka sama obnovuje každých 5 sekund.
-------
===== PŘÍLOHY =====
==== Zdrojový kód main.cpp ====
#include "mbed.h"
#include "EthernetInterface.h"
#include "SDFileSystem.h"
#include
#include
#define HTTPD_SERVER_PORT 80
#define HTTPD_MAX_REQ_LENGTH 1023
#define HTTPD_MAX_HDR_LENGTH 255
Serial uart(USBTX, USBRX);
EthernetInterface eth;
TCPSocketServer server;
TCPSocketConnection client;
char buffer[HTTPD_MAX_REQ_LENGTH+1];
char httpHeader[HTTPD_MAX_HDR_LENGTH+1];
char *uristr;
char *eou;
char *qrystr;
int r_on=0, g_on=0, b_on=0;
int r_col=0, g_col=0, b_col=0, s2_col=80, s3_col=80;
void display_page(void){
sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n");
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\r\n\t\tK64F HTTP RGB controller \r\n\t\t\r\n\t\r\n\t\r\n\t\tK64F RGB on-line controller
");
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\r\n\t\t\t\r\n\t\t\t\tRGB controls & status \r\n\t\t\t\tSW2 status \r\n\t\t\t\tSW3 status \r\n\t\t\t \r\n\t\t\t\r\n\t\t\t\t ");
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\t\t ",r_col, g_col, b_col);
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\t\t ",s2_col);
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\t\t ",s3_col);
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"\r\n\t\t\t \r\n\t\t
\r\n\t\r\n");
client.send(httpHeader,strlen(httpHeader));
}
int main (void)
{
// RGB LED outputs
DigitalOut rled(LED_RED, 1);
DigitalOut gled(LED_GREEN, 1);
DigitalOut bled(LED_BLUE, 1);
// SW2 & SW3 inputs
DigitalIn sw2(PTC6);
DigitalIn sw3(PTA4);
// Serial Interface eth;
uart.baud(115200);
uart.printf("Initializing\n");
// EthernetInterface eth;
uart.printf("Initializing Ethernet\n");
eth.init(); //Use DHCP
uart.printf("Connecting\n");
eth.connect();
uart.printf("IP Address is %s\n", eth.getIPAddress());
// TCPSocketServer server;
server.bind(HTTPD_SERVER_PORT);
server.listen();
uart.printf("Server Listening\n");
while (true) {
uart.printf("\nWaiting for new connection...\r\n");
server.accept(client);
client.set_blocking(false, 1500); // Timeout after (1.5)s
if(r_on){ //zadost o rozsviceni cervene LED
rled=0; //led aktivni logickou 0
}
else{
rled=1;
}
if(g_on){ //zadost o rozsviceni zelene LED
gled=0; //led aktivni logickou 0
}
else{
gled=1;
}
if(b_on){ //zadost o rozsviceni modre LED
bled=0; //led aktivni logickou 0
}
else{
bled=1;
}
if(sw2){ //nacteni stavu tlacitka SW2
s2_col = 70; //pokud neni tlacitko zmacknute zobrazi se vysoky sloupecek
}
else{
s2_col = 30; //pokud je tlacitko zmacknute zobrazi se nizky sloupecek
}
if(sw3){
s3_col = 70;
}
else{
s3_col = 30;
}
uart.printf("Connection from: %s\r\n", client.get_address());
while (true) {
int n = client.receive(buffer, sizeof(buffer));
if (n <= 0) break;
uart.printf("Recieved Data: %d\r\n\r\n%.*s\r\n",n,n,buffer);
if (n >= 1024) {
sprintf(httpHeader,"HTTP/1.1 413 Request Entity Too Large \r\nContent-Type: text\r\nConnection: Close\r\n\r\n");
client.send(httpHeader,strlen(httpHeader));
client.send(buffer,n);
break;
} else {
buffer[n]=0;
}
if(!strstr(buffer, "Authorization: Basic TVBPQToyMDE0")){ //MPOA 2014
sprintf(httpHeader,"HTTP/1.1 401 Authorization Required \r\nContent-Type: text\r\nWWW-Authenticate: Basic realm='Login required!'\r\n\r\n");
client.send(httpHeader,strlen(httpHeader));
sprintf(httpHeader, "\r\n\t\r\n\t\tError \r\n\t\r\n\t\r\n\t\t401 Unauthorised.
\r\n\t\r\n");
client.send(httpHeader,strlen(httpHeader));
client.close();
}
if (!strncmp(buffer, "GET ", 4)) {
uristr = buffer + 4;
eou = strstr(uristr, " ");
if (eou == NULL) {
sprintf(httpHeader,"HTTP/1.1 400 Bad Request \r\nContent-Type: text\r\nConnection: Close\r\n\r\n");
client.send(httpHeader,strlen(httpHeader));
client.send(buffer,n);
}
else {
*eou = 0;
display_page();
client.close();
}
}
else if (!strncmp(buffer, "POST ", 5)) {
int n = client.receive(buffer, sizeof(buffer));
if (strstr(buffer, "R=on")) {
r_on = 1;
r_col = 255;
}
else{
r_on = 0;
r_col = 0;
}
if (strstr(buffer, "G=on")) {
g_on = 1;
g_col = 255;
}
else{
g_on = 0;
g_col = 0;
}
if (strstr(buffer, "B=on")) {
b_on = 1;
b_col = 255;
}
else{
b_on = 0;
b_col = 0;
}
display_page();
client.close();
}
}
client.close();
}
}
-------