kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
Add connectivity to Stratux on WiFi and port 30011 and other minor updates
rodzic
330077f8de
commit
5bf77bf719
|
@ -111,7 +111,7 @@ static void ListLogFile(void)
|
|||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
uint32_t FileTime = SPIFFSlog_ReadShortFileTime((const char *)NMEA.ParmPtr(0), NMEA.ParmLen(0));
|
||||
uint32_t FileTime = FlashLog_ReadShortFileTime((const char *)NMEA.ParmPtr(0), NMEA.ParmLen(0));
|
||||
if(FileTime==0) return;
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
|
@ -120,7 +120,7 @@ static void ListLogFile(void)
|
|||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
SPIFFSlog_ListFile(FileTime);
|
||||
FlashLog_ListFile(FileTime);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -220,7 +220,7 @@ static void ProcessCtrlC(void) // print system
|
|||
static void ProcessCtrlL(void) // print system state to the console
|
||||
{
|
||||
#ifdef WITH_SPIFFS
|
||||
SPIFFSlog_ListFiles();
|
||||
FlashLog_ListFiles();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
#include "ctrl.h"
|
||||
#include "proc.h"
|
||||
|
||||
#ifdef WITH_STRATUX
|
||||
#include "stratux.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WIFI
|
||||
#include "wifi.h"
|
||||
#endif
|
||||
|
@ -556,6 +560,11 @@ void OLED_DrawStatusBar(u8g2_t *OLED, GPS_Position *GPS) // status bar on top
|
|||
{ u8g2_SetFont(OLED, u8g2_font_open_iconic_embedded_1x_t);
|
||||
u8g2_DrawGlyph(OLED, 36, 11, 0x4A); }
|
||||
#endif
|
||||
#ifdef WITH_STRATUX
|
||||
if(Stratux_isConnected())
|
||||
{ u8g2_SetFont(OLED, u8g2_font_open_iconic_embedded_1x_t);
|
||||
u8g2_DrawGlyph(OLED, 43, 11, 0x50); }
|
||||
#endif
|
||||
#ifdef WITH_WIFI
|
||||
if(WIFI_isConnected())
|
||||
{ u8g2_SetFont(OLED, u8g2_font_open_iconic_embedded_1x_t);
|
||||
|
|
|
@ -1661,7 +1661,7 @@ void IO_Configuration(void)
|
|||
|
||||
#ifdef WITH_M5_JACEK
|
||||
GPS_ANT_Dir();
|
||||
GPS_ANT_Sel(1); // 0 = external entenna
|
||||
GPS_ANT_Sel(0); // 0 = external entenna
|
||||
#endif
|
||||
|
||||
#ifdef PIN_PERIPH_RST
|
||||
|
|
245
main/log.cpp
245
main/log.cpp
|
@ -23,94 +23,98 @@ static void AddPath(char *Name, const char *FileName, const char *Path)
|
|||
|
||||
#ifdef WITH_SPIFFS
|
||||
|
||||
static const char *SDcard_Path = "/sdcard/TLG";
|
||||
static const char *SPIFFSlog_Path = "/spiffs"; // path to log files
|
||||
static const char *SPIFFSlog_Ext = ".TLG"; // extension for log files, could be as well .TLA
|
||||
static const uint32_t SPIFFSlog_MaxTime = 7200; // 2 hour max. per single log file
|
||||
static const uint32_t SPIFFSlog_MaxSize = 0x20000; // 128KB max. per single log file
|
||||
// static uint32_t SPIFFSlogOldestTime;
|
||||
uint32_t SPIFFSlog_FileTime=0;
|
||||
char SPIFFSlog_FileName[32]; // current log file name if open
|
||||
static FILE *SPIFFSlog_File=0; // current log file if open
|
||||
static const char *SDcard_Path = "/sdcard/TLG"; // with sub-directory which is created if does not exist
|
||||
static const char *FlashLog_Path = "/spiffs"; // path to log files
|
||||
static const char *FlashLog_Ext = ".TLG"; // extension for log files, could be as well .TLA
|
||||
static const uint32_t FlashLog_MaxTime = 7200; // 2 hour max. per single log file
|
||||
static const uint32_t FlashLog_MaxSize = 0x20000; // 128KB max. per single log file
|
||||
// static uint32_t FlashLog_OldestTime;
|
||||
uint32_t FlashLog_FileTime=0;
|
||||
char FlashLog_FileName[32]; // current log file name if open
|
||||
static FILE *FlashLog_File=0; // current log file if open
|
||||
|
||||
FIFO<OGN_LogPacket<OGN_Packet>, 32> LOG_FIFO;
|
||||
FIFO<OGN_LogPacket<OGN_Packet>, 32> FlashLog_FIFO;
|
||||
|
||||
int SPIFFSlog_ShortFileName(char *FileName, uint32_t Time) // make just the short (without path) file name for given start date
|
||||
{ int Len = Format_Hex(FileName, Time); // Time in %08X format
|
||||
strcpy(FileName+Len, SPIFFSlog_Ext); Len+=strlen(SPIFFSlog_Ext); // add extension
|
||||
FileName[Len]=0; return Len; } // return the name length, should be 12 characters
|
||||
int FlashLog_ShortFileName(char *FileName, uint32_t Time) // make the short (without path) file name for given start date
|
||||
{ int Len = Format_Hex(FileName, Time); // Time in %08X format
|
||||
strcpy(FileName+Len, FlashLog_Ext); Len+=strlen(FlashLog_Ext); // add extension
|
||||
FileName[Len]=0; return Len; } // return the name length, should be 12 characters
|
||||
|
||||
int SPIFFSlog_FullFileName(char *FileName, uint32_t Time) // make the full (long) log file name for given start time
|
||||
{ strcpy(FileName, SPIFFSlog_Path); // copy the path
|
||||
int FlashLog_FullFileName(char *FileName, uint32_t Time) // make the full (long) log file name for given start time
|
||||
{ strcpy(FileName, FlashLog_Path); // copy the path
|
||||
int Len = strlen(FileName);
|
||||
if(FileName[Len-1]!='/') FileName[Len++]='/';
|
||||
return Len += SPIFFSlog_ShortFileName(FileName+Len, Time); } // return the length of the file name
|
||||
return Len += FlashLog_ShortFileName(FileName+Len, Time); } // return the length of the file name
|
||||
|
||||
uint32_t SPIFFSlog_ReadShortFileTime(const char *FileName, int Len) // extract the time from the short file name
|
||||
{ if(Len!=12) return 0; // file name must be 12 char long
|
||||
if(memcmp(FileName+8, SPIFFSlog_Ext, 4)!=0) return 0; // extension must be .TLx (x is normally G or A)
|
||||
uint32_t FlashLog_ReadShortFileTime(const char *FileName, int Len) // extract the time from the short file name
|
||||
{ if(Len!=12) return 0; // file name must be 12 char long
|
||||
if(memcmp(FileName+8, FlashLog_Ext, 4)!=0) return 0; // extension must be .TLx (x is normally G or A)
|
||||
uint32_t Time=0;
|
||||
if(Read_Hex(Time, FileName)!=8) return 0; // read start time, give up if other format
|
||||
return Time; } // return the extracted time
|
||||
if(Read_Hex(Time, FileName)!=8) return 0; // read start time, give up if other format
|
||||
return Time; } // return the extracted time (or zero when unexpected name format)
|
||||
|
||||
uint32_t SPIFFSlog_ReadShortFileTime(const char *FileName) //
|
||||
{ return SPIFFSlog_ReadShortFileTime(FileName, strlen(FileName)); }
|
||||
uint32_t FlashLog_ReadShortFileTime(const char *FileName) //
|
||||
{ return FlashLog_ReadShortFileTime(FileName, strlen(FileName)); }
|
||||
|
||||
int SPIFFSlog_CopyToSD(void) // copy log files to SD card
|
||||
#ifdef WITH_SD
|
||||
int FlashLog_CopyToSD(bool Remove) // copy log files to SD card
|
||||
{ int Files=0;
|
||||
struct stat DstStat;
|
||||
struct utimbuf DstTime;
|
||||
char SrcName[32];
|
||||
char DstName[32];
|
||||
const int BuffSize=2048;
|
||||
uint8_t Buffer[BuffSize];
|
||||
DIR *Dir=opendir(SPIFFSlog_Path); if(!Dir) return -1; // open directory, give up if not possible
|
||||
char SrcName[32]; // full name of the source file
|
||||
char DstName[32]; // full name of the destination file
|
||||
const int BuffSize=2048; //
|
||||
uint8_t Buffer[BuffSize]; // buffer to copy from source to destination
|
||||
DIR *Dir=opendir(FlashLog_Path); if(!Dir) return -1; // open directory, give up if not possible
|
||||
for( ; ; )
|
||||
{ vTaskDelay(1); // give some time to parallel tasks
|
||||
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
|
||||
{ vTaskDelay(1); // give some time to parallel tasks
|
||||
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=SPIFFSlog_ReadShortFileTime(Name); // read time from the file name
|
||||
if(Time==0) continue; // skip if not .TLG format
|
||||
AddPath(SrcName, Name, SPIFFSlog_Path);
|
||||
// strcpy(SrcName, SPIFFSlog_Path); strcat(SrcName, Name); // form full source file name
|
||||
AddPath(DstName, Name, SDcard_Path);
|
||||
// strcpy(DstName, SDcard_Path); strcat(DstName, Name); // form full destination file name
|
||||
FILE *SrcFile = fopen(SrcName, "rb"); if(SrcFile==0) continue; // open source file
|
||||
FILE *DstFile = fopen(DstName, "wb");
|
||||
{ if(mkdir(SDcard_Path, 0777)<0) continue;
|
||||
DstFile = fopen(DstName, "wb"); }
|
||||
if(DstFile==0) { fclose(SrcFile); continue; } // open destination file
|
||||
uint32_t Time=FlashLog_ReadShortFileTime(Name); // read time from the file name
|
||||
if(Time==0) continue; // skip if not .TLG format
|
||||
AddPath(DstName, Name, SDcard_Path); // full name of the destination file
|
||||
if(stat(DstName, &DstStat)>=0) continue; // if the destination file exists already
|
||||
AddPath(SrcName, Name, FlashLog_Path); // full name of the source file
|
||||
FILE *DstFile = fopen(DstName, "wb"); // open destination file
|
||||
if(DstFile==0) // if can't open destination file
|
||||
{ if(mkdir(SDcard_Path, 0777)<0) break; // attempt to create sub-directory
|
||||
DstFile = fopen(DstName, "wb"); } // and open the dest. file again
|
||||
if(DstFile==0) break; // if not possible to open the dest. file then give up
|
||||
FILE *SrcFile = fopen(SrcName, "rb"); // open source file
|
||||
if(SrcFile==0) { fclose(DstFile); continue; } // if not possible then skip to next source
|
||||
for( ; ; )
|
||||
{ int Read=fread(Buffer, 1, BuffSize, SrcFile); if(Read<=0) break; // keep copying
|
||||
{ int Read=fread(Buffer, 1, BuffSize, SrcFile); if(Read<=0) break; // keep copying
|
||||
int Write=fwrite(Buffer, 1, Read, DstFile); if(Read<BuffSize || Write<Read) break; } // until EOF
|
||||
fclose(SrcFile); // close source file
|
||||
fclose(DstFile); // close destination file
|
||||
if(stat(DstName, &DstStat)>=0) // get file attributes (maybe not really needed)
|
||||
{ DstTime.actime = Time; // set access and modification times of the dest. file
|
||||
fclose(SrcFile); // close source file
|
||||
fclose(DstFile); // close destination file
|
||||
if(stat(DstName, &DstStat)>=0) // get file attributes (maybe not really needed)
|
||||
{ DstTime.actime = Time; // set access and modification times of the dest. file
|
||||
DstTime.modtime = Time;
|
||||
utime(DstName, &DstTime); } // write to the FAT
|
||||
Files++; }
|
||||
closedir(Dir); // close directory (for searching of log files)
|
||||
return Files; }
|
||||
utime(DstName, &DstTime); } // write to the FAT
|
||||
if(Remove) unlink(SrcName); // remove source file if requested
|
||||
Files++; } // count copied files
|
||||
closedir(Dir); // close directory (for searching of log files)
|
||||
return Files; } // return number of copied files
|
||||
#endif
|
||||
|
||||
int SPIFFSlog_FindOldestFile(uint32_t &Oldest, uint32_t After) // find the oldest log file, but not older than given time
|
||||
int FlashLog_FindOldestFile(uint32_t &Oldest, uint32_t After) // find the oldest log file, but not older than given time
|
||||
{ int Files=0;
|
||||
Oldest=0xFFFFFFFF; // possibly oldest time
|
||||
DIR *Dir=opendir(SPIFFSlog_Path); if(!Dir) return -1; // open directory, give up if not possible
|
||||
DIR *Dir=opendir(FlashLog_Path); if(!Dir) return -1; // open directory, give up if not possible
|
||||
for( ; ; )
|
||||
{ vTaskDelay(1);
|
||||
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=SPIFFSlog_ReadShortFileTime(Name); // read time from the file name, skip if other format
|
||||
uint32_t Time=FlashLog_ReadShortFileTime(Name); // read time from the file name, skip if other format
|
||||
if(Time<=After) continue; // but not older than
|
||||
if(Time<Oldest) Oldest=Time; // search for oldest start time
|
||||
Files++; }
|
||||
closedir(Dir);
|
||||
return Files; } // return number of log files
|
||||
|
||||
int SPIFFSlog_ListFiles(void) // list log files sorted by time
|
||||
int FlashLog_ListFiles(void) // list log files sorted by time
|
||||
{ int Files=0;
|
||||
char Line[64];
|
||||
char FullName[32];
|
||||
|
@ -120,15 +124,15 @@ int SPIFFSlog_ListFiles(void) // list log files
|
|||
for( ; ; )
|
||||
{ vTaskDelay(1); // not to overload the priority level
|
||||
uint32_t Time = 0;
|
||||
SPIFFSlog_FindOldestFile(Time, PrevTime); // find the next oldest file
|
||||
FlashLog_FindOldestFile(Time, PrevTime); // find the next oldest file
|
||||
if(Time==0xFFFFFFFF) break; // if none found then stop the list
|
||||
PrevTime=Time;
|
||||
SPIFFSlog_FullFileName(FullName, Time);
|
||||
FlashLog_FullFileName(FullName, Time);
|
||||
if(stat(FullName, &Stat)<0) continue; // get file info
|
||||
int Size = Stat.st_size; // if above minimum size: skip
|
||||
strcpy(Line, "$POGNL,");
|
||||
uint8_t Len=7;
|
||||
// strcpy(Line+Len, FullName+strlen(SPIFFSlog_Path)); Len+=12; // print the short name only
|
||||
// strcpy(Line+Len, FullName+strlen(FlashLog_Path)); Len+=12; // print the short name only
|
||||
const char *Name = strrchr(FullName, '/'); Name++;
|
||||
strcpy(Line+Len, Name); Len+=strlen(Name); // print the short name only
|
||||
Line[Len++]=',';
|
||||
|
@ -143,9 +147,9 @@ int SPIFFSlog_ListFiles(void) // list log files
|
|||
return Files; }
|
||||
|
||||
/*
|
||||
int SPIFFSlog_ListFiles(void) //
|
||||
int FlashLog_ListFiles(void) //
|
||||
{ int Files=0;
|
||||
char FullName[32]; strcpy(FullName, SPIFFSlogPath); int PathLen=strlen(SPIFFSlogPath);
|
||||
char FullName[32]; strcpy(FullName, FlashLogPath); int PathLen=strlen(FlashLogPath);
|
||||
char HHMMSS[8];
|
||||
struct stat Stat;
|
||||
DIR *Dir=opendir(SPIFFSlogPath); if(!Dir) return -1; // open the file directory
|
||||
|
@ -153,7 +157,7 @@ int SPIFFSlog_ListFiles(void) //
|
|||
{ 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 = SPIFFSlog_ReadShortFileTime(Name); if(Time==0) continue;
|
||||
uint32_t Time = FlashLog_ReadShortFileTime(Name); if(Time==0) continue;
|
||||
strcpy(FullName+PathLen, Name);
|
||||
if(stat(FullName, &Stat)<0) continue; // get file info
|
||||
int Size = Stat.st_size; // if above minimum size: skip
|
||||
|
@ -170,10 +174,10 @@ int SPIFFSlog_ListFiles(void) //
|
|||
return Files; }
|
||||
*/
|
||||
|
||||
int SPIFFSlog_ListFile(const char *FileName, uint32_t FileTime) // print the content of the given log file
|
||||
int FlashLog_ListFile(const char *FileName, uint32_t FileTime) // print the content, thue every packet of the given log file in APRS format
|
||||
{ char Line[128];
|
||||
// xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
// Format_String(CONS_UART_Write, "SPIFFSlog_ListFile(");
|
||||
// Format_String(CONS_UART_Write, "FlashLog_ListFile(");
|
||||
// Format_String(CONS_UART_Write, FileName);
|
||||
// Format_String(CONS_UART_Write, ")\n");
|
||||
// xSemaphoreGive(CONS_Mutex);
|
||||
|
@ -181,44 +185,44 @@ int SPIFFSlog_ListFile(const char *FileName, uint32_t FileTime) // print the
|
|||
OGN_LogPacket<OGN_Packet> Packet;
|
||||
int Packets=0;
|
||||
for( ; ; )
|
||||
{ if(fread(&Packet, Packet.Bytes, 1, File)!=1) break;
|
||||
{ if(fread(&Packet, Packet.Bytes, 1, File)!=1) break; // read the next packet
|
||||
if(!Packet.isCorrect()) continue;
|
||||
if(Packet.Packet.Header.NonPos) continue;
|
||||
uint32_t Time = Packet.getTime(FileTime);
|
||||
if(Packet.Packet.Header.NonPos) continue; // skip non-position packets (although we could print them too)
|
||||
uint32_t Time = Packet.getTime(FileTime); // [sec] get exact time from short time in the packet and the file start time
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
uint8_t Len=Packet.Packet.WriteAPRS(Line, Time);
|
||||
Format_String(CONS_UART_Write, Line, 0, Len);
|
||||
uint8_t Len=Packet.Packet.WriteAPRS(Line, Time); // print the packet in the APRS format
|
||||
Format_String(CONS_UART_Write, Line, 0, Len); // send the APRS to the console
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
vTaskDelay(10);
|
||||
Packets++; }
|
||||
vTaskDelay(10); // limit the printout to some 100 packet/sec
|
||||
Packets++; } // count printed packets
|
||||
fclose(File);
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); //
|
||||
Format_String(CONS_UART_Write, FileName);
|
||||
Format_String(CONS_UART_Write, " => ");
|
||||
Format_UnsDec(CONS_UART_Write, (uint32_t)Packets);
|
||||
Format_String(CONS_UART_Write, " packets\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
return Packets; }
|
||||
return Packets; } // return number of packets sent to the console
|
||||
|
||||
int SPIFFSlog_ListFile(uint32_t FileTime) //
|
||||
int FlashLog_ListFile(uint32_t FileTime) //
|
||||
{ char FileName[32];
|
||||
SPIFFSlog_FullFileName(FileName, FileTime);
|
||||
return SPIFFSlog_ListFile(FileName, FileTime); }
|
||||
FlashLog_FullFileName(FileName, FileTime);
|
||||
return FlashLog_ListFile(FileName, FileTime); }
|
||||
|
||||
static int SPIFFSlog_CleanEmpty(int MinSize=0) // delete empty files or below certain minimum size
|
||||
static int FlashLog_CleanEmpty(int MinSize=0) // delete empty files or below certain minimum size
|
||||
{ const int MaxDelFiles = 4;
|
||||
uint32_t DelFile[MaxDelFiles];
|
||||
int DelFiles=0;
|
||||
char FullName[32];
|
||||
strcpy(FullName, SPIFFSlog_Path); int PathLen=strlen(FullName);
|
||||
strcpy(FullName, FlashLog_Path); int PathLen=strlen(FullName);
|
||||
if(FullName[PathLen-1]!='/') FullName[PathLen++]='/';
|
||||
struct stat Stat;
|
||||
DIR *Dir=opendir(SPIFFSlog_Path); if(!Dir) return -1; // open the file directory
|
||||
DIR *Dir=opendir(FlashLog_Path); if(!Dir) return -1; // open the file directory
|
||||
for( ; ; ) // run through the directory
|
||||
{ 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 = SPIFFSlog_ReadShortFileTime(Name); if(Time==0) continue;
|
||||
uint32_t Time = FlashLog_ReadShortFileTime(Name); if(Time==0) continue;
|
||||
strcpy(FullName+PathLen, Name);
|
||||
if( Time>=0x10000000 && Time<0x80000000 ) // heuristic data selection
|
||||
{ if(stat(FullName, &Stat)<0) continue; // get file info
|
||||
|
@ -227,26 +231,26 @@ static int SPIFFSlog_CleanEmpty(int MinSize=0) // delete empty f
|
|||
vTaskDelay(1); }
|
||||
closedir(Dir);
|
||||
for( int File=0; File<DelFiles; File++)
|
||||
{ SPIFFSlog_FullFileName(FullName, DelFile[File]);
|
||||
{ FlashLog_FullFileName(FullName, DelFile[File]);
|
||||
unlink(FullName);
|
||||
vTaskDelay(1); }
|
||||
return DelFiles; }
|
||||
|
||||
static int SPIFFSlog_Clean(size_t MinFree) // clean oldest file when running short in space
|
||||
static int FlashLog_Clean(size_t MinFree) // clean oldest file when running short in space
|
||||
{ size_t Total, Used;
|
||||
if(SPIFFS_Info(Total, Used)!=0) return -1; // check SPIFFS status, give up if not possible
|
||||
size_t Free = Total-Used; // [B] amount of free space
|
||||
if(MinFree) { if(Free>= MinFree ) return 0; } // give up if enough space
|
||||
else { if(Free>=(Total/2)) return 0; } // if MinFree not specified, take Total/4
|
||||
uint32_t Oldest=0xFFFFFFFF;
|
||||
int Files=SPIFFSlog_FindOldestFile(Oldest, 0); // find the oldest file
|
||||
int Files=FlashLog_FindOldestFile(Oldest, 0); // find the oldest file
|
||||
if(Files<0) return Files;
|
||||
if(Files<=2) return 0; // if two or less files give up
|
||||
char FullName[32];
|
||||
SPIFFSlog_FullFileName(FullName, Oldest); // oldest file name
|
||||
FlashLog_FullFileName(FullName, Oldest); // oldest file name
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "SPIFFSlog_Clean() ");
|
||||
Format_String(CONS_UART_Write, "FlashLog_Clean() ");
|
||||
Format_String(CONS_UART_Write, FullName);
|
||||
CONS_UART_Write(' ');
|
||||
Format_UnsDec(CONS_UART_Write, (uint32_t)Files);
|
||||
|
@ -256,52 +260,57 @@ static int SPIFFSlog_Clean(size_t MinFree) // clean old
|
|||
if(unlink(FullName)<0) return -1; // remove the oldest file
|
||||
return 1; }
|
||||
|
||||
static int SPIFFSlog_Clean(size_t MinFree, int Loops) // repeat the clean procedure several times
|
||||
static int FlashLog_Clean(size_t MinFree, int Loops) // repeat the clean procedure several times
|
||||
{ int Count=0;
|
||||
for( ; Loops>0; Loops--)
|
||||
{ if(SPIFFSlog_Clean(MinFree)<=0) break;
|
||||
{ if(FlashLog_Clean(MinFree)<=0) break;
|
||||
vTaskDelay(1); Count++; }
|
||||
return Count; }
|
||||
|
||||
static int SPIFFSlog_Open(uint32_t Time) // open a new log file for given start time
|
||||
{ if(SPIFFSlog_File) { fclose(SPIFFSlog_File); SPIFFSlog_File=0; } // if a file open already, close it
|
||||
SPIFFSlog_CleanEmpty(32); // remove empty files or shorter than 32 bytes
|
||||
SPIFFSlog_Clean(2*SPIFFSlog_MaxSize, 8); // clean files to get free space at least twice the max. file sie
|
||||
SPIFFSlog_FullFileName(SPIFFSlog_FileName, Time); // name of the new log file
|
||||
SPIFFSlog_FileTime=Time; // record the time of the log file
|
||||
SPIFFSlog_File = fopen(SPIFFSlog_FileName, "wb"); // open the new file
|
||||
static int FlashLog_Open(uint32_t Time) // open a new log file for given start time
|
||||
{ if(FlashLog_File) { fclose(FlashLog_File); FlashLog_File=0; } // if a file open already, close it
|
||||
FlashLog_CleanEmpty(32); // remove empty files or shorter than 32 bytes
|
||||
FlashLog_Clean(2*FlashLog_MaxSize, 8); // clean files to get free space at least twice the max. file sie
|
||||
FlashLog_FullFileName(FlashLog_FileName, Time); // name of the new log file
|
||||
FlashLog_FileTime=Time; // record the time of the log file
|
||||
FlashLog_File = fopen(FlashLog_FileName, "wb"); // open the new file
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "SPIFFSlog_Open() ");
|
||||
Format_String(CONS_UART_Write, SPIFFSlog_FileName);
|
||||
Format_String(CONS_UART_Write, "FlashLog_Open() ");
|
||||
Format_String(CONS_UART_Write, FlashLog_FileName);
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
if(SPIFFSlog_File==0) SPIFFSlog_Clean(0, 8); // if the file cannot be open clean again
|
||||
return SPIFFSlog_File!=0; } // 1=success, 0=failure: new log file could not be open
|
||||
if(FlashLog_File==0) FlashLog_Clean(0, 8); // if the file cannot be open clean again
|
||||
return FlashLog_File!=0; } // 1=success, 0=failure: new log file could not be open
|
||||
|
||||
static int SPIFFSlog(OGN_LogPacket<OGN_Packet> *Packet, int Packets, uint32_t Time) // log a batch of OGN packets
|
||||
{ if(SPIFFSlog_File)
|
||||
{ uint32_t TimeSinceStart = Time-SPIFFSlog_FileTime; // [sec] for how long this file is open already ?
|
||||
if( (TimeSinceStart>=SPIFFSlog_MaxTime) || (ftell(SPIFFSlog_File)>=SPIFFSlog_MaxSize) ) // is it too long in time or in size ?
|
||||
{ fclose(SPIFFSlog_File); SPIFFSlog_File=0; } // decide to close the current log file
|
||||
static int FlashLog(OGN_LogPacket<OGN_Packet> *Packet, int Packets, uint32_t Time) // log a batch of OGN packets
|
||||
{ if(FlashLog_File) // if log file already open
|
||||
{ uint32_t TimeSinceStart = Time-FlashLog_FileTime; // [sec] for how long this file is open already ?
|
||||
if( (TimeSinceStart>=FlashLog_MaxTime) || (ftell(FlashLog_File)>=FlashLog_MaxSize) ) // is it too long in time or in size ?
|
||||
{ fclose(FlashLog_File); FlashLog_File=0; } // decide to close the current log file
|
||||
}
|
||||
if(SPIFFSlog_File==0) SPIFFSlog_Open(Time); // if file closed, then attempt to open a new one
|
||||
if(SPIFFSlog_File==0) return -1; // if file still not open, then give up
|
||||
if(fwrite(Packet, Packet->Bytes, Packets, SPIFFSlog_File)!=Packets) // write the packet to the log file
|
||||
{ fclose(SPIFFSlog_File); SPIFFSlog_File=0; SPIFFSlog_Clean(0, 8); return -1; } // if failure then close the log file and report error
|
||||
if(FlashLog_File==0)
|
||||
{
|
||||
#ifdef WITH_SD
|
||||
FlashLog_CopyToSD();
|
||||
#endif
|
||||
FlashLog_Open(Time); } // if file closed, then attempt to open a new one
|
||||
if(FlashLog_File==0) return -1; // if file still not open, then give up
|
||||
if(fwrite(Packet, Packet->Bytes, Packets, FlashLog_File)!=Packets) // write the packet to the log file
|
||||
{ fclose(FlashLog_File); FlashLog_File=0; FlashLog_Clean(0, 8); return -1; } // if failure then close the log file and report error
|
||||
return Packets; } // report success
|
||||
#endif // WITH_SPIFFS
|
||||
|
||||
static int Copy(void) // copy the packets from the LOG_FIFO to the log file
|
||||
static int Copy(void) // copy the packets from the FlashLog_FIFO to the log file
|
||||
{ OGN_LogPacket<OGN_Packet> *Packet;
|
||||
size_t Packets = LOG_FIFO.getReadBlock(Packet); // ask for a block o packets
|
||||
size_t Packets = FlashLog_FIFO.getReadBlock(Packet); // ask for a block o packets
|
||||
if(Packets==0) return 0; // if none: give up
|
||||
uint32_t Time = TimeSync_Time(); // Time is to create new log file
|
||||
#ifdef WITH_SPIFFS
|
||||
int Err=SPIFFSlog(Packet, Packets, Time); // log the batch of packets
|
||||
if(Err<0) { SPIFFSlog_Clean(0, 8); Err=SPIFFSlog(Packet, Packets, Time); } // if failed: give it another try
|
||||
// if(Err<0) SPIFFSlog_Clean(0, 8);
|
||||
int Err=FlashLog(Packet, Packets, Time); // log the batch of packets
|
||||
if(Err<0) { FlashLog_Clean(0, 8); Err=FlashLog(Packet, Packets, Time); } // if failed: give it another try
|
||||
// if(Err<0) FlashLog_Clean(0, 8);
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "vTaskLOG() ");
|
||||
|
@ -312,7 +321,7 @@ static int Copy(void) // copy the p
|
|||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
#endif
|
||||
LOG_FIFO.flushReadBlock(Packets); // remove the copied packets from the LOG_FIFO
|
||||
FlashLog_FIFO.flushReadBlock(Packets); // remove the copied packets from the FlashLog_FIFO
|
||||
#ifdef WITH_SPIFFS
|
||||
return Err;
|
||||
#else
|
||||
|
@ -325,7 +334,7 @@ static int Copy(void) // copy the p
|
|||
#endif
|
||||
void vTaskLOG(void* pvParameters)
|
||||
{
|
||||
LOG_FIFO.Clear();
|
||||
FlashLog_FIFO.Clear();
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
|
@ -345,15 +354,15 @@ void vTaskLOG(void* pvParameters)
|
|||
|
||||
#ifdef WITH_SD
|
||||
#ifdef WITH_SPIFFS
|
||||
SPIFFSlog_CopyToSD(); // copy all flash log files to the SD card
|
||||
FlashLog_CopyToSD(); // copy all flash log files to the SD card
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TickType_t PrevTick = 0;
|
||||
for( ; ; )
|
||||
{ // vTaskDelay(200); // wait idle 0.2sec
|
||||
TickType_t Tick=xTaskGetTickCount(); //
|
||||
size_t Packets = LOG_FIFO.Full(); // how many packets in the queue ?
|
||||
TickType_t Tick=xTaskGetTickCount(); // system tick count now
|
||||
size_t Packets = FlashLog_FIFO.Full(); // how many packets in the queue ?
|
||||
// #ifdef DEBUG_PRINT
|
||||
// xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
// Format_String(CONS_UART_Write, "TaskLOG() ");
|
||||
|
|
26
main/log.h
26
main/log.h
|
@ -1,20 +1,20 @@
|
|||
#include "fifo.h"
|
||||
#include "ogn.h"
|
||||
|
||||
extern FIFO<OGN_LogPacket<OGN_Packet>, 32> LOG_FIFO;
|
||||
extern FIFO<OGN_LogPacket<OGN_Packet>, 32> FlashLog_FIFO;
|
||||
|
||||
extern uint32_t SPIFFSlog_FileTime; // [sec] start time of the current log file
|
||||
extern char SPIFFSlogFileName[32]; // current log file name if open
|
||||
int SPIFFSlog_FullFileName(char *FileName, uint32_t Time); // create full name (including hte path) of the log file corresponding to Time
|
||||
int SPIFFSlog_ShortFileName(char *FileName, uint32_t Time);
|
||||
uint32_t SPIFFSlog_ReadShortFileTime(const char *FileName, int Len);
|
||||
uint32_t SPIFFSlog_ReadShortFileTime(const char *FileName);
|
||||
int SPIFFSlog_CopyToSD(void);
|
||||
int SPIFFSlog_FindOldestFile(uint32_t &Oldest, uint32_t After=0); // find the oldest log file
|
||||
int SPIFFSlog_ListFiles(void); // list the log files on the console
|
||||
int SPIFFSlog_ListFile(uint32_t FileTime); //
|
||||
int SPIFFSlog_ListFile(const char *FileName, uint32_t FileTime); //
|
||||
// int SPIFFSlog_ListFile(const char *FileName, int Len); //
|
||||
extern uint32_t FlashLog_FileTime; // [sec] start time of the current log file
|
||||
extern char FlashLog_FileName[32]; // current log file name if open
|
||||
int FlashLog_FullFileName(char *FileName, uint32_t Time); // create full name (including hte path) of the log file corresponding to Time
|
||||
int FlashLog_ShortFileName(char *FileName, uint32_t Time);
|
||||
uint32_t FlashLog_ReadShortFileTime(const char *FileName, int Len);
|
||||
uint32_t FlashLog_ReadShortFileTime(const char *FileName);
|
||||
int FlashLog_CopyToSD(bool Remove=0);
|
||||
int FlashLog_FindOldestFile(uint32_t &Oldest, uint32_t After=0); // find the oldest log file
|
||||
int FlashLog_ListFiles(void); // list the log files on the console
|
||||
int FlashLog_ListFile(uint32_t FileTime); //
|
||||
int FlashLog_ListFile(const char *FileName, uint32_t FileTime); //
|
||||
// int FlashLog_ListFile(const char *FileName, int Len); //
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
|
|
@ -100,8 +100,8 @@ void app_main(void)
|
|||
#ifdef WITH_WIFI
|
||||
xTaskCreate(vTaskWIFI, "WIFI", 4096, 0, tskIDLE_PRIORITY+2, 0);
|
||||
#endif
|
||||
#ifdef WITH_WIFI
|
||||
xTaskCreate(vTaskSTX, "STX", 4096, 0, tskIDLE_PRIORITY+2, 0);
|
||||
#ifdef WITH_STRATUX
|
||||
xTaskCreate(vTaskSTX, "STX", 4096, 0, tskIDLE_PRIORITY+3, 0);
|
||||
#endif
|
||||
#if defined(WITH_OLED) || defined(WITH_U8G2_OLED) || defined(WITH_ST7789) || defined(WITH_ILI9341)
|
||||
xTaskCreate(vTaskDISP, "DISP", 2048, 0, tskIDLE_PRIORITY+2, 0);
|
||||
|
|
51
main/ogn.h
51
main/ogn.h
|
@ -1407,6 +1407,44 @@ class GPS_Position: public GPS_Time
|
|||
{ int16_t LatAngle = calcLatAngle16(Latitude);
|
||||
LatitudeCosine = calcLatCosine(LatAngle); }
|
||||
|
||||
int WriteAPRS(char *Out, const char *Call, const char *Icon, uint32_t ID)
|
||||
{ int Len=0;
|
||||
Len+=Format_String(Out+Len, Call); // Call
|
||||
Len+=Format_String(Out+Len, ">APRS:/");
|
||||
Len+=WriteHHMMSS(Out+Len); // Time
|
||||
Out[Len++]='h';
|
||||
Len+=WriteIGCcoord(Out+Len, Latitude, 2, "NS"); // [DDMM.MM] Latitude
|
||||
char LatW = Out[Len-2];
|
||||
Out[Len-2]=Out[Len-3]; Out[Len-3]=Out[Len-4]; Out[Len-4]='.';
|
||||
Out[Len++]=Icon[0];
|
||||
Len+=WriteIGCcoord(Out+Len, Longitude, 3, "EW"); // [DDDMM.MM] Longitude
|
||||
char LonW = Out[Len-2];
|
||||
Out[Len-2]=Out[Len-3]; Out[Len-3]=Out[Len-4]; Out[Len-4]='.';
|
||||
Out[Len++]=Icon[1];
|
||||
Len+=Format_UnsDec(Out+Len, Heading/10, 3); // [deg] Heading
|
||||
Out[Len++]='/';
|
||||
Len+=Format_UnsDec(Out+Len, ((uint32_t)Speed*199+512)>>10, 3); // [kt] speed
|
||||
Out[Len++] = '/'; Out[Len++] = 'A'; Out[Len++] = '='; Len+=Format_UnsDec(Out+Len, (MetersToFeet(Altitude)+5)/10, 6); // [feet] altitude
|
||||
Out[Len++]=' '; Out[Len++]='!'; Out[Len++]='W'; Out[Len++]=LatW; Out[Len++]=LonW; Out[Len++]='!'; // more accurate Lat/Lon
|
||||
Out[Len++]=' '; Out[Len++]='i'; Out[Len++]='d'; Len+=Format_Hex(Out+Len, ID); // ID
|
||||
|
||||
Out[Len++] = ' '; Len+=Format_SignDec(Out+Len, ((int32_t)ClimbRate*10079+256)>>9, 3); Out[Len++] = 'f'; Out[Len++] = 'p'; Out[Len++] = 'm'; // [fpm]
|
||||
Out[Len++] = ' '; Len+=Format_SignDec(Out+Len, TurnRate/3, 2, 1); Out[Len++] = 'r'; Out[Len++] = 'o'; Out[Len++] = 't'; // [ROT]
|
||||
|
||||
if(hasBaro)
|
||||
{ int32_t Alt=(StdAltitude+5)/10; // [m] standard pressure altitude
|
||||
if(Alt<0) Alt=0;
|
||||
Out[Len++] = ' '; Out[Len++] = 'F'; Out[Len++] = 'L';
|
||||
Len+=Format_UnsDec(Out+Len, MetersToFeet((uint32_t)Alt), 5, 2); } // [feet] "Flight Level"
|
||||
|
||||
uint16_t DOP=PDOP; if(DOP==0) DOP=HDOP;
|
||||
uint16_t HorPrec=(DOP*2+5)/10; if(HorPrec>63) HorPrec=63; // [m]
|
||||
uint16_t VerPrec=(DOP*3+5)/10; if(VerPrec>63) VerPrec=63; // [m]
|
||||
Out[Len++] = ' '; Out[Len++] = 'g'; Out[Len++] = 'p'; Out[Len++] = 's';
|
||||
Len+=Format_UnsDec(Out+Len, HorPrec); Out[Len++] = 'x'; Len+=Format_UnsDec(Out+Len, VerPrec);
|
||||
|
||||
Out[Len]=0; return Len; }
|
||||
|
||||
static int WriteIGCcoord(char *Out, int32_t Coord, uint8_t DegSize, const char *SignChar)
|
||||
{ int Len=0;
|
||||
bool Neg = Coord<0; if(Neg) Coord=(-Coord);
|
||||
|
@ -1417,15 +1455,18 @@ class GPS_Position: public GPS_Time
|
|||
Out[Len++]=SignChar[Neg];
|
||||
return Len; }
|
||||
|
||||
int WriteHHMMSS(char *Out)
|
||||
{ Format_UnsDec(Out , Hour, 2);
|
||||
Format_UnsDec(Out+2, Min , 2);
|
||||
Format_UnsDec(Out+4, Sec , 2);
|
||||
return 6; }
|
||||
|
||||
int WriteIGC(char *Out)
|
||||
{ // if(!isValid()) return 0;
|
||||
int Len=0;
|
||||
Out[Len++] = 'B';
|
||||
if(isTimeValid())
|
||||
{ Len+=Format_UnsDec(Out+Len, Hour, 2);
|
||||
Len+=Format_UnsDec(Out+Len, Min, 2);
|
||||
Len+=Format_UnsDec(Out+Len, Sec, 2); }
|
||||
else Len+=Format_String(Out+Len, " ");
|
||||
if(isTimeValid()) Len+=WriteHHMMSS(Out+Len);
|
||||
else Len+=Format_String(Out+Len, " ");
|
||||
if(isValid())
|
||||
{ Len+=WriteIGCcoord(Out+Len, Latitude, 2, "NS");
|
||||
Len+=WriteIGCcoord(Out+Len, Longitude, 3, "EW");
|
||||
|
|
90
main/ogn1.h
90
main/ogn1.h
|
@ -152,14 +152,32 @@ class OGN1_Packet // Packet structure for the OGN tracker
|
|||
(long int)HeaderWord, (long int)Data[0], (long int)Data[1],
|
||||
(long int)Data[2], (long int)Data[3] ); }
|
||||
|
||||
uint8_t Read(const char *Inp)
|
||||
{ uint8_t Len=0;
|
||||
if(Inp[0]==' ') Inp++;
|
||||
int Chars = Read_Hex(HeaderWord, Inp); if(Chars!=8) return 0;
|
||||
Inp+=Chars; Len+=4;
|
||||
for( uint8_t Idx=0; Idx<4; Idx++)
|
||||
{ if(Inp[0]==' ') Inp++;
|
||||
int Chars = Read_Hex(Data[Idx], Inp); if(Chars!=8) return 0;
|
||||
Inp+=Chars; Len+=4; }
|
||||
return Len; }
|
||||
|
||||
uint8_t Dump(char *Out)
|
||||
{ uint8_t Len=0;
|
||||
Len+=Format_Hex(Out+Len, HeaderWord);
|
||||
for(int Idx=0; Idx<4; Idx++)
|
||||
{ Out[Len++]=' '; Len+=Format_Hex(Out+Len, Data[Idx]); }
|
||||
return Len; }
|
||||
|
||||
void DumpBytes(void) const
|
||||
{ for(uint8_t Idx=0; Idx<Bytes; Idx++)
|
||||
{ printf(" %02X", Byte()[Idx]); }
|
||||
printf("\n"); }
|
||||
|
||||
int WriteDeviceStatus(char *Out)
|
||||
{ return sprintf(Out, " h%02X v%02X %dsat/%d %ldm %3.1fhPa %+4.1fdegC %3.1f%% %4.2fV %d/%+4.1fdBm %d/min",
|
||||
Status.Hardware, Status.Firmware, Status.Satellites, Status.FixQuality, (long int)DecodeAltitude(),
|
||||
{ return sprintf(Out, " h%02X v%02X %dsat/%d/%ddB %ldm %3.1fhPa %+4.1fdegC %3.1f%% %4.2fV %d/%+4.1fdBm %d/min",
|
||||
Status.Hardware, Status.Firmware, Status.Satellites, Status.FixQuality, 8+Status.SatSNR, (long int)DecodeAltitude(),
|
||||
0.08*Status.Pressure, 0.1*DecodeTemperature(), 0.1*DecodeHumidity(),
|
||||
(1.0/64)*DecodeVoltage(), Status.TxPower+4, -0.5*Status.RadioNoise, (1<<Status.RxRate)-1 );
|
||||
}
|
||||
|
@ -205,8 +223,8 @@ class OGN1_Packet // Packet structure for the OGN tracker
|
|||
void PrintDeviceStatus(void) const
|
||||
{ printf("%c:%06lX R%c%c %02ds:",
|
||||
'0'+Header.AddrType, (long int)Header.Address, '0'+Header.Relay, Header.Emergency?'E':' ', Status.Time);
|
||||
printf(" h%02X v%02X %dsat/%d %ldm %3.1fhPa %+4.1fdegC %3.1f%% %4.2fV Tx:%ddBm Rx:%+4.1fdBm %d/min",
|
||||
Status.Hardware, Status.Firmware, Status.Satellites, Status.FixQuality, (long int)DecodeAltitude(),
|
||||
printf(" h%02X v%02X %dsat/%d/%ddB %ldm %3.1fhPa %+4.1fdegC %3.1f%% %4.2fV Tx:%ddBm Rx:%+4.1fdBm %d/min",
|
||||
Status.Hardware, Status.Firmware, Status.Satellites, Status.FixQuality, 8+Status.SatSNR, (long int)DecodeAltitude(),
|
||||
0.08*Status.Pressure, 0.1*DecodeTemperature(), 0.1*DecodeHumidity(),
|
||||
(1.0/64)*DecodeVoltage(), Status.TxPower+4, -0.5*Status.RadioNoise, (1<<Status.RxRate)-1 );
|
||||
printf("\n");
|
||||
|
@ -219,7 +237,7 @@ class OGN1_Packet // Packet structure for the OGN tracker
|
|||
printf(" %d/%dD/%4.1f", (int)Position.FixQuality, (int)Position.FixMode+2, 0.1*(10+DecodeDOP()) );
|
||||
if(Position.Time<60) printf(" %02ds:", (int)Position.Time);
|
||||
else printf(" ---:");
|
||||
printf(" [%+10.6f, %+11.6f]deg %ldm",
|
||||
printf(" [%+010.6f,%+011.6f]deg %ldm",
|
||||
0.0001/60*DecodeLatitude(), 0.0001/60*DecodeLongitude(), (long int)DecodeAltitude() );
|
||||
if(hasBaro())
|
||||
{ printf("[%+dm]", (int)getBaroAltDiff() ); }
|
||||
|
@ -227,6 +245,64 @@ class OGN1_Packet // Packet structure for the OGN tracker
|
|||
0.1*DecodeSpeed(), 0.1*DecodeHeading(), 0.1*DecodeClimbRate(), 0.1*DecodeTurnRate() );
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int WriteJSON(char *JSON) const
|
||||
{ int Len=0;
|
||||
Len+=Format_String(JSON+Len, "\"addr\":\"");
|
||||
Len+=Format_Hex(JSON+Len, (uint8_t) (Header.Address>>16));
|
||||
Len+=Format_Hex(JSON+Len, (uint16_t)(Header.Address));
|
||||
JSON[Len++]='\"';
|
||||
JSON[Len++]=',';
|
||||
Len+=Format_String(JSON+Len, "\"addr_type\":");
|
||||
JSON[Len++] = HexDigit(Header.AddrType);
|
||||
if(!Header.Encrypted && !Header.NonPos) // if non-encrypted position
|
||||
{ Len+=Format_String(JSON+Len, ",\"acft_type\":\"");
|
||||
JSON[Len++] = HexDigit(Position.AcftType);
|
||||
JSON[Len++]='\"';
|
||||
Len+=Format_String(JSON+Len, ",\"acft_cat\":\""); // GDL90 aircraft category
|
||||
// no-info, glider, tow, heli, parachute, drop-plane, hang-glider, para-glider, powered, jet, UFO, balloon, Zeppelin, UAV, ground vehicle, static } ;
|
||||
const uint8_t AcftCat[16] = { 0, 9, 1, 7, 11, 1, 12, 12, 1, 2, 0, 10, 10, 14, 18, 19 } ;
|
||||
Len+=Format_Hex(JSON+Len, AcftCat[Position.AcftType]);
|
||||
JSON[Len++]='\"';
|
||||
Len+=Format_String(JSON+Len, ",\"stealth\":");
|
||||
JSON[Len++] = '0'+Position.Stealth;
|
||||
Len+=Format_String(JSON+Len, ",\"lat_deg\":");
|
||||
Len+=Format_SignDec(JSON+Len, (int32_t)(((int64_t)50*DecodeLatitude()+1)/3), 8, 7, 1);
|
||||
Len+=Format_String(JSON+Len, ",\"lon_deg\":");
|
||||
Len+=Format_SignDec(JSON+Len, (int32_t)(((int64_t)50*DecodeLongitude()+1)/3), 8, 7, 1);
|
||||
int32_t Altitude=DecodeAltitude();
|
||||
Len+=Format_String(JSON+Len, ",\"alt_msl_m\":");
|
||||
Len+=Format_UnsDec(JSON+Len, (uint32_t)Altitude);
|
||||
if(hasBaro())
|
||||
{ Altitude+=getBaroAltDiff();
|
||||
Len+=Format_String(JSON+Len, ",\"alt_std_m\":");
|
||||
Len+=Format_SignDec(JSON+Len, Altitude, 1, 0, 1); }
|
||||
Len+=Format_String(JSON+Len, ",\"track_deg\":");
|
||||
Len+=Format_UnsDec(JSON+Len, DecodeHeading(), 2, 1);
|
||||
Len+=Format_String(JSON+Len, ",\"speed_mps\":");
|
||||
Len+=Format_UnsDec(JSON+Len, DecodeSpeed(), 2, 1);
|
||||
Len+=Format_String(JSON+Len, ",\"climb_mps\":");
|
||||
Len+=Format_SignDec(JSON+Len, DecodeClimbRate(), 2, 1, 1);
|
||||
Len+=Format_String(JSON+Len, ",\"turn_dps\":");
|
||||
Len+=Format_SignDec(JSON+Len, DecodeTurnRate(), 2, 1, 1);
|
||||
Len+=Format_String(JSON+Len, ",\"DOP\":");
|
||||
Len+=Format_UnsDec(JSON+Len, 10+DecodeDOP(), 2, 1); }
|
||||
if(!Header.Encrypted && Header.NonPos) // non-encrypted status and info
|
||||
{ if(Status.ReportType==0) // status
|
||||
{ }
|
||||
if(Status.ReportType==1) // info
|
||||
{ char Value[16];
|
||||
uint8_t InfoType;
|
||||
uint8_t Idx=0;
|
||||
for( ; ; )
|
||||
{ uint8_t Chars = readInfo(Value, InfoType, Idx);
|
||||
if(Chars==0) break;
|
||||
if(InfoType<InfoParmNum)
|
||||
{ Len+=sprintf(JSON+Len, ",\"%s\":\"%s\"", InfoParmName(InfoType), Value); }
|
||||
Idx+=Chars; }
|
||||
}
|
||||
}
|
||||
return Len; }
|
||||
/*
|
||||
void Encode(MAV_ADSB_VEHICLE *MAV)
|
||||
{ MAV->ICAO_address = HeaderWord&0x03FFFFFF;
|
||||
|
@ -459,7 +535,7 @@ class OGN1_Packet // Packet structure for the OGN tracker
|
|||
|
||||
Len+=Format_UnsDec(Msg+Len, (DecodeHeading()+5)/10, 3);
|
||||
Msg[Len++] = '/';
|
||||
Len+=Format_UnsDec(Msg+Len, (199*DecodeSpeed()+512)>>10, 3);
|
||||
Len+=Format_UnsDec(Msg+Len, ((uint32_t)DecodeSpeed()*199+512)>>10, 3);
|
||||
Msg[Len++] = '/'; Msg[Len++] = 'A'; Msg[Len++] = '='; Len+=Format_UnsDec(Msg+Len, MetersToFeet(DecodeAltitude()), 6);
|
||||
|
||||
Msg[Len++] = ' ';
|
||||
|
@ -471,7 +547,7 @@ class OGN1_Packet // Packet structure for the OGN tracker
|
|||
|
||||
Msg[Len++] = ' '; Msg[Len++] = 'i'; Msg[Len++] = 'd'; Len+=Format_Hex(Msg+Len, ((uint32_t)Position.AcftType<<26) | ((uint32_t)Header.AddrType<<24) | Header.Address);
|
||||
|
||||
Msg[Len++] = ' '; Len+=Format_SignDec(Msg+Len, (10079*DecodeClimbRate()+256)>>9, 3); Msg[Len++] = 'f'; Msg[Len++] = 'p'; Msg[Len++] = 'm';
|
||||
Msg[Len++] = ' '; Len+=Format_SignDec(Msg+Len, ((int32_t)DecodeClimbRate()*10079+256)>>9, 3); Msg[Len++] = 'f'; Msg[Len++] = 'p'; Msg[Len++] = 'm';
|
||||
Msg[Len++] = ' '; Len+=Format_SignDec(Msg+Len, DecodeTurnRate()/3, 2, 1); Msg[Len++] = 'r'; Msg[Len++] = 'o'; Msg[Len++] = 't';
|
||||
|
||||
if(hasBaro())
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
#include "fifo.h"
|
||||
|
||||
#include "flight.h" // flight status
|
||||
|
||||
#ifdef WITH_FLASHLOG // log own track to unused Flash pages (STM32 only)
|
||||
#include "flashlog.h"
|
||||
#endif
|
||||
|
@ -87,22 +85,22 @@ FlightMonitor Flight;
|
|||
|
||||
#ifdef WITH_LOG
|
||||
|
||||
static int SPIFFSlog(OGN_RxPacket<OGN_Packet> *Packet, uint32_t Time)
|
||||
{ OGN_LogPacket<OGN_Packet> *LogPacket = LOG_FIFO.getWrite(); if(LogPacket==0) return -1; // allocate new packet in the LOG_FIFO
|
||||
static int FlashLog(OGN_RxPacket<OGN_Packet> *Packet, uint32_t Time)
|
||||
{ OGN_LogPacket<OGN_Packet> *LogPacket = FlashLog_FIFO.getWrite(); if(LogPacket==0) return -1; // allocate new packet in the LOG_FIFO
|
||||
LogPacket->Packet = Packet->Packet; // copy the packet
|
||||
LogPacket->Flags=0x80;
|
||||
LogPacket->setTime(Time);
|
||||
LogPacket->setCheck();
|
||||
LOG_FIFO.Write(); // finalize the write
|
||||
FlashLog_FIFO.Write(); // finalize the write
|
||||
return 1; }
|
||||
|
||||
static int SPIFFSlog(OGN_TxPacket<OGN_Packet> *Packet, uint32_t Time)
|
||||
{ OGN_LogPacket<OGN_Packet> *LogPacket = LOG_FIFO.getWrite(); if(LogPacket==0) return -1;
|
||||
static int FlashLog(OGN_TxPacket<OGN_Packet> *Packet, uint32_t Time)
|
||||
{ OGN_LogPacket<OGN_Packet> *LogPacket = FlashLog_FIFO.getWrite(); if(LogPacket==0) return -1;
|
||||
LogPacket->Packet = Packet->Packet;
|
||||
LogPacket->Flags=0x00;
|
||||
LogPacket->setTime(Time);
|
||||
LogPacket->setCheck();
|
||||
LOG_FIFO.Write();
|
||||
FlashLog_FIFO.Write();
|
||||
return 1; }
|
||||
|
||||
#endif // WITH_LOG
|
||||
|
@ -379,7 +377,7 @@ static void ProcessRxPacket(OGN_RxPacket<OGN_Packet> *RxPacket, uint8_t RxPacket
|
|||
#ifdef WITH_LOG
|
||||
bool Signif = PrevRxPacket!=0;
|
||||
if(!Signif) Signif=OGN_isSignif(&(RxPacket->Packet), &(PrevRxPacket->Packet));
|
||||
if(Signif) SPIFFSlog(RxPacket, RxTime); // log only significant packets
|
||||
if(Signif) FlashLog(RxPacket, RxTime); // log only significant packets
|
||||
#endif
|
||||
#ifdef WITH_PFLAA
|
||||
if( Parameters.Verbose // print PFLAA on the console for received packets
|
||||
|
@ -689,7 +687,7 @@ void vTaskPROC(void* pvParameters)
|
|||
#ifdef WITH_LOG
|
||||
bool isSignif = OGN_isSignif(&(PosPacket.Packet), &PrevLoggedPacket);
|
||||
if(isSignif)
|
||||
{ SPIFFSlog(&PosPacket, PosTime);
|
||||
{ FlashLog(&PosPacket, PosTime);
|
||||
PrevLoggedPacket = PosPacket.Packet; }
|
||||
#endif
|
||||
} else // if GPS position is not complete, contains no valid position, etc.
|
||||
|
@ -745,7 +743,7 @@ void vTaskPROC(void* pvParameters)
|
|||
if(doTx)
|
||||
{
|
||||
#ifdef WITH_LOG
|
||||
SPIFFSlog(&StatPacket, PosTime); // log the status packet
|
||||
FlashLog(&StatPacket, PosTime); // log the status packet
|
||||
#endif
|
||||
*StatusPacket = StatPacket; // copy status packet into the Tx queue
|
||||
StatusPacket->Packet.Whiten(); // whiten for transmission
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
extern uint32_t BatteryVoltage; // [1/256 mV] averaged
|
||||
extern int32_t BatteryVoltageRate; // [1/256 mV] averaged
|
||||
#include "flight.h"
|
||||
|
||||
#ifdef WITH_LOOKOUT // traffic awareness and warnings
|
||||
#include "lookout.h"
|
||||
extern LookOut Look;
|
||||
#endif
|
||||
|
||||
extern uint32_t BatteryVoltage; // [1/256 mV] averaged
|
||||
extern int32_t BatteryVoltageRate; // [1/256 mV] averaged
|
||||
|
||||
extern FlightMonitor Flight;
|
||||
|
||||
#ifdef WITH_ESP32
|
||||
const uint8_t RelayQueueSize = 32;
|
||||
|
|
|
@ -37,6 +37,9 @@ class Socket
|
|||
if(Err!=0) { Disconnect(); return -3; }
|
||||
return Link; }
|
||||
|
||||
// int Connect()
|
||||
// { Link = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); }
|
||||
|
||||
void Disconnect(void)
|
||||
{ if(Link>=0) { close(Link); Link=(-1); }
|
||||
if(Host) { freeaddrinfo(Host); Host=0; }
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#include "tcpip_adapter.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event_loop.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include "format.h"
|
||||
|
||||
#include "fifo.h"
|
||||
#include "socket.h"
|
||||
|
||||
#include "proc.h"
|
||||
|
||||
#include "stratux.h"
|
||||
|
||||
#define DEBUG_PRINT
|
||||
|
@ -19,9 +18,10 @@
|
|||
|
||||
// ==============================================================================================
|
||||
|
||||
wifi_config_t WIFI_Config; // WIFI config: ESSID, etc.
|
||||
uint32_t WIFI_LocalIP = 0; // WIFI local IP address
|
||||
bool WIFI_isConnected(void) { return WIFI_LocalIP!=0; }
|
||||
wifi_config_t WIFI_Config; // WIFI config: ESSID, etc.
|
||||
tcpip_adapter_ip_info_t WIFI_IP = { 0, 0, 0 }; // WIFI local IP address, mask and gateway
|
||||
|
||||
bool WIFI_isConnected(void) { return WIFI_IP.ip.addr!=0; }
|
||||
|
||||
static esp_err_t WIFI_event_handler(void *ctx, system_event_t *event)
|
||||
{
|
||||
|
@ -104,9 +104,8 @@ static esp_err_t WIFI_Disconnect(void) // disconnect from W
|
|||
|
||||
static uint32_t WIFI_getLocalIP(void) // get local IP, once DHCP phase is done
|
||||
{ esp_err_t Err;
|
||||
tcpip_adapter_ip_info_t Info;
|
||||
Err=tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &Info); if(Err!=ESP_OK) return 0;
|
||||
return Info.ip.addr; }
|
||||
Err=tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &WIFI_IP); if(Err!=ESP_OK) return 0;
|
||||
return WIFI_IP.ip.addr; }
|
||||
|
||||
uint8_t IP_Print(char *Out, uint32_t IP)
|
||||
{ uint8_t Len=0;
|
||||
|
@ -125,17 +124,33 @@ void IP_Print(void (*Output)(char), uint32_t IP)
|
|||
|
||||
// ==============================================================================================
|
||||
|
||||
static char Stratux_Host[32] = { 0 };
|
||||
static const char *Stratux_Port = "30011";
|
||||
static Socket Stratux_Socket;
|
||||
|
||||
static FIFO<char, 512> Stratux_TxFIFO;
|
||||
static FIFO<uint8_t, 256> Stratux_RxFIFO;
|
||||
|
||||
bool Stratux_isConnected(void)
|
||||
{ return 0; }
|
||||
{ return WIFI_isConnected() && Stratux_Socket.isConnected(); }
|
||||
|
||||
int Stratux_Read (uint8_t &Byte)
|
||||
{ return 0; }
|
||||
{ return Stratux_RxFIFO.Read(Byte); }
|
||||
|
||||
void Stratux_Write (char Byte)
|
||||
{ }
|
||||
{ Stratux_TxFIFO.Write(Byte); }
|
||||
|
||||
static int Stratux_TxPush(size_t MaxLen=256) // transmit part of the TxFIFO to the Stratux link
|
||||
{ char *Data; size_t Len=Stratux_TxFIFO.getReadBlock(Data); // see how much data is there in the queue for transmission
|
||||
if(Len==0) return 0; // if block is empty then give up
|
||||
if(Len>MaxLen) Len=MaxLen; // limit the block size
|
||||
int Ret=Stratux_Socket.Send(Data, Len); // write the block to the Stratux socket
|
||||
if(Ret!=Len) return -1; // if an error then give up
|
||||
Stratux_TxFIFO.flushReadBlock(Len); // remove the transmitted block from the FIFO
|
||||
return Len; } // return number of transmitted bytes
|
||||
|
||||
extern "C"
|
||||
void vTaskWIFI(void* pvParameters)
|
||||
void vTaskSTX(void* pvParameters)
|
||||
{ esp_err_t Err;
|
||||
vTaskDelay(1000);
|
||||
|
||||
|
@ -161,7 +176,7 @@ void vTaskWIFI(void* pvParameters)
|
|||
|
||||
for( ; ; ) // main (endless) loop
|
||||
{ vTaskDelay(1000);
|
||||
if(Parameters.StratuxPass[0]==0) continue;
|
||||
if(Parameters.StratuxWIFI[0]==0) continue;
|
||||
Err=WIFI_Connect(Parameters.StratuxWIFI, Parameters.StratuxPass);
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
|
@ -177,24 +192,58 @@ void vTaskWIFI(void* pvParameters)
|
|||
#endif
|
||||
if(Err) { vTaskDelay(10000); continue; }
|
||||
|
||||
WIFI_LocalIP=0;
|
||||
WIFI_IP.ip.addr = 0;
|
||||
for(uint8_t Idx=0; Idx<10; Idx++) // wait to obtain local IP from DHCP
|
||||
{ vTaskDelay(1000);
|
||||
WIFI_LocalIP = WIFI_getLocalIP();
|
||||
if(WIFI_LocalIP) break; }
|
||||
if(WIFI_getLocalIP()) break; }
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "LocalIP: ");
|
||||
IP_Print(CONS_UART_Write, WIFI_LocalIP);
|
||||
// Format_Hex(CONS_UART_Write, WIFI_LocalIP);
|
||||
Format_String(CONS_UART_Write, "Local IP: ");
|
||||
IP_Print(CONS_UART_Write, WIFI_IP.ip.addr);
|
||||
Format_String(CONS_UART_Write, " GW: ");
|
||||
IP_Print(CONS_UART_Write, WIFI_IP.gw.addr);
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
if(WIFI_LocalIP==0) { WIFI_Disconnect(); continue; } // if getting local IP failed then give up
|
||||
if(WIFI_IP.ip.addr==0) { WIFI_Disconnect(); continue; } // if getting local IP failed then give up
|
||||
|
||||
Stratux_TxFIFO.Clear();
|
||||
|
||||
uint8_t Len=IP_Print(Stratux_Host, WIFI_IP.gw.addr); Stratux_Host[Len]=0;
|
||||
int ConnErr=Stratux_Socket.Connect(Stratux_Host, Stratux_Port); // connect to the Stratux GPS server
|
||||
if(ConnErr>=0) // if connection succesfull
|
||||
{ Stratux_Socket.setReceiveTimeout(1);
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "Connected to ");
|
||||
IP_Print(CONS_UART_Write, Stratux_Socket.getIP());
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
for( ; ; )
|
||||
{ int Len=Stratux_TxPush(); if(Len<0) break;
|
||||
if(Len==0) vTaskDelay(5);
|
||||
// #ifdef DEBUG_PRINT
|
||||
// xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
// Format_String(CONS_UART_Write, "Stratux_TxPush() => ");
|
||||
// Format_SignDec(CONS_UART_Write, Len);
|
||||
// Format_String(CONS_UART_Write, "\n");
|
||||
// xSemaphoreGive(CONS_Mutex);
|
||||
// #endif
|
||||
}
|
||||
|
||||
vTaskDelay(10000); }
|
||||
else
|
||||
{ xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "Failed to connect to Stratux -> ");
|
||||
Format_SignDec(CONS_UART_Write, ConnErr);
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex); }
|
||||
|
||||
Stratux_Socket.Disconnect();
|
||||
vTaskDelay(5000);
|
||||
WIFI_Disconnect(); WIFI_LocalIP=0;
|
||||
WIFI_Disconnect(); WIFI_IP.ip.addr=0;
|
||||
vTaskDelay(2000);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "socket.h"
|
||||
|
||||
#include "proc.h"
|
||||
|
||||
#ifdef WITH_WIFI
|
||||
|
||||
#define DEBUG_PRINT
|
||||
|
@ -79,7 +81,7 @@ static esp_err_t WIFI_ActiveScan(wifi_ap_record_t *AP, uint16_t &APs)
|
|||
Err = esp_wifi_scan_start(&Config, 1); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_wifi_scan_get_ap_records(&APs, AP); return Err; }
|
||||
|
||||
static esp_err_t WIFI_PassiveScan(wifi_ap_record_t *AP, uint16_t &APs)
|
||||
static esp_err_t WIFI_PassiveScan(wifi_ap_record_t *AP, uint16_t &APs) //
|
||||
{ esp_err_t Err;
|
||||
wifi_scan_config_t Config = { ssid:0, bssid:0, channel:0, show_hidden:0,
|
||||
scan_type:WIFI_SCAN_TYPE_PASSIVE,
|
||||
|
@ -102,7 +104,7 @@ static esp_err_t WIFI_Connect(wifi_ap_record_t *AP, const char *Pass) // connect
|
|||
Err = esp_wifi_connect(); if(Err!=ESP_OK) return Err;
|
||||
return Err; }
|
||||
|
||||
static esp_err_t WIFI_Disconnect(void)
|
||||
static esp_err_t WIFI_Disconnect(void) // disconnect from WiFi AP
|
||||
{ esp_err_t Err=esp_wifi_disconnect();
|
||||
return Err; }
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue