import now fully working

work
Ondřej Hruška 7 years ago
parent ba2b73a287
commit 2f4cd08c60
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 2
      esphttpdconfig.mk.example
  2. 2
      front-end
  3. 198
      user/cgi_persist.c
  4. 10
      user/config_xmacros.h
  5. 6
      user/screen.c
  6. 2
      user/serial.c
  7. 15
      user/wifimgr.c
  8. 1
      user/wifimgr.h

@ -40,7 +40,7 @@ ESP_SPI_FLASH_SIZE_K = 1024
GLOBAL_CFLAGS = \ GLOBAL_CFLAGS = \
-DASYNC_LOG=1 \ -DASYNC_LOG=1 \
-DDEBUG_INI=0 \ -DDEBUG_INI=1 \
-DDEBUG_D2D=0 \ -DDEBUG_D2D=0 \
-DDEBUG_ROUTER=0 \ -DDEBUG_ROUTER=0 \
-DDEBUG_CAPTDNS=0 \ -DDEBUG_CAPTDNS=0 \

@ -1 +1 @@
Subproject commit 8327ff010893935c0c517c729727464f66badd89 Subproject commit a96b522ca899c687d70b9ad92f708cd416b8d460

@ -13,6 +13,7 @@ Cgi/template routines for configuring non-wifi settings
#include "ini_parser.h" #include "ini_parser.h"
#define SET_REDIR_SUC "/cfg/system" #define SET_REDIR_SUC "/cfg/system"
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
static bool ICACHE_FLASH_ATTR static bool ICACHE_FLASH_ATTR
verify_admin_pw(const char *pw) verify_admin_pw(const char *pw)
@ -79,7 +80,7 @@ cgiPersistRestoreHard(HttpdConnData *connData)
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
// -------------- Export --------------
#define httpdSend_orDie(conn, data, len) do { if (!httpdSend((conn), (data), (len))) return false; } while (0) #define httpdSend_orDie(conn, data, len) do { if (!httpdSend((conn), (data), (len))) return false; } while (0)
@ -217,17 +218,154 @@ cgiPersistExport(HttpdConnData *connData)
} }
void iniCb(const char *section, const char *key, const char *value, void *userData) // -------------- IMPORT --------------
struct IniUpload {
TerminalConfigBundle *term_backup;
WiFiConfigBundle *wifi_backup;
SystemConfigBundle *sys_backup;
bool term_ok;
bool wifi_ok;
bool sys_ok;
};
static void ICACHE_FLASH_ATTR iniCb(const char *section, const char *key, const char *value, void *userData)
{ {
dbg(">>> SET: [%s] %s = %s", section, key, value); HttpdConnData *connData = (HttpdConnData *)userData;
struct IniUpload *state;
if (!connData || !connData->cgiData) {
error("userData or state is NULL!");
return;
}
state = connData->cgiData;
// cgi_dbg("%s.%s = %s", section, key, value);
#define X XSET_ASSIGN
bool suc = true;
bool found = false;
// notify flag, unused here
bool uart_changed = false;
if (streq(section, "terminal")) {
#define XSTRUCT termconf
XTABLE_TERMCONF
#undef XSTRUCT
if (!suc) state->term_ok = false;
}
else if (streq(section, "wifi")) {
#define XSTRUCT wificonf
XTABLE_WIFICONF
#undef XSTRUCT
if (!suc) state->wifi_ok = false;
}
else if (streq(section, "system")) {
#define XSTRUCT sysconf
XTABLE_SYSCONF
#undef XSTRUCT
if (!suc) state->sys_ok = false;
}
if (!found) cgi_warn("Unknown key %s.%s!", section, key);
#undef X
} }
static void ICACHE_FLASH_ATTR
freeIniUploadStruct(HttpdConnData *connData)
{
cgi_dbg("Free struct...");
struct IniUpload *state;
if (connData && connData->cgiData) {
state = connData->cgiData;
if (state->sys_backup != NULL) free(state->sys_backup);
if (state->wifi_backup != NULL) free(state->wifi_backup);
if (state->term_backup != NULL) free(state->term_backup);
free(state);
connData->cgiData = NULL;
}
}
httpd_cgi_state ICACHE_FLASH_ATTR static httpd_cgi_state ICACHE_FLASH_ATTR
postRecvHdl(HttpdConnData *connData, char *data, int len) postRecvHdl(HttpdConnData *connData, char *data, int len)
{ {
struct IniUpload *state = connData->cgiData;
if (!state) return HTTPD_CGI_DONE;
// Discard the boundary marker (there is only one)
char *bdr = connData->post->multipartBoundary;
char *foundat = strstr(data, bdr);
if (foundat != NULL) {
*foundat = '#'; // make it a comment
}
cgi_dbg("INI parse - postRecvHdl");
ini_parse(data, (size_t) len); ini_parse(data, (size_t) len);
cgi_dbg("Closing parser");
ini_parse_end(); ini_parse_end();
cgi_dbg("INI parse - end.");
// abort if bad screen size
bool tooLarge = (termconf->width*termconf->height > MAX_SCREEN_SIZE);
state->term_ok &= !tooLarge;
if (tooLarge) cgi_warn("Bad term screen size!");
bool suc = state->term_ok && state->wifi_ok && state->sys_ok;
cgi_dbg("Evaluating results...");
if (!state->term_ok) cgi_warn("Terminal settings rejected.");
if (!state->wifi_ok) cgi_warn("WiFi settings rejected.");
if (!state->sys_ok) cgi_warn("System settings rejected.");
if (!suc) {
cgi_warn("Some validation failed, reverting all!");
memcpy(termconf, state->term_backup, sizeof(TerminalConfigBundle));
memcpy(wificonf, state->wifi_backup, sizeof(WiFiConfigBundle));
memcpy(sysconf, state->sys_backup, sizeof(SystemConfigBundle));
}
else {
cgi_dbg("Applying terminal settings");
terminal_apply_settings();
cgi_dbg("Applying system settings");
sysconf_apply_settings();
cgi_dbg("Applying WiFi settings (scheduling...)");
wifimgr_apply_settings_later(1000);
cgi_dbg("Persisting results");
persist_store();
}
cgi_dbg("Redirect");
char buff[100];
char *b = buff;
if (suc) {
httpdRedirect(connData, SET_REDIR_SUC"?msg=Settings%20loaded%20and%20applied.");
} else {
b += sprintf(b, SET_REDIR_SUC"?errmsg=Errors%%20in:%%20");
bool comma = false;
if (!state->sys_ok) {
b += sprintf(b, "System%%20config");
comma = true;
}
if (!state->wifi_ok) {
if (comma) b += sprintf(b, ",%%20");
b += sprintf(b, "WiFi%%20config");
}
if (!state->term_ok) {
if (comma) b += sprintf(b, ",%%20");
b += sprintf(b, "Terminal%%20config");
}
httpdRedirect(connData, buff);
}
// Clean up.
freeIniUploadStruct(connData);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
@ -240,27 +378,59 @@ postRecvHdl(HttpdConnData *connData, char *data, int len)
httpd_cgi_state ICACHE_FLASH_ATTR httpd_cgi_state ICACHE_FLASH_ATTR
cgiPersistImport(HttpdConnData *connData) cgiPersistImport(HttpdConnData *connData)
{ {
struct IniUpload *state = NULL;
if (connData->conn == NULL) { if (connData->conn == NULL) {
//Connection aborted. Clean up. //Connection aborted. Clean up.
freeIniUploadStruct(connData);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "text/plain");
httpdEndHeaders(connData);
char *start = strstr(connData->post->buff, "\r\n\r\n"); char *start = strstr(connData->post->buff, "\r\n\r\n");
if (start == NULL) { if (start == NULL) {
error("Malformed attachment POST!"); error("Malformed attachment POST!");
goto end;
httpdStartResponse(connData, 400);
httpdHeader(connData, "Content-Type", "text/plain");
httpdEndHeaders(connData);
httpdSend(connData, "Bad format.", -1);
return HTTPD_CGI_DONE;
}
cgi_info("Starting INI parser for uploaded file...");
state = malloc(sizeof(struct IniUpload));
if (!state) {
error("state struct alloc fail");
return HTTPD_CGI_DONE;
} }
state->sys_backup = NULL;
state->wifi_backup = NULL;
state->term_backup = NULL;
connData->cgiData = state;
cgi_dbg("Allocating backup buffers");
state->sys_backup = malloc(sizeof(SystemConfigBundle));
state->wifi_backup = malloc(sizeof(WiFiConfigBundle));
state->term_backup = malloc(sizeof(TerminalConfigBundle));
cgi_dbg("Copying orig data");
memcpy(state->sys_backup, sysconf, sizeof(SystemConfigBundle));
memcpy(state->wifi_backup, wificonf, sizeof(WiFiConfigBundle));
memcpy(state->term_backup, termconf, sizeof(TerminalConfigBundle));
ini_parse_begin(iniCb, NULL); state->sys_ok = true;
ini_parse(start, (size_t) connData->post->buffLen - (start - connData->post->buff)); state->wifi_ok = true;
state->term_ok = true;
cgi_dbg("Parser starts!");
ini_parse_begin(iniCb, connData);
size_t datalen = (size_t) connData->post->buffLen - (start - connData->post->buff);
ini_parse(start, datalen);
connData->recvHdl = postRecvHdl; connData->recvHdl = postRecvHdl;
end: // continues in recvHdl
// TODO redirect return HTTPD_CGI_MORE;
return HTTPD_CGI_DONE;
} }

@ -84,6 +84,16 @@ enum xset_result xset_ustring(const char *name, u8 *field, const char *buff, con
else if (res == XSET_FAIL) { redir_url += sprintf(redir_url, #name","); } \ else if (res == XSET_FAIL) { redir_url += sprintf(redir_url, #name","); } \
} }
/** used for INI */
#define XSET_ASSIGN(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \
if (streq(#name, key)) { \
found = true; \
type *_p = (type *) &XSTRUCT->name; \
enum xset_result res = xset(#name, _p, value, (const void*) (xsarg)); \
if (res == XSET_SET) { xnotify; } \
else if (res == XSET_FAIL) { suc = false; } \
}
#define XGET_CGI_FUNC(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \ #define XGET_CGI_FUNC(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \
if ((allow) && streq(token, #name)) xget(buff, deref XSTRUCT->name); if ((allow) && streq(token, #name)) xget(buff, deref XSTRUCT->name);

@ -250,11 +250,11 @@ xset_term_bm(const char *name, char *field, const char *buff, const void *arg)
} }
if (char_i >= TERM_BTN_MSG_LEN-1) { if (char_i >= TERM_BTN_MSG_LEN-1) {
cgi_warn("Too long! %d", acu); cgi_warn("Too long! %d", char_i);
return XSET_FAIL; return XSET_FAIL;
} }
cgi_dbg("acu %d", acu); // cgi_dbg("acu %d", acu);
buff_bm[char_i++] = (char)acu; buff_bm[char_i++] = (char)acu;
// prepare for next char // prepare for next char
@ -277,7 +277,7 @@ xset_term_bm(const char *name, char *field, const char *buff, const void *arg)
buff_bm[char_i++] = (char)acu; buff_bm[char_i++] = (char)acu;
} }
buff_bm[char_i] = 0; buff_bm[char_i] = 0;
cgi_dbg("%s, chari = %d", buff_bm, char_i); // cgi_dbg("%s, chari = %d", buff_bm, char_i);
if (!streq(field, buff_bm)) { if (!streq(field, buff_bm)) {
strncpy(field, buff_bm, TERM_BTN_MSG_LEN); strncpy(field, buff_bm, TERM_BTN_MSG_LEN);

@ -42,7 +42,7 @@ buf_pop(void *unused)
LOCAL void my_putc(char c) LOCAL void my_putc(char c)
{ {
UART_WriteCharCRLF(UART1, (u8) c, 10); UART_WriteCharCRLF(UART1, (u8) c, 200);
} }
/** /**

@ -292,6 +292,21 @@ configure_ap(void)
} }
} }
static ETSTimer tim;
static void ICACHE_FLASH_ATTR
wifimgr_apply_settings_later_Cb(void *unused)
{
wifimgr_apply_settings();
}
void ICACHE_FLASH_ATTR
wifimgr_apply_settings_later(uint32_t delay_ms)
{
wifi_info("[WiFi] Scheduling settings apply in %d ms", delay_ms);
TIMER_START(&tim, wifimgr_apply_settings_later_Cb, delay_ms, 0);
}
/** /**
* Register the WiFi event listener, cycle WiFi, apply settings * Register the WiFi event listener, cycle WiFi, apply settings
*/ */

@ -82,6 +82,7 @@ extern WiFiConfigBundle * const wificonf;
void wifimgr_restore_defaults(void); void wifimgr_restore_defaults(void);
void wifimgr_apply_settings(void); void wifimgr_apply_settings(void);
void wifimgr_apply_settings_later(uint32_t delay_ms);
int getStaIpAsString(char *buffer); int getStaIpAsString(char *buffer);

Loading…
Cancel
Save