diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7bdfeea..e487e7c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,4 +3,4 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
-project(irblaster)
+project(fanctl)
diff --git a/DECODED.txt b/DECODED.txt
deleted file mode 100644
index ef7b5d4..0000000
--- a/DECODED.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-hum1 10000000 01111111 00010000 11101111 1
-hum2 10000000 01111111 01010000 10101111 1
-hum3 10000000 01111111 10010000 01101111 1
-mode1 10000000 01111111 00011000 11100111 1
-mode2 10000000 01111111 10011000 01100111 1
-mode3 10000000 01111111 00001000 11110111 1
-mode4 10000000 01111111 10001000 01110111 1
-night 10000000 01111111 10000000 01111111 1
-power 10000000 01111111 00000000 11111111 1
-speed1 10000000 01111111 10101000 01010111 1
-speed2 10000000 01111111 01101000 10010111 1
-speed3 10000000 01111111 00101000 11010111 1
-
-Format:
-
-38.5kHz
-
-Preamble: 9ms transmit, 4.5ms gap
-Zero: 600us transmit, 600us gap.
-One: 600us transmit, 1.7ms gap
diff --git a/Makefile b/Makefile
index 5108515..08f87c8 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,6 @@
# project subdirectory.
#
-PROJECT_NAME := hello-world
+PROJECT_NAME := fanctl
include $(IDF_PATH)/make/project.mk
diff --git a/components/fileserver/CMakeLists.txt b/components/fileserver/CMakeLists.txt
deleted file mode 100644
index 0d00082..0000000
--- a/components/fileserver/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-set(COMPONENT_ADD_INCLUDEDIRS
- "include" "files")
-
-set(COMPONENT_SRCDIRS
- "src" "files")
-
-set(COMPONENT_REQUIRES tcpip_adapter esp_http_server httpd_utils common_utils)
-
-#begin staticfiles
-# generated by rebuild_file_tables
-set(COMPONENT_EMBED_FILES
- "files/embed/favicon.ico"
- "files/embed/index.html")
-#end staticfiles
-
-register_component()
diff --git a/components/fileserver/README.txt b/components/fileserver/README.txt
deleted file mode 100644
index 588ad42..0000000
--- a/components/fileserver/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-File and template serving support for the http_server bundled with ESP-IDF.
-
diff --git a/components/fileserver/component.mk b/components/fileserver/component.mk
deleted file mode 100644
index 87ae05a..0000000
--- a/components/fileserver/component.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-
-COMPONENT_SRCDIRS := src
-COMPONENT_ADD_INCLUDEDIRS := include
diff --git a/components/fileserver/files/embed/favicon.ico b/components/fileserver/files/embed/favicon.ico
deleted file mode 100644
index 0bd5a51..0000000
Binary files a/components/fileserver/files/embed/favicon.ico and /dev/null differ
diff --git a/components/fileserver/files/embed/index.html b/components/fileserver/files/embed/index.html
deleted file mode 100644
index d9138bd..0000000
--- a/components/fileserver/files/embed/index.html
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
-
-ESP node
-
-
-
-ESP node {version}
-
-IR blaster
-
-Restart node
-
-
diff --git a/components/fileserver/files/rebuild_file_tables.php b/components/fileserver/files/rebuild_file_tables.php
deleted file mode 100755
index b0018e2..0000000
--- a/components/fileserver/files/rebuild_file_tables.php
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env php
- 'text/plain',
- 'htm' => 'text/html',
- 'html' => 'text/html',
- 'php' => 'text/html',
- 'css' => 'text/css',
- 'js' => 'application/javascript',
- 'json' => 'application/json',
- 'xml' => 'application/xml',
- 'swf' => 'application/x-shockwave-flash',
- 'flv' => 'video/x-flv',
-
- 'pem' => 'application/x-pem-file',
-
- // images
- 'png' => 'image/png',
- 'jpe' => 'image/jpeg',
- 'jpeg' => 'image/jpeg',
- 'jpg' => 'image/jpeg',
- 'gif' => 'image/gif',
- 'bmp' => 'image/bmp',
- 'ico' => 'image/vnd.microsoft.icon',
- 'tiff' => 'image/tiff',
- 'tif' => 'image/tiff',
- 'svg' => 'image/svg+xml',
- 'svgz' => 'image/svg+xml',
-
- // archives
- 'zip' => 'application/zip',
- 'rar' => 'application/x-rar-compressed',
- 'exe' => 'application/x-msdownload',
- 'msi' => 'application/x-msdownload',
- 'cab' => 'application/vnd.ms-cab-compressed',
-
- // audio/video
- 'mp3' => 'audio/mpeg',
- 'qt' => 'video/quicktime',
- 'mov' => 'video/quicktime',
-
- // adobe
- 'pdf' => 'application/pdf',
- 'psd' => 'image/vnd.adobe.photoshop',
- 'ai' => 'application/postscript',
- 'eps' => 'application/postscript',
- 'ps' => 'application/postscript',
-
- // ms office
- 'doc' => 'application/msword',
- 'rtf' => 'application/rtf',
- 'xls' => 'application/vnd.ms-excel',
- 'ppt' => 'application/vnd.ms-powerpoint',
-
- // open office
- 'odt' => 'application/vnd.oasis.opendocument.text',
- 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
- );
-
- $parts = explode('.', $f);
- $suffix = end($parts);
- $mime = $mimes[$suffix] ?? 'application/octet-stream';
-
- $len = filesize('embed/'.$f);
-
- $struct_array[] = "[FILE_$a] = {{$start}, {$end}, \"{$f}\", \"{$mime}\"},";
-
- return
- 'extern const uint8_t '.$start.'[];'."\n".
- 'extern const uint8_t '.$end.'[];';
-}, $files);
-
-$externlist = implode("\n", $externs);
-$structlist = implode("\n ", $struct_array);
-
-
-file_put_contents('www_files_enum.h', <<
-#include "www_files_enum.h"
-
-$externlist
-
-const struct embedded_file_info EMBEDDED_FILE_LOOKUP[] = {
- $structlist
-};
-
-const size_t EMBEDDED_FILE_LOOKUP_LEN = $files_count;
-
-FILE
-);
diff --git a/components/fileserver/files/www_files_enum.c b/components/fileserver/files/www_files_enum.c
deleted file mode 100644
index 86b8421..0000000
--- a/components/fileserver/files/www_files_enum.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// Generated by 'rebuild_file_tables'
-#include
-#include "www_files_enum.h"
-
-extern const uint8_t _binary_favicon_ico_start[];
-extern const uint8_t _binary_favicon_ico_end[];
-extern const uint8_t _binary_index_html_start[];
-extern const uint8_t _binary_index_html_end[];
-
-const struct embedded_file_info EMBEDDED_FILE_LOOKUP[] = {
- [FILE_FAVICON_ICO] = {_binary_favicon_ico_start, _binary_favicon_ico_end, "favicon.ico", "image/vnd.microsoft.icon"},
- [FILE_INDEX_HTML] = {_binary_index_html_start, _binary_index_html_end, "index.html", "text/html"},
-};
-
-const size_t EMBEDDED_FILE_LOOKUP_LEN = 2;
diff --git a/components/fileserver/files/www_files_enum.h b/components/fileserver/files/www_files_enum.h
deleted file mode 100644
index b81113b..0000000
--- a/components/fileserver/files/www_files_enum.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Generated by 'rebuild_file_tables'
-
-#ifndef _EMBEDDED_FILES_ENUM_H
-#define _EMBEDDED_FILES_ENUM_H
-
-#include "fileserver/embedded_files.h"
-
-enum embedded_file_id {
- FILE_FAVICON_ICO = 0,
- FILE_INDEX_HTML = 1
-};
-
-#endif // _EMBEDDED_FILES_ENUM_H
diff --git a/components/fileserver/include/fileserver/embedded_files.h b/components/fileserver/include/fileserver/embedded_files.h
deleted file mode 100644
index a86f8ae..0000000
--- a/components/fileserver/include/fileserver/embedded_files.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Created on 2018/10/17 by Ondrej Hruska
-//
-
-#ifndef FBNODE_EMBEDDED_FILES_H
-#define FBNODE_EMBEDDED_FILES_H
-
-#include
-#include
-#include
-
-struct embedded_file_info {
- const uint8_t * start;
- const uint8_t * end;
- const char * name;
- const char * mime;
-};
-
-enum file_access_level {
- /** Public = file accessed by a wildcard route */
- FILE_ACCESS_PUBLIC = 0,
- /** Protected = file included in a template or explicitly specified in a route */
- FILE_ACCESS_PROTECTED = 1,
- /** Files protected against read-out */
- FILE_ACCESS_PRIVATE = 2,
-};
-
-extern const struct embedded_file_info EMBEDDED_FILE_LOOKUP[];
-extern const size_t EMBEDDED_FILE_LOOKUP_LEN;
-
-/**
- * Find an embedded file by its name.
- *
- * This function is weak. It crawls the EMBEDDED_FILE_LOOKUP table and checks for exact match, also
- * testing with www_get_static_file_access_check if the access is allowed.
- *
- * @param name - file name
- * @param access - access level (public - wildcard fallthrough, protected - files for the server, loaded explicitly)
- * @param[out] file - the file struct is stored here if found, unchanged if not found.
- * @return status code
- */
-esp_err_t www_get_static_file(const char *name, enum file_access_level access, const struct embedded_file_info **file);
-
-/**
- * Check file access permission (if using the default www_get_static_file implementation).
- *
- * This function is weak. The default implementation returns always true.
- */
-bool www_get_static_file_access_check(const struct embedded_file_info *file, enum file_access_level access);
-
-#endif //FBNODE_EMBEDDED_FILES_H
diff --git a/components/fileserver/include/fileserver/token_subs.h b/components/fileserver/include/fileserver/token_subs.h
deleted file mode 100644
index 1e396b4..0000000
--- a/components/fileserver/include/fileserver/token_subs.h
+++ /dev/null
@@ -1,216 +0,0 @@
-//
-// This module implements token substitution in files served by the server.
-//
-// Tokens are in the form {token}, or {escape:token}, where escape can be:
-// - h ... html escape (plain text in a html file, attribute value)
-// - j ... js escape (for use in JS strings)
-//
-// When no escape is specified, the token substitution is written verbatim into the response.
-//
-// var foo = "{j:foo}";
-//
-// {generated-html-goes-here}
-//
-// Token can be made optional by adding '?' at the end (this can't be used for includes).
-// Such token then simply becomes empty string when not substituted, as opposed to being included in the page verbatim.
-//
-//
-//
-// token names can contain alnum, dash, period and underscore, and are case sensitive.
-//
-//
-// It is further possible to include a static file with optional key-value replacements. These serve as defaults.
-//
-// {@_subfile.html}
-// {@_subfile.html|key=value lalala}
-// {@_subfile.html|key=value lalala|other=value}
-//
-// File inclusion can be nested, and the files can use replacement tokens as specified by the include statement
-//
-// Created on 2019/01/24 by Ondrej Hruska
-//
-
-#ifndef FBNODE_TOKEN_SUBS_H
-#define FBNODE_TOKEN_SUBS_H
-
-#include "embedded_files.h"
-#include
-#include
-#include
-
-/** Max length of a token buffer (must suffice for all included filenames) */
-#define MAX_TOKEN_LEN 32
-
-/** Max length of a key-value substitution when using tpl_kv_replacer;
- * This is also used internally for in-line replacements in file imports. */
-#define TPL_KV_KEY_LEN 24
-/** Max length of a substituion in tpl_kv_replacer */
-#define TPL_KV_SUBST_LEN 64
-
-/**
- * Escape type - argument for httpd_resp_send_chunk_escaped()
- */
-typedef enum {
- TPL_ESCAPE_NONE = 0,
- TPL_ESCAPE_HTML,
- TPL_ESCAPE_JS,
-} tpl_escape_t;
-
-enum {
- HTOPT_NONE = 0,
- HTOPT_NO_HEADERS = 1 << 0,
- HTOPT_NO_CLOSE = 1 << 1,
- HTOPT_INCLUDE = HTOPT_NO_HEADERS|HTOPT_NO_CLOSE,
-};
-
-/**
- * Send string using a given escaping scheme
- *
- * @param r
- * @param buf - buf to send
- * @param len - buf len, or HTTPD_RESP_USE_STRLEN
- * @param escape - escaping type
- * @return success
- */
-esp_err_t httpd_resp_send_chunk_escaped(httpd_req_t *r, const char *buf, ssize_t len, tpl_escape_t escape);
-
-/**
- * Template substitution callback. Data shall be sent using httpd_resp_send_chunk_escaped().
- *
- * @param[in,out] context - user-defined page state data
- * @param[in] token - replacement token
- * @return ESP_OK if the token was substituted, ESP_ERR_NOT_FOUND if it is unknown, other errors on e.g. send failure
- */
-typedef esp_err_t (*template_subst_t)(httpd_req_t *r, void *context, const char *token, tpl_escape_t escape);
-
-/**
- * Send a template file as a response. The content type from the file struct will be used.
- *
- * Use HTOPT_INCLUDE when used to embed a file inside a template.
- *
- * @param r - request
- * @param file_index - file index in EMBEDDED_FILE_LOOKUP
- * @param replacer - substitution callback, can be NULL if only includes are to be processed
- * @param context - arbitrary context, will be passed to the replacer function; can be NULL
- * @param opts - flag options (HTOPT_*)
- */
-esp_err_t httpd_send_template_file(httpd_req_t *r, int file_index, template_subst_t replacer, void *context, uint32_t opts);
-
-/**
- * Same as httpd_send_template_file, but using an `embedded_file_info` struct.
- */
-esp_err_t httpd_send_template_file_struct(httpd_req_t *r, const struct embedded_file_info *file, template_subst_t replacer, void *context, uint32_t opts);
-
-/**
- * Process and send a string template.
- * The content-type header should be set beforehand, if different from the default (text/html).
- *
- * Use HTOPT_INCLUDE when used to embed a file inside a template.
- *
- * @param r - request
- * @param template - template string (does not have to be terminated by a null byte)
- * @param template_len - length of the template string; -1 to use strlen()
- * @param replacer - substitution callback, can be NULL if only includes are to be processed
- * @param context - arbitrary context, will be passed to the replacer function; can be NULL
- * @param opts - flag options (HTOPT_*)
- */
-esp_err_t httpd_send_template(httpd_req_t *r, const char *template, ssize_t template_len, template_subst_t replacer, void *context, uint32_t opts);
-
-/**
- * Send a static file. This can be used to just send a file, or to embed a static template as a token substitution.
- *
- * Use HTOPT_INCLUDE when used to embed a file inside a template.
- *
- * Note: use httpd_resp_send_chunk_escaped() or httpd_resp_send_chunk() to send a plain string.
- *
- * @param r - request
- * @param file_index - file index in EMBEDDED_FILE_LOOKUP
- * @param escape - escape option
- * @param opts - flag options (HTOPT_*)
- * @return
- */
-esp_err_t httpd_send_static_file(httpd_req_t *r, int file_index, tpl_escape_t escape, uint32_t opts);
-
-/**
- * Same as httpd_send_template_file, but using an `embedded_file_info` struct.
- */
-esp_err_t httpd_send_static_file_struct(httpd_req_t *r, const struct embedded_file_info *file, tpl_escape_t escape, uint32_t opts);
-
-struct tpl_kv_entry {
- char key[TPL_KV_KEY_LEN]; // copied here
- char subst[TPL_KV_SUBST_LEN]; // copied here
- SLIST_ENTRY(tpl_kv_entry) link;
-};
-
-SLIST_HEAD(tpl_kv_list, tpl_kv_entry);
-
-/**
- * key-value replacer that works with a dynamically allocated SLIST.
- *
- * @param r - request
- * @param context - context - must be a pointer to `struct tpl_kv_list`
- * @param token - token to replace
- * @param escape - escape option
- * @return OK/not found/other
- */
-esp_err_t tpl_kv_replacer(httpd_req_t *r, void *context, const char *token, tpl_escape_t escape);
-
-/**
- * Add a pair into the substitutions list
- *
- * @param head - list head
- * @param key - key, copied
- * @param subst - value, copied
- * @return success (fails if malloc failed)
- */
-esp_err_t tpl_kv_add(struct tpl_kv_list *head, const char *key, const char *subst);
-
-/**
- * Convenience function that converts an IP address to string and adds it as a substitution
- *
- * @param head - list head
- * @param key - key, copied
- * @param ip4h - host order ipv4 address
- * @return success
- */
-esp_err_t tpl_kv_add_ipv4str(struct tpl_kv_list *head, const char *key, uint32_t ip4h);
-
-/** add int as a substitution; key is copied */
-esp_err_t tpl_kv_add_int(struct tpl_kv_list *head, const char *key, int32_t num);
-
-/** add long as a substitution; key is copied */
-esp_err_t tpl_kv_add_long(struct tpl_kv_list *head, const char *key, int64_t num);
-
-/** add printf-formatted value; key is copied */
-esp_err_t tpl_kv_sprintf(struct tpl_kv_list *head, const char *key, const char *format, ...)
- __attribute__((format(printf,3,4)));
-
-/**
- * Init a substitutions list (on the stack)
- *
- * @return the list
- */
-static inline struct tpl_kv_list tpl_kv_init(void)
-{
- return (struct tpl_kv_list) {.slh_first = NULL};
-}
-
-/**
- * Free the list (head is left alone because it was allocated on the stack)
- * @param head
- */
-void tpl_kv_free(struct tpl_kv_list *head);
-
-/**
- * Send the map as an ASCII table separated by Record Separator (30) and Unit Separator (31).
- * Content type is set to application/octet-stream.
- *
- * key 31 value 30
- * key 31 value 30
- * key 31 value
- *
- * @param req
- */
-esp_err_t tpl_kv_send_as_ascii_map(httpd_req_t *req, struct tpl_kv_list *head);
-
-#endif //FBNODE_TOKEN_SUBS_H
diff --git a/components/fileserver/readme/README.md b/components/fileserver/readme/README.md
deleted file mode 100644
index 42d6883..0000000
--- a/components/fileserver/readme/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-Place the `rebuild_file_tables.php` script in a `files` subfolder of the main component.
-It requires PHP 7 to run.
-
-This is what the setup should look like
-
-```
-main/files/embed/index.html
-main/files/rebuild_file_tables.php
-main/CMakeLists.txt
-main/main.c
-```
-
-Add this to your CMakeLists.txt before `register_component`:
-
-```
-#begin staticfiles
-#end staticfiles
-```
-
-The script will update CMakeLists.txt and generate `files_enum.c` and `files_enum.h` when run.
-
-```
-main/files/files_enum.h
-main/files/files_enum.c
-```
-
-Ensure `files/files_enum.c` is included in the build.
-
-`www_get_static_file()` is implemented as weak to let you provide custom access authentication logic.
diff --git a/components/fileserver/readme/rebuild_file_tables.php b/components/fileserver/readme/rebuild_file_tables.php
deleted file mode 100755
index 2d81c59..0000000
--- a/components/fileserver/readme/rebuild_file_tables.php
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/env php
- 'text/plain',
- 'htm' => 'text/html',
- 'html' => 'text/html',
- 'php' => 'text/html',
- 'css' => 'text/css',
- 'js' => 'application/javascript',
- 'json' => 'application/json',
- 'xml' => 'application/xml',
- 'swf' => 'application/x-shockwave-flash',
- 'flv' => 'video/x-flv',
-
- 'pem' => 'application/x-pem-file',
-
- // images
- 'png' => 'image/png',
- 'jpe' => 'image/jpeg',
- 'jpeg' => 'image/jpeg',
- 'jpg' => 'image/jpeg',
- 'gif' => 'image/gif',
- 'bmp' => 'image/bmp',
- 'ico' => 'image/vnd.microsoft.icon',
- 'tiff' => 'image/tiff',
- 'tif' => 'image/tiff',
- 'svg' => 'image/svg+xml',
- 'svgz' => 'image/svg+xml',
-
- // archives
- 'zip' => 'application/zip',
- 'rar' => 'application/x-rar-compressed',
- 'exe' => 'application/x-msdownload',
- 'msi' => 'application/x-msdownload',
- 'cab' => 'application/vnd.ms-cab-compressed',
-
- // audio/video
- 'mp3' => 'audio/mpeg',
- 'qt' => 'video/quicktime',
- 'mov' => 'video/quicktime',
-
- // adobe
- 'pdf' => 'application/pdf',
- 'psd' => 'image/vnd.adobe.photoshop',
- 'ai' => 'application/postscript',
- 'eps' => 'application/postscript',
- 'ps' => 'application/postscript',
-
- // ms office
- 'doc' => 'application/msword',
- 'rtf' => 'application/rtf',
- 'xls' => 'application/vnd.ms-excel',
- 'ppt' => 'application/vnd.ms-powerpoint',
-
- // open office
- 'odt' => 'application/vnd.oasis.opendocument.text',
- 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
- );
-
- $parts = explode('.', $f);
- $suffix = end($parts);
- $mime = $mimes[$suffix] ?? 'application/octet-stream';
-
- $len = filesize('embed/'.$f);
-
- $struct_array[] = "[FILE_$a] = {{$start}, {$end}, \"{$f}\", \"{$mime}\"},";
-
- return
- 'extern const uint8_t '.$start.'[];'."\n".
- 'extern const uint8_t '.$end.'[];';
-}, $files);
-
-$externlist = implode("\n", $externs);
-$structlist = implode("\n ", $struct_array);
-
-
-file_put_contents('files_enum.h', <<
-#include
-
-enum embedded_file_id {
- $keylist,
- FILE_MAX
-};
-
-struct embedded_file_info {
- const uint8_t * start;
- const uint8_t * end;
- const char * name;
- const char * mime;
-};
-
-$externlist
-
-extern const struct embedded_file_info EMBEDDED_FILE_LOOKUP[];
-
-#endif // _EMBEDDED_FILES_ENUM_H
-
-FILE
-);
-
-file_put_contents("files_enum.c", <<
-#include "files_enum.h"
-
-const struct embedded_file_info EMBEDDED_FILE_LOOKUP[] = {
- $structlist
-};
-
-FILE
-);
diff --git a/components/fileserver/src/embedded_files.c b/components/fileserver/src/embedded_files.c
deleted file mode 100644
index e61f348..0000000
--- a/components/fileserver/src/embedded_files.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include
-#include "fileserver/embedded_files.h"
-#include "string.h"
-
-esp_err_t __attribute__((weak))
-www_get_static_file(const char *name, enum file_access_level access, const struct embedded_file_info **file)
-{
- // simple search by name
- for(int i = 0; i < EMBEDDED_FILE_LOOKUP_LEN; i++) {
- if (0 == strcmp(EMBEDDED_FILE_LOOKUP[i].name, name)) {
- *file = &EMBEDDED_FILE_LOOKUP[i];
- return ESP_OK;
- }
- }
-
- return ESP_ERR_NOT_FOUND;
-}
-
-bool __attribute__((weak))
-www_get_static_file_access_check(const struct embedded_file_info *file, enum file_access_level access) {
- return true;
-}
diff --git a/components/fileserver/src/token_subs.c b/components/fileserver/src/token_subs.c
deleted file mode 100644
index fd5b67a..0000000
--- a/components/fileserver/src/token_subs.c
+++ /dev/null
@@ -1,580 +0,0 @@
-//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "fileserver/embedded_files.h"
-#include "fileserver/token_subs.h"
-
-#define ESP_TRY(x) \
- do { \
- esp_err_t try_er = (x); \
- if (try_er != ESP_OK) return try_er; \
- } while(0)
-
-static const char* TAG = "token_subs";
-
-// TODO implement buffering to avoid sending many tiny chunks when escaping
-
-/* encode for HTML. returns 0 or 1 - 1 = success */
-static esp_err_t send_html_chunk(httpd_req_t *r, const char *data, ssize_t len)
-{
- assert(r);
- assert(data);
-
- int start = 0, end = 0;
- char c;
- if (len < 0) len = (int) strlen(data);
- if (len==0) return ESP_OK;
-
- for (end = 0; end < len; end++) {
- c = data[end];
- if (c == 0) {
- // we found EOS
- break; // not return - the last chunk is printed after the loop
- }
-
- if (c == '"' || c == '\'' || c == '<' || c == '>') {
- if (start < end) ESP_TRY(httpd_resp_send_chunk(r, data + start, end - start));
- start = end + 1;
- }
-
- if (c == '"') ESP_TRY(httpd_resp_send_chunk(r, """, 5));
- else if (c == '\'') ESP_TRY(httpd_resp_send_chunk(r, "'", 5));
- else if (c == '<') ESP_TRY(httpd_resp_send_chunk(r, "<", 4));
- else if (c == '>') ESP_TRY(httpd_resp_send_chunk(r, ">", 4));
- }
-
- if (start < end) ESP_TRY(httpd_resp_send_chunk(r, data + start, end - start));
- return ESP_OK;
-}
-
-/* encode for JS. returns 0 or 1 - 1 = success */
-static esp_err_t send_js_chunk(httpd_req_t *r, const char *data, ssize_t len)
-{
- assert(r);
- assert(data);
-
- int start = 0, end = 0;
- char c;
- if (len < 0) len = (int) strlen(data);
- if (len==0) return ESP_OK;
-
- for (end = 0; end < len; end++) {
- c = data[end];
- if (c == 0) {
- // we found EOS
- break; // not return - the last chunk is printed after the loop
- }
-
- if (c == '"' || c == '\\' || c == '/' || c == '\'' || c == '<' || c == '>' || c == '\n' || c == '\r') {
- if (start < end) ESP_TRY(httpd_resp_send_chunk(r, data + start, end - start));
- start = end + 1;
- }
-
- if (c == '"') ESP_TRY(httpd_resp_send_chunk(r, "\\\"", 2));
- else if (c == '\'') ESP_TRY(httpd_resp_send_chunk(r, "\\'", 2));
- else if (c == '\\') ESP_TRY(httpd_resp_send_chunk(r, "\\\\", 2));
- else if (c == '/') ESP_TRY(httpd_resp_send_chunk(r, "\\/", 2));
- else if (c == '<') ESP_TRY(httpd_resp_send_chunk(r, "\\u003C", 6));
- else if (c == '>') ESP_TRY(httpd_resp_send_chunk(r, "\\u003E", 6));
- else if (c == '\n') ESP_TRY(httpd_resp_send_chunk(r, "\\n", 2));
- else if (c == '\r') ESP_TRY(httpd_resp_send_chunk(r, "\\r", 2));
- }
-
- if (start < end) ESP_TRY(httpd_resp_send_chunk(r, data + start, end - start));
- return ESP_OK;
-}
-
-
-esp_err_t httpd_resp_send_chunk_escaped(httpd_req_t *r, const char *buf, ssize_t len, tpl_escape_t escape)
-{
- switch (escape) {
- default: // this enum should be exhaustive, but in case something went wrong, just print it verbatim
-
- case TPL_ESCAPE_NONE:
- return httpd_resp_send_chunk(r, buf, len);
-
- case TPL_ESCAPE_HTML:
- return send_html_chunk(r, buf, len);
-
- case TPL_ESCAPE_JS:
- return send_js_chunk(r, buf, len);
- }
-}
-
-esp_err_t httpd_send_static_file(httpd_req_t *r, int file_index, tpl_escape_t escape, uint32_t opts)
-{
- assert(file_index < EMBEDDED_FILE_LOOKUP_LEN);
- const struct embedded_file_info *file = &EMBEDDED_FILE_LOOKUP[file_index];
-
- return httpd_send_static_file_struct(r, file, escape, opts);
-}
-
-esp_err_t httpd_send_static_file_struct(httpd_req_t *r, const struct embedded_file_info *file, tpl_escape_t escape, uint32_t opts)
-{
- if (0 == (opts & HTOPT_NO_HEADERS)) {
- ESP_TRY(httpd_resp_set_type(r, file->mime));
- ESP_TRY(httpd_resp_set_hdr(r, "Cache-Control", "max-age=86400, public, must-revalidate"));
- }
-
- ESP_TRY(httpd_resp_send_chunk_escaped(r, (const char *) file->start, (size_t)(file->end - file->start), escape));
-
- if (0 == (opts & HTOPT_NO_CLOSE)) {
- ESP_TRY(httpd_resp_send_chunk(r, NULL, 0));
- }
-
- return ESP_OK;
-}
-
-esp_err_t httpd_send_template_file(httpd_req_t *r,
- int file_index,
- template_subst_t replacer,
- void *context,
- uint32_t opts)
-{
- assert(file_index < EMBEDDED_FILE_LOOKUP_LEN);
- const struct embedded_file_info *file = &EMBEDDED_FILE_LOOKUP[file_index];
- return httpd_send_template_file_struct(r,file,replacer,context,opts);
-}
-
-esp_err_t httpd_send_template_file_struct(httpd_req_t *r,
- const struct embedded_file_info *file,
- template_subst_t replacer,
- void *context,
- uint32_t opts)
-{
- if (0 == (opts & HTOPT_NO_HEADERS)) {
- ESP_TRY(httpd_resp_set_type(r, file->mime));
- ESP_TRY(httpd_resp_set_hdr(r, "Cache-Control", "no-cache, no-store, must-revalidate"));
- }
-
- return httpd_send_template(r, (const char *) file->start, (size_t)(file->end - file->start), replacer, context, opts);
-}
-
-esp_err_t tpl_kv_replacer(httpd_req_t *r, void *context, const char *token, tpl_escape_t escape)
-{
- assert(context);
- assert(token);
-
- struct tpl_kv_entry *entry;
- struct tpl_kv_list *head = context;
- SLIST_FOREACH(entry, head, link) {
- if (0==strcmp(entry->key, token)) {
- return httpd_resp_send_chunk_escaped(r, entry->subst, -1, escape);
- }
- }
-
- return ESP_ERR_NOT_FOUND;
-}
-
-struct stacked_replacer_context {
- template_subst_t replacer0;
- void *context0;
- template_subst_t replacer1;
- void *context1;
-};
-
-esp_err_t stacked_replacer(httpd_req_t *r, void *context, const char *token, tpl_escape_t escape)
-{
- assert(context);
- assert(token);
-
- struct stacked_replacer_context *combo = context;
-
- if (ESP_OK == combo->replacer0(r, combo->context0, token, escape)) {
- return ESP_OK;
- }
-
- if (ESP_OK == combo->replacer1(r, combo->context1, token, escape)) {
- return ESP_OK;
- }
-
- return ESP_ERR_NOT_FOUND;
-}
-
-esp_err_t httpd_send_template(httpd_req_t *r,
- const char *template, ssize_t template_len,
- template_subst_t replacer,
- void *context,
- uint32_t opts)
-{
- if (template_len < 0) template_len = strlen(template);
-
- // replacer and context may be NULL
- assert(template);
- assert(r);
-
- // data end
- const char * const end = template + template_len;
-
- // start of to-be-processed data
- const char * pos = template;
-
- // start position for finding opening braces, updated after a failed match to avoid infinite loop on the same bad token
- const char * searchpos = pos;
-
- // tokens must be copied to a buffer to allow adding the terminating null byte
- char token_buf[MAX_TOKEN_LEN];
-
- while (pos < end) {
- const char * openbr = strchr(searchpos, '{');
- if (openbr == NULL) {
- // no more templates
- ESP_TRY(httpd_resp_send_chunk(r, pos, (size_t) (end - pos)));
- break;
- }
-
- // this brace could start a valid template. check if it seems valid...
- const char * closebr = strchr(openbr, '}');
- if (closebr == NULL) {
- // there are no further closing braces, so it can't be a template
-
- // we also know there can't be any more substitutions, because they would lack a closing } too
- ESP_TRY(httpd_resp_send_chunk(r, pos, (size_t) (end - pos)));
- break;
- }
-
- // see if the braces content looks like a token
- const char *t = openbr + 1;
- bool token_valid = true;
- struct tpl_kv_list substitutions_head = tpl_kv_init();
- struct tpl_kv_entry *new_subst_pair = NULL;
-
- // a token can be either a name for replacement by the replacer func, or an include with static kv replacements
- bool is_include = false;
- bool token_is_optional = false;
- const char *token_end = NULL; // points one char after the end of the token
-
- // parsing the token
- {
- if (*t == '@') {
- ESP_LOGD(TAG, "Parsing an Include token");
- is_include = true;
- t++;
- }
-
- enum {
- P_NAME, P_KEY, P_VALUE
- } state = P_NAME;
-
- const char *kv_start = NULL;
- while (t != closebr || state == P_VALUE) {
- char c = *t;
-
- if (state == P_NAME) {
- if (!((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- c == '.' || c == '_' || c == '-' || c == ':')) {
-
- if (!is_include && c == '?') {
- token_end = t;
- token_is_optional = true;
- } else {
- if (is_include && c == '|') {
- token_end = t;
- state = P_KEY;
- kv_start = t + 1;
- // pipe separates the include's filename and literal substitutions
- // we know there is a closing } somewhere, and {@....| doesn't occur normally, so let's assume it's correct
- }
- else {
- token_valid = false;
- break;
- }
- }
- }
- }
- else if (state == P_KEY) {
- if (!((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- c == '.' || c == '_' || c == '-')) {
- if (c == '=') {
- new_subst_pair = calloc(sizeof(struct tpl_kv_entry), 1);
- const size_t klen = MIN(TPL_KV_KEY_LEN, t - kv_start);
- strncpy(new_subst_pair->key, kv_start, klen);
- new_subst_pair->key[klen] = 0;
-
- kv_start = t + 1;
-
- state = P_VALUE;
- // pipe separates the include's filename and literal substitutions
- // we know there is a closing } somewhere, and {@....| doesn't occur normally, so let's assume it's correct
- }
- }
- }
- else if (state == P_VALUE) {
- if (c == '|' || c == '}') {
- const size_t vlen = MIN(TPL_KV_SUBST_LEN, t - kv_start);
- strncpy(new_subst_pair->subst, kv_start, vlen);
- new_subst_pair->subst[vlen] = 0;
-
- // attach the kv pair to the list
- SLIST_INSERT_HEAD(&substitutions_head, new_subst_pair, link);
- ESP_LOGD(TAG, "Adding subs kv %s -> %s", new_subst_pair->key, new_subst_pair->subst);
- new_subst_pair = NULL;
-
- kv_start = t + 1; // go past the pipe
- state = P_KEY;
-
- if (t == closebr) {
- break; // found the ending brace, so let's quit the kv parse loop
- }
- }
- }
-
- t++;
- }
- // clean up after a messed up subs kv pairs syntax
- if (new_subst_pair != NULL) {
- free(new_subst_pair);
- }
- }
-
- if (!token_valid) {
- // false match, include it in the block to send before the next token
- searchpos = openbr + 1;
- ESP_LOGD(TAG, "Skip invalid token near %10s", openbr);
- continue;
- }
-
- // now we know it looks like a substitution token
-
- // flush data before the token
- if (pos != openbr) ESP_TRY(httpd_resp_send_chunk(r, pos, (size_t) (openbr - pos)));
-
- const char *token_start = openbr;
-
- tpl_escape_t escape = TPL_ESCAPE_NONE;
-
- // extract and terminate the token
- size_t token_len = MIN(MAX_TOKEN_LEN-1, closebr - openbr - 1);
- if (token_end) {
- token_len = MIN(token_len, token_end - openbr - 1);
- }
-
- if (is_include) {
- token_start += 1; // skip the @
- token_len -= 1;
- } else {
- if (0 == strncmp("h:", openbr + 1, 2)) {
- escape = TPL_ESCAPE_HTML;
- token_start += 2;
- token_len -= 2;
- }
- else if (0 == strncmp("j:", openbr + 1, 2)) {
- escape = TPL_ESCAPE_JS;
- token_start += 2;
- token_len -= 2;
- }
- }
-
- strncpy(token_buf, token_start+1, token_len);
- token_buf[token_len] = 0;
-
- ESP_LOGD(TAG, "Token: %s", token_buf);
-
- esp_err_t rv;
-
- if (is_include) {
- ESP_LOGD(TAG, "Trying to include a sub-file");
-
- const struct embedded_file_info *file = NULL;
- rv = www_get_static_file(token_buf, FILE_ACCESS_PROTECTED, &file);
- if (rv != ESP_OK) {
- ESP_LOGE(TAG, "Failed to statically include \"%s\" in a template - %s", token_buf, esp_err_to_name(rv));
- // this will cause the token to be emitted verbatim
- } else {
- ESP_LOGD(TAG, "Descending...");
-
- // combine the two replacers
- struct stacked_replacer_context combo = {
- .replacer0 = replacer,
- .context0 = context,
- .replacer1 = tpl_kv_replacer,
- .context1 = &substitutions_head
- };
-
- rv = httpd_send_template_file_struct(r, file, stacked_replacer, &combo, HTOPT_INCLUDE);
- ESP_LOGD(TAG, "...back in parent");
- }
-
- // tear down the list
- tpl_kv_free(&substitutions_head);
-
- if (rv != ESP_OK) {
- // just send it verbatim...
- ESP_TRY(httpd_resp_send_chunk(r, openbr, (size_t) (closebr - openbr + 1)));
- }
- } else {
- if (replacer) {
- ESP_LOGD(TAG, "Running replacer for \"%s\" with escape %d", token_buf, escape);
- rv = replacer(r, context, token_buf, escape);
-
- if (rv != ESP_OK) {
- if (rv == ESP_ERR_NOT_FOUND) {
- ESP_LOGD(TAG, "Token rejected");
- // optional token becomes empty string if not replaced
- if (!token_is_optional) {
- ESP_LOGD(TAG, "Not optional, keeping verbatim");
- // replacer rejected the token, keep it verbatim
- ESP_TRY(httpd_resp_send_chunk(r, openbr, (size_t) (closebr - openbr + 1)));
- }
- }
- else {
- ESP_LOGE(TAG, "Unexpected error from replacer func: 0x%02x - %s", rv, esp_err_to_name(rv));
- return rv;
- }
- }
- } else {
- ESP_LOGD(TAG, "Not replacer");
- // no replacer, only includes - used for 'static' files
- if (!token_is_optional) {
- ESP_LOGD(TAG, "Token not optional, keeping verbatim");
- ESP_TRY(httpd_resp_send_chunk(r, openbr, (size_t) (closebr - openbr + 1)));
- }
- }
- }
-
- searchpos = pos = closebr + 1;
- }
-
- if (0 == (opts & HTOPT_NO_CLOSE)) {
- ESP_TRY(httpd_resp_send_chunk(r, NULL, 0));
- }
-
- return ESP_OK;
-}
-
-
-esp_err_t tpl_kv_add_int(struct tpl_kv_list *head, const char *key, int32_t num)
-{
- char buf[12];
- itoa(num, buf, 10);
- return tpl_kv_add(head, key, buf);
-}
-
-esp_err_t tpl_kv_add_long(struct tpl_kv_list *head, const char *key, int64_t num)
-{
- char buf[21];
- sprintf(buf, "%"PRIi64, num);
- return tpl_kv_add(head, key, buf);
-}
-
-esp_err_t tpl_kv_add_ipv4str(struct tpl_kv_list *head, const char *key, uint32_t ip4h)
-{
- char buf[IP4ADDR_STRLEN_MAX];
- ip4_addr_t addr;
- addr.addr = lwip_htonl(ip4h);
- ip4addr_ntoa_r(&addr, buf, IP4ADDR_STRLEN_MAX);
-
- return tpl_kv_add(head, key, buf);
-}
-
-esp_err_t tpl_kv_add(struct tpl_kv_list *head, const char *key, const char *subst)
-{
- ESP_LOGD(TAG, "kv add subs %s := %s", key, subst);
- struct tpl_kv_entry *entry = calloc(sizeof(struct tpl_kv_entry), 1);
- if (entry == NULL) return ESP_ERR_NO_MEM;
-
- assert(strlen(key) < TPL_KV_KEY_LEN);
- assert(strlen(subst) < TPL_KV_SUBST_LEN);
-
- strncpy(entry->key, key, TPL_KV_KEY_LEN);
- entry->key[TPL_KV_KEY_LEN - 1] = 0;
-
- strncpy(entry->subst, subst, TPL_KV_SUBST_LEN - 1);
- entry->subst[TPL_KV_KEY_LEN - 1] = 0;
-
- SLIST_INSERT_HEAD(head, entry, link);
- return ESP_OK;
-}
-
-esp_err_t tpl_kv_sprintf(struct tpl_kv_list *head, const char *key, const char *format, ...)
-{
- ESP_LOGD(TAG, "kv printf %s := %s", key, format);
- struct tpl_kv_entry *entry = calloc(sizeof(struct tpl_kv_entry), 1);
- if (entry == NULL) return ESP_ERR_NO_MEM;
-
- assert(strlen(key) < TPL_KV_KEY_LEN);
-
- strncpy(entry->key, key, TPL_KV_KEY_LEN);
- entry->key[TPL_KV_KEY_LEN - 1] = 0;
-
- va_list list;
- va_start(list, format);
- vsnprintf(entry->subst, TPL_KV_SUBST_LEN, format, list);
- va_end(list);
- entry->subst[TPL_KV_KEY_LEN - 1] = 0;
-
- SLIST_INSERT_HEAD(head, entry, link);
- return ESP_OK;
-}
-
-void tpl_kv_free(struct tpl_kv_list *head)
-{
- struct tpl_kv_entry *item, *next;
- SLIST_FOREACH_SAFE(item, head, link, next) {
- free(item);
- }
-}
-
-esp_err_t tpl_kv_send_as_ascii_map(httpd_req_t *req, struct tpl_kv_list *head)
-{
- httpd_resp_set_type(req, "text/plain; charset=utf-8");
-
-#define BUF_CAP 512
- char *buf_head = calloc(BUF_CAP, 1);
- if (!buf_head) {
- ESP_LOGE(TAG, "Malloc err");
- return ESP_FAIL;
- }
- char *buf = buf_head;
- size_t cap = BUF_CAP;
- struct tpl_kv_entry *entry;
-
- // GCC nested function
- esp_err_t send_part() {
- esp_err_t suc = httpd_resp_send_chunk(req, buf_head, BUF_CAP-cap);
- buf = buf_head;
- cap = BUF_CAP;
- if (suc != ESP_OK) {
- ESP_LOGE(TAG, "Error sending buffer");
- free(buf_head);
- httpd_resp_send_chunk(req, NULL, 0);
- }
- return suc;
- }
-
- SLIST_FOREACH(entry, head, link) {
- buf = append(buf, entry->key, &cap);
- if (!buf) ESP_TRY(send_part());
- buf = append(buf, "\x1f", &cap);
- if (!buf) ESP_TRY(send_part());
- buf = append(buf, entry->subst, &cap);
- if (!buf) ESP_TRY(send_part());
- if (entry->link.sle_next) {
- buf = append(buf, "\x1e", &cap);
- if (!buf) ESP_TRY(send_part());
- }
- }
- // send leftovers
- if (buf != buf_head) {
- esp_err_t suc = httpd_resp_send_chunk(req, buf_head, BUF_CAP-cap);
- if (suc != ESP_OK) {
- ESP_LOGE(TAG, "Error sending buffer");
- }
- }
-
- // Commit
- httpd_resp_send_chunk(req, NULL, 0);
- free(buf_head);
- return ESP_OK;
-}
diff --git a/components/httpd_utils/CMakeLists.txt b/components/httpd_utils/CMakeLists.txt
deleted file mode 100644
index e5fe530..0000000
--- a/components/httpd_utils/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-set(COMPONENT_ADD_INCLUDEDIRS
- "include")
-
-set(COMPONENT_SRCDIRS
- "src")
-
-set(COMPONENT_REQUIRES tcpip_adapter esp_http_server common_utils)
-
-register_component()
diff --git a/components/httpd_utils/README.txt b/components/httpd_utils/README.txt
deleted file mode 100644
index c3e034e..0000000
--- a/components/httpd_utils/README.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Functions enriching the HTTP server bundled with ESP-IDF.
-This package includes HTTP-related utilities, captive
-portal implementation, and a cookie-based session system with a
-key-value store and expirations.
diff --git a/components/httpd_utils/component.mk b/components/httpd_utils/component.mk
deleted file mode 100644
index 87ae05a..0000000
--- a/components/httpd_utils/component.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-
-COMPONENT_SRCDIRS := src
-COMPONENT_ADD_INCLUDEDIRS := include
diff --git a/components/httpd_utils/include/httpd_utils/captive.h b/components/httpd_utils/include/httpd_utils/captive.h
deleted file mode 100644
index d656b41..0000000
--- a/components/httpd_utils/include/httpd_utils/captive.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef HTTPD_UTILS_CAPTIVE_H
-#define HTTPD_UTILS_CAPTIVE_H
-
-#include
-#include
-
-/**
- * Redirect if needed when a captive portal capture is detected
- *
- * @param r
- * @return ESP_OK on redirect, ESP_ERR_NOT_FOUND if not needed, other error on failure
- */
-esp_err_t httpd_captive_redirect(httpd_req_t *r);
-
-/**
- * Get URL to redirect to. WEAK.
- *
- * @param r
- * @param buf
- * @param maxlen
- * @return http(s)://foo.bar/
- */
-esp_err_t httpd_captive_redirect_get_url(httpd_req_t *r, char *buf, size_t maxlen);
-
-/**
- * Get captive portal domain. WEAK.
- *
- * @return foo.bar
- */
-const char * httpd_captive_redirect_get_domain();
-
-#endif //HTTPD_UTILS_CAPTIVE_H
diff --git a/components/httpd_utils/include/httpd_utils/fd_to_ipv4.h b/components/httpd_utils/include/httpd_utils/fd_to_ipv4.h
deleted file mode 100644
index 6cb647d..0000000
--- a/components/httpd_utils/include/httpd_utils/fd_to_ipv4.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef HTTPD_FDIPV4_H
-#define HTTPD_FDIPV4_H
-
-/**
- * Get IP address for a FD
- *
- * @param fd
- * @param[out] ipv4
- * @return success
- */
-esp_err_t fd_to_ipv4(int fd, in_addr_t *ipv4);
-
-#endif //HTTPD_FDIPV4_H
diff --git a/components/httpd_utils/include/httpd_utils/redirect.h b/components/httpd_utils/include/httpd_utils/redirect.h
deleted file mode 100644
index 77fdebc..0000000
--- a/components/httpd_utils/include/httpd_utils/redirect.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef HTTPD_UTILS_REDIRECT_H
-#define HTTPD_UTILS_REDIRECT_H
-
-#include
-#include
-
-/**
- * Redirect to other URI - sends a HTTP response from the http server
- *
- * @param r - request
- * @param uri - target uri
- * @return success
- */
-esp_err_t httpd_redirect_to(httpd_req_t *r, const char *uri);
-
-#endif // HTTPD_UTILS_REDIRECT_H
diff --git a/components/httpd_utils/include/httpd_utils/session.h b/components/httpd_utils/include/httpd_utils/session.h
deleted file mode 100644
index 1ff409b..0000000
--- a/components/httpd_utils/include/httpd_utils/session.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * Session store system main include file
- *
- * Created on 2019/07/13.
- */
-
-#ifndef HTTPD_UTILS_SESSION_H
-#define HTTPD_UTILS_SESSION_H
-
-#include "session_kvmap.h"
-#include "session_store.h"
-
-// Customary keys
-
-/** Session key for OK flash message */
-#define SESS_FLASH_OK "flash_ok"
-/** Session key for error flash message */
-#define SESS_FLASH_ERR "flash_err"
-/** Session key for a "logged in" flag. Value is 1 if logged in. */
-#define SESS_AUTHED "authed"
-
-// ..
-
-/**
- * Redirect to /login form if unauthed,
- * but also retrieve the session key-value store for further use
- */
-#define HTTP_GET_AUTHED_SESSION(kvstore, r) do { \
- kvstore = httpd_req_find_session_and((r), SESS_GET_DATA); \
- if (NULL == kvstore || NULL == sess_kv_map_get(kvstore, SESS_AUTHED)) { \
- return httpd_redirect_to((r), "/login"); \
- } \
-} while(0)
-
-/**
- * Start or resume a session without checking for authed status.
- * When started, the session cookie is added to the response immediately.
- *
- * @param[out] kvstore - a place to store the allocated or retrieved session kvmap
- * @param[in] r - request
- * @return success
- */
-esp_err_t HTTP_GET_SESSION(sess_kv_map_t **kvstore, httpd_req_t *r);
-
-/**
- * Redirect to the login form if unauthed.
- * This is the same as `HTTP_GET_AUTHED_SESSION`, except the kvstore variable is
- * not needed in the uri handler calling this, so it is declared internally.
- */
-#define HTTP_REDIRECT_IF_UNAUTHED(r) do { \
- sess_kv_map_t *_kvstore; \
- HTTP_GET_AUTHED_SESSION(_kvstore, r); \
-} while(0)
-
-#endif // HTTPD_UTILS_SESSION_H
diff --git a/components/httpd_utils/include/httpd_utils/session_kvmap.h b/components/httpd_utils/include/httpd_utils/session_kvmap.h
deleted file mode 100644
index e091bd5..0000000
--- a/components/httpd_utils/include/httpd_utils/session_kvmap.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Simple key-value map for session data storage.
- * Takes care of dynamic allocation and cleanup.
- *
- * Created on 2019/01/28.
- */
-
-#ifndef SESSION_KVMAP_H
-#define SESSION_KVMAP_H
-
-/**
- * Prototype for a free() func to clean up session-held objects
- */
-typedef void (*sess_kv_free_func_t)(void *obj);
-
-typedef struct sess_kv_map sess_kv_map_t;
-
-#define SESS_KVMAP_KEY_LEN 16
-
-/**
- * Allocate a new session key-value store
- *
- * @return the store, NULL on error
- */
-sess_kv_map_t *sess_kv_map_alloc(void);
-
-/**
- * Free the session kv store.
- *
- * @param head - store head
- */
-void sess_kv_map_free(void *head);
-
-/**
- * Get a value from the session kv store.
- *
- * @param head - store head
- * @param key - key to get a value for
- * @return the value, or NULL if not found
- */
-void *sess_kv_map_get(sess_kv_map_t *head, const char *key);
-
-/**
- * Get and remove a value from the session store.
- *
- * The free function is not called in this case and the recipient is
- * responsible for cleaning it up correctly.
- *
- * @param head - store head
- * @param key - key to get a value for
- * @return the value, or NULL if not found
- */
-void * sess_kv_map_take(sess_kv_map_t *head, const char *key);
-
-/**
- * Remove an entry from the session by its key name.
- * The slot is not free'd yet, but is made available for reuse.
- *
- * @param head - store head
- * @param key - key to remove
- * @return success
- */
-esp_err_t sess_kv_map_remove(sess_kv_map_t *head, const char *key);
-
-/**
- * Set a key value. If there is an old value stored, it will be freed by its free function and replaced by the new one.
- * Otherwise a new slot is allocated for it, or a previously released one is reused.
- *
- * @param head - store head
- * @param key - key to assign to
- * @param value - new value
- * @param free_fn - value free func
- * @return success
- */
-esp_err_t sess_kv_map_set(sess_kv_map_t *head, const char *key, void *value, sess_kv_free_func_t free_fn);
-
-#endif //SESSION_KVMAP_H
diff --git a/components/httpd_utils/include/httpd_utils/session_store.h b/components/httpd_utils/include/httpd_utils/session_store.h
deleted file mode 100644
index 2266944..0000000
--- a/components/httpd_utils/include/httpd_utils/session_store.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Cookie-based session store
- */
-
-#ifndef SESSION_STORE_H
-#define SESSION_STORE_H
-
-#include "esp_http_server.h"
-
-#define SESSION_EXPIRY_TIME_S 60*30
-#define SESSION_COOKIE_NAME "SESSID"
-
-/** function that frees a session data object */
-typedef void (*sess_data_free_fn_t)(void *);
-
-enum session_find_action {
- SESS_DROP, SESS_GET_DATA
-};
-
-/**
- * Find session and either get data, or drop it.
- *
- * @param cookie
- * @param action
- * @return
- */
-void *session_find_and(const char *cookie, enum session_find_action action);
-
-/**
- * Initialize the session store.
- * Safely empty it if initialized
- */
-void session_store_init(void);
-
-// placeholder for when no data is stored
-#define SESSION_DUMMY ((void *) 1)
-
-/**
- * Create a new session. Data must not be NULL, because it wouldn't be possible
- * to distinguish between NULL value and session not found in return values.
- * It can be e.g. 1 if no data storage is needed.
- *
- * @param data - data object to attach to the session
- * @param free_fn - function that disposes of the data when the session expires
- * @return NULL on error, or the new session ID. This is a live pointer into the session structure,
- * must be copied if stored, as it can become invalid at any time
- */
-const char *session_new(void *data, sess_data_free_fn_t free_fn);
-
-/**
- * Find a session by it's ID (from a cookie)
- *
- * @param cookie - session ID string
- * @return session data (void*), or NULL
- */
-void *session_find(const char *cookie);
-
-/**
- * Loop through all sessions and drop these that expired.
- */
-void session_drop_expired(void);
-
-/**
- * Drop a session by its ID. Does nothing if not found.
- *
- * @param cookie - session ID string
- */
-void session_drop(const char *cookie);
-
-/**
- * Parse the Cookie header from a request, and do something with the corresponding session.
- *
- * To also delete the cookie, use req_delete_session_cookie(r)
- *
- * @param r - request
- * @param action - what to do with the session
- * @return session data, NULL if removed or not found
- */
-void *httpd_req_find_session_and(httpd_req_t *r, enum session_find_action action);
-
-/**
- * Add a header that deletes the session cookie
- *
- * @param r - request
- */
-void httpd_resp_delete_session_cookie(httpd_req_t *r);
-
-/**
- * Add a header that sets the session cookie.
- *
- * This must be called after creating a session (e.g. user logged in) to make it persistent.
- *
- * @attention NOT RE-ENTRANT, CAN'T BE USED AGAIN UNTIL THE REQUEST IT WAS CALLED FOR IS DISPATCHED.
- *
- * @param r - request
- * @param cookie - cookie ID
- */
-void httpd_resp_set_session_cookie(httpd_req_t *r, const char *cookie);
-
-#endif //SESSION_STORE_H
diff --git a/components/httpd_utils/src/captive.c b/components/httpd_utils/src/captive.c
deleted file mode 100644
index 2be20d3..0000000
--- a/components/httpd_utils/src/captive.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "httpd_utils/captive.h"
-#include "httpd_utils/fd_to_ipv4.h"
-#include "httpd_utils/redirect.h"
-#include
-
-static const char *TAG="captive";
-
-const char * __attribute__((weak))
-httpd_captive_redirect_get_domain(void)
-{
- return "fb_node.captive";
-}
-
-esp_err_t __attribute__((weak))
-httpd_captive_redirect_get_url(httpd_req_t *r, char *buf, size_t maxlen)
-{
- buf = append(buf, "http://", &maxlen);
- buf = append(buf, httpd_captive_redirect_get_domain(), &maxlen);
- append(buf, "/", &maxlen);
-
- return ESP_OK;
-}
-
-esp_err_t httpd_captive_redirect(httpd_req_t *r)
-{
- // must be static to survive being used in the redirect header
- static char s_buf[64];
-
- wifi_mode_t mode = 0;
- esp_wifi_get_mode(&mode);
-
- // Check if we have an softap interface. No point checking IPs and hostnames if the client can't be on AP.
- if (mode == WIFI_MODE_STA || mode == WIFI_MODE_NULL) {
- goto no_redirect;
- }
-
- int fd = httpd_req_to_sockfd(r);
-
- tcpip_adapter_ip_info_t apip;
- tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &apip);
-
- u32_t client_addr;
- if(ESP_OK != fd_to_ipv4(fd, &client_addr)) {
- return ESP_FAIL;
- }
-
- ESP_LOGD(TAG, "[captive] Client addr = 0x%08x, ap addr 0x%08x, ap nmask 0x%08x",
- client_addr,
- apip.ip.addr,
- apip.netmask.addr
- );
-
- // Check if client IP looks like from our AP dhcps
- if ((client_addr & apip.netmask.addr) != (apip.ip.addr & apip.netmask.addr)) {
- ESP_LOGD(TAG, "[captive] Client not in AP IP range");
- goto no_redirect;
- }
-
- // Get requested hostname from the header
- esp_err_t rv = httpd_req_get_hdr_value_str(r, "Host", s_buf, 64);
- if (rv != ESP_OK) {
- ESP_LOGW(TAG, "[captive] No host in request?");
- goto no_redirect;
- }
-
- ESP_LOGD(TAG, "[captive] Candidate for redirect: %s%s", s_buf, r->uri);
-
- // Never redirect if host is an IP
- if (strlen(s_buf)>7) {
- bool isIP = 1;
- for (int x = 0; x < strlen(s_buf); x++) {
- if (s_buf[x] != '.' && (s_buf[x] < '0' || s_buf[x] > '9')) {
- isIP = 0;
- break;
- }
- }
-
- if (isIP) {
- ESP_LOGD(TAG, "[captive] Access via IP, no redirect needed");
- goto no_redirect;
- }
- }
-
- // Redirect if host differs
- // - this can be e.g. connectivitycheck.gstatic.com or the equivalent for ios
-
- if (0 != strcmp(s_buf, httpd_captive_redirect_get_domain())) {
- ESP_LOGD(TAG, "[captive] Host differs, redirecting...");
-
- httpd_captive_redirect_get_url(r, s_buf, 64);
- return httpd_redirect_to(r, s_buf);
- } else {
- ESP_LOGD(TAG, "[captive] Host is OK");
- goto no_redirect;
- }
-
- no_redirect:
- return ESP_ERR_NOT_FOUND;
-}
diff --git a/components/httpd_utils/src/fd_to_ipv4.c b/components/httpd_utils/src/fd_to_ipv4.c
deleted file mode 100644
index 7f6377f..0000000
--- a/components/httpd_utils/src/fd_to_ipv4.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-
-#include "httpd_utils/fd_to_ipv4.h"
-
-static const char *TAG = "fd2ipv4";
-
-/**
- * Get IP address for a FD
- *
- * @param fd
- * @param[out] ipv4
- * @return success
- */
-esp_err_t fd_to_ipv4(int fd, in_addr_t *ipv4)
-{
- struct sockaddr_in6 addr;
- size_t len = sizeof(addr);
- int rv = getpeername(fd, (struct sockaddr *) &addr, &len);
- if (rv != 0) {
- ESP_LOGE(TAG, "Failed to get IP addr for fd %d", fd);
- return ESP_FAIL;
- }
-
- uint32_t client_addr = 0;
- if (addr.sin6_family == AF_INET6) {
- // this would fail in a real ipv6 network
- // with ipv4 the addr is simply in the last ipv6 byte
- struct sockaddr_in6 *s = &addr;
- client_addr = s->sin6_addr.un.u32_addr[3];
- }
- else {
- struct sockaddr_in *s = (struct sockaddr_in *) &addr;
- client_addr = s->sin_addr.s_addr;
- }
-
- *ipv4 = client_addr;
- return ESP_OK;
-}
diff --git a/components/httpd_utils/src/redirect.c b/components/httpd_utils/src/redirect.c
deleted file mode 100644
index 5a174df..0000000
--- a/components/httpd_utils/src/redirect.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-
-#include "httpd_utils/redirect.h"
-
-static const char *TAG="redirect";
-
-esp_err_t httpd_redirect_to(httpd_req_t *r, const char *uri)
-{
- ESP_LOGD(TAG, "Redirect to %s", uri);
-
- httpd_resp_set_hdr(r, "Location", uri);
- httpd_resp_set_status(r, "303 See Other");
- httpd_resp_set_type(r, HTTPD_TYPE_TEXT);
- const char *msg = "Redirect";
- return httpd_resp_send(r, msg, -1);
-}
diff --git a/components/httpd_utils/src/session_kvmap.c b/components/httpd_utils/src/session_kvmap.c
deleted file mode 100644
index f96638f..0000000
--- a/components/httpd_utils/src/session_kvmap.c
+++ /dev/null
@@ -1,181 +0,0 @@
-//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "httpd_utils/session_kvmap.h"
-
-static const char *TAG = "sess_kvmap";
-
-// this struct is opaque, a stub like this is sufficient for the head pointer.
-struct sess_kv_entry;
-
-/** Session head structure, dynamically allocated */
-SLIST_HEAD(sess_kv_map, sess_kv_entry);
-
-struct sess_kv_entry {
- SLIST_ENTRY(sess_kv_entry) link;
- char key[SESS_KVMAP_KEY_LEN];
- void *value;
- sess_kv_free_func_t free_fn;
-};
-
-struct sess_kv_map *sess_kv_map_alloc(void)
-{
- ESP_LOGD(TAG, "kv store alloc");
- struct sess_kv_map *map = calloc(sizeof(struct sess_kv_map), 1);
- assert(map);
- SLIST_INIT(map);
- return map;
-}
-
-void sess_kv_map_free(void *head_v)
-{
- struct sess_kv_map* head = head_v;
-
- ESP_LOGD(TAG, "kv store free");
- assert(head);
- struct sess_kv_entry *item, *tmp;
- SLIST_FOREACH_SAFE(item, head, link, tmp) {
- if (item->free_fn) {
- item->free_fn(item->value);
- free(item);
- }
- }
- free(head);
-}
-
-
-void * sess_kv_map_get(struct sess_kv_map *head, const char *key)
-{
- assert(head);
- assert(key);
- ESP_LOGD(TAG, "kv store get %s", key);
-
- struct sess_kv_entry *item;
- SLIST_FOREACH(item, head, link) {
- if (0==strcmp(item->key, key)) {
- ESP_LOGD(TAG, "got ok");
- return item->value;
- }
- }
-
- ESP_LOGD(TAG, "not found in store");
- return NULL;
-}
-
-void * sess_kv_map_take(struct sess_kv_map *head, const char *key)
-{
- assert(head);
- assert(key);
- ESP_LOGD(TAG, "kv store take %s", key);
-
- struct sess_kv_entry *item;
- SLIST_FOREACH(item, head, link) {
- if (0==strcmp(item->key, key)) {
- item->key[0] = 0;
- item->free_fn = NULL;
- ESP_LOGD(TAG, "taken ok");
- return item->value;
- }
- }
-
- ESP_LOGD(TAG, "not found in store");
- return NULL;
-}
-
-esp_err_t sess_kv_map_remove(struct sess_kv_map *head, const char *key)
-{
- assert(head);
- assert(key);
- ESP_LOGD(TAG, "kv store remove %s", key);
-
- struct sess_kv_entry *item;
- SLIST_FOREACH(item, head, link) {
- if (0==strcmp(item->key, key)) {
- if (item->free_fn) {
- item->free_fn(item->value);
- }
- item->key[0] = 0;
- item->value = NULL;
- item->free_fn = NULL;
- return ESP_OK;
- }
- }
-
- ESP_LOGD(TAG, "couldn't remove, not found: %s", key);
- return ESP_ERR_NOT_FOUND;
-}
-
-
-esp_err_t sess_kv_map_set(struct sess_kv_map *head, const char *key, void *value, sess_kv_free_func_t free_fn)
-{
- assert(head);
- assert(key);
- ESP_LOGD(TAG, "kv set value for key %s", key);
-
- size_t key_len = strlen(key);
- if (key_len > SESS_KVMAP_KEY_LEN-1) {
- ESP_LOGE(TAG, "Key too long: %s", key);
- // discard illegal key
- return ESP_FAIL;
- }
-
- if (key_len == 0) {
- ESP_LOGE(TAG, "Key too short: \"%s\"", key);
- // discard illegal key
- return ESP_FAIL;
- }
-
- struct sess_kv_entry *item = NULL;
- struct sess_kv_entry *empty_item = NULL; // found item with no content
- SLIST_FOREACH(item, head, link) {
- ESP_LOGD(TAG, "test item with key %s, ptr %p > %p", item->key, item, item->link.sle_next);
- if (0 == item->key[0]) {
- ESP_LOGD(TAG, "found an empty slot");
- empty_item = item;
- }
- else if (0==strcmp(item->key, key)) {
- ESP_LOGD(TAG, "old value replaced");
- if (item->free_fn) {
- item->free_fn(item->value);
- }
- item->value = value;
- item->free_fn = free_fn;
- return ESP_OK;
- } else {
- ESP_LOGD(TAG, "skip this one");
- }
- }
-
- struct sess_kv_entry *new_item = NULL;
-
- // insert new or reuse an empty item
- if (empty_item) {
- new_item = empty_item;
- ESP_LOGD(TAG, "empty item reused (%p)", new_item);
- } else {
- ESP_LOGD(TAG, "alloc new item");
- // key not found, add a new entry.
- new_item = calloc(sizeof(struct sess_kv_entry), 1);
- if (!new_item) {
- ESP_LOGE(TAG, "New entry alloc failed");
- return ESP_ERR_NO_MEM;
- }
- }
-
- strcpy(new_item->key, key);
- new_item->free_fn = free_fn;
- new_item->value = value;
-
- if (!empty_item) {
- ESP_LOGD(TAG, "insert new item into list");
- // this item was malloc'd
- SLIST_INSERT_HEAD(head, new_item, link);
- }
-
- return ESP_OK;
-}
diff --git a/components/httpd_utils/src/session_store.c b/components/httpd_utils/src/session_store.c
deleted file mode 100644
index 3e00cef..0000000
--- a/components/httpd_utils/src/session_store.c
+++ /dev/null
@@ -1,220 +0,0 @@
-//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "httpd_utils/session_store.h"
-
-// TODO add a limit on simultaneously open sessions (can cause memory exhaustion DoS)
-
-#define COOKIE_LEN 32
-static const char *TAG = "session";
-
-struct session {
- char cookie[COOKIE_LEN + 1];
- void *data;
- TickType_t last_activity_time;
- LIST_ENTRY(session) link;
- sess_data_free_fn_t free_fn;
-};
-
-static LIST_HEAD(sessions_, session) s_store;
-
-static SemaphoreHandle_t sess_store_lock = NULL;
-static bool sess_store_inited = false;
-
-
-void session_store_init(void)
-{
- if (sess_store_inited) {
- xSemaphoreTake(sess_store_lock, portMAX_DELAY);
- {
- struct session *it, *tit;
- LIST_FOREACH_SAFE(it, &s_store, link, tit) {
- ESP_LOGW(TAG, "Session cookie expired: \"%s\"", it->cookie);
- if (it->free_fn) it->free_fn(it->data);
- // no relink, we dont care if the list breaks after this - we're removing all of it
- free(it);
- }
- }
- LIST_INIT(&s_store);
- xSemaphoreGive(sess_store_lock);
- } else {
- LIST_INIT(&s_store);
- sess_store_lock = xSemaphoreCreateMutex();
- sess_store_inited = true;
- }
-}
-
-/**
- * Fill buffer with base64 symbols. Does not add a trailing null byte
- *
- * @param buf
- * @param len
- */
-static void esp_fill_random_alnum(char *buf, size_t len)
-{
-#define alphabet_len 64
- static const char alphabet[alphabet_len] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
-
- unsigned int seed = xTaskGetTickCount();
-
- assert(buf != NULL);
- for (int i = 0; i < len; i++) {
- int index = rand_r(&seed) % alphabet_len;
- *buf++ = (uint8_t) alphabet[index];
- }
-}
-
-const char *session_new(void *data, sess_data_free_fn_t free_fn)
-{
- assert(data != NULL);
-
- struct session *item = calloc(sizeof(struct session), 1);
- if (item == NULL) return NULL;
-
- item->data = data;
- item->free_fn = free_fn;
- esp_fill_random_alnum(item->cookie, COOKIE_LEN);
- item->cookie[COOKIE_LEN] = 0; // add the terminator
-
- xSemaphoreTake(sess_store_lock, portMAX_DELAY);
- {
- item->last_activity_time = xTaskGetTickCount();
-
- LIST_INSERT_HEAD(&s_store, item, link);
- }
- xSemaphoreGive(sess_store_lock);
-
- ESP_LOGD(TAG, "New HTTP session: %s", item->cookie);
-
- return item->cookie;
-}
-
-void *session_find_and(const char *cookie, enum session_find_action action)
-{
- // no point in searching if the length is wrong
- if (strlen(cookie) != COOKIE_LEN) {
- ESP_LOGW(TAG, "Wrong session cookie length: \"%s\"", cookie);
- return NULL;
- }
-
- struct session *it = NULL;
-
- bool found = false;
- xSemaphoreTake(sess_store_lock, portMAX_DELAY);
- {
- LIST_FOREACH(it, &s_store, link) {
- if (0==strcmp(it->cookie, cookie)) {
- ESP_LOGD(TAG, "Session cookie matched: \"%s\"", cookie);
-
- it->last_activity_time = xTaskGetTickCount();
- found = true;
- break;
- }
- }
- if (found && action == SESS_DROP) {
- if (it->free_fn) it->free_fn(it->data);
- LIST_REMOVE(it, link);
- free(it);
- ESP_LOGD(TAG, "Dropped session: \"%s\"", cookie);
- }
- }
- xSemaphoreGive(sess_store_lock);
- if (found) {
- if (action == SESS_DROP) {
- // it was dropped inside the guarded block
- // the return value is not used with DROP
- return NULL;
- }
- else if(action == SESS_GET_DATA) {
- return it->data;
- }
- }
-
- ESP_LOGW(TAG, "Session cookie not found: \"%s\"", cookie);
- return NULL;
-}
-
-void *session_find(const char *cookie)
-{
- return session_find_and(cookie, SESS_GET_DATA);
-}
-
-void session_drop(const char *cookie)
-{
- session_find_and(cookie, SESS_DROP);
-}
-
-void session_drop_expired(void)
-{
- struct session *it;
- struct session *tit;
-
- xSemaphoreTake(sess_store_lock, portMAX_DELAY);
- {
- TickType_t now = xTaskGetTickCount();
-
- LIST_FOREACH_SAFE(it, &s_store, link, tit) {
- TickType_t elapsed = now - it->last_activity_time;
- if (elapsed > pdMS_TO_TICKS(SESSION_EXPIRY_TIME_S*1000)) {
- ESP_LOGD(TAG, "Session cookie expired: \"%s\"", it->cookie);
- if (it->free_fn) it->free_fn(it->data);
- LIST_REMOVE(it, link);
- free(it);
- }
- }
- }
- xSemaphoreGive(sess_store_lock);
-}
-
-
-void *httpd_req_find_session_and(httpd_req_t *r, enum session_find_action action)
-{
- // this could be called periodically, but it's sufficient to run it at each request
- // it won't slow anything down unless there are hundreds of sessions
- session_drop_expired();
-
- static char buf[256];
- esp_err_t rv = httpd_req_get_hdr_value_str(r, "Cookie", buf, 256);
- if (rv == ESP_OK || rv == ESP_ERR_HTTPD_RESULT_TRUNC) {
- ESP_LOGD(TAG, "Cookie header: %s", buf);
-
- // probably OK, see if we have a cookie
- char *start = strstr(buf, SESSION_COOKIE_NAME"=");
- if (start != 0) {
- start += strlen(SESSION_COOKIE_NAME"=");
- char *end = strchr(start, ';');
- if (end != NULL) *end = 0;
-
- ESP_LOGD(TAG, "Cookie is: %s", start);
- return session_find_and(start, action);
- }
- } else {
- ESP_LOGD(TAG, "No cookie.");
- }
-
- return NULL;
-}
-
-void httpd_resp_delete_session_cookie(httpd_req_t *r)
-{
- httpd_resp_set_hdr(r, "Set-Cookie", SESSION_COOKIE_NAME"=");
-}
-
-
-// Static because the value is passed and stored by reference, so it wouldn't live long enough if it was on stack,
-// and there also isn't any hook for freeing it if we used malloc(). This is an SDK bug.
-static char cookie_hdr_buf[COOKIE_LEN + 10];
-
-// !!! this must not be called concurrently from a different thread.
-// That is no problem so long as the server stays single-threaded
-void httpd_resp_set_session_cookie(httpd_req_t *r, const char *cookie)
-{
- snprintf(cookie_hdr_buf, COOKIE_LEN + 10, "SESSID=%s", cookie);
- httpd_resp_set_hdr(r, "Set-Cookie", cookie_hdr_buf);
-}
diff --git a/components/httpd_utils/src/session_utils.c b/components/httpd_utils/src/session_utils.c
deleted file mode 100644
index c1ef068..0000000
--- a/components/httpd_utils/src/session_utils.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * TODO file description
- *
- * Created on 2019/07/13.
- */
-
-#ifndef SESSION_UTILS_C_H
-#define SESSION_UTILS_C_H
-
-#include
-#include
-#include "httpd_utils/session_kvmap.h"
-#include "httpd_utils/session_store.h"
-
-/**
- * Start or resume a session.
- */
-esp_err_t HTTP_GET_SESSION(sess_kv_map_t **ppkvstore, httpd_req_t *r)
-{
- sess_kv_map_t *kvstore;
- kvstore = httpd_req_find_session_and((r), SESS_GET_DATA);
- if (NULL == kvstore) {
- kvstore = sess_kv_map_alloc();
- if (!kvstore) return ESP_ERR_NO_MEM;
-
- const char *cookie = session_new(kvstore, sess_kv_map_free);
- if (cookie == NULL) {
- // session alloc failed
- sess_kv_map_free(kvstore);
- *ppkvstore = NULL;
- return ESP_ERR_NO_MEM;
- }
- httpd_resp_set_session_cookie(r, cookie);
- }
-
- *ppkvstore = kvstore;
- return ESP_OK;
-}
-
-
-#endif //SESSION_UTILS_C_H
diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt
index fcfeb61..bf7d008 100644
--- a/main/CMakeLists.txt
+++ b/main/CMakeLists.txt
@@ -1,16 +1,14 @@
idf_component_register(SRCS
- irblaster_main.c
+ fanctl_main.c
settings.c
shutdown_handlers.c
sntp_cli.c
utils.c
wifi_conn.c
- irblast.c
console/console_ioimpl.c
console/console_server.c
console/register_cmds.c
console/telnet_parser.c
- web/websrv.c
console/commands/cmd_dump.c
console/commands/cmd_factory_reset.c
console/commands/cmd_heap.c
diff --git a/main/irblaster_main.c b/main/fanctl_main.c
similarity index 96%
rename from main/irblaster_main.c
rename to main/fanctl_main.c
index bc25ec5..83737ac 100644
--- a/main/irblaster_main.c
+++ b/main/fanctl_main.c
@@ -15,7 +15,6 @@
#include "console/console_server.h"
-#include "web/websrv.h"
#include "wifi_conn.h"
#include "console/register_cmds.h"
@@ -38,8 +37,6 @@ void app_main(void) {
ESP_ERROR_CHECK(esp_netif_init());
if (g_Settings.wifi_enabled && (g_Settings.sta_enabled || g_Settings.ap_enabled)) {
initialise_wifi();
-
- websrv_init();
g_State.wifi_inited = true;
} else {
// initialise the bare minimum so wifi config can be changed
@@ -52,8 +49,6 @@ void app_main(void) {
g_State.wifi_inited = true;
}
- irblast_setup();
-
console_init(NULL);
register_console_commands();
diff --git a/main/web/websrv.c b/main/web/websrv.c
deleted file mode 100644
index d5cd730..0000000
--- a/main/web/websrv.c
+++ /dev/null
@@ -1,217 +0,0 @@
-#include
-#include
-
-#include
-#include
-#include
-
-#include "websrv.h"
-#include "esp_http_server.h"
-#include "utils.h"
-#include "irblast.h"
-
-#include "www_files_enum.h"
-
-static const char *TAG = "websrv";
-
-static httpd_handle_t s_hServer = NULL;
-
-// Embedded files (must also be listed in CMakeLists.txt as COMPONENT_EMBED_TXTFILES)
-efile(index_file, "index_html");
-
-static struct tpl_kv_list build_index_replacements_kv(void) {
- //char name[TPL_KV_KEY_LEN];
- struct tpl_kv_list kv = tpl_kv_init();
- tpl_kv_add(&kv, "version", APP_VERSION);
- return kv;
-}
-
-/* Main page */
-static esp_err_t handler_index(httpd_req_t *req) {
- struct tpl_kv_list kv = build_index_replacements_kv();
-
- esp_err_t suc = httpd_send_template_file(req, FILE_INDEX_HTML, tpl_kv_replacer, &kv, 0);
- tpl_kv_free(&kv);
- return suc;
-}
-
-/* Update XHR for new index page data */
-static esp_err_t handler_update(httpd_req_t *req) {
- struct tpl_kv_list kv = build_index_replacements_kv();
-
- esp_err_t suc = tpl_kv_send_as_ascii_map(req, &kv);
- tpl_kv_free(&kv);
- return suc;
-}
-
-/* Set a param */
-static esp_err_t handler_set(httpd_req_t *req) {
- char buf[64];
- int n = httpd_req_recv(req, buf, 63);
- if (n < 0) {
- ESP_LOGW(TAG, "rx er");
- goto err;
- }
- buf[n] = 0;
-
- char keybuf[20];
- char valbuf[20];
- if (ESP_OK != httpd_query_key_value(buf, "key", keybuf, 20)) goto err;
- if (ESP_OK != httpd_query_key_value(buf, "value", valbuf, 20)) goto err;
-
- // TODO
- ESP_LOGW(TAG, "bad key %s", keybuf);
- goto err;
-
- return httpd_resp_send(req, NULL, 0);
-
- err:
- return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, NULL);
-}
-
-/* Request emulator reboot */
-static esp_err_t handler_reboot(httpd_req_t *req) {
- httpd_resp_send(req, ""
- ""
- ""
- ""
- "Reboot requested. Reloading in 10 seconds.
"
- "Try now.", -1);
-
- ESP_LOGI(TAG, "Restarting ESP...");
- esp_restart();
-}
-
-/* Request emulator reboot */
-static esp_err_t handler_irblast(httpd_req_t *req) {
- char buf[64];
- esp_err_t err = httpd_req_get_url_query_str(req, buf, 63);
- if (err != ESP_OK) {
- ESP_LOGW(TAG, "param er: %s", esp_err_to_name(err));
- goto err;
- }
- ESP_LOGI(TAG, "querystring: %s", buf);
-
- char valbuf[20];
- if (ESP_OK != httpd_query_key_value(buf, "do", valbuf, 20)) {
- ESP_LOGW(TAG, "fail to get \"do\" param");
- goto err;
- }
- valbuf[19] = 0;
-
- ESP_LOGI(TAG, "IR cmd to send: %s", valbuf);
-
- const char *cmdnames[] = {
- [IRBLAST_ONOFF] = "onoff",
- [IRBLAST_DAYNIGHT] = "daynight",
- [IRBLAST_SPEED1] = "speed1",
- [IRBLAST_SPEED2] = "speed2",
- [IRBLAST_SPEED3] = "speed3",
- [IRBLAST_MODE1] = "mode1",
- [IRBLAST_MODE2] = "mode2",
- [IRBLAST_MODE3] = "mode3",
- [IRBLAST_MODE4] = "mode4",
- [IRBLAST_HUM1] = "hum1",
- [IRBLAST_HUM2] = "hum2",
- [IRBLAST_HUM3] = "hum3",
- NULL
- };
-
- for (int i = 0; cmdnames[i]; i++) {
- if (strncasecmp(cmdnames[i], valbuf, 20) == 0) {
- httpd_resp_send(req, "{\"success\":true}", -1);
- irblast_send((enum irblast_cmd) i);
- return ESP_OK;
- }
- }
- err:
- return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, NULL);
-}
-
-/* An HTTP GET handler */
-static esp_err_t handler_staticfiles(httpd_req_t *r) {
- const struct embedded_file_info *file;
- const char *fname = r->user_ctx;
- enum file_access_level access = FILE_ACCESS_PROTECTED;
-
- // wildcard files must be public
- if (fname == NULL) {
- fname = r->uri + 1; // URI always starts with slash, but we dont want a slash in the file name
- access = FILE_ACCESS_PUBLIC;
- }
-
-#if USE_CAPTIVE_PORTAL
- // First check if this is a phone taken here by the captive portal
- esp_err_t rv = httpd_captive_redirect(r);
- if (rv != ESP_ERR_NOT_FOUND) return rv;
-#endif
-
- if (ESP_OK != www_get_static_file(fname, access, &file)) {
- ESP_LOGW(TAG, "File not found: %s", fname);
- return httpd_resp_send_404(r);
- } else {
- if (streq(file->mime, "text/html")) {
- // using the template func to allow includes
- return httpd_send_template_file_struct(r, file, /*replacer*/NULL, /*ctx*/NULL, /*opts*/0);
- } else {
- return httpd_send_static_file_struct(r, file, TPL_ESCAPE_NONE, 0);
- }
- }
-}
-
-static const httpd_uri_t routes[] = {
- {
- .uri = "/",
- .method = HTTP_GET,
- .handler = handler_index,
- },
- {
- .uri = "/data",
- .method = HTTP_GET,
- .handler = handler_update,
- },
- {
- .uri = "/set",
- .method = HTTP_POST,
- .handler = handler_set,
- },
- {
- .uri = "/reboot",
- .method = HTTP_GET,
- .handler = handler_reboot,
- },
- {
- .uri = "/irblast",
- .method = HTTP_GET,
- .handler = handler_irblast,
- },
- {
- .uri = "*", // any file except protected (e.g. not HTML, PEM etc)
- .method = HTTP_GET,
- .handler = handler_staticfiles,
- },
-};
-
-esp_err_t websrv_init(void) {
- httpd_config_t config = HTTPD_DEFAULT_CONFIG();
- config.max_open_sockets = 3;
-
- config.uri_match_fn = httpd_uri_match_wildcard;
- config.lru_purge_enable = true;
-
- ESP_LOGI(TAG, "Starting HTTP server on port: '%d'", config.server_port);
-
- esp_err_t suc = httpd_start(&s_hServer, &config);
- if (suc == ESP_OK) {
- ESP_LOGI(TAG, "HTTP server started");
-
- for (int i = 0; i < sizeof(routes) / sizeof(httpd_uri_t); i++) {
- httpd_register_uri_handler(s_hServer, &routes[i]);
- }
-
- return ESP_OK;
- }
-
- ESP_LOGE(TAG, "Error starting server!");
- return suc;
-}
diff --git a/main/web/websrv.h b/main/web/websrv.h
deleted file mode 100644
index 3bc9679..0000000
--- a/main/web/websrv.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Integrated webserver
- *
- * Created on 2019/07/13.
- */
-
-#ifndef CSPEMU_WEBSRV_H
-#define CSPEMU_WEBSRV_H
-
-#include
-
-esp_err_t websrv_init(void);
-
-#endif //CSPEMU_WEBSRV_H