Skip to content

Commit

Permalink
Change how we serve full and simple indexes, add portal page and logo…
Browse files Browse the repository at this point in the history
… to that (#68)

* Implement one URI for index pages, takes a parameter, ?view=full|simple|etc
* Add an access portal page, add a logo to that and the dump page.
* Fix default myconfig
* fix a stoopid, possibly disruptive bug that I introduced when unpacking html in my 1st commit
  • Loading branch information
easytarget authored Oct 7, 2020
1 parent 1399d87 commit 5ced309
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 128 deletions.
33 changes: 4 additions & 29 deletions Docs/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
109 changes: 83 additions & 26 deletions app_httpd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@

#include "index_ov2640.h"
#include "index_ov3660.h"
#include "viewers.h"
#include "index_other.h"
#include "css.h"
#include "src/favicons.h"
#include "src/logo.h"
#include "storage.h"

//#define DEBUG_STREAM_DATA // Debug: dump info for each stream frame on serial port
Expand Down Expand Up @@ -698,12 +699,18 @@ static esp_err_t favicon_ico_handler(httpd_req_t *req){
return httpd_resp_send(req, (const char *)favicon_ico, favicon_ico_len);
}

static esp_err_t logo_svg_handler(httpd_req_t *req){
httpd_resp_set_type(req, "image/svg+xml");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)logo_svg, logo_svg_len);
}

static esp_err_t dump_handler(httpd_req_t *req){
flashLED(75);
Serial.println("\nDump Requested");
Serial.print("Preferences file: ");
dumpPrefs(SPIFFS);
static char dumpOut[1200] = "n";
static char dumpOut[1200] = "";
char * d = dumpOut;
// Header
d+= sprintf(d,"<html><head><meta charset=\"utf-8\">\n");
Expand All @@ -713,6 +720,7 @@ static esp_err_t dump_handler(httpd_req_t *req){
d+= sprintf(d,"<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\">\n");
d+= sprintf(d,"<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\">\n");
d+= sprintf(d,"</head>\n<body>\n");
d+= sprintf(d,"<img src=\"/logo.svg\" style=\"position: relative; float: right;\">\n");
d+= sprintf(d,"<h1>ESP32 Cam Webserver</h1>\n");
// Module
d+= sprintf(d,"Name: %s<br>\n", myName);
Expand Down Expand Up @@ -804,14 +812,6 @@ static esp_err_t style_handler(httpd_req_t *req){
return httpd_resp_send(req, (const char *)style_css, style_css_len);
}

static esp_err_t miniviewer_handler(httpd_req_t *req){
flashLED(75);
Serial.println("Simple viewer requested");
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)miniviewer_html, miniviewer_html_len);
}

static esp_err_t streamviewer_handler(httpd_req_t *req){
flashLED(75);
Serial.println("Stream Viewer requested");
Expand All @@ -821,15 +821,74 @@ static esp_err_t streamviewer_handler(httpd_req_t *req){
}

static esp_err_t index_handler(httpd_req_t *req){
char* buf;
size_t buf_len;
char view[32] = {0,};

flashLED(75);
Serial.println("Index page requested");
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
sensor_t * s = esp_camera_sensor_get();
if (s->id.PID == OV3660_PID) {
return httpd_resp_send(req, (const char *)index_ov3660_html, index_ov3660_html_len);
// See if we have a specific target (full/simple/?portal) and serve as appropriate
buf_len = httpd_req_get_url_query_len(req) + 1;
if (buf_len > 1) {
buf = (char*)malloc(buf_len);
if(!buf){
httpd_resp_send_500(req);
return ESP_FAIL;
}
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
if (httpd_query_key_value(buf, "view", view, sizeof(view)) == ESP_OK) {
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
free(buf);
} else {
if (captivePortal) {
strcpy(view,"simple");
}
// no target specified; default.
#if defined(DEFAULT_INDEX_FULL)
strcpy(view,"full");
#else
strcpy(view,"simple");
#endif
// If a captive portal page is created, we can use it here
if (captivePortal) {
strcpy(view,"portal");
}
}

if (strncmp(view,"simple", sizeof(view)) == 0) {
Serial.println("Simple index page requested");
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)index_simple_html, index_simple_html_len);
} else if(strncmp(view,"full", sizeof(view)) == 0) {
Serial.println("Full index page requested");
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
sensor_t * s = esp_camera_sensor_get();
if (s->id.PID == OV3660_PID) {
return httpd_resp_send(req, (const char *)index_ov3660_html, index_ov3660_html_len);
}
return httpd_resp_send(req, (const char *)index_ov2640_html, index_ov2640_html_len);
} else if(strncmp(view,"portal", sizeof(view)) == 0) {
//Prototype captive portal landing page.
Serial.println("Portal page requested");
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)portal_html, portal_html_len);
} else {
Serial.print("Unknown page requested: ");
Serial.println(view);
httpd_resp_send_404(req);
return ESP_FAIL;
}
return httpd_resp_send(req, (const char *)index_ov2640_html, index_ov2640_html_len);
}

