Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: UIPEthernet_GSOE
main.cpp
- Committer:
- hudakz
- Date:
- 2020-06-05
- Revision:
- 15:9beb9b99695d
- Parent:
- 14:810ac368dd6e
- Child:
- 18:02264a85fdda
File content as of revision 15:9beb9b99695d:
#include "mbed.h"
#include <string>
#include "UipEthernet.h"
#include "TcpServer.h"
#include "TcpClient.h"
//#define DEBUG
// Static IP address must be unique and compatible with your network.
#define IP "192.168.1.35"
#define GATEWAY "192.168.1.1"
#define NETMASK "255.255.255.0"
#define PORT 80
const uint8_t MAC[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 };
UipEthernet net(MAC, D11, D12, D13, D10); // mosi, miso, sck, cs
TcpServer server; // Ethernet server
TcpClient* client;
char httpBuf[1500];
char httpHeader[256];
const int OFF = 0;
const int ON = 1;
DigitalOut output(D3); // A digital output to be switched on/off
float roomTemp = 21.8f; // A temperature sensor output
const char PASSWORD[] = "secret"; // Change as you like
/**
* @brief Analyses the received URL
* @note The string passed to this function will look like this:
* GET /HTTP/1.....
* GET /password HTTP/1.....
* GET /password/ HTTP/1.....
* GET /password/?sw=1 HTTP/1.....
* GET /password/?sw=0 HTTP/1.....
* @param url URL string
* @retval -3 just refresh page
* -2 no command given but password valid
* -1 invalid password
* 0 switch off
* 1 switch on
*/
int8_t analyseURL(char* url)
{
if (strlen(url) < (5 + strlen(PASSWORD) + 1))
return(-1);
//if (url.substr(5, PASSWORD.size()) != PASSWORD)
if (strncmp(url + 5, PASSWORD, strlen(PASSWORD)) != 0)
return(-1);
uint8_t pos = 5 + strlen(PASSWORD);
//if (url.substr(pos, 1) != "/")
if (*(url + pos) != '/')
return(-1);
//if (url.substr(pos++, 1) == " ")
if (*(url + pos++) == ' ')
return(-2);
//string cmd(url.substr(pos, 5));
*(url + pos + 5) = '\0'; // terminate the cmd string
char* cmd = ((url + pos));
if (strcmp(cmd, "?sw=0") == 0)
return(0);
if (strcmp(cmd, "?sw=1") == 0)
return(1);
return(-3);
}
/**
* @brief
* @note
* @param
* @retval
*/
char* movedPermanently(uint8_t flag)
{
memset(httpBuf, 0, sizeof(httpBuf));
if (flag == 1) {
strcpy(httpBuf, "/");
strcat(httpBuf, PASSWORD);
strcat(httpBuf, "/");
}
strcat(httpBuf, "<h1>301 Moved Permanently</h1>\r\n");
return(httpBuf);
}
/**
* @brief
* @note
* @param
* @retval
*/
char* showWebPage(int status)
{
char roomTempStr[10] = { };
//roomTemp = ds1820.read();
sprintf(roomTempStr, "%3.1f", roomTemp);
memset(httpBuf, 0, sizeof(httpBuf));
/*$off*/
strcat
(
httpBuf,
"<head>"
"<meta charset=\"utf-8\">"
"<meta name=\"viewport\" content=\" initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=0;\"/>"
"<title>Smart Home</title>"
"<link href='http://fonts.googleapis.com/css?family=Droid+Sans&v1' rel='stylesheet' type='text/css'>"
"<style>"
".switch {"
"position: relative;"
"display: inline-block;"
"width: 60px;"
"height: 34px;"
"}"
".switch input {display:none;}"
".slider {"
"position: absolute;"
"cursor: pointer;"
"top: 0;"
"left: 0;"
"right: 0;"
"bottom: 0;"
"border-radius: 34px;"
"background-color: #ccc;"
"-webkit-transition: .4s;"
"transition: .4s;"
"}"
".slider:before {"
"position: absolute;"
"content: \"\";"
"height: 26px;"
"width: 26px;"
"left: 4px;"
"bottom: 4px;"
"border-radius: 50%;"
"background-color: white;"
"-webkit-transition: .4s;"
"transition: .4s;"
"}"
"input:checked + .slider {"
"background-color: #8ce196;"
"}"
"input:focus + .slider {"
"box-shadow: 0 0 1px #8ce196;"
"}"
"input:checked + .slider:before {"
"-webkit-transform: translateX(26px);"
"-ms-transform: translateX(26px);"
"transform: translateX(26px);"
"}"
"</style>"
"</head>"
"<body>"
"<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>"
"<pre>Temperature:\t"
);
strcat(httpBuf, roomTempStr);
strcat(httpBuf, "°C</pre>");
strcat
(
httpBuf,
"<pre>Heating:\t"
);
if(status == ON) {
strcat
(
httpBuf,
"<a href=\"./?sw=0\" class=\"switch\"> "
"<input type=\"checkbox\" checked>"
);
}
else {
strcat
(
httpBuf,
"<a href=\"./?sw=1\" class=\"switch\"> "
"<input type=\"checkbox\">"
);
}
strcat
(
httpBuf,
"<div class=\"slider\"></div>"
"</a>"
"</pre>"
"<hr>"
"<pre>2017 ARMmbed</pre>"
"</body>"
);
/*$on*/
return httpBuf;
}
/**
* @brief
* @note
* @param
* @retval
*/
void sendHTTP(TcpClient* client, char* header, char* content)
{
char content_length[10] = { };
sprintf(content_length, "%u\r\n", strlen(content));
strcat(header, "\r\nContent-Type: text/html\r\n");
strcat(header, "Content-Length: ");
strcat(header, content_length);
strcat(header, "Pragma: no-cache\r\n");
strcat(header, "Connection: About to close\r\n\r\n");
char c = content[0];
memmove(httpBuf + strlen(header), httpBuf, strlen(content)); // make room for the header
strcpy(httpBuf, header); // copy the header on front of the content
httpBuf[strlen(header)] = c;
client->send((uint8_t*)httpBuf, strlen(httpBuf));
}
/**
* @brief
* @note
* @param
* @retval
*/
int main(void)
{
printf("Starting ...\r\n");
//net.set_network(IP, NETMASK, GATEWAY); // include this for using static IP address
if (net.connect(30) != 0) {
// 'connect' timeout in seconds (defaults to 60 sec)
printf("Unable to connet.\r\n");
return -1;
}
// Show the network address
SocketAddress addr;
net.get_ip_address(&addr);
printf("IP address: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
net.get_netmask(&addr);
printf("Netmask: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
net.get_gateway(&addr);
printf("Gateway: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None");
/* Open the server on ethernet stack */
server.open(&net);
/* Bind the HTTP port (TCP 80) to the server */
server.bind(PORT);
/* Can handle 4 simultaneous connections */
server.listen(4);
while (true) {
client = server.accept();
if (client) {
switch (client->recv((uint8_t*)httpBuf, client->available())) {
case 0:
printf("recieved buffer is empty.\n\r");
break;
case -1:
printf("failed to read data from client.\n\r");
break;
default:
#ifdef DEBUG
printf("Client with IP address %s connected.\r\n\r\n", client->getpeername());
printf("Data received:\r\n%s\n\r", receiveBuf);
#endif
if (strncmp(httpBuf, "GET", 3) != 0) {
strcpy(httpHeader, "HTTP/1.0 200 OK");
strcpy(httpBuf, "<h1>200 OK</h1>");
sendHTTP(client, httpHeader, httpBuf);
}
else
if ((strncmp(httpBuf, "GET", 3) == 0) && (strncmp(httpBuf + 3, " / ", 3 == 0))) {
strcpy(httpHeader, "HTTP/1.0 200 OK");
strcpy(httpBuf, "<p>Usage: http://host_or_ip/password</p>\r\n");
sendHTTP(client, httpHeader, httpBuf);
}
else {
int cmd = analyseURL(httpBuf);
switch (cmd) {
case -3:
// update webpage
strcpy(httpHeader, "HTTP/1.0 200 OK");
sendHTTP(client, httpHeader, showWebPage(output));
break;
case -2:
// redirect to the right base url
strcpy(httpHeader, "HTTP/1.0 301 Moved Permanently\r\nLocation: ");
sendHTTP(client, httpHeader, movedPermanently(1));
break;
case -1:
strcpy(httpHeader, "HTTP/1.0 401 Unauthorized");
strcpy(httpBuf, "<h1>401 Unauthorized</h1>");
sendHTTP(client, httpHeader, httpBuf);
break;
case 0:
output = OFF; // output off
strcpy(httpHeader, "HTTP/1.0 200 OK");
sendHTTP(client, httpHeader, showWebPage(output));
break;
case 1:
output = ON; // output on
strcpy(httpHeader, "HTTP/1.0 200 OK");
sendHTTP(client, httpHeader, showWebPage(output));
break;
}
}
}
client->close();
}
}
}