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
Diff: main.cpp
- Revision:
- 15:9beb9b99695d
- Parent:
- 14:810ac368dd6e
- Child:
- 18:02264a85fdda
--- a/main.cpp Sat Sep 07 17:53:02 2019 +0000
+++ b/main.cpp Fri Jun 05 15:15:01 2020 +0000
@@ -4,28 +4,23 @@
#include "TcpServer.h"
#include "TcpClient.h"
-using namespace std;
-
//#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 receiveBuf[1024];
+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.8; // A temperature sensor output
-const string PASSWORD = "secret"; // Change as you like
-string httpHeader; // HTTP header
-string httpContent; // HTTP content
+float roomTemp = 21.8f; // A temperature sensor output
+const char PASSWORD[] = "secret"; // Change as you like
/**
* @brief Analyses the received URL
@@ -42,30 +37,33 @@
* 0 switch off
* 1 switch on
*/
-int8_t analyseURL(string& url)
+int8_t analyseURL(char* url)
{
- if (url.length() < 5 + PASSWORD.size() + 1)
+ if (strlen(url) < (5 + strlen(PASSWORD) + 1))
return(-1);
- if (url.substr(5, PASSWORD.size()) != PASSWORD)
+ //if (url.substr(5, PASSWORD.size()) != PASSWORD)
+ if (strncmp(url + 5, PASSWORD, strlen(PASSWORD)) != 0)
return(-1);
- uint8_t pos = 5 + PASSWORD.size();
+ uint8_t pos = 5 + strlen(PASSWORD);
- if (url.substr(pos, 1) != "/")
+ //if (url.substr(pos, 1) != "/")
+
+ if (*(url + pos) != '/')
return(-1);
- if (url.substr(pos++, 1) == " ")
+ //if (url.substr(pos++, 1) == " ")
+ if (*(url + pos++) == ' ')
return(-2);
- string cmd(url.substr(pos, 5));
-
- if (cmd == "?sw=0")
+ //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 (cmd == "?sw=1")
+ if (strcmp(cmd, "?sw=1") == 0)
return(1);
-
return(-3);
}
@@ -75,16 +73,17 @@
* @param
* @retval
*/
-string& movedPermanently(uint8_t flag)
+char* movedPermanently(uint8_t flag)
{
- if (flag == 1)
- httpContent = "/" + PASSWORD + "/";
- else
- httpContent = "";
+ memset(httpBuf, 0, sizeof(httpBuf));
+ if (flag == 1) {
+ strcpy(httpBuf, "/");
+ strcat(httpBuf, PASSWORD);
+ strcat(httpBuf, "/");
+ }
- httpContent += "<h1>301 Moved Permanently</h1>\r\n";
-
- return(httpContent);
+ strcat(httpBuf, "<h1>301 Moved Permanently</h1>\r\n");
+ return(httpBuf);
}
/**
@@ -93,92 +92,108 @@
* @param
* @retval
*/
-string& showWebPage(int status)
+char* showWebPage(int status)
{
- char roomTempStr[5];
+ char roomTempStr[10] = { };
//roomTemp = ds1820.read();
+
sprintf(roomTempStr, "%3.1f", roomTemp);
-
+ memset(httpBuf, 0, sizeof(httpBuf));
/*$off*/
- httpContent =
+ 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>"
+ "<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" + string(roomTempStr) + "°C</pre>"
- "<pre>Heating:\t";
-
+ "<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) {
- httpContent +=
- "<a href=\"./?sw=0\" class=\"switch\"> "
- "<input type=\"checkbox\" checked>";
+ strcat
+ (
+ httpBuf,
+ "<a href=\"./?sw=0\" class=\"switch\"> "
+ "<input type=\"checkbox\" checked>"
+ );
}
else {
- httpContent +=
- "<a href=\"./?sw=1\" class=\"switch\"> "
- "<input type=\"checkbox\">";
+ strcat
+ (
+ httpBuf,
+ "<a href=\"./?sw=1\" class=\"switch\"> "
+ "<input type=\"checkbox\">"
+ );
}
-
- httpContent +=
- "<div class=\"slider\"></div>"
- "</a>"
- "</pre>"
- "<hr>"
- "<pre>2017 ARMmbed</pre>"
- "</body>";
-
- return httpContent;
+ strcat
+ (
+ httpBuf,
+ "<div class=\"slider\"></div>"
+ "</a>"
+ "</pre>"
+ "<hr>"
+ "<pre>2017 ARMmbed</pre>"
+ "</body>"
+ );
/*$on*/
+ return httpBuf;
}
/**
@@ -187,23 +202,23 @@
* @param
* @retval
*/
-void sendHTTP(TcpClient& client, string& header, string& content)
+void sendHTTP(TcpClient* client, char* header, char* content)
{
- /*$off*/
- char content_length[5] = { };
+ char content_length[10] = { };
+
+ sprintf(content_length, "%u\r\n", strlen(content));
- header +=
- "\r\nContent-Type: text/html\r\n"
- "Content-Length: ";
- sprintf(content_length, "%d", content.length());
- header +=
- string(content_length) + "\r\n"
- "Pragma: no-cache\r\n"
- "Connection: About to close\r\n\r\n";
+ 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");
- string webpage = header + content;
- client.send((uint8_t*)webpage.c_str(), webpage.length());
- /*$on*/
+ 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));
}
/**
@@ -217,22 +232,21 @@
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)
+ 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
- const char* ip = net.get_ip_address();
- const char* netmask = net.get_netmask();
- const char* gateway = net.get_gateway();
-
- printf("IP address: %s\r\n", ip ? ip : "None");
- printf("Netmask: %s\r\n", netmask ? netmask : "None");
- printf("Gateway: %s\r\n\r\n", gateway ? gateway : "None");
- printf("------------------------------------------------------------------\r\n");
- printf("Usage: Type %s/%s/ into your web browser and hit ENTER\r\n", ip, PASSWORD.c_str());
- printf("------------------------------------------------------------------\r\n");
+ 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);
@@ -245,63 +259,66 @@
while (true) {
client = server.accept();
-
if (client) {
- client->recv((uint8_t*)receiveBuf, client->available());
-#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
- string received(receiveBuf);
-
- if (received.substr(0, 3) != "GET") {
- httpHeader = "HTTP/1.0 200 OK";
- httpContent = "<h1>200 OK</h1>";
- sendHTTP(*client, httpHeader, httpContent);
- client->close();
- continue;
- }
-
- if (received.substr(0, 6) == "GET / ") {
- httpHeader = "HTTP/1.0 200 OK";
- httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n";
- sendHTTP(*client, httpHeader, httpContent);
- client->close();
- continue;
- }
-
- int cmd = analyseURL(received);
-
- switch (cmd) {
- case -3:
- // update webpage
- httpHeader = "HTTP/1.0 200 OK";
- sendHTTP(*client, httpHeader, showWebPage(output));
- break;
-
- case -2:
- // redirect to the right base url
- httpHeader = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
- sendHTTP(*client, httpHeader, movedPermanently(1));
+ switch (client->recv((uint8_t*)httpBuf, client->available())) {
+ case 0:
+ printf("recieved buffer is empty.\n\r");
break;
case -1:
- httpHeader = "HTTP/1.0 401 Unauthorized";
- httpContent = "<h1>401 Unauthorized</h1>";
- sendHTTP(*client, httpHeader, httpContent);
+ printf("failed to read data from client.\n\r");
break;
- case 0:
- output = OFF; // output off
- httpHeader = "HTTP/1.0 200 OK";
- sendHTTP(*client, httpHeader, showWebPage(output));
- 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 1:
- output = ON; // output on
- 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();