void startCameraServer(int hPort, int sPort){
Expand Down Expand Up @@ -860,12 +919,6 @@ void startCameraServer(int hPort, int sPort){
.handler = capture_handler,
.user_ctx = NULL
};
httpd_uri_t miniviewer_uri = {
.uri = "/view",
.method = HTTP_GET,
.handler = miniviewer_handler,
.user_ctx = NULL
};
httpd_uri_t style_uri = {
.uri = "/style.css",
.method = HTTP_GET,
Expand All @@ -890,14 +943,18 @@ void startCameraServer(int hPort, int sPort){
.handler = favicon_ico_handler,
.user_ctx = NULL
};
// DEBUG
httpd_uri_t logo_svg_uri = {
.uri = "/logo.svg",
.method = HTTP_GET,
.handler = logo_svg_handler,
.user_ctx = NULL
};
httpd_uri_t dump_uri = {
.uri = "/dump",
.method = HTTP_GET,
.handler = dump_handler,
.user_ctx = NULL
};
// DEBUG
httpd_uri_t stream_uri = {
.uri = "/",
.method = HTTP_GET,
Expand Down Expand Up @@ -942,11 +999,11 @@ void startCameraServer(int hPort, int sPort){
httpd_register_uri_handler(camera_httpd, &cmd_uri);
httpd_register_uri_handler(camera_httpd, &status_uri);
httpd_register_uri_handler(camera_httpd, &capture_uri);
httpd_register_uri_handler(camera_httpd, &miniviewer_uri);
httpd_register_uri_handler(camera_httpd, &style_uri);
httpd_register_uri_handler(camera_httpd, &favicon_16x16_uri);
httpd_register_uri_handler(camera_httpd, &favicon_32x32_uri);
httpd_register_uri_handler(camera_httpd, &favicon_ico_uri);
httpd_register_uri_handler(camera_httpd, &logo_svg_uri);
httpd_register_uri_handler(camera_httpd, &dump_uri);
}

Expand Down
10 changes: 4 additions & 6 deletions css.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/*
* Master CSS file included in the camer_index_* and miniviewer HTML
* Master CSS file for the camera pages
*/

const uint8_t style_css[] = R"=====(
/*
const uint8_t style_css[] = R"=====(/*
* CSS for the esp32 cam webserver
*/

Expand Down Expand Up @@ -358,7 +357,6 @@ select {
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
)=====";
})=====";

size_t style_css_len = sizeof(style_css);
size_t style_css_len = sizeof(style_css)-1;
48 changes: 35 additions & 13 deletions viewers.h → index_other.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/*
* Miniviewer and streamviewer
* simpleviewer and streamviewer
*/

const uint8_t miniviewer_html[] = R"=====(
<!doctype html>
const uint8_t index_simple_html[] = R"=====(<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title id="title">ESP32-CAM MiniViewer</title>
<title id="title">ESP32-CAM Simplified View</title>
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="stylesheet" type="text/css" href="/style.css">
Expand Down Expand Up @@ -273,20 +272,18 @@
}

