mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 11:36:59 +03:00
Merge branch 'master' into httpd
Conflicts: components/wifi-manager/http_server.c components/wifi-manager/wifi_manager.c main/config.c main/config.h
This commit is contained in:
@@ -4,5 +4,6 @@ idf_component_register(SRCS "dns_server.c" "http_server.c" "wifi_manager.c"
|
||||
PRIV_REQUIRES newlib freertos spi_flash nvs_flash mdns pthread wpa_supplicant cmd_system esp_http_server
|
||||
EMBED_FILES style.css code.js index.html bootstrap.min.css.gz jquery.min.js.gz popper.min.js.gz bootstrap.min.js.gz
|
||||
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -765,6 +765,30 @@ function checkStatus(){
|
||||
lastMsg = msg;
|
||||
}
|
||||
}
|
||||
if (data.hasOwnProperty('Voltage')) {
|
||||
var voltage = data['Voltage'];
|
||||
var layer;
|
||||
if (voltage > 0) {
|
||||
if (inRange(voltage, 5.8, 6.2) || inRange(voltage, 8.8, 9.2)) {
|
||||
layer = bat0;
|
||||
} else if (inRange(voltage, 6.2, 6.8) || inRange(voltage, 9.2, 10.0)) {
|
||||
layer = bat1;
|
||||
} else if (inRange(voltage, 6.8, 7.1) || inRange(voltage, 10.0, 10.5)) {
|
||||
layer = bat2;
|
||||
} else if (inRange(voltage, 7.1, 7.5) || inRange(voltage, 10.5, 11.0)) {
|
||||
layer = bat3;
|
||||
} else {
|
||||
layer = bat4;
|
||||
}
|
||||
layer.setAttribute("display","inline");
|
||||
}
|
||||
}
|
||||
if (data.hasOwnProperty('Jack')) {
|
||||
var jack = data['Jack'];
|
||||
if (jack == '1') {
|
||||
o_jack.setAttribute("display","inline");
|
||||
}
|
||||
}
|
||||
blockAjax = false;
|
||||
})
|
||||
.fail(function(xhr, ajaxOptions, thrownError) {
|
||||
@@ -787,6 +811,15 @@ function getConfig() {
|
||||
}
|
||||
} else if (key == 'autoexec1') {
|
||||
$("textarea#autoexec1").val(data[key].value);
|
||||
var re = / -o "?(\S+)\b/g;
|
||||
var m = re.exec(data[key].value);
|
||||
if (m[1] =='I2S') {
|
||||
o_i2s.setAttribute("display","inline");
|
||||
} else if (m[1] =='SPDIF') {
|
||||
o_spdif.setAttribute("display","inline");
|
||||
} else if (m[1] =='BT') {
|
||||
o_bt.setAttribute("display","inline");
|
||||
}
|
||||
} else if (key == 'host_name') {
|
||||
$("input#dhcp-name1").val(data[key].value);
|
||||
$("input#dhcp-name2").val(data[key].value);
|
||||
@@ -837,3 +870,7 @@ function showMessage(message, severity) {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function inRange(x, min, max) {
|
||||
return ((x-min)*(x-max) <= 0);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# please read the SDK documents if you need to do this.
|
||||
#
|
||||
COMPONENT_EMBED_FILES := style.css code.js index.html bootstrap.min.css.gz jquery.min.js.gz popper.min.js.gz bootstrap.min.js.gz
|
||||
|
||||
#CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
|
||||
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG \
|
||||
-I$(COMPONENT_PATH)/../tools
|
||||
|
||||
655
components/wifi-manager/http_server.c
Normal file
655
components/wifi-manager/http_server.c
Normal file
@@ -0,0 +1,655 @@
|
||||
/*
|
||||
Copyright (c) 2017-2019 Tony Pottier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@file http_server.c
|
||||
@author Tony Pottier
|
||||
@brief Defines all functions necessary for the HTTP server to run.
|
||||
|
||||
Contains the freeRTOS task for the HTTP listener and all necessary support
|
||||
function to process requests, decode URLs, serve files, etc. etc.
|
||||
|
||||
@note http_server task cannot run without the wifi_manager task!
|
||||
@see https://idyl.io
|
||||
@see https://github.com/tonyp7/esp32-wifi-manager
|
||||
*/
|
||||
|
||||
#include "http_server.h"
|
||||
#include "cmd_system.h"
|
||||
#include <inttypes.h>
|
||||
#include "squeezelite-ota.h"
|
||||
#include "nvs_utilities.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "cJSON.h"
|
||||
#include "esp_system.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "config.h"
|
||||
|
||||
#define HTTP_STACK_SIZE (5*1024)
|
||||
|
||||
/* @brief tag used for ESP serial console messages */
|
||||
static const char TAG[] = "http_server";
|
||||
/* @brief task handle for the http server */
|
||||
static TaskHandle_t task_http_server = NULL;
|
||||
static StaticTask_t task_http_buffer;
|
||||
#if RECOVERY_APPLICATION
|
||||
static StackType_t task_http_stack[HTTP_STACK_SIZE];
|
||||
#else
|
||||
static StackType_t EXT_RAM_ATTR task_http_stack[HTTP_STACK_SIZE];
|
||||
#endif
|
||||
SemaphoreHandle_t http_server_config_mutex = NULL;
|
||||
|
||||
/**
|
||||
* @brief embedded binary data.
|
||||
* @see file "component.mk"
|
||||
* @see https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#embedding-binary-data
|
||||
*/
|
||||
extern const uint8_t style_css_start[] asm("_binary_style_css_start");
|
||||
extern const uint8_t style_css_end[] asm("_binary_style_css_end");
|
||||
extern const uint8_t jquery_gz_start[] asm("_binary_jquery_min_js_gz_start");
|
||||
extern const uint8_t jquery_gz_end[] asm("_binary_jquery_min_js_gz_end");
|
||||
extern const uint8_t popper_gz_start[] asm("_binary_popper_min_js_gz_start");
|
||||
extern const uint8_t popper_gz_end[] asm("_binary_popper_min_js_gz_end");
|
||||
extern const uint8_t bootstrap_js_gz_start[] asm("_binary_bootstrap_min_js_gz_start");
|
||||
extern const uint8_t bootstrap_js_gz_end[] asm("_binary_bootstrap_min_js_gz_end");
|
||||
extern const uint8_t bootstrap_css_gz_start[] asm("_binary_bootstrap_min_css_gz_start");
|
||||
extern const uint8_t bootstrap_css_gz_end[] asm("_binary_bootstrap_min_css_gz_end");
|
||||
extern const uint8_t code_js_start[] asm("_binary_code_js_start");
|
||||
extern const uint8_t code_js_end[] asm("_binary_code_js_end");
|
||||
extern const uint8_t index_html_start[] asm("_binary_index_html_start");
|
||||
extern const uint8_t index_html_end[] asm("_binary_index_html_end");
|
||||
|
||||
|
||||
/* const http headers stored in ROM */
|
||||
const static char http_hdr_template[] = "HTTP/1.1 200 OK\nContent-type: %s\nAccept-Ranges: bytes\nContent-Length: %d\nContent-Encoding: %s\nAccess-Control-Allow-Origin: *\n\n";
|
||||
const static char http_html_hdr[] = "HTTP/1.1 200 OK\nContent-type: text/html\nAccess-Control-Allow-Origin: *\nAccept-Encoding: identity\n\n";
|
||||
const static char http_css_hdr[] = "HTTP/1.1 200 OK\nContent-type: text/css\nCache-Control: public, max-age=31536000\nAccess-Control-Allow-Origin: *\n\n";
|
||||
const static char http_js_hdr[] = "HTTP/1.1 200 OK\nContent-type: text/javascript\nAccess-Control-Allow-Origin: *\n\n";
|
||||
const static char http_svg_hdr[] = "HTTP/1.1 200 OK\nContent-type: image/svg+xml\nAccess-Control-Allow-Origin: *\n\n";
|
||||
const static char http_400_hdr[] = "HTTP/1.1 400 Bad Request\nContent-Length: 0\n\n";
|
||||
const static char http_404_hdr[] = "HTTP/1.1 404 Not Found\nContent-Length: 0\n\n";
|
||||
const static char http_503_hdr[] = "HTTP/1.1 503 Service Unavailable\nContent-Length: 0\n\n";
|
||||
const static char http_ok_json_no_cache_hdr[] = "HTTP/1.1 200 OK\nContent-type: application/json\nCache-Control: no-store, no-cache, must-revalidate, max-age=0\nPragma: no-cache\nAccess-Control-Allow-Origin: *\nAccept-Encoding: identity\n\n";
|
||||
const static char http_redirect_hdr_start[] = "HTTP/1.1 302 Found\nLocation: http://";
|
||||
const static char http_redirect_hdr_end[] = "/\n\n";
|
||||
|
||||
|
||||
void http_server_start() {
|
||||
ESP_LOGD(TAG, "http_server_start ");
|
||||
if(task_http_server == NULL) {
|
||||
task_http_server = xTaskCreateStatic( (TaskFunction_t) &http_server, "http_server", HTTP_STACK_SIZE, NULL,
|
||||
WIFI_MANAGER_TASK_PRIORITY, task_http_stack, &task_http_buffer);
|
||||
}
|
||||
}
|
||||
void http_server(void *pvParameters) {
|
||||
http_server_config_mutex = xSemaphoreCreateMutex();
|
||||
struct netconn *conn, *newconn;
|
||||
err_t err;
|
||||
conn = netconn_new(NETCONN_TCP);
|
||||
netconn_bind(conn, IP_ADDR_ANY, 80);
|
||||
netconn_listen(conn);
|
||||
ESP_LOGI(TAG, "HTTP Server listening on 80/tcp");
|
||||
do {
|
||||
err = netconn_accept(conn, &newconn);
|
||||
if(err == ERR_OK) {
|
||||
http_server_netconn_serve(newconn);
|
||||
netconn_delete(newconn);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Error accepting new connection. Terminating HTTP server");
|
||||
}
|
||||
taskYIELD(); /* allows the freeRTOS scheduler to take over if needed. */
|
||||
} while(err == ERR_OK);
|
||||
|
||||
netconn_close(conn);
|
||||
netconn_delete(conn);
|
||||
vSemaphoreDelete(http_server_config_mutex);
|
||||
http_server_config_mutex = NULL;
|
||||
vTaskDelete( NULL );
|
||||
}
|
||||
|
||||
|
||||
char* http_server_get_header(char *request, char *header_name, int *len) {
|
||||
*len = 0;
|
||||
char *ret = NULL;
|
||||
char *ptr = NULL;
|
||||
|
||||
ptr = strstr(request, header_name);
|
||||
if(ptr) {
|
||||
ret = ptr + strlen(header_name);
|
||||
ptr = ret;
|
||||
while (*ptr != '\0' && *ptr != '\n' && *ptr != '\r') {
|
||||
(*len)++;
|
||||
ptr++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
char* http_server_search_header(char *request, char *header_name, int *len, char ** parm_name, char ** next_position, char * bufEnd) {
|
||||
*len = 0;
|
||||
char *ret = NULL;
|
||||
char *ptr = NULL;
|
||||
int currentLength=0;
|
||||
|
||||
ESP_LOGV(TAG, "searching for header name: [%s]", header_name);
|
||||
ptr = strstr(request, header_name);
|
||||
|
||||
|
||||
if(ptr!=NULL && ptr<bufEnd) {
|
||||
ret = ptr + strlen(header_name);
|
||||
ptr = ret;
|
||||
currentLength=(int)(ptr-request);
|
||||
ESP_LOGV(TAG, "found string at %d", currentLength);
|
||||
|
||||
while (*ptr != '\0' && *ptr != '\n' && *ptr != '\r' && *ptr != ':' && ptr<bufEnd) {
|
||||
ptr++;
|
||||
}
|
||||
if(*ptr==':') {
|
||||
currentLength=(int)(ptr-ret);
|
||||
ESP_LOGV(TAG, "Found parameter name end, length : %d", currentLength);
|
||||
// save the parameter name: the string between header name and ":"
|
||||
*parm_name=malloc(currentLength+1);
|
||||
if(*parm_name==NULL) {
|
||||
ESP_LOGE(TAG, "Unable to allocate memory for new header name");
|
||||
return NULL;
|
||||
}
|
||||
memset(*parm_name, 0x00,currentLength+1);
|
||||
strncpy(*parm_name,ret,currentLength);
|
||||
ESP_LOGV(TAG, "Found parameter name : %s ", *parm_name);
|
||||
ptr++;
|
||||
while (*ptr == ' ' && ptr<bufEnd) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
}
|
||||
ret=ptr;
|
||||
while (*ptr != '\0' && *ptr != '\n' && *ptr != '\r'&& ptr<bufEnd) {
|
||||
(*len)++;
|
||||
ptr++;
|
||||
}
|
||||
// Terminate value inside its actual buffer so we can treat it as individual string
|
||||
*ptr='\0';
|
||||
currentLength=(int)(ptr-ret);
|
||||
ESP_LOGV(TAG, "Found parameter value end, length : %d, value: %s", currentLength,ret );
|
||||
|
||||
*next_position=++ptr;
|
||||
return ret;
|
||||
}
|
||||
ESP_LOGD(TAG, "No more match for : %s", header_name);
|
||||
return NULL;
|
||||
}
|
||||
void http_server_send_resource_file(struct netconn *conn,const uint8_t * start, const uint8_t * end, char * content_type,char * encoding) {
|
||||
uint16_t len=end - start;
|
||||
size_t buff_length= sizeof(http_hdr_template)+strlen(content_type)+strlen(encoding);
|
||||
char * http_hdr=malloc(buff_length);
|
||||
if( http_hdr == NULL) {
|
||||
ESP_LOGE(TAG, "Cound not allocate %d bytes for headers.",buff_length);
|
||||
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(http_hdr,0x00,buff_length);
|
||||
snprintf(http_hdr, buff_length-1,http_hdr_template,content_type,len,encoding);
|
||||
netconn_write(conn, http_hdr, strlen(http_hdr), NETCONN_NOCOPY);
|
||||
ESP_LOGD(TAG, "sending response : %s",http_hdr);
|
||||
netconn_write(conn, start, end - start, NETCONN_NOCOPY);
|
||||
free(http_hdr);
|
||||
}
|
||||
}
|
||||
|
||||
err_t http_server_send_config_json(struct netconn *conn) {
|
||||
char * json = config_alloc_get_json(false);
|
||||
if(json!=NULL){
|
||||
ESP_LOGD(TAG, "config json : %s",json );
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY);
|
||||
netconn_write(conn, json, strlen(json), NETCONN_NOCOPY);
|
||||
free(json);
|
||||
}
|
||||
else{
|
||||
ESP_LOGD(TAG, "Error retrieving config json string. ");
|
||||
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void http_server_process_config(struct netconn *conn, char *inbuf) {
|
||||
|
||||
// Here, we are passed a buffer which contains the http request
|
||||
|
||||
// netbuf_data(inbuf, (void**)&buf, &buflen);
|
||||
// err = netconn_recv(conn, &inbuf);
|
||||
// if(err == ERR_OK) {
|
||||
//
|
||||
// /* extract the first line of the request */
|
||||
// char *save_ptr = buf;
|
||||
// char *line = strtok_r(save_ptr, new_line, &save_ptr);
|
||||
// ESP_LOGD(TAG, "Processing line %s",line);
|
||||
ESP_LOGD(TAG, "Processing request buffer: \n%s",inbuf);
|
||||
char *last = NULL;
|
||||
char *ptr = NULL;
|
||||
last = ptr = inbuf;
|
||||
bool bHeaders= true;
|
||||
while(ptr!=NULL && *ptr != '\0') {
|
||||
// Move to the end of the line, or to the end of the buffer
|
||||
if(bHeaders) {
|
||||
while (*ptr != '\0' && *ptr != '\n' && *ptr != '\r') {
|
||||
ptr++;
|
||||
}
|
||||
// terminate the header string
|
||||
if( *(ptr) == '\0' ) {
|
||||
ESP_LOGD(TAG, "End of buffer found");
|
||||
return;
|
||||
}
|
||||
*ptr = '\0';
|
||||
if( *(ptr+1) == '\n' ) {
|
||||
*(ptr+1)='\0';
|
||||
ptr+=2;
|
||||
}
|
||||
if(ptr==last) {
|
||||
ESP_LOGD(TAG, "Processing body. ");
|
||||
break;
|
||||
}
|
||||
if(strlen(last)>0) {
|
||||
ESP_LOGD(TAG, "Found Header Line %s ", last);
|
||||
//Content-Type: application/json
|
||||
}
|
||||
else {
|
||||
ESP_LOGD(TAG, "Found end of headers");
|
||||
bHeaders = false;
|
||||
}
|
||||
last=ptr;
|
||||
}
|
||||
else {
|
||||
//ESP_LOGD(TAG, "Body content: %s", last);
|
||||
//cJSON * json = cJSON_Parse(last);
|
||||
//cJSON_Delete(json);
|
||||
//todo: implement body json parsing
|
||||
// right now, body is coming as compressed, so we need some type of decompression to happen.
|
||||
return;
|
||||
}
|
||||
}
|
||||
return ;
|
||||
|
||||
}
|
||||
|
||||
void dump_net_buffer(void * buf, u16_t buflen) {
|
||||
char * curbuf = malloc(buflen+1);
|
||||
ESP_LOGV(TAG, "netconn buffer, length=%u",buflen);
|
||||
if(curbuf==NULL) {
|
||||
ESP_LOGE(TAG, "Unable to show netconn buffer. Malloc failed");
|
||||
}
|
||||
memset(curbuf,0x0, buflen+1);
|
||||
memcpy(curbuf,buf,buflen);
|
||||
ESP_LOGV(TAG, "netconn buffer content:\n%s",curbuf);
|
||||
free(curbuf);
|
||||
}
|
||||
|
||||
void http_server_netconn_serve(struct netconn *conn) {
|
||||
|
||||
struct netbuf *inbuf;
|
||||
char *buf = NULL;
|
||||
u16_t buflen = 0;
|
||||
err_t err;
|
||||
ip_addr_t remote_add;
|
||||
u16_t port;
|
||||
ESP_LOGV(TAG, "Serving page. Getting device AP address.");
|
||||
const char new_line[2] = "\n";
|
||||
char * ap_ip_address= config_alloc_get_default(NVS_TYPE_STR, "ap_ip_address", DEFAULT_AP_IP, 0);
|
||||
if(ap_ip_address==NULL){
|
||||
ESP_LOGE(TAG, "Unable to retrieve default AP IP Address");
|
||||
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
|
||||
netconn_close(conn);
|
||||
return;
|
||||
}
|
||||
ESP_LOGV(TAG, "Getting remote device IP address.");
|
||||
netconn_getaddr(conn, &remote_add, &port, 0);
|
||||
char * remote_address = strdup(ip4addr_ntoa(ip_2_ip4(&remote_add)));
|
||||
ESP_LOGD(TAG, "Local Access Point IP address is: %s. Remote device IP address is %s. Receiving request buffer", ap_ip_address, remote_address);
|
||||
|
||||
u16_t bufsize = 0;
|
||||
netconn_set_recvtimeout(conn, 50);
|
||||
while (netconn_recv(conn, &inbuf) == ERR_OK) {
|
||||
do {
|
||||
u8_t *rcvbuf;
|
||||
u16_t rcvlen;
|
||||
netbuf_data(inbuf, (void**)&rcvbuf, &rcvlen);
|
||||
dump_net_buffer(rcvbuf, rcvlen);
|
||||
if (buflen + rcvlen > bufsize) {
|
||||
bufsize += 2048;
|
||||
buf = realloc(buf, bufsize);
|
||||
}
|
||||
memcpy(buf + buflen, rcvbuf, rcvlen);
|
||||
buflen += rcvlen;
|
||||
ESP_LOGI(TAG, "received netbuf of %hu", rcvlen);
|
||||
} while (netbuf_next(inbuf) != -1);
|
||||
netbuf_delete(inbuf);
|
||||
}
|
||||
|
||||
if(buflen) {
|
||||
ESP_LOGV(TAG, "Getting data buffer.");
|
||||
int lenH = 0;
|
||||
/* extract the first line of the request */
|
||||
char *save_ptr = buf;
|
||||
char *line = strtok_r(save_ptr, new_line, &save_ptr);
|
||||
char *temphost = http_server_get_header(save_ptr, "Host: ", &lenH);
|
||||
char * host = malloc(lenH+1);
|
||||
memset(host,0x00,lenH+1);
|
||||
if(lenH>0){
|
||||
strlcpy(host,temphost,lenH+1);
|
||||
}
|
||||
ESP_LOGD(TAG, "http_server_netconn_serve Host: [%s], host: [%s], Processing line [%s]",remote_address,host,line);
|
||||
|
||||
if(line) {
|
||||
|
||||
/* captive portal functionality: redirect to access point IP for HOST that are not the access point IP OR the STA IP */
|
||||
const char * host_name=NULL;
|
||||
if((err=tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &host_name )) !=ESP_OK) {
|
||||
ESP_LOGE(TAG, "Unable to get host name. Error: %s",esp_err_to_name(err));
|
||||
}
|
||||
else {
|
||||
ESP_LOGI(TAG,"System host name %s, http requested host: %s.",host_name, host);
|
||||
}
|
||||
|
||||
/* determine if Host is from the STA IP address */
|
||||
wifi_manager_lock_sta_ip_string(portMAX_DELAY);
|
||||
bool access_from_sta_ip = lenH > 0?strcasestr(host, wifi_manager_get_sta_ip_string()):false;
|
||||
wifi_manager_unlock_sta_ip_string();
|
||||
bool access_from_host_name = (host_name!=NULL) && strcasestr(host,host_name);
|
||||
|
||||
if(lenH > 0 && !strcasestr(host, ap_ip_address) && !(access_from_sta_ip || access_from_host_name)) {
|
||||
ESP_LOGI(TAG, "Redirecting host [%s] to AP IP Address : %s",remote_address, ap_ip_address);
|
||||
netconn_write(conn, http_redirect_hdr_start, sizeof(http_redirect_hdr_start) - 1, NETCONN_NOCOPY);
|
||||
netconn_write(conn, ap_ip_address, strlen(ap_ip_address), NETCONN_NOCOPY);
|
||||
netconn_write(conn, http_redirect_hdr_end, sizeof(http_redirect_hdr_end) - 1, NETCONN_NOCOPY);
|
||||
}
|
||||
else {
|
||||
//static stuff
|
||||
/* default page */
|
||||
if(strstr(line, "GET / ")) {
|
||||
netconn_write(conn, http_html_hdr, sizeof(http_html_hdr) - 1, NETCONN_NOCOPY);
|
||||
netconn_write(conn, index_html_start, index_html_end- index_html_start, NETCONN_NOCOPY);
|
||||
}
|
||||
else if(strstr(line, "GET /code.js ")) {
|
||||
netconn_write(conn, http_js_hdr, sizeof(http_js_hdr) - 1, NETCONN_NOCOPY);
|
||||
netconn_write(conn, code_js_start, code_js_end - code_js_start, NETCONN_NOCOPY);
|
||||
}
|
||||
else if(strstr(line, "GET /style.css ")) {
|
||||
netconn_write(conn, http_css_hdr, sizeof(http_css_hdr) - 1, NETCONN_NOCOPY);
|
||||
netconn_write(conn, style_css_start, style_css_end - style_css_start, NETCONN_NOCOPY);
|
||||
}
|
||||
else if(strstr(line, "GET /jquery.js ")) {
|
||||
http_server_send_resource_file(conn,jquery_gz_start, jquery_gz_end, "text/javascript", "gzip" );
|
||||
}
|
||||
else if(strstr(line, "GET /popper.js ")) {
|
||||
http_server_send_resource_file(conn,popper_gz_start, popper_gz_end, "text/javascript", "gzip" );
|
||||
}
|
||||
else if(strstr(line, "GET /bootstrap.js ")) {
|
||||
http_server_send_resource_file(conn,bootstrap_js_gz_start, bootstrap_js_gz_end, "text/javascript", "gzip" );
|
||||
}
|
||||
else if(strstr(line, "GET /bootstrap.css ")) {
|
||||
http_server_send_resource_file(conn,bootstrap_css_gz_start, bootstrap_css_gz_end, "text/css", "gzip" );
|
||||
}
|
||||
|
||||
//dynamic stuff
|
||||
else if(strstr(line, "GET /scan.json ")) {
|
||||
ESP_LOGI(TAG, "Starting wifi scan");
|
||||
wifi_manager_scan_async();
|
||||
}
|
||||
else if(strstr(line, "GET /ap.json ")) {
|
||||
/* if we can get the mutex, write the last version of the AP list */
|
||||
ESP_LOGI(TAG, "Processing ap.json request");
|
||||
if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) {
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY);
|
||||
char *buff = wifi_manager_alloc_get_ap_list_json();
|
||||
wifi_manager_unlock_json_buffer();
|
||||
if(buff!=NULL){
|
||||
netconn_write(conn, buff, strlen(buff), NETCONN_NOCOPY);
|
||||
free(buff);
|
||||
}
|
||||
else {
|
||||
ESP_LOGD(TAG, "Error retrieving ap list json string. ");
|
||||
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
|
||||
ESP_LOGE(TAG, "http_server_netconn_serve: GET /ap.json failed to obtain mutex");
|
||||
}
|
||||
/* request a wifi scan */
|
||||
ESP_LOGI(TAG, "Starting wifi scan");
|
||||
wifi_manager_scan_async();
|
||||
ESP_LOGI(TAG, "Done serving ap.json");
|
||||
}
|
||||
else if(strstr(line, "GET /config.json ")) {
|
||||
ESP_LOGI(TAG, "Serving config.json");
|
||||
ESP_LOGI(TAG, "About to get config from flash");
|
||||
http_server_send_config_json(conn);
|
||||
ESP_LOGD(TAG, "Done serving config.json");
|
||||
}
|
||||
else if(strstr(line, "POST /config.json ")) {
|
||||
ESP_LOGI(TAG, "Serving POST config.json");
|
||||
int lenA=0;
|
||||
char * last_parm=save_ptr;
|
||||
char * next_parm=save_ptr;
|
||||
char * last_parm_name=NULL;
|
||||
bool bErrorFound=false;
|
||||
bool bOTA=false;
|
||||
char * otaURL=NULL;
|
||||
// todo: implement json body parsing
|
||||
//http_server_process_config(conn,save_ptr);
|
||||
|
||||
while(last_parm!=NULL) {
|
||||
// Search will return
|
||||
ESP_LOGD(TAG, "Getting parameters from X-Custom headers");
|
||||
last_parm = http_server_search_header(next_parm, "X-Custom-", &lenA, &last_parm_name,&next_parm,buf+buflen);
|
||||
if(last_parm!=NULL && last_parm_name!=NULL) {
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: POST config.json, config %s=%s", last_parm_name, last_parm);
|
||||
if(strcmp(last_parm_name, "fwurl")==0) {
|
||||
// we're getting a request to do an OTA from that URL
|
||||
ESP_LOGW(TAG, "Found OTA request!");
|
||||
otaURL=strdup(last_parm);
|
||||
bOTA=true;
|
||||
}
|
||||
else {
|
||||
ESP_LOGV(TAG, "http_server_netconn_serve: POST config.json Storing parameter");
|
||||
if(config_set_value(NVS_TYPE_STR, last_parm_name , last_parm) != ESP_OK){
|
||||
ESP_LOGE(TAG, "Unable to save nvs value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(last_parm_name!=NULL) {
|
||||
free(last_parm_name);
|
||||
last_parm_name=NULL;
|
||||
}
|
||||
}
|
||||
if(bErrorFound) {
|
||||
netconn_write(conn, http_400_hdr, sizeof(http_400_hdr) - 1, NETCONN_NOCOPY); //400 invalid request
|
||||
}
|
||||
else {
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); //200ok
|
||||
if(bOTA) {
|
||||
|
||||
#if RECOVERY_APPLICATION
|
||||
ESP_LOGW(TAG, "Starting process OTA for url %s",otaURL);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Restarting system to process OTA for url %s",otaURL);
|
||||
#endif
|
||||
wifi_manager_reboot_ota(otaURL);
|
||||
free(otaURL);
|
||||
}
|
||||
}
|
||||
ESP_LOGI(TAG, "Done Serving POST config.json");
|
||||
}
|
||||
else if(strstr(line, "POST /connect.json ")) {
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: POST /connect.json");
|
||||
bool found = false;
|
||||
int lenS = 0, lenP = 0, lenN = 0;
|
||||
char *ssid = NULL, *password = NULL;
|
||||
ssid = http_server_get_header(save_ptr, "X-Custom-ssid: ", &lenS);
|
||||
password = http_server_get_header(save_ptr, "X-Custom-pwd: ", &lenP);
|
||||
char * new_host_name_b = http_server_get_header(save_ptr, "X-Custom-host_name: ", &lenN);
|
||||
if(lenN > 0){
|
||||
lenN++;
|
||||
char * new_host_name = malloc(lenN);
|
||||
strlcpy(new_host_name, new_host_name_b, lenN);
|
||||
if(config_set_value(NVS_TYPE_STR, "host_name", new_host_name) != ESP_OK){
|
||||
ESP_LOGE(TAG, "Unable to save host name configuration");
|
||||
}
|
||||
free(new_host_name);
|
||||
}
|
||||
|
||||
if(ssid && lenS <= MAX_SSID_SIZE && password && lenP <= MAX_PASSWORD_SIZE) {
|
||||
wifi_config_t* config = wifi_manager_get_wifi_sta_config();
|
||||
memset(config, 0x00, sizeof(wifi_config_t));
|
||||
memcpy(config->sta.ssid, ssid, lenS);
|
||||
memcpy(config->sta.password, password, lenP);
|
||||
ESP_LOGD(TAG, "http_server_netconn_serve: wifi_manager_connect_async() call, with ssid: %s, password: %s", config->sta.ssid, config->sta.password);
|
||||
wifi_manager_connect_async();
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); //200ok
|
||||
found = true;
|
||||
}
|
||||
else{
|
||||
ESP_LOGE(TAG, "SSID or Password invalid");
|
||||
}
|
||||
|
||||
|
||||
if(!found) {
|
||||
/* bad request the authentification header is not complete/not the correct format */
|
||||
netconn_write(conn, http_400_hdr, sizeof(http_400_hdr) - 1, NETCONN_NOCOPY);
|
||||
ESP_LOGE(TAG, "bad request the authentification header is not complete/not the correct format");
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: done serving connect.json");
|
||||
}
|
||||
else if(strstr(line, "DELETE /connect.json ")) {
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: DELETE /connect.json");
|
||||
/* request a disconnection from wifi and forget about it */
|
||||
wifi_manager_disconnect_async();
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: done serving DELETE /connect.json");
|
||||
}
|
||||
else if(strstr(line, "POST /reboot_ota.json ")) {
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: POST reboot_ota.json");
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
|
||||
wifi_manager_reboot(OTA);
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST reboot_ota.json");
|
||||
}
|
||||
else if(strstr(line, "POST /reboot.json ")) {
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: POST reboot.json");
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
|
||||
wifi_manager_reboot(RESTART);
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST reboot.json");
|
||||
}
|
||||
else if(strstr(line, "POST /recovery.json ")) {
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: POST recovery.json");
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
|
||||
wifi_manager_reboot(RECOVERY);
|
||||
ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST recovery.json");
|
||||
}
|
||||
else if(strstr(line, "GET /status.json ")) {
|
||||
ESP_LOGI(TAG, "Serving status.json");
|
||||
if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) {
|
||||
char *buff = wifi_manager_alloc_get_ip_info_json();
|
||||
wifi_manager_unlock_json_buffer();
|
||||
if(buff) {
|
||||
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY);
|
||||
netconn_write(conn, buff, strlen(buff), NETCONN_NOCOPY);
|
||||
free(buff);
|
||||
}
|
||||
else {
|
||||
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
|
||||
ESP_LOGE(TAG, "http_server_netconn_serve: GET /status failed to obtain mutex");
|
||||
}
|
||||
ESP_LOGI(TAG, "Done Serving status.json");
|
||||
}
|
||||
else {
|
||||
netconn_write(conn, http_400_hdr, sizeof(http_400_hdr) - 1, NETCONN_NOCOPY);
|
||||
ESP_LOGE(TAG, "bad request from host: %s, request %s",remote_address, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, "URL not found processing for remote host : %s",remote_address);
|
||||
netconn_write(conn, http_404_hdr, sizeof(http_404_hdr) - 1, NETCONN_NOCOPY);
|
||||
}
|
||||
free(host);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
free(ap_ip_address);
|
||||
free(remote_address);
|
||||
netconn_close(conn);
|
||||
/* free the buffer */
|
||||
|
||||
}
|
||||
|
||||
bool http_server_lock_json_object(TickType_t xTicksToWait) {
|
||||
ESP_LOGD(TAG, "Locking config json object");
|
||||
if(http_server_config_mutex) {
|
||||
if( xSemaphoreTake( http_server_config_mutex, xTicksToWait ) == pdTRUE ) {
|
||||
ESP_LOGV(TAG, "config Json object locked!");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
ESP_LOGW(TAG, "Semaphore take failed. Unable to lock config Json object mutex");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ESP_LOGW(TAG, "Unable to lock config Json object mutex");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void http_server_unlock_json_object() {
|
||||
ESP_LOGD(TAG, "Unlocking json buffer!");
|
||||
xSemaphoreGive( http_server_config_mutex );
|
||||
}
|
||||
|
||||
void strreplace(char *src, char *str, char *rep)
|
||||
{
|
||||
char *p = strstr(src, str);
|
||||
if(p)
|
||||
{
|
||||
int len = strlen(src)+strlen(rep)-strlen(str);
|
||||
char r[len];
|
||||
memset(r, 0, len);
|
||||
if( p >= src ) {
|
||||
strncpy(r, src, p-src);
|
||||
r[p-src]='\0';
|
||||
strncat(r, rep, strlen(rep));
|
||||
strncat(r, p+strlen(str), p+strlen(str)-src+strlen(src));
|
||||
strcpy(src, r);
|
||||
strreplace(p+strlen(rep), str, rep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,10 +708,12 @@ esp_err_t recovery_post_handler(httpd_req_t *req){
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool is_captive_portal_host_name(http_req_t *req){
|
||||
bool is_captive_portal_host_name(httpd_req_t *req){
|
||||
const char * host_name=NULL;
|
||||
const char * ap_host_name=NULL;
|
||||
|
||||
char * ap_ip_address=NULL;
|
||||
bool request_contains_hostname = false;
|
||||
esp_err_t hn_err =ESP_OK, err=ESP_OK;
|
||||
ESP_LOGD_LOC(TAG, "Getting adapter host name");
|
||||
if((err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &host_name )) !=ESP_OK) {
|
||||
ESP_LOGE_LOC(TAG, "Unable to get host name. Error: %s",esp_err_to_name(err));
|
||||
@@ -723,10 +725,6 @@ bool is_captive_portal_host_name(http_req_t *req){
|
||||
ESP_LOGD_LOC(TAG, "Getting host name from request");
|
||||
char *req_host = alloc_get_http_header(req, "Host");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(tcpip_adapter_is_netif_up(TCPIP_ADAPTER_IF_AP)){
|
||||
ESP_LOGD_LOC(TAG, "Soft AP is enabled. getting ip info");
|
||||
// Access point is up and running. Get the current IP address
|
||||
@@ -757,23 +755,6 @@ bool is_captive_portal_host_name(http_req_t *req){
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if((request_contains_hostname = (host_name!=NULL) && (req_host!=NULL) && strcasestr(req_host,host_name)) == true){
|
||||
ESP_LOGD_LOC(TAG,"http request host = system host name %s", req_host);
|
||||
}
|
||||
@@ -781,9 +762,10 @@ bool is_captive_portal_host_name(http_req_t *req){
|
||||
ESP_LOGD_LOC(TAG,"http request host = AP system host name %s", req_host);
|
||||
}
|
||||
|
||||
FREE_AND_NULL(ap_ip_address);
|
||||
FREE_AND_NULL(req_host);
|
||||
|
||||
|
||||
return request_contains_hostname;
|
||||
}
|
||||
esp_err_t redirect_200_ev_handler(httpd_req_t *req){
|
||||
esp_err_t err=ESP_OK;
|
||||
|
||||
@@ -24,6 +24,47 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="info">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="jack" width="24" height="24" viewBox="0 0 24 24">
|
||||
<g id="o_jack" display="none">
|
||||
<path d="m 16.074253,15.636738 v -1.05413 h 5.893274 c 1.16249,0 2.108261,-0.855111 2.108261,-1.906183 0,-1.051073 -0.945771,-1.906236 -2.108261,-1.906236 H 16.074253 V 9.7160604 c 0,-0.5812492 -0.472879,-1.0541321 -1.054131,-1.0541321 H 6.7847349 c -1.256731,0 -2.301908,0.9212057 -2.496867,2.1237027 h -0.451896 c -0.540407,0 -1.001317,0.349129 -1.173459,0.835611 H 0.47312787 c -0.23285,0 -0.42164599,0.188794 -0.42164599,0.421651 v 1.251779 c 0,0.232857 0.18879599,0.421652 0.42164599,0.421652 H 2.6550809 c 0.165919,0.497866 0.632365,0.857588 1.180831,0.857588 h 0.45312 c 0.19781,1.199177 1.241345,2.116956 2.495659,2.116956 h 8.2353861 c 0.581297,0 1.054176,-0.472883 1.054176,-1.05413 z m 5.060935,-4.023245 v 2.125811 h -0.844935 v -2.125811 z m 2.097293,1.062932 c 0,0.582933 -0.561524,1.057661 -1.253986,1.062668 v -2.125337 c 0.692462,0.0049 1.253986,0.47963 1.253986,1.062669 z m -3.785535,-1.062932 v 2.125811 h -3.372693 v -2.125811 z m -18.55215712,0.851 H 2.5901939 v 0.408475 H 0.89478888 Z m 2.94118302,1.266114 c -0.221897,0 -0.40247,-0.185737 -0.40247,-0.414062 v -1.273547 c 0,-0.228271 0.180573,-0.41401 0.40247,-0.41401 h 0.418855 v 2.101671 h -0.418855 z m 2.948763,2.116956 c -0.929997,0 -1.6866,-0.756601 -1.6866,-1.686608 v -0.0087 -2.944976 -0.01545 c 0,-0.930006 0.756603,-1.6866072 1.6866,-1.6866072 h 8.2353871 c 0.114313,0 0.210838,0.096554 0.210838,0.2108266 v 5.9206786 c 0,0.114268 -0.09656,0.210824 -0.210838,0.210824 z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="output" width="24" height="24" viewBox="0 0 24 24">
|
||||
<g id="o_i2s" display="none">
|
||||
<path d="M2 7L2 8L2 9L2 10L2 11L2 12L2 13L2 14L2 15L2 16L2 17L3 17L3 16L3 15L3 14L3 13L3 12L3 11L3 10L3 9L3 8L2 7M6 7L6 8L6 9L7 9L7 8L8 8L9 8L10 8L10 9L11 9L11 10L11 11L10 11L10 12L9 12L9 13L8 13L8 14L7 14L7 15L6 15L6 16L6 17L7 17L8 17L9 17L10 17L11 17L12 17L12 16L11 16L10 16L9 16L8 16L8 15L9 15L9 14L10 14L10 13L11 13L11 12L12 12L12 11L12 10L12 9L12 8L11 8L11 7L10 7L9 7L8 7L6 7M16 7L16 8L15 8L15 9L15 10L15 11L16 11L16 12L17 12L18 12L18 13L19 13L20 13L21 13L21 14L21 15L20 15L20 16L19 16L18 16L17 16L16 16L16 15L15 15L15 16L15 17L16 17L17 17L18 17L19 17L20 17L21 17L21 16L22 16L22 15L22 14L22 13L21 13L21 12L20 12L20 11L19 11L18 11L17 11L16 11L16 10L16 9L17 9L17 8L18 8L19 8L20 8L21 8L21 9L22 9L22 8L22 7L21 7L20 7L19 7L18 7L16 7z"/>
|
||||
</g>
|
||||
<g id="o_bt" display="none">
|
||||
<path d="M3 7L3 8L3 9L3 10L3 11L3 12L3 13L3 14L3 15L3 16L3 17L4 17L5 17L6 17L7 17L8 17L9 17L9 16L10 16L10 15L10 14L10 13L10 12L9 12L9 11L10 11L10 10L10 9L10 8L9 8L9 7L8 7L7 7L6 7L5 7L3 7M12 7L12 8L13 8L14 8L15 8L16 8L16 9L16 10L16 11L16 12L16 13L16 14L16 15L16 16L16 17L17 17L17 16L17 15L17 14L17 13L17 12L17 11L17 10L17 9L17 8L18 8L19 8L20 8L21 8L21 7L20 7L19 7L18 7L17 7L16 7L15 7L14 7L12 7z"/>
|
||||
<path style="fill:#272B30;" d="M4 8L4 9L4 10L4 11L5 11L6 11L7 11L8 11L8 10L9 10L9 9L9 8L8 8L7 8L6 8L4 8M4 12L4 13L4 14L4 15L4 16L5 16L6 16L7 16L8 16L8 15L9 15L9 14L9 13L8 13L8 12L7 12L6 12L4 12z"/>
|
||||
</g>
|
||||
<g id="o_spdif" display="none">
|
||||
<path d="M3 1L3 2L2 2L2 3L2 4L2 5L3 5L3 6L4 6L5 6L5 7L6 7L7 7L8 7L8 8L8 9L7 9L7 10L6 10L5 10L4 10L3 10L3 9L2 9L2 10L2 11L3 11L4 11L5 11L6 11L7 11L8 11L8 10L9 10L9 9L9 8L9 7L8 7L8 6L7 6L7 5L6 5L5 5L4 5L3 5L3 4L3 3L4 3L4 2L5 2L6 2L7 2L8 2L8 3L9 3L9 2L9 1L8 1L7 1L6 1L5 1L3 1M13 1L13 2L13 3L13 4L12 4L12 5L12 6L12 7L12 8L11 8L11 9L11 10L11 11L10 11L10 12L10 13L11 13L11 12L11 11L12 11L12 10L12 9L12 8L13 8L13 7L13 6L13 5L14 5L14 4L14 3L14 2L15 2L15 1L13 1M16 1L16 2L16 3L16 4L16 5L16 6L16 7L16 8L16 9L16 10L16 11L17 11L17 10L17 9L17 8L17 7L18 7L19 7L20 7L21 7L21 6L22 6L22 5L22 4L22 3L22 2L21 2L21 1L20 1L19 1L18 1L16 1z"/>
|
||||
<path style="fill:#272B30;" d="M17 2L17 3L17 4L17 5L17 6L18 6L19 6L20 6L20 5L21 5L21 4L21 3L20 3L20 2L19 2L17 2z"/>
|
||||
<path d="M2 13L2 14L2 15L2 16L2 17L2 18L2 19L2 20L2 21L2 22L2 23L3 23L4 23L5 23L6 23L7 23L8 23L8 22L9 22L9 21L10 21L10 20L10 19L10 18L10 17L10 16L10 15L9 15L9 14L8 14L7 14L7 13L6 13L5 13L4 13L2 13M13 13L13 14L13 15L13 16L13 17L13 18L13 19L13 20L13 21L13 22L13 23L14 23L14 22L14 21L14 20L14 19L14 18L14 17L14 16L14 15L14 14L13 13M17 13L17 14L17 15L17 16L17 17L17 18L17 19L17 20L17 21L17 22L17 23L18 23L18 22L18 21L18 20L18 19L18 18L19 18L20 18L21 18L22 18L22 17L21 17L20 17L19 17L18 17L18 16L18 15L18 14L19 14L20 14L21 14L22 14L22 13L21 13L20 13L19 13L17 13z"/>
|
||||
<path style="fill:#272B30;" d="M3 14L3 15L3 16L3 17L3 18L3 19L3 20L3 21L3 22L4 22L5 22L6 22L7 22L7 21L8 21L8 20L9 20L9 19L9 18L9 17L9 16L8 16L8 15L7 15L7 14L6 14L5 14L3 14z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="battery" width="24" height="24" viewBox="0 0 24 24">
|
||||
<g id="bat0" display="none">
|
||||
<path d="M19 8v8h-17v-8h17zm2-2h-21v12h21v-12zm1 9h.75c.69 0 1.25-.56 1.25-1.25v-3.5c0-.69-.56-1.25-1.25-1.25h-.75v6z"/>
|
||||
</g>
|
||||
<g id="bat1" display="none">
|
||||
<path d="M19 8v8h-17v-8h17zm2-2h-21v12h21v-12zm1 9h.75c.69 0 1.25-.56 1.25-1.25v-3.5c0-.69-.56-1.25-1.25-1.25h-.75v6zm-16-6h-3v6h3v-6z"/>
|
||||
</g>
|
||||
<g id="bat2" display="none">
|
||||
<path d="M19 8v8h-17v-8h17zm2-2h-21v12h21v-12zm1 9h.75c.69 0 1.25-.56 1.25-1.25v-3.5c0-.69-.56-1.25-1.25-1.25h-.75v6zm-16-6h-3v6h3v-6zm4 0h-3v6h3v-6z"/>
|
||||
</g>
|
||||
<g id="bat3" display="none">
|
||||
<path d="M19 8v8h-17v-8h17zm2-2h-21v12h21v-12zm1 9h.75c.69 0 1.25-.56 1.25-1.25v-3.5c0-.69-.56-1.25-1.25-1.25h-.75v6zm-16-6h-3v6h3v-6zm4 0h-3v6h3v-6zm4 0h-3v6h3v-6z"/>
|
||||
</g>
|
||||
<g id="bat4" display="none">
|
||||
<path d="M19 8v8h-17v-8h17zm2-2h-21v12h21v-12zm1 9h.75c.69 0 1.25-.56 1.25-1.25v-3.5c0-.69-.56-1.25-1.25-1.25h-.75v6zm-16-6h-3v6h3v-6zm4 0h-3v6h3v-6zm4 0h-3v6h3v-6zm4 0h-3v6h3v-6z"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<ul id="navbar" class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="tab" href="#tab-wifi">WiFi</a>
|
||||
|
||||
@@ -308,6 +308,33 @@ span#flash-status {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
#info {
|
||||
padding-top: 7px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
svg#battery {
|
||||
fill: #ddd;
|
||||
}
|
||||
|
||||
svg#output {
|
||||
fill: #ddd;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
svg#jack {
|
||||
fill: #ddd;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
ul#navbar {
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
||||
#content {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
@@ -335,6 +362,7 @@ td.value {
|
||||
|
||||
iframe#dummyframe {
|
||||
float: right;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div#message {
|
||||
|
||||
@@ -59,10 +59,12 @@ Contains the freeRTOS task and all necessary support
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/adc.h"
|
||||
#include "cJSON.h"
|
||||
#include "nvs_utilities.h"
|
||||
#include "config.h"
|
||||
#include "trace.h"
|
||||
#include "cmd_system.h"
|
||||
#include "http_server_handlers.h"
|
||||
|
||||
#include "http_server_handlers.h"
|
||||
#include "monitor.h"
|
||||
|
||||
#ifndef RECOVERY_APPLICATION
|
||||
#define RECOVERY_APPLICATION 0
|
||||
@@ -71,12 +73,7 @@ Contains the freeRTOS task and all necessary support
|
||||
#ifndef SQUEEZELITE_ESP32_RELEASE_URL
|
||||
#define SQUEEZELITE_ESP32_RELEASE_URL "https://github.com/sle118/squeezelite-esp32/releases"
|
||||
#endif
|
||||
#ifdef TAS57xx
|
||||
#define JACK_GPIO 34
|
||||
#define JACK_LEVEL !gpio_get_level(JACK_GPIO)?"1":"0";
|
||||
#else
|
||||
#define JACK_LEVEL "N/A"
|
||||
#endif
|
||||
|
||||
#define STR_OR_BLANK(p) p==NULL?"":p
|
||||
#define FREE_AND_NULL(p) if(p!=NULL){ free(p); p=NULL;}
|
||||
/* objects used to manipulate the main queue of events */
|
||||
@@ -456,7 +453,7 @@ cJSON * wifi_manager_get_basic_info(cJSON **old){
|
||||
cJSON_AddNumberToObject(root,"recovery", RECOVERY_APPLICATION );
|
||||
cJSON_AddItemToObject(root, "ota_dsc", cJSON_CreateString(ota_get_status()));
|
||||
cJSON_AddNumberToObject(root,"ota_pct", ota_get_pct_complete() );
|
||||
cJSON_AddItemToObject(root, "Jack", cJSON_CreateString(JACK_LEVEL));
|
||||
cJSON_AddItemToObject(root, "Jack", cJSON_CreateString(jack_inserted_svc() ? "1" : "0"));
|
||||
cJSON_AddNumberToObject(root,"Voltage", adc1_get_raw(ADC1_CHANNEL_7) / 4095. * (10+174)/10. * 1.1);
|
||||
cJSON_AddNumberToObject(root,"disconnect_count", num_disconnect );
|
||||
cJSON_AddNumberToObject(root,"avg_conn_time", num_disconnect>0?(total_connected_time/num_disconnect):0 );
|
||||
|
||||
Reference in New Issue
Block a user