Compare commits

...

14 Commits

10 changed files with 157 additions and 20 deletions

14
Kconfig
View File

@ -916,8 +916,6 @@ menu "WebGUIApp"
endif endif
endmenu endmenu
menu "MQTT settings" menu "MQTT settings"
config WEBGUIAPP_MQTT_ENABLE config WEBGUIAPP_MQTT_ENABLE
bool "Enabled MQTT transport" bool "Enabled MQTT transport"
@ -981,6 +979,18 @@ menu "WebGUIApp"
endif endif
endmenu endmenu
menu "System log"
config WEBGUIAPP_SYSLOG_MAX_CHUNKS
int "Number of syslog parts"
range 1 10
default 4
config WEBGUIAPP_SYSLOG_CHUNK_SIZE
int "Size of one part in kilobytes"
range 1 256
default 50
endmenu
if WEBGUIAPP_WIFI_ENABLE || WEBGUIAPP_ETHERNET_ENABLE || WEBGUIAPP_GPRS_ENABLE if WEBGUIAPP_WIFI_ENABLE || WEBGUIAPP_ETHERNET_ENABLE || WEBGUIAPP_GPRS_ENABLE
menu "DNS settings" menu "DNS settings"

View File

@ -84,9 +84,11 @@ typedef struct
void (*HandlerRoutine)(char *VarData, void *arg); void (*HandlerRoutine)(char *VarData, void *arg);
} dyn_var_handler_t; } dyn_var_handler_t;
#define BLOCK_OPERATION_TIMEOUT 30
#define MEM_OBLECT_MAX_LENGTH 32 #define MEM_OBLECT_MAX_LENGTH 32
typedef struct typedef struct
{ {
int transid;
int opertype; int opertype;
int operphase; int operphase;
int part; int part;
@ -97,7 +99,7 @@ typedef struct
struct stat file_stat; struct stat file_stat;
FILE *f; FILE *f;
int open_file_timeout; int open_file_timeout;
} blockdata_transaction_t; } cb_blockdata_transfer_t;
esp_err_t start_file_server(void); esp_err_t start_file_server(void);
HTTP_IO_RESULT HTTPPostApp(httpd_req_t *req, const char *filename, char *PostData); HTTP_IO_RESULT HTTPPostApp(httpd_req_t *req, const char *filename, char *PostData);
@ -108,8 +110,9 @@ esp_err_t download_get_handler(httpd_req_t *req);
esp_err_t upload_post_handler(httpd_req_t *req); esp_err_t upload_post_handler(httpd_req_t *req);
esp_err_t delete_post_handler(httpd_req_t *req); esp_err_t delete_post_handler(httpd_req_t *req);
esp_err_t ParseBlockDataObject(char *argres, blockdata_transaction_t *ft); esp_err_t ParseBlockDataObject(char *argres, cb_blockdata_transfer_t *ft);
void FileBlockHandler(char *argres, int rw, const char* path); void FileBlockHandler(char *argres, int rw, const char* path);
void FileListHandler(char *argres, int rw, const char* path); void FileListHandler(char *argres, int rw, const char* path);
void FileBlockTimeoutCounter();
#endif /* COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_HTTPSERVER_H_ */ #endif /* COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_HTTPSERVER_H_ */

View File

@ -121,8 +121,9 @@ esp_err_t ServiceDataHandler(data_message_t *MSG);
sys_error_code SysVarsPayloadHandler(data_message_t *MSG); sys_error_code SysVarsPayloadHandler(data_message_t *MSG);
void GetSysErrorDetales(sys_error_code err, const char **br, const char **ds); void GetSysErrorDetales(sys_error_code err, const char **br, const char **ds);
#ifdef CONFIG_WEBGUIAPP_I2C_ENABLE
esp_err_t eepr_i2c_read(uint16_t addr, uint8_t *data, int length); esp_err_t eepr_i2c_read(uint16_t addr, uint8_t *data, int length);
esp_err_t eepr_i2c_write(uint16_t addr, uint8_t *data, int length); esp_err_t eepr_i2c_write(uint16_t addr, uint8_t *data, int length);
#endif
#endif /* COMPONENTS_WEBGUIAPP_INCLUDE_SYSTEMAPPLICATION_H_ */ #endif /* COMPONENTS_WEBGUIAPP_INCLUDE_SYSTEMAPPLICATION_H_ */

View File