swapButton.onclick = () => {
window.open('/','_self');
window.open('/?view=full','_self');
}

})
</script>
</html>
)=====";
</html>)=====";

size_t miniviewer_html_len = sizeof(miniviewer_html);
size_t index_simple_html_len = sizeof(index_simple_html)-1;

/* Stream Viewer */

const uint8_t streamviewer_html[] = R"=====(
<!doctype html>
const uint8_t streamviewer_html[] = R"=====(<!doctype html>
<html>
<head>
<meta charset="utf-8">
Expand Down Expand Up @@ -432,7 +429,32 @@ size_t miniviewer_html_len = sizeof(miniviewer_html);
}
})
</script>
</html>
)=====";
</html>)=====";

size_t streamviewer_html_len = sizeof(streamviewer_html);
size_t streamviewer_html_len = sizeof(streamviewer_html)-1;

/* Prototype Captive Portal page */

const uint8_t portal_html[] = R"=====(<!doctype html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title id="title">ESP32-CAM portal</title>
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body>
<img src="/logo.svg" style="position: relative; float: right;">
<h1>ESP32 cam access portal</h1>
<div class="input-group">
<a href="/?view=simple" title="Click here for a simple view with minimum control" style="text-decoration: none;"><button>Simple Viewer</button></a>
<a href="/?view=full" title="Click here for the main camera page with full controls" style="text-decoration: none;"><button>Full Viewer</button></a>
</div>
<hr>
<a href="/dump" title="Information dump page" target="_blank">Camera Details</a><br>
<a href="https://github.com/easytarget/esp32-cam-webserver" title="Code homepage on GitHub">ESP32 cam webserver on GitHub</a>
</body></html>)=====";

size_t portal_html_len = sizeof(portal_html)-1;
12 changes: 5 additions & 7 deletions index_ov2640.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
* primary HTML for the OV2640 camera module
*/

const uint8_t index_ov2640_html[] = R"=====(
<!doctype html>
const uint8_t index_ov2640_html[] = R"=====(<!doctype html>
<html>
<head>
<meta charset="utf-8">
Expand Down Expand Up @@ -265,7 +264,7 @@ const uint8_t index_ov2640_html[] = R"=====(
<div id="code_ver" class="default-action"></div>
</div>
<div class="input-group hidden" id="stream-group">
<label for="stream_url" id="stream_link">Stream URL</label>
<label for="stream_url" id="stream_link">Stream</label>
<div id="stream_url" class="default-action">Unknown</div>
</div>
</nav>
Expand Down Expand Up @@ -589,7 +588,7 @@ const uint8_t index_ov2640_html[] = R"=====(
}

swapButton.onclick = () => {
window.open('/view','_self');
window.open('/?view=simple','_self');
}

// saveFaceButton.onclick = () => {
Expand Down Expand Up @@ -626,7 +625,6 @@ const uint8_t index_ov2640_html[] = R"=====(

})
</script>
</html>
)=====";
</html>)=====";

size_t index_ov2640_html_len = sizeof(index_ov2640_html);
size_t index_ov2640_html_len = sizeof(index_ov2640_html)-1;
2 changes: 1 addition & 1 deletion index_ov3660.h
Original file line number Diff line number Diff line change
Expand Up @@ -636,4 +636,4 @@ const uint8_t index_ov3660_html[] = R"=====(
</html>
)=====";

size_t index_ov3660_html_len = sizeof(index_ov3660_html);
size_t index_ov3660_html_len = sizeof(index_ov3660_html)-1;
Loading

0 comments on commit 5ced309

Please sign in to comment.