From ba74f34bb536c1eb80076f9e288bffc93f7330ce Mon Sep 17 00:00:00 2001 From: Pawel Jalocha Date: Tue, 3 Nov 2020 02:47:57 +0000 Subject: [PATCH] Separate HTTP server code, list log files and download them in APRS format --- main/ap.cpp | 253 +-------------------------------- main/http.cpp | 385 ++++++++++++++++++++++++++++++++++++++++++++++++++ main/http.h | 4 + main/log.cpp | 2 +- main/log.h | 2 + 5 files changed, 393 insertions(+), 253 deletions(-) create mode 100644 main/http.cpp create mode 100644 main/http.h diff --git a/main/ap.cpp b/main/ap.cpp index 05b4dcb..2777051 100644 --- a/main/ap.cpp +++ b/main/ap.cpp @@ -12,6 +12,7 @@ #include "socket.h" #include "proc.h" #include "wifi.h" +#include "http.h" // #define DEBUG_PRINT @@ -19,258 +20,6 @@ // ============================================================================================================ -static void SelectList(httpd_req_t *Req, const char *Name, const char **List, int Size, int Sel=0) -{ char Line[8]; - httpd_resp_sendstr_chunk(Req, "\n"); } - -static void ParmForm_Info(httpd_req_t *Req) // produce HTML form for aircraft parameters -{ - httpd_resp_sendstr_chunk(Req, "
\n\n"); - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "
Info
Pilot
Crew
Base airfield
Registration
Manufacturer
Model
Type
\n"); } - -static void ParmForm_Acft(httpd_req_t *Req) // produce HTML form for aircraft parameters -{ char Line[16]; - - httpd_resp_sendstr_chunk(Req, "
\n\n"); - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - const char *AddrTypeTable[4] = { "Random", "ICAO", "FLARM", "OGN" } ; - httpd_resp_sendstr_chunk(Req, "\n"); - - const char *AcftTypeTable[16] = { "Unknown", "(moto)Glider", "Tow-plane", "Helicopter", "Parachute", "Drop-plane", "Hang-glider", "Para-glider", - "Powered-aircraft", "Jet-aircraft", "UFO", "Balloon", "Airship", "UAV/drone", "Ground support", "Static object" } ; - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "
Aircraft
Address>16)); Format_Hex(Line+2, (uint16_t)Parameters.Address); - httpd_resp_send_chunk(Req, Line, 6); - httpd_resp_sendstr_chunk(Req, "\">
Addr-Type\n"); - SelectList(Req, "AddrType", AddrTypeTable, 4, Parameters.AddrType); - httpd_resp_sendstr_chunk(Req, "
Acft-Type\n"); - SelectList(Req, "AcftType", AcftTypeTable, 16, Parameters.AcftType); - httpd_resp_sendstr_chunk(Req, "
\n"); } - -static void ParmForm_Other(httpd_req_t *Req) // produce HTML form for aircraft parameters -{ char Line[16]; int Len; - - httpd_resp_sendstr_chunk(Req, "
\n\n"); - httpd_resp_sendstr_chunk(Req, "\n"); - - const char *FreqPlanTable[16] = { "Auto", "Europe/Africa", "USA/Canada", "Australia/Chile", "New Zeeland", "Izrael" }; - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "
Other
Freq. plan\n"); - SelectList(Req, "FreqPlan", FreqPlanTable, 6, Parameters.FreqPlan); - httpd_resp_sendstr_chunk(Req, "
Tx power [dBm]
Freq.corr. [ppm]
Console baud
Verbose
OLED page sel.
\n"); } - -static void ParmForm_AP(httpd_req_t *Req) // Wi-Fi access point parameters { char Line[16]; int Len; -{ char Line[16]; int Len; - - httpd_resp_sendstr_chunk(Req, "
\n\n"); - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - - httpd_resp_sendstr_chunk(Req, "
Wi-Fi AP
SSID
Password
Data port
Tx [dBm]
\n"); } - -static esp_err_t parm_get_handler(httpd_req_t *Req) -{ char Line[32]; int Len; - uint16_t URLlen=httpd_req_get_url_query_len(Req); - if(URLlen) - { char *URL = (char *)malloc(URLlen+1); - httpd_req_get_url_query_str(Req, URL, URLlen+1); -#ifdef DEBUG_PRINT - xSemaphoreTake(CONS_Mutex, portMAX_DELAY); - Format_String(CONS_UART_Write, "parm_get_handler() => ["); - Format_SignDec(CONS_UART_Write, URLlen); - Format_String(CONS_UART_Write, "] "); - Format_String(CONS_UART_Write, URL); - Format_String(CONS_UART_Write, "\n"); - xSemaphoreGive(CONS_Mutex); -#endif - char *Line=URL; - for( ; ; ) - { Parameters.ReadLine(Line); - Line = strchr(Line, '&'); if(Line==0) break; - Line++; } - free(URL); - Parameters.WriteToNVS(); } - httpd_resp_sendstr_chunk(Req, "\ -\n\ -\n\ -\n\ -\n\ -\n\ -\n\ -OGN-Tracker configuration\n\ -"); - - httpd_resp_sendstr_chunk(Req, "

OGN-Tracker configuration

\n"); - httpd_resp_sendstr_chunk(Req, "CPU ID: "); - Len=Format_Hex(Line, getUniqueID()); - httpd_resp_send_chunk(Req, Line, Len); - httpd_resp_sendstr_chunk(Req, "
\n"); - - httpd_resp_sendstr_chunk(Req, "\n\n\n\n\n\n
\n"); - ParmForm_Acft(Req); - httpd_resp_sendstr_chunk(Req, "
\n"); - ParmForm_Other(Req); - httpd_resp_sendstr_chunk(Req, "
\n"); - ParmForm_Info(Req); - httpd_resp_sendstr_chunk(Req, "
\n"); - ParmForm_AP(Req); - httpd_resp_sendstr_chunk(Req, "
\n"); - httpd_resp_sendstr_chunk(Req, "
\n"); - httpd_resp_sendstr_chunk(Req, "\n"); - httpd_resp_sendstr_chunk(Req, "\n"); - httpd_resp_sendstr_chunk(Req, "
\n"); - httpd_resp_sendstr_chunk(Req, "
\n"); - httpd_resp_sendstr_chunk(Req, "\n\n"); - -/* - httpd_resp_sendstr_chunk(Req, "
\n"); - httpd_resp_sendstr_chunk(Req, "\n"); - httpd_resp_sendstr_chunk(Req, ""); - httpd_resp_sendstr_chunk(Req, "
\n"); -*/ - httpd_resp_sendstr_chunk(Req, 0); - return ESP_OK; } - -static esp_err_t top_get_handler(httpd_req_t *Req) -{ - httpd_resp_set_status(Req, "307 Temporary Redirect"); - httpd_resp_set_hdr(Req, "Location", "/parm.html"); - httpd_resp_send(Req, 0, 0); -/* - httpd_resp_sendstr_chunk(Req, "\ -\n\ -\n\ -OGN-Tracker status\n\ -"); - - httpd_resp_sendstr_chunk(Req, "

OGN-Tracker

\n"); - httpd_resp_sendstr_chunk(Req, "Configuration page\n"); - - httpd_resp_sendstr_chunk(Req, "\n"); - httpd_resp_sendstr_chunk(Req, 0); -*/ - return ESP_OK; } - -static const httpd_uri_t HTTPtop = -{ .uri = "/", - .method = HTTP_GET, - .handler = top_get_handler, - .user_ctx = 0 }; - -static const httpd_uri_t HTTPparm = -{ .uri = "/parm.html", - .method = HTTP_GET, - .handler = parm_get_handler, - .user_ctx = 0 }; - -static httpd_handle_t HTTPserver = 0; - -static esp_err_t HTTP_Start(int MaxSockets=4, int Port=80) -{ httpd_config_t Config = HTTPD_DEFAULT_CONFIG(); - Config.server_port = Port; - Config.task_priority = tskIDLE_PRIORITY+3; - Config.max_open_sockets = MaxSockets; - esp_err_t Err=httpd_start(&HTTPserver, &Config); if(Err!=ESP_OK) return Err; - httpd_register_uri_handler(HTTPserver, &HTTPtop); - httpd_register_uri_handler(HTTPserver, &HTTPparm); - return Err; } - -static void HTTP_Stop(void) -{ if(HTTPserver) httpd_stop(HTTPserver); HTTPserver=0; } - -// ============================================================================================================ - DataServer PortServer; static FIFO AP_TxFIFO; diff --git a/main/http.cpp b/main/http.cpp new file mode 100644 index 0000000..dc38210 --- /dev/null +++ b/main/http.cpp @@ -0,0 +1,385 @@ +#include +#include +#include +#include + +#include "hal.h" + +// #include "tcpip_adapter.h" +// #include "esp_wifi.h" +// #include "esp_event_loop.h" +#include "esp_http_server.h" + +#include "format.h" +// #include "fifo.h" +// #include "socket.h" +#include "proc.h" +// #include "wifi.h" +#include "log.h" +#include "http.h" + +// #define DEBUG_PRINT + +#ifdef WITH_HTTP + +// ============================================================================================================ + +static void SelectList(httpd_req_t *Req, const char *Name, const char **List, int Size, int Sel=0) +{ char Line[8]; + httpd_resp_sendstr_chunk(Req, "\n"); } + +static void ParmForm_Info(httpd_req_t *Req) // produce HTML form for aircraft parameters +{ + httpd_resp_sendstr_chunk(Req, "
\n\n"); + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "
Info
Pilot
Crew
Base airfield
Registration
Manufacturer
Model
Type
\n"); } + +static void ParmForm_Acft(httpd_req_t *Req) // produce HTML form for aircraft parameters +{ char Line[16]; + + httpd_resp_sendstr_chunk(Req, "
\n\n"); + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + const char *AddrTypeTable[4] = { "Random", "ICAO", "FLARM", "OGN" } ; + httpd_resp_sendstr_chunk(Req, "\n"); + + const char *AcftTypeTable[16] = { "Unknown", "(moto)Glider", "Tow-plane", "Helicopter", "Parachute", "Drop-plane", "Hang-glider", "Para-glider", + "Powered-aircraft", "Jet-aircraft", "UFO", "Balloon", "Airship", "UAV/drone", "Ground support", "Static object" } ; + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "
Aircraft
Address>16)); Format_Hex(Line+2, (uint16_t)Parameters.Address); + httpd_resp_send_chunk(Req, Line, 6); + httpd_resp_sendstr_chunk(Req, "\">
Addr-Type\n"); + SelectList(Req, "AddrType", AddrTypeTable, 4, Parameters.AddrType); + httpd_resp_sendstr_chunk(Req, "
Acft-Type\n"); + SelectList(Req, "AcftType", AcftTypeTable, 16, Parameters.AcftType); + httpd_resp_sendstr_chunk(Req, "
\n"); } + +static void ParmForm_Other(httpd_req_t *Req) // produce HTML form for aircraft parameters +{ char Line[16]; int Len; + + httpd_resp_sendstr_chunk(Req, "
\n\n"); + httpd_resp_sendstr_chunk(Req, "\n"); + + const char *FreqPlanTable[16] = { "Auto", "Europe/Africa", "USA/Canada", "Australia/Chile", "New Zeeland", "Izrael" }; + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "
Other
Freq. plan\n"); + SelectList(Req, "FreqPlan", FreqPlanTable, 6, Parameters.FreqPlan); + httpd_resp_sendstr_chunk(Req, "
Tx power [dBm]
Freq.corr. [ppm]
Console baud
Verbose
Page sel. mask
\n"); } + +#ifdef WITH_AP +static void ParmForm_AP(httpd_req_t *Req) // Wi-Fi access point parameters { char Line[16]; int Len; +{ char Line[16]; int Len; + + httpd_resp_sendstr_chunk(Req, "
\n\n"); + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + + httpd_resp_sendstr_chunk(Req, "
Wi-Fi
SSID
Password
Data port
Tx [dBm]>2, 2, 1); + httpd_resp_send_chunk(Req, Line, Len); + httpd_resp_sendstr_chunk(Req, "\">
\n"); } +#endif + +static esp_err_t parm_get_handler(httpd_req_t *Req) +{ char Line[32]; int Len; + uint16_t URLlen=httpd_req_get_url_query_len(Req); + if(URLlen) + { char *URL = (char *)malloc(URLlen+1); + httpd_req_get_url_query_str(Req, URL, URLlen+1); +#ifdef DEBUG_PRINT + xSemaphoreTake(CONS_Mutex, portMAX_DELAY); + Format_String(CONS_UART_Write, "parm_get_handler() => ["); + Format_SignDec(CONS_UART_Write, URLlen); + Format_String(CONS_UART_Write, "] "); + Format_String(CONS_UART_Write, URL); + Format_String(CONS_UART_Write, "\n"); + xSemaphoreGive(CONS_Mutex); +#endif + char *Line=URL; + for( ; ; ) + { Parameters.ReadLine(Line); + Line = strchr(Line, '&'); if(Line==0) break; + Line++; } + free(URL); + Parameters.WriteToNVS(); } + httpd_resp_sendstr_chunk(Req, "\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +OGN-Tracker configuration\n\ +"); + + httpd_resp_sendstr_chunk(Req, "

OGN-Tracker configuration

\n"); + httpd_resp_sendstr_chunk(Req, "CPU ID: "); + Len=Format_Hex(Line, getUniqueID()); + httpd_resp_send_chunk(Req, Line, Len); + httpd_resp_sendstr_chunk(Req, "
\n"); + + httpd_resp_sendstr_chunk(Req, "\n\n\n\n\n\n
\n"); + ParmForm_Acft(Req); + httpd_resp_sendstr_chunk(Req, "
\n"); + ParmForm_Info(Req); + httpd_resp_sendstr_chunk(Req, "
\n"); +#ifdef WITH_AP + ParmForm_AP(Req); + httpd_resp_sendstr_chunk(Req, "
\n"); +#endif + ParmForm_Other(Req); + httpd_resp_sendstr_chunk(Req, "
\n"); + httpd_resp_sendstr_chunk(Req, "
\n"); + httpd_resp_sendstr_chunk(Req, "\n"); + httpd_resp_sendstr_chunk(Req, "\n"); + httpd_resp_sendstr_chunk(Req, "
\n"); + httpd_resp_sendstr_chunk(Req, "
\n"); + httpd_resp_sendstr_chunk(Req, "\n\n"); + +/* + httpd_resp_sendstr_chunk(Req, "
\n"); + httpd_resp_sendstr_chunk(Req, "\n"); + httpd_resp_sendstr_chunk(Req, ""); + httpd_resp_sendstr_chunk(Req, "
\n"); +*/ + // httpd_resp_sendstr_chunk(Req, 0); + httpd_resp_send_chunk(Req, 0, 0); + return ESP_OK; } + +static esp_err_t top_get_handler(httpd_req_t *Req) +{ + httpd_resp_set_status(Req, "307 Temporary Redirect"); + httpd_resp_set_hdr(Req, "Location", "/parm.html"); + httpd_resp_send(Req, 0, 0); +/* + httpd_resp_sendstr_chunk(Req, "\ +\n\ +\n\ +OGN-Tracker status\n\ +"); + + httpd_resp_sendstr_chunk(Req, "

OGN-Tracker

\n"); + httpd_resp_sendstr_chunk(Req, "Configuration page\n"); + + httpd_resp_sendstr_chunk(Req, "\n"); + httpd_resp_sendstr_chunk(Req, 0); +*/ + return ESP_OK; } + +static int Format_DateTime(char *Out, time_t Time) +{ struct tm *TM = gmtime(&Time); + int Len=Format_UnsDec(Out, (uint16_t)1900+TM->tm_year, 4); + Out[Len++]='.'; + Len+=Format_UnsDec(Out+Len, (uint16_t)1+TM->tm_mon, 2); + Out[Len++]='.'; + Len+=Format_UnsDec(Out+Len, (uint16_t)TM->tm_mday, 2); + Out[Len++]=' '; + Len+=Format_UnsDec(Out+Len, (uint16_t)TM->tm_hour, 2); + Out[Len++]=':'; + Len+=Format_UnsDec(Out+Len, (uint16_t)TM->tm_min, 2); + Out[Len++]=':'; + Len+=Format_UnsDec(Out+Len, (uint16_t)TM->tm_sec, 2); + return Len; } + +static esp_err_t SendLog(httpd_req_t *Req, const char *FileName, uint32_t FileTime, bool Bin=0) +{ char Line[128]; + httpd_resp_set_type(Req, "text/plain"); + FILE *File = fopen(FileName, "rb"); if(File==0) { httpd_resp_send_chunk(Req, 0, 0); return ESP_OK; } + OGN_LogPacket Packet; + for( ; ; ) + { if(fread(&Packet, Packet.Bytes, 1, File)!=1) break; // read the next packet + if(!Packet.isCorrect()) continue; + uint32_t Time = Packet.getTime(FileTime); // [sec] get exact time from short time in the packet and the file start time + uint8_t Len=Packet.Packet.WriteAPRS(Line, Time); // print the packet in the APRS format + if(Len==0) continue; // if cannot be printed for whatever reason + httpd_resp_send_chunk(Req, Line, Len); + vTaskDelay(1); } + fclose(File); + httpd_resp_send_chunk(Req, 0, 0); + return ESP_OK; } + +static esp_err_t log_get_handler(httpd_req_t *Req) +{ char FullName[32]; char Line[32]; struct stat Stat; + // httpd_resp_set_status(Req, "307 Temporary Redirect"); + // httpd_resp_set_hdr(Req, "Location", "/parm.html"); + const char *Path= "/spiffs"; + + uint16_t URLlen=httpd_req_get_url_query_len(Req); + if(URLlen) + { char *URL = (char *)malloc(URLlen+1); + httpd_req_get_url_query_str(Req, URL, URLlen+1); + char Name[16]; + bool SendFile = httpd_query_key_value(URL, "File", Name, 16)==ESP_OK; + free(URL); + if(SendFile) + { AddPath(FullName, Name, Path); + uint32_t Time=FlashLog_ReadShortFileTime(Name); + if(Time) return SendLog(Req, FullName, Time); } + } + httpd_resp_sendstr_chunk(Req, "\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +OGN-Tracker log files\n\ +"); + + httpd_resp_sendstr_chunk(Req, "

OGN-Tracker log files

\n"); + + DIR *Dir=opendir(Path); + if(Dir) + { httpd_resp_sendstr_chunk(Req, "\n\n"); + for( ; ; ) + { struct dirent *Ent = readdir(Dir); if(!Ent) break; // read next directory entry, break if all read + if(Ent->d_type != DT_REG) continue; // skip non-regular files + char *Name = Ent->d_name; + uint32_t Time=FlashLog_ReadShortFileTime(Name); // read time from the file name + if(Time==0) continue; // skip if not .TLG format + AddPath(FullName, Name, Path); + uint32_t Size=0; + if(stat(FullName, &Stat)>=0) // get file info + Size = Stat.st_size; + httpd_resp_sendstr_chunk(Req, "\n"); + vTaskDelay(1); } + httpd_resp_sendstr_chunk(Req, "
File[KB]Date
"); + httpd_resp_sendstr_chunk(Req, Name); + httpd_resp_sendstr_chunk(Req, ""); + int Len=Format_UnsDec(Line, (Size+512)>>10); + httpd_resp_send_chunk(Req, Line, Len); + httpd_resp_sendstr_chunk(Req, ""); + Len=Format_DateTime(Line, Time); + httpd_resp_send_chunk(Req, Line, Len); + httpd_resp_sendstr_chunk(Req, "
\n"); + closedir(Dir); + } else httpd_resp_sendstr_chunk(Req, "

Cannot open the log directory !

\n"); + httpd_resp_sendstr_chunk(Req, "\n\n"); + httpd_resp_send_chunk(Req, 0, 0); + return ESP_OK; } + +static const httpd_uri_t HTTPtop = +{ .uri = "/", + .method = HTTP_GET, + .handler = top_get_handler, + .user_ctx = 0 }; + +static const httpd_uri_t HTTPparm = +{ .uri = "/parm.html", + .method = HTTP_GET, + .handler = parm_get_handler, + .user_ctx = 0 }; + +static const httpd_uri_t HTTPlog = +{ .uri = "/log.html", + .method = HTTP_GET, + .handler = log_get_handler, + .user_ctx = 0 }; + +static httpd_handle_t HTTPserver = 0; + +esp_err_t HTTP_Start(int MaxSockets, int Port) +{ httpd_config_t Config = HTTPD_DEFAULT_CONFIG(); + Config.server_port = Port; + Config.task_priority = tskIDLE_PRIORITY+3; + Config.max_open_sockets = MaxSockets; + esp_err_t Err=httpd_start(&HTTPserver, &Config); if(Err!=ESP_OK) return Err; + httpd_register_uri_handler(HTTPserver, &HTTPtop); // top URL + httpd_register_uri_handler(HTTPserver, &HTTPparm); // parameters URL + httpd_register_uri_handler(HTTPserver, &HTTPlog); // log files URL + return Err; } + +void HTTP_Stop(void) +{ if(HTTPserver) httpd_stop(HTTPserver); HTTPserver=0; } + +// ============================================================================================================ + +#endif // WITH_HTTP diff --git a/main/http.h b/main/http.h new file mode 100644 index 0000000..310dd4b --- /dev/null +++ b/main/http.h @@ -0,0 +1,4 @@ + +esp_err_t HTTP_Start(int MaxSockets=4, int Port=80); + +void HTTP_Stop(void); diff --git a/main/log.cpp b/main/log.cpp index 77b5b01..33c6a69 100644 --- a/main/log.cpp +++ b/main/log.cpp @@ -15,7 +15,7 @@ // #define DEBUG_PRINT -static void AddPath(char *Name, const char *FileName, const char *Path) +void AddPath(char *Name, const char *FileName, const char *Path) { if(Path==0) { strcpy(Name, FileName); return; } strcpy(Name, Path); int Len=strlen(Name); if(Name[Len-1]!='/') Name[Len++]='/'; diff --git a/main/log.h b/main/log.h index 9e99b37..fe335ca 100644 --- a/main/log.h +++ b/main/log.h @@ -3,6 +3,8 @@ extern FIFO, 32> FlashLog_FIFO; +void AddPath(char *Name, const char *FileName, const char *Path); + extern bool FlashLog_SaveReq; extern uint32_t FlashLog_FileTime; // [sec] start time of the current log file extern char FlashLog_FileName[32]; // current log file name if open