@ -42,5 +42,6 @@ void SetAppVars( rest_var_t* appvars, int size);
bool GetUserAppNeedReset(void); bool GetUserAppNeedReset(void);
void SetUserAppNeedReset(bool res); void SetUserAppNeedReset(bool res);
void LogFile(char *fname, char *format, ...); void LogFile(char *fname, char *format, ...);
void SysLog(char *format, ...);
#endif /* COMPONENTS_WEBGUIAPPCOMPONENT_INCLUDE_WEBGUIAPP_H_ */ #endif /* COMPONENTS_WEBGUIAPPCOMPONENT_INCLUDE_WEBGUIAPP_H_ */

View File

@ -24,6 +24,8 @@
#include "esp_log.h" #include "esp_log.h"
#include "esp_err.h" #include "esp_err.h"
#ifdef CONFIG_WEBGUIAPP_I2C_ENABLE
#define TAG "EEPROMDriver" #define TAG "EEPROMDriver"
#define I2C_MASTER_TIMEOUT_MS 1000 #define I2C_MASTER_TIMEOUT_MS 1000
@ -149,3 +151,5 @@ esp_err_t eepr_i2c_write(uint16_t addr, uint8_t *data, int length)
return ESP_OK; return ESP_OK;
} }
#endif

View File

@ -29,6 +29,7 @@
/* /*
{ {
"transid": 623787878,
"opertype" : 1, [1-READ, 2-DELETE, 3-WRITE] "opertype" : 1, [1-READ, 2-DELETE, 3-WRITE]
"part": 0, [] "part": 0, []
"parts": 3, [] "parts": 3, []
@ -38,16 +39,16 @@
} }
*/ */
#define READ_ORERATION 1 #define READ_ORERATION 1
#define DELETE_ORERATION 2 #define DELETE_ORERATION 2
#define WRITE_ORERATION 3 #define WRITE_ORERATION 3
static cb_blockdata_transfer_t FileTransaction = {
static blockdata_transaction_t FileTransaction = {
.opertype = 0 .opertype = 0
}; };
esp_err_t ParseBlockDataObject(char *argres, blockdata_transaction_t *ft) esp_err_t ParseBlockDataObject(char *argres, cb_blockdata_transfer_t *ft)
{ {
struct jReadElement result; struct jReadElement result;
jRead(argres, "", &result); jRead(argres, "", &result);
@ -57,6 +58,33 @@ esp_err_t ParseBlockDataObject(char *argres, blockdata_transaction_t *ft)
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
jRead(argres, "{'transid'", &result);
if (result.elements == 1)
{
int trans = atoi((char*) result.pValue);
if (ft->open_file_timeout != 0)
{
if (trans != ft->transid)
{
ESP_LOGW(TAG, "Attempt second client access while first is not finished");
snprintf(argres, VAR_MAX_VALUE_LENGTH, "\"Device is busy, please try later\"");
return ESP_ERR_NOT_FINISHED;
}
}
else
{
ft->transid = trans;
//ESP_LOGI(TAG, "New transaction with id %d", ft->transid);
}
}
else
{
snprintf(argres, VAR_MAX_VALUE_LENGTH, "\"ERROR:key 'transid' not found, frontend update needed\"");
return ESP_ERR_INVALID_ARG;
}
jRead(argres, "{'opertype'", &result); jRead(argres, "{'opertype'", &result);
if (result.elements == 1) if (result.elements == 1)
{ {
@ -139,12 +167,14 @@ esp_err_t ParseBlockDataObject(char *argres, blockdata_transaction_t *ft)
} }
void FileBlockHandler(char *argres, int rw, const char* path) void FileBlockHandler(char *argres, int rw, const char *path)
{ {
if (ParseBlockDataObject(argres, &FileTransaction) != ESP_OK) if (ParseBlockDataObject(argres, &FileTransaction) != ESP_OK)
return; return;
FileTransaction.open_file_timeout = BLOCK_OPERATION_TIMEOUT; //restart timeout on every block
//Phase of file operation calculate //Phase of file operation calculate
FileTransaction.operphase = 0; //Simple read or write FileTransaction.operphase = 0; //Simple read or write
if (FileTransaction.parts == 1) if (FileTransaction.parts == 1)
@ -166,6 +196,7 @@ void FileBlockHandler(char *argres, int rw, const char* path)
{ {
ESP_LOGE("FILE_API", "File does not exist : %s", FileTransaction.mem_object); ESP_LOGE("FILE_API", "File does not exist : %s", FileTransaction.mem_object);
snprintf(argres, VAR_MAX_VALUE_LENGTH, "\"ERROR:DIR_NOT_FOUND\""); snprintf(argres, VAR_MAX_VALUE_LENGTH, "\"ERROR:DIR_NOT_FOUND\"");
FileTransaction.open_file_timeout = 0;
return; return;
} }
} }
@ -185,6 +216,7 @@ void FileBlockHandler(char *argres, int rw, const char* path)
if (FileTransaction.opertype == DELETE_ORERATION) if (FileTransaction.opertype == DELETE_ORERATION)
{ {
unlink(FileTransaction.filepath); unlink(FileTransaction.filepath);
FileTransaction.open_file_timeout = 0;
snprintf(argres, VAR_MAX_VALUE_LENGTH, "\"DELETED OK\""); snprintf(argres, VAR_MAX_VALUE_LENGTH, "\"DELETED OK\"");
return; return;
} }
@ -216,6 +248,8 @@ void FileBlockHandler(char *argres, int rw, const char* path)
if (FileTransaction.operphase == 2 || FileTransaction.operphase == 3) if (FileTransaction.operphase == 2 || FileTransaction.operphase == 3)
{ {
fclose(FileTransaction.f); fclose(FileTransaction.f);
FileTransaction.f = NULL;
FileTransaction.open_file_timeout = 0;
ESP_LOGI("FILE_API", "Close file for read : %s", FileTransaction.mem_object); ESP_LOGI("FILE_API", "Close file for read : %s", FileTransaction.mem_object);
} }
dlen = 0; dlen = 0;
@ -226,6 +260,7 @@ void FileBlockHandler(char *argres, int rw, const char* path)
struct jWriteControl jwc; struct jWriteControl jwc;
jwOpen(&jwc, argres, VAR_MAX_VALUE_LENGTH, JW_OBJECT, JW_COMPACT); jwOpen(&jwc, argres, VAR_MAX_VALUE_LENGTH, JW_OBJECT, JW_COMPACT);
jwObj_int(&jwc, "transid", FileTransaction.transid);
jwObj_int(&jwc, "opertype", FileTransaction.opertype); jwObj_int(&jwc, "opertype", FileTransaction.opertype);
jwObj_int(&jwc, "parts", FileTransaction.parts); jwObj_int(&jwc, "parts", FileTransaction.parts);
jwObj_int(&jwc, "part", FileTransaction.part); jwObj_int(&jwc, "part", FileTransaction.part);
@ -236,6 +271,7 @@ void FileBlockHandler(char *argres, int rw, const char* path)
jwClose(&jwc); jwClose(&jwc);
free(scr); free(scr);
free(dst); free(dst);
} }
else if (FileTransaction.opertype == WRITE_ORERATION) else if (FileTransaction.opertype == WRITE_ORERATION)
{ {
@ -268,18 +304,22 @@ void FileBlockHandler(char *argres, int rw, const char* path)
if (FileTransaction.operphase == 2 || FileTransaction.operphase == 3) if (FileTransaction.operphase == 2 || FileTransaction.operphase == 3)
{ {
fclose(FileTransaction.f); fclose(FileTransaction.f);
FileTransaction.f = NULL;
FileTransaction.open_file_timeout = 0;
ESP_LOGI("FILE_API", "Close file for write : %s", FileTransaction.mem_object); ESP_LOGI("FILE_API", "Close file for write : %s", FileTransaction.mem_object);
} }
free(dst); free(dst);
struct jWriteControl jwc; struct jWriteControl jwc;
jwOpen(&jwc, argres, VAR_MAX_VALUE_LENGTH, JW_OBJECT, JW_COMPACT); jwOpen(&jwc, argres, VAR_MAX_VALUE_LENGTH, JW_OBJECT, JW_COMPACT);
jwObj_int(&jwc, "transid", FileTransaction.transid);
jwObj_int(&jwc, "opertype", FileTransaction.opertype); jwObj_int(&jwc, "opertype", FileTransaction.opertype);
jwObj_int(&jwc, "parts", FileTransaction.parts); jwObj_int(&jwc, "parts", FileTransaction.parts);
jwObj_int(&jwc, "part", FileTransaction.part); jwObj_int(&jwc, "part", FileTransaction.part);
jwObj_string(&jwc, "mem_object", FileTransaction.mem_object); jwObj_string(&jwc, "mem_object", FileTransaction.mem_object);
jwObj_int(&jwc, "size", write); jwObj_int(&jwc, "size", write);
jwClose(&jwc); jwClose(&jwc);
} }
else else
{ {
@ -297,7 +337,20 @@ void FileBlockHandler(char *argres, int rw, const char* path)
} }
void FileListHandler(char *argres, int rw, const char* path) void FileBlockTimeoutCounter()
{
if (FileTransaction.open_file_timeout)
{
if (--FileTransaction.open_file_timeout == 0)
{
if (FileTransaction.f != NULL)
fclose(FileTransaction.f);
}
}
//ESP_LOGI(TAG, "Block timeout %d", FileTransaction.open_file_timeout);
}
void FileListHandler(char *argres, int rw, const char *path)
{ {
char entrypath[FILE_PATH_MAX]; char entrypath[FILE_PATH_MAX];
char entrysize[16]; char entrysize[16];

View File

@ -45,6 +45,7 @@ static bool isPPPinitializing = false;
#define MAX_COMMAND_REPEATE_NUMBER 15 #define MAX_COMMAND_REPEATE_NUMBER 15
#define WATCHDOG_INTERVAL 30 #define WATCHDOG_INTERVAL 30
#define WAIT_FOR_GET_IP 30
static bool isPPPConn = false; static bool isPPPConn = false;
static int attimeout = 1000; static int attimeout = 1000;
@ -265,7 +266,7 @@ static void GSMInitTask(void *pvParameter) {
} }
ESP_LOGI(TAG, "PPP data mode OK"); ESP_LOGI(TAG, "PPP data mode OK");
xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, portMAX_DELAY); xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, pdMS_TO_TICKS(WAIT_FOR_GET_IP * 1000));
isPPPinitializing = false; isPPPinitializing = false;
vTaskDelete(NULL); vTaskDelete(NULL);
@ -279,8 +280,8 @@ modem_init_fail:
void PPPModemColdStart(void) { void PPPModemColdStart(void) {
ResetType = 0; ResetType = 0;
xTaskCreate(GSMInitTask, "GSMInitTask", 1024 * 6, &ResetType, 3, xTaskCreatePinnedToCore(GSMInitTask, "GSMInitTask", 1024 * 6, &ResetType, 3,
&initTaskhandle); &initTaskhandle, 1);
ESP_LOGI(TAG, "Start GSM cold initialization task"); ESP_LOGI(TAG, "Start GSM cold initialization task");
} }
@ -302,7 +303,7 @@ static void GSMRunTask(void *pvParameter) {
} }
void PPPModemStart(void) { void PPPModemStart(void) {
xTaskCreate(GSMRunTask, "GSMRunTask", 1024 * 4, &ResetType, 3, NULL); xTaskCreatePinnedToCore(GSMRunTask, "GSMRunTask", 1024 * 4, &ResetType, 3, NULL, 1);
} }
int PPPModemGetRSSI(void) { int PPPModemGetRSSI(void) {

View File

@ -536,7 +536,7 @@ const rest_var_t SystemVariables[] =
{ 0, "gsm_dns2", &SysConfig.gsmSettings.DNSAddr2, VAR_IPADDR, RW, 0, 0 }, { 0, "gsm_dns2", &SysConfig.gsmSettings.DNSAddr2, VAR_IPADDR, RW, 0, 0 },
{ 0, "gsm_dns3", &SysConfig.gsmSettings.DNSAddr3, VAR_IPADDR, RW, 0, 0 }, { 0, "gsm_dns3", &SysConfig.gsmSettings.DNSAddr3, VAR_IPADDR, RW, 0, 0 },
{ 0, "gsm_stat", &funct_gsm_stat, VAR_FUNCT, R, 0, 0 }, { 0, "gsm_stat", &funct_gsm_stat, VAR_FUNCT, R, 0, 0 },
#ifdef CONFIG_WEBGUIAPP_MODEM_AT_ACCESS #ifdef CONFIG_WEBGUIAPP_MODEM_AT_ACCESS
{ 0, "gsm_at_timeout", &funct_gsm_at_timeout, VAR_FUNCT, R, 0, 0 }, { 0, "gsm_at_timeout", &funct_gsm_at_timeout, VAR_FUNCT, R, 0, 0 },
{ 0, "gsm_at", &funct_gsm_at, VAR_FUNCT, R, 0, 0 }, { 0, "gsm_at", &funct_gsm_at, VAR_FUNCT, R, 0, 0 },
#endif #endif
@ -553,7 +553,7 @@ const rest_var_t SystemVariables[] =
{ 0, "serial_baud", &SysConfig.serialSettings.BaudRate, VAR_INT, RW, 1200, 4096000 }, { 0, "serial_baud", &SysConfig.serialSettings.BaudRate, VAR_INT, RW, 1200, 4096000 },
{ 0, "serial_break", &SysConfig.serialSettings.InputBrake, VAR_INT, RW, 1, 50 }, { 0, "serial_break", &SysConfig.serialSettings.InputBrake, VAR_INT, RW, 1, 50 },
{ 0, "serial_visible", (bool*) (&VAR_TRUE), VAR_BOOL, R, 0, 1 }, { 0, "serial_visible", (bool*) (&VAR_TRUE), VAR_BOOL, R, 0, 1 },
#else #else
{ 0, "serial_visible", (bool*) (&VAR_FALSE), VAR_BOOL, R, 0, 1 }, { 0, "serial_visible", (bool*) (&VAR_FALSE), VAR_BOOL, R, 0, 1 },
#endif #endif

View File

@ -154,7 +154,7 @@ void SecondTickSystem(void *param)
{ {
++UpTime; ++UpTime;
MidnightTimer(); MidnightTimer();
FileBlockTimeoutCounter();
} }
uint32_t GetUpTime(void) uint32_t GetUpTime(void)

View File

@ -109,7 +109,7 @@ esp_err_t WebGuiAppInit(void)
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND
|| ||
MANUAL_RESET == 1 MANUAL_RESET == 1
#if (MAIN_FUNCTIONAL_BUTTON_GPIO >= 0) #if (MAIN_FUNCTIONAL_BUTTON_GPIO >= 0)
|| gpio_get_level(MAIN_FUNCTIONAL_BUTTON_GPIO) == 0 || gpio_get_level(MAIN_FUNCTIONAL_BUTTON_GPIO) == 0
#endif #endif
) )
@ -592,6 +592,70 @@ void SetUserAppNeedReset(bool res)
isUserAppNeedReset = res; isUserAppNeedReset = res;
} }
#define LOG_MAX_CHUNK_SIZE CONFIG_WEBGUIAPP_SYSLOG_CHUNK_SIZE
#define LOG_MAX_CHUNKS CONFIG_WEBGUIAPP_SYSLOG_MAX_CHUNKS
#define DEFAULT_LOG_FILE_NAME "syslog"
#define LOG_PARTITION "/data/"
static void ComposeLogFilename(int chunk, char *filename)
{
char chunkstr[2];
strcpy(filename, LOG_PARTITION);
strcat(filename, DEFAULT_LOG_FILE_NAME);
itoa(chunk, chunkstr, 10);
strcat(filename, chunkstr);
strcat(filename, ".log");
}
void SysLog(char *format, ...)
{
char tstamp[ISO8601_TIMESTAMP_LENGTH + 2];
static int cur_chunk = 0, isstart = 1;
char filename[32];
struct stat file_stat;
FILE *f;
ComposeLogFilename(cur_chunk, filename);
//If first call after reboot, try to find not full chunk
if (isstart)
{
while (file_stat.st_size > LOG_MAX_CHUNK_SIZE * 1024 && cur_chunk <= LOG_MAX_CHUNKS - 1)
{
cur_chunk++;
ComposeLogFilename(cur_chunk, filename);
}
isstart = 0;
}
stat(filename, &file_stat);
//next if full, else append to current
if (file_stat.st_size > LOG_MAX_CHUNK_SIZE * 1024)
{
if (++cur_chunk > LOG_MAX_CHUNKS - 1)
cur_chunk = 0;
ComposeLogFilename(cur_chunk, filename);
f = fopen(filename, "w");
}
else
f = fopen(filename, "a");
if (f == NULL)
{
ESP_LOGE(TAG, "Failed to open file %s for writing", filename);
return;
}
va_list arg;
va_start(arg, format);
va_end(arg);
strcpy(tstamp, "\r\n");
char ts[ISO8601_TIMESTAMP_LENGTH];
GetISO8601Time(ts);
strcat(tstamp, ts);
strcat(tstamp, " ");
fwrite(tstamp, 1, strlen(tstamp), f);
vfprintf(f, format, arg);
fclose(f);
}
void LogFile(char *fname, char *format, ...) void LogFile(char *fname, char *format, ...)
{ {
char filename[32]; char filename[32];