Add connectivity to Stratux on WiFi and port 30011 and other minor updates

pull/30/head
Pawel Jalocha 2020-08-29 18:54:47 +01:00
rodzic 330077f8de
commit 5bf77bf719
13 zmienionych plików z 377 dodań i 187 usunięć

Wyświetl plik

@ -111,7 +111,7 @@ static void ListLogFile(void)
Format_String(CONS_UART_Write, "\n"); Format_String(CONS_UART_Write, "\n");
xSemaphoreGive(CONS_Mutex); xSemaphoreGive(CONS_Mutex);
#endif #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; if(FileTime==0) return;
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
@ -120,7 +120,7 @@ static void ListLogFile(void)
Format_String(CONS_UART_Write, "\n"); Format_String(CONS_UART_Write, "\n");
xSemaphoreGive(CONS_Mutex); xSemaphoreGive(CONS_Mutex);
#endif #endif
SPIFFSlog_ListFile(FileTime); FlashLog_ListFile(FileTime);
} }
#endif #endif
@ -220,7 +220,7 @@ static void ProcessCtrlC(void) // print system
static void ProcessCtrlL(void) // print system state to the console static void ProcessCtrlL(void) // print system state to the console
{ {
#ifdef WITH_SPIFFS #ifdef WITH_SPIFFS
SPIFFSlog_ListFiles(); FlashLog_ListFiles();
#endif #endif
} }

Wyświetl plik

@ -15,6 +15,10 @@
#include "ctrl.h" #include "ctrl.h"
#include "proc.h" #include "proc.h"
#ifdef WITH_STRATUX
#include "stratux.h"
#endif
#ifdef WITH_WIFI #ifdef WITH_WIFI
#include "wifi.h" #include "wifi.h"
#endif #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_SetFont(OLED, u8g2_font_open_iconic_embedded_1x_t);
u8g2_DrawGlyph(OLED, 36, 11, 0x4A); } u8g2_DrawGlyph(OLED, 36, 11, 0x4A); }
#endif #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 #ifdef WITH_WIFI
if(WIFI_isConnected()) if(WIFI_isConnected())
{ u8g2_SetFont(OLED, u8g2_font_open_iconic_embedded_1x_t); { u8g2_SetFont(OLED, u8g2_font_open_iconic_embedded_1x_t);

Wyświetl plik

@ -1661,7 +1661,7 @@ void IO_Configuration(void)
#ifdef WITH_M5_JACEK #ifdef WITH_M5_JACEK
GPS_ANT_Dir(); GPS_ANT_Dir();
GPS_ANT_Sel(1); // 0 = external entenna GPS_ANT_Sel(0); // 0 = external entenna
#endif #endif
#ifdef PIN_PERIPH_RST #ifdef PIN_PERIPH_RST

Wyświetl plik

@ -23,64 +23,66 @@ static void AddPath(char *Name, const char *FileName, const char *Path)
#ifdef WITH_SPIFFS #ifdef WITH_SPIFFS
static const char *SDcard_Path = "/sdcard/TLG"; static const char *SDcard_Path = "/sdcard/TLG"; // with sub-directory which is created if does not exist
static const char *SPIFFSlog_Path = "/spiffs"; // path to log files static const char *FlashLog_Path = "/spiffs"; // path to log files
static const char *SPIFFSlog_Ext = ".TLG"; // extension for log files, could be as well .TLA static const char *FlashLog_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 FlashLog_MaxTime = 7200; // 2 hour max. per single log file
static const uint32_t SPIFFSlog_MaxSize = 0x20000; // 128KB max. per single log file static const uint32_t FlashLog_MaxSize = 0x20000; // 128KB max. per single log file
// static uint32_t SPIFFSlogOldestTime; // static uint32_t FlashLog_OldestTime;
uint32_t SPIFFSlog_FileTime=0; uint32_t FlashLog_FileTime=0;
char SPIFFSlog_FileName[32]; // current log file name if open char FlashLog_FileName[32]; // current log file name if open
static FILE *SPIFFSlog_File=0; // current log file 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 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 { int Len = Format_Hex(FileName, Time); // Time in %08X format
strcpy(FileName+Len, SPIFFSlog_Ext); Len+=strlen(SPIFFSlog_Ext); // add extension strcpy(FileName+Len, FlashLog_Ext); Len+=strlen(FlashLog_Ext); // add extension
FileName[Len]=0; return Len; } // return the name length, should be 12 characters 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 int FlashLog_FullFileName(char *FileName, uint32_t Time) // make the full (long) log file name for given start time
{ strcpy(FileName, SPIFFSlog_Path); // copy the path { strcpy(FileName, FlashLog_Path); // copy the path
int Len = strlen(FileName); int Len = strlen(FileName);
if(FileName[Len-1]!='/') FileName[Len++]='/'; 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 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(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) if(memcmp(FileName+8, FlashLog_Ext, 4)!=0) return 0; // extension must be .TLx (x is normally G or A)
uint32_t Time=0; uint32_t Time=0;
if(Read_Hex(Time, FileName)!=8) return 0; // read start time, give up if other format if(Read_Hex(Time, FileName)!=8) return 0; // read start time, give up if other format
return Time; } // return the extracted time return Time; } // return the extracted time (or zero when unexpected name format)
uint32_t SPIFFSlog_ReadShortFileTime(const char *FileName) // uint32_t FlashLog_ReadShortFileTime(const char *FileName) //
{ return SPIFFSlog_ReadShortFileTime(FileName, strlen(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; { int Files=0;
struct stat DstStat; struct stat DstStat;
struct utimbuf DstTime; struct utimbuf DstTime;
char SrcName[32]; char SrcName[32]; // full name of the source file
char DstName[32]; char DstName[32]; // full name of the destination file
const int BuffSize=2048; const int BuffSize=2048; //
uint8_t Buffer[BuffSize]; uint8_t Buffer[BuffSize]; // buffer to copy from source to destination
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( ; ; ) for( ; ; )
{ vTaskDelay(1); // give some time to parallel tasks { vTaskDelay(1); // give some time to parallel tasks
struct dirent *Ent = readdir(Dir); if(!Ent) break; // read next directory entry, break if all read 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 if(Ent->d_type != DT_REG) continue; // skip non-regular files
char *Name = Ent->d_name; char *Name = Ent->d_name;
uint32_t Time=SPIFFSlog_ReadShortFileTime(Name); // read time from the file name uint32_t Time=FlashLog_ReadShortFileTime(Name); // read time from the file name
if(Time==0) continue; // skip if not .TLG format if(Time==0) continue; // skip if not .TLG format
AddPath(SrcName, Name, SPIFFSlog_Path); AddPath(DstName, Name, SDcard_Path); // full name of the destination file
// strcpy(SrcName, SPIFFSlog_Path); strcat(SrcName, Name); // form full source file name if(stat(DstName, &DstStat)>=0) continue; // if the destination file exists already
AddPath(DstName, Name, SDcard_Path); AddPath(SrcName, Name, FlashLog_Path); // full name of the source file
// strcpy(DstName, SDcard_Path); strcat(DstName, Name); // form full destination file name FILE *DstFile = fopen(DstName, "wb"); // open destination file
FILE *SrcFile = fopen(SrcName, "rb"); if(SrcFile==0) continue; // open source file if(DstFile==0) // if can't open destination file
FILE *DstFile = fopen(DstName, "wb"); { if(mkdir(SDcard_Path, 0777)<0) break; // attempt to create sub-directory
{ if(mkdir(SDcard_Path, 0777)<0) continue; DstFile = fopen(DstName, "wb"); } // and open the dest. file again
DstFile = fopen(DstName, "wb"); } if(DstFile==0) break; // if not possible to open the dest. file then give up
if(DstFile==0) { fclose(SrcFile); continue; } // open destination file FILE *SrcFile = fopen(SrcName, "rb"); // open source file
if(SrcFile==0) { fclose(DstFile); continue; } // if not possible then skip to next source
for( ; ; ) 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 int Write=fwrite(Buffer, 1, Read, DstFile); if(Read<BuffSize || Write<Read) break; } // until EOF
@ -90,27 +92,29 @@ int SPIFFSlog_CopyToSD(void) // copy log files
{ DstTime.actime = Time; // set access and modification times of the dest. file { DstTime.actime = Time; // set access and modification times of the dest. file
DstTime.modtime = Time; DstTime.modtime = Time;
utime(DstName, &DstTime); } // write to the FAT utime(DstName, &DstTime); } // write to the FAT
Files++; } if(Remove) unlink(SrcName); // remove source file if requested
Files++; } // count copied files
closedir(Dir); // close directory (for searching of log files) closedir(Dir); // close directory (for searching of log files)
return 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; { int Files=0;
Oldest=0xFFFFFFFF; // possibly oldest time 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( ; ; ) for( ; ; )
{ vTaskDelay(1); { vTaskDelay(1);
struct dirent *Ent = readdir(Dir); if(!Ent) break; // read next directory entry, break if all read 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 if(Ent->d_type != DT_REG) continue; // skip non-regular files
char *Name = Ent->d_name; 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<=After) continue; // but not older than
if(Time<Oldest) Oldest=Time; // search for oldest start time if(Time<Oldest) Oldest=Time; // search for oldest start time
Files++; } Files++; }
closedir(Dir); closedir(Dir);
return Files; } // return number of log files 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; { int Files=0;
char Line[64]; char Line[64];
char FullName[32]; char FullName[32];
@ -120,15 +124,15 @@ int SPIFFSlog_ListFiles(void) // list log files
for( ; ; ) for( ; ; )
{ vTaskDelay(1); // not to overload the priority level { vTaskDelay(1); // not to overload the priority level
uint32_t Time = 0; 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 if(Time==0xFFFFFFFF) break; // if none found then stop the list
PrevTime=Time; PrevTime=Time;
SPIFFSlog_FullFileName(FullName, Time); FlashLog_FullFileName(FullName, Time);
if(stat(FullName, &Stat)<0) continue; // get file info if(stat(FullName, &Stat)<0) continue; // get file info
int Size = Stat.st_size; // if above minimum size: skip int Size = Stat.st_size; // if above minimum size: skip
strcpy(Line, "$POGNL,"); strcpy(Line, "$POGNL,");
uint8_t Len=7; 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++; const char *Name = strrchr(FullName, '/'); Name++;
strcpy(Line+Len, Name); Len+=strlen(Name); // print the short name only strcpy(Line+Len, Name); Len+=strlen(Name); // print the short name only
Line[Len++]=','; Line[Len++]=',';
@ -143,9 +147,9 @@ int SPIFFSlog_ListFiles(void) // list log files
return Files; } return Files; }
/* /*
int SPIFFSlog_ListFiles(void) // int FlashLog_ListFiles(void) //
{ int Files=0; { 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]; char HHMMSS[8];
struct stat Stat; struct stat Stat;
DIR *Dir=opendir(SPIFFSlogPath); if(!Dir) return -1; // open the file directory 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 { 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 if(Ent->d_type != DT_REG) continue; // skip non-regular files
char *Name = Ent->d_name; 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); strcpy(FullName+PathLen, Name);
if(stat(FullName, &Stat)<0) continue; // get file info if(stat(FullName, &Stat)<0) continue; // get file info
int Size = Stat.st_size; // if above minimum size: skip int Size = Stat.st_size; // if above minimum size: skip
@ -170,10 +174,10 @@ int SPIFFSlog_ListFiles(void) //
return Files; } 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]; { char Line[128];
// xSemaphoreTake(CONS_Mutex, portMAX_DELAY); // 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, FileName);
// Format_String(CONS_UART_Write, ")\n"); // Format_String(CONS_UART_Write, ")\n");
// xSemaphoreGive(CONS_Mutex); // xSemaphoreGive(CONS_Mutex);
@ -181,44 +185,44 @@ int SPIFFSlog_ListFile(const char *FileName, uint32_t FileTime) // print the
OGN_LogPacket<OGN_Packet> Packet; OGN_LogPacket<OGN_Packet> Packet;
int Packets=0; int Packets=0;
for( ; ; ) 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.isCorrect()) continue;
if(Packet.Packet.Header.NonPos) continue; if(Packet.Packet.Header.NonPos) continue; // skip non-position packets (although we could print them too)
uint32_t Time = Packet.getTime(FileTime); 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); xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
uint8_t Len=Packet.Packet.WriteAPRS(Line, Time); uint8_t Len=Packet.Packet.WriteAPRS(Line, Time); // print the packet in the APRS format
Format_String(CONS_UART_Write, Line, 0, Len); Format_String(CONS_UART_Write, Line, 0, Len); // send the APRS to the console
xSemaphoreGive(CONS_Mutex); xSemaphoreGive(CONS_Mutex);
vTaskDelay(10); vTaskDelay(10); // limit the printout to some 100 packet/sec
Packets++; } Packets++; } // count printed packets
fclose(File); fclose(File);
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); xSemaphoreTake(CONS_Mutex, portMAX_DELAY); //
Format_String(CONS_UART_Write, FileName); Format_String(CONS_UART_Write, FileName);
Format_String(CONS_UART_Write, " => "); Format_String(CONS_UART_Write, " => ");
Format_UnsDec(CONS_UART_Write, (uint32_t)Packets); Format_UnsDec(CONS_UART_Write, (uint32_t)Packets);
Format_String(CONS_UART_Write, " packets\n"); Format_String(CONS_UART_Write, " packets\n");
xSemaphoreGive(CONS_Mutex); 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]; { char FileName[32];
SPIFFSlog_FullFileName(FileName, FileTime); FlashLog_FullFileName(FileName, FileTime);
return SPIFFSlog_ListFile(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; { const int MaxDelFiles = 4;
uint32_t DelFile[MaxDelFiles]; uint32_t DelFile[MaxDelFiles];
int DelFiles=0; int DelFiles=0;
char FullName[32]; 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++]='/'; if(FullName[PathLen-1]!='/') FullName[PathLen++]='/';
struct stat Stat; 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 for( ; ; ) // run through the directory
{ struct dirent *Ent = readdir(Dir); if(!Ent) break; // read next directory entry, break if all read { 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 if(Ent->d_type != DT_REG) continue; // skip non-regular files
char *Name = Ent->d_name; 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); strcpy(FullName+PathLen, Name);
if( Time>=0x10000000 && Time<0x80000000 ) // heuristic data selection if( Time>=0x10000000 && Time<0x80000000 ) // heuristic data selection
{ if(stat(FullName, &Stat)<0) continue; // get file info { 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); } vTaskDelay(1); }
closedir(Dir); closedir(Dir);
for( int File=0; File<DelFiles; File++) for( int File=0; File<DelFiles; File++)
{ SPIFFSlog_FullFileName(FullName, DelFile[File]); { FlashLog_FullFileName(FullName, DelFile[File]);
unlink(FullName); unlink(FullName);
vTaskDelay(1); } vTaskDelay(1); }
return DelFiles; } 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; { size_t Total, Used;
if(SPIFFS_Info(Total, Used)!=0) return -1; // check SPIFFS status, give up if not possible 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 size_t Free = Total-Used; // [B] amount of free space
if(MinFree) { if(Free>= MinFree ) return 0; } // give up if enough 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 else { if(Free>=(Total/2)) return 0; } // if MinFree not specified, take Total/4
uint32_t Oldest=0xFFFFFFFF; 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<0) return Files;
if(Files<=2) return 0; // if two or less files give up if(Files<=2) return 0; // if two or less files give up
char FullName[32]; char FullName[32];
SPIFFSlog_FullFileName(FullName, Oldest); // oldest file name FlashLog_FullFileName(FullName, Oldest); // oldest file name
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); 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); Format_String(CONS_UART_Write, FullName);
CONS_UART_Write(' '); CONS_UART_Write(' ');
Format_UnsDec(CONS_UART_Write, (uint32_t)Files); 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 if(unlink(FullName)<0) return -1; // remove the oldest file
return 1; } 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; { int Count=0;
for( ; Loops>0; Loops--) for( ; Loops>0; Loops--)
{ if(SPIFFSlog_Clean(MinFree)<=0) break; { if(FlashLog_Clean(MinFree)<=0) break;
vTaskDelay(1); Count++; } vTaskDelay(1); Count++; }
return Count; } return Count; }
static int SPIFFSlog_Open(uint32_t Time) // open a new log file for given start time static int FlashLog_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 { if(FlashLog_File) { fclose(FlashLog_File); FlashLog_File=0; } // if a file open already, close it
SPIFFSlog_CleanEmpty(32); // remove empty files or shorter than 32 bytes FlashLog_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 FlashLog_Clean(2*FlashLog_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 FlashLog_FullFileName(FlashLog_FileName, Time); // name of the new log file
SPIFFSlog_FileTime=Time; // record the time of the log file FlashLog_FileTime=Time; // record the time of the log file
SPIFFSlog_File = fopen(SPIFFSlog_FileName, "wb"); // open the new file FlashLog_File = fopen(FlashLog_FileName, "wb"); // open the new file
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
Format_String(CONS_UART_Write, "SPIFFSlog_Open() "); Format_String(CONS_UART_Write, "FlashLog_Open() ");
Format_String(CONS_UART_Write, SPIFFSlog_FileName); Format_String(CONS_UART_Write, FlashLog_FileName);
Format_String(CONS_UART_Write, "\n"); Format_String(CONS_UART_Write, "\n");
xSemaphoreGive(CONS_Mutex); xSemaphoreGive(CONS_Mutex);
#endif #endif
if(SPIFFSlog_File==0) SPIFFSlog_Clean(0, 8); // if the file cannot be open clean again if(FlashLog_File==0) FlashLog_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 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 static int FlashLog(OGN_LogPacket<OGN_Packet> *Packet, int Packets, uint32_t Time) // log a batch of OGN packets
{ if(SPIFFSlog_File) { if(FlashLog_File) // if log file already open
{ uint32_t TimeSinceStart = Time-SPIFFSlog_FileTime; // [sec] for how long this file is open already ? { uint32_t TimeSinceStart = Time-FlashLog_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 ? if( (TimeSinceStart>=FlashLog_MaxTime) || (ftell(FlashLog_File)>=FlashLog_MaxSize) ) // is it too long in time or in size ?
{ fclose(SPIFFSlog_File); SPIFFSlog_File=0; } // decide to close the current log file { 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(FlashLog_File==0)
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 #ifdef WITH_SD
{ fclose(SPIFFSlog_File); SPIFFSlog_File=0; SPIFFSlog_Clean(0, 8); return -1; } // if failure then close the log file and report error 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 return Packets; } // report success
#endif // WITH_SPIFFS #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; { 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 if(Packets==0) return 0; // if none: give up
uint32_t Time = TimeSync_Time(); // Time is to create new log file uint32_t Time = TimeSync_Time(); // Time is to create new log file
#ifdef WITH_SPIFFS #ifdef WITH_SPIFFS
int Err=SPIFFSlog(Packet, Packets, Time); // log the batch of packets int Err=FlashLog(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) { FlashLog_Clean(0, 8); Err=FlashLog(Packet, Packets, Time); } // if failed: give it another try
// if(Err<0) SPIFFSlog_Clean(0, 8); // if(Err<0) FlashLog_Clean(0, 8);
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
Format_String(CONS_UART_Write, "vTaskLOG() "); Format_String(CONS_UART_Write, "vTaskLOG() ");
@ -312,7 +321,7 @@ static int Copy(void) // copy the p
xSemaphoreGive(CONS_Mutex); xSemaphoreGive(CONS_Mutex);
#endif #endif
#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 #ifdef WITH_SPIFFS
return Err; return Err;
#else #else
@ -325,7 +334,7 @@ static int Copy(void) // copy the p
#endif #endif
void vTaskLOG(void* pvParameters) void vTaskLOG(void* pvParameters)
{ {
LOG_FIFO.Clear(); FlashLog_FIFO.Clear();
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
@ -345,15 +354,15 @@ void vTaskLOG(void* pvParameters)
#ifdef WITH_SD #ifdef WITH_SD
#ifdef WITH_SPIFFS #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
#endif #endif
TickType_t PrevTick = 0; TickType_t PrevTick = 0;
for( ; ; ) for( ; ; )
{ // vTaskDelay(200); // wait idle 0.2sec { // vTaskDelay(200); // wait idle 0.2sec
TickType_t Tick=xTaskGetTickCount(); // TickType_t Tick=xTaskGetTickCount(); // system tick count now
size_t Packets = LOG_FIFO.Full(); // how many packets in the queue ? size_t Packets = FlashLog_FIFO.Full(); // how many packets in the queue ?
// #ifdef DEBUG_PRINT // #ifdef DEBUG_PRINT
// xSemaphoreTake(CONS_Mutex, portMAX_DELAY); // xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
// Format_String(CONS_UART_Write, "TaskLOG() "); // Format_String(CONS_UART_Write, "TaskLOG() ");

Wyświetl plik

@ -1,20 +1,20 @@
#include "fifo.h" #include "fifo.h"
#include "ogn.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 uint32_t FlashLog_FileTime; // [sec] start time of the current log file
extern char SPIFFSlogFileName[32]; // current log file name if open extern char FlashLog_FileName[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 FlashLog_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); int FlashLog_ShortFileName(char *FileName, uint32_t Time);
uint32_t SPIFFSlog_ReadShortFileTime(const char *FileName, int Len); uint32_t FlashLog_ReadShortFileTime(const char *FileName, int Len);
uint32_t SPIFFSlog_ReadShortFileTime(const char *FileName); uint32_t FlashLog_ReadShortFileTime(const char *FileName);
int SPIFFSlog_CopyToSD(void); int FlashLog_CopyToSD(bool Remove=0);
int SPIFFSlog_FindOldestFile(uint32_t &Oldest, uint32_t After=0); // find the oldest log file int FlashLog_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 FlashLog_ListFiles(void); // list the log files on the console
int SPIFFSlog_ListFile(uint32_t FileTime); // int FlashLog_ListFile(uint32_t FileTime); //
int SPIFFSlog_ListFile(const char *FileName, uint32_t FileTime); // int FlashLog_ListFile(const char *FileName, uint32_t FileTime); //
// int SPIFFSlog_ListFile(const char *FileName, int Len); // // int FlashLog_ListFile(const char *FileName, int Len); //
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"

Wyświetl plik

@ -100,8 +100,8 @@ void app_main(void)
#ifdef WITH_WIFI #ifdef WITH_WIFI
xTaskCreate(vTaskWIFI, "WIFI", 4096, 0, tskIDLE_PRIORITY+2, 0); xTaskCreate(vTaskWIFI, "WIFI", 4096, 0, tskIDLE_PRIORITY+2, 0);
#endif #endif
#ifdef WITH_WIFI #ifdef WITH_STRATUX
xTaskCreate(vTaskSTX, "STX", 4096, 0, tskIDLE_PRIORITY+2, 0); xTaskCreate(vTaskSTX, "STX", 4096, 0, tskIDLE_PRIORITY+3, 0);
#endif #endif
#if defined(WITH_OLED) || defined(WITH_U8G2_OLED) || defined(WITH_ST7789) || defined(WITH_ILI9341) #if defined(WITH_OLED) || defined(WITH_U8G2_OLED) || defined(WITH_ST7789) || defined(WITH_ILI9341)
xTaskCreate(vTaskDISP, "DISP", 2048, 0, tskIDLE_PRIORITY+2, 0); xTaskCreate(vTaskDISP, "DISP", 2048, 0, tskIDLE_PRIORITY+2, 0);

Wyświetl plik

@ -1407,6 +1407,44 @@ class GPS_Position: public GPS_Time
{ int16_t LatAngle = calcLatAngle16(Latitude); { int16_t LatAngle = calcLatAngle16(Latitude);
LatitudeCosine = calcLatCosine(LatAngle); } 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) static int WriteIGCcoord(char *Out, int32_t Coord, uint8_t DegSize, const char *SignChar)
{ int Len=0; { int Len=0;
bool Neg = Coord<0; if(Neg) Coord=(-Coord); bool Neg = Coord<0; if(Neg) Coord=(-Coord);
@ -1417,14 +1455,17 @@ class GPS_Position: public GPS_Time
Out[Len++]=SignChar[Neg]; Out[Len++]=SignChar[Neg];
return Len; } 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) int WriteIGC(char *Out)
{ // if(!isValid()) return 0; { // if(!isValid()) return 0;
int Len=0; int Len=0;
Out[Len++] = 'B'; Out[Len++] = 'B';
if(isTimeValid()) if(isTimeValid()) Len+=WriteHHMMSS(Out+Len);
{ 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, " "); else Len+=Format_String(Out+Len, " ");
if(isValid()) if(isValid())
{ Len+=WriteIGCcoord(Out+Len, Latitude, 2, "NS"); { Len+=WriteIGCcoord(Out+Len, Latitude, 2, "NS");

Wyświetl plik

@ -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)HeaderWord, (long int)Data[0], (long int)Data[1],
(long int)Data[2], (long int)Data[3] ); } (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 void DumpBytes(void) const
{ for(uint8_t Idx=0; Idx<Bytes; Idx++) { for(uint8_t Idx=0; Idx<Bytes; Idx++)
{ printf(" %02X", Byte()[Idx]); } { printf(" %02X", Byte()[Idx]); }
printf("\n"); } printf("\n"); }
int WriteDeviceStatus(char *Out) 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", { 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, (long int)DecodeAltitude(), Status.Hardware, Status.Firmware, Status.Satellites, Status.FixQuality, 8+Status.SatSNR, (long int)DecodeAltitude(),
0.08*Status.Pressure, 0.1*DecodeTemperature(), 0.1*DecodeHumidity(), 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 ); (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 void PrintDeviceStatus(void) const
{ printf("%c:%06lX R%c%c %02ds:", { printf("%c:%06lX R%c%c %02ds:",
'0'+Header.AddrType, (long int)Header.Address, '0'+Header.Relay, Header.Emergency?'E':' ', Status.Time); '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", 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, (long int)DecodeAltitude(), Status.Hardware, Status.Firmware, Status.Satellites, Status.FixQuality, 8+Status.SatSNR, (long int)DecodeAltitude(),
0.08*Status.Pressure, 0.1*DecodeTemperature(), 0.1*DecodeHumidity(), 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 ); (1.0/64)*DecodeVoltage(), Status.TxPower+4, -0.5*Status.RadioNoise, (1<<Status.RxRate)-1 );
printf("\n"); 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()) ); 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); if(Position.Time<60) printf(" %02ds:", (int)Position.Time);
else printf(" ---:"); 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() ); 0.0001/60*DecodeLatitude(), 0.0001/60*DecodeLongitude(), (long int)DecodeAltitude() );
if(hasBaro()) if(hasBaro())
{ printf("[%+dm]", (int)getBaroAltDiff() ); } { 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() ); 0.1*DecodeSpeed(), 0.1*DecodeHeading(), 0.1*DecodeClimbRate(), 0.1*DecodeTurnRate() );
printf("\n"); 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) void Encode(MAV_ADSB_VEHICLE *MAV)
{ MAV->ICAO_address = HeaderWord&0x03FFFFFF; { 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); Len+=Format_UnsDec(Msg+Len, (DecodeHeading()+5)/10, 3);
Msg[Len++] = '/'; 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++] = '/'; Msg[Len++] = 'A'; Msg[Len++] = '='; Len+=Format_UnsDec(Msg+Len, MetersToFeet(DecodeAltitude()), 6);
Msg[Len++] = ' '; 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++] = ' '; 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'; Msg[Len++] = ' '; Len+=Format_SignDec(Msg+Len, DecodeTurnRate()/3, 2, 1); Msg[Len++] = 'r'; Msg[Len++] = 'o'; Msg[Len++] = 't';
if(hasBaro()) if(hasBaro())

Wyświetl plik

@ -13,8 +13,6 @@
#include "fifo.h" #include "fifo.h"
#include "flight.h" // flight status
#ifdef WITH_FLASHLOG // log own track to unused Flash pages (STM32 only) #ifdef WITH_FLASHLOG // log own track to unused Flash pages (STM32 only)
#include "flashlog.h" #include "flashlog.h"
#endif #endif
@ -87,22 +85,22 @@ FlightMonitor Flight;
#ifdef WITH_LOG #ifdef WITH_LOG
static int SPIFFSlog(OGN_RxPacket<OGN_Packet> *Packet, uint32_t Time) static int FlashLog(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 { 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->Packet = Packet->Packet; // copy the packet
LogPacket->Flags=0x80; LogPacket->Flags=0x80;
LogPacket->setTime(Time); LogPacket->setTime(Time);
LogPacket->setCheck(); LogPacket->setCheck();
LOG_FIFO.Write(); // finalize the write FlashLog_FIFO.Write(); // finalize the write
return 1; } return 1; }
static int SPIFFSlog(OGN_TxPacket<OGN_Packet> *Packet, uint32_t Time) static int FlashLog(OGN_TxPacket<OGN_Packet> *Packet, uint32_t Time)
{ OGN_LogPacket<OGN_Packet> *LogPacket = LOG_FIFO.getWrite(); if(LogPacket==0) return -1; { OGN_LogPacket<OGN_Packet> *LogPacket = FlashLog_FIFO.getWrite(); if(LogPacket==0) return -1;
LogPacket->Packet = Packet->Packet; LogPacket->Packet = Packet->Packet;
LogPacket->Flags=0x00; LogPacket->Flags=0x00;
LogPacket->setTime(Time); LogPacket->setTime(Time);
LogPacket->setCheck(); LogPacket->setCheck();
LOG_FIFO.Write(); FlashLog_FIFO.Write();
return 1; } return 1; }
#endif // WITH_LOG #endif // WITH_LOG
@ -379,7 +377,7 @@ static void ProcessRxPacket(OGN_RxPacket<OGN_Packet> *RxPacket, uint8_t RxPacket
#ifdef WITH_LOG #ifdef WITH_LOG
bool Signif = PrevRxPacket!=0; bool Signif = PrevRxPacket!=0;
if(!Signif) Signif=OGN_isSignif(&(RxPacket->Packet), &(PrevRxPacket->Packet)); 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 #endif
#ifdef WITH_PFLAA #ifdef WITH_PFLAA
if( Parameters.Verbose // print PFLAA on the console for received packets if( Parameters.Verbose // print PFLAA on the console for received packets
@ -689,7 +687,7 @@ void vTaskPROC(void* pvParameters)
#ifdef WITH_LOG #ifdef WITH_LOG
bool isSignif = OGN_isSignif(&(PosPacket.Packet), &PrevLoggedPacket); bool isSignif = OGN_isSignif(&(PosPacket.Packet), &PrevLoggedPacket);
if(isSignif) if(isSignif)
{ SPIFFSlog(&PosPacket, PosTime); { FlashLog(&PosPacket, PosTime);
PrevLoggedPacket = PosPacket.Packet; } PrevLoggedPacket = PosPacket.Packet; }
#endif #endif
} else // if GPS position is not complete, contains no valid position, etc. } else // if GPS position is not complete, contains no valid position, etc.
@ -745,7 +743,7 @@ void vTaskPROC(void* pvParameters)
if(doTx) if(doTx)
{ {
#ifdef WITH_LOG #ifdef WITH_LOG
SPIFFSlog(&StatPacket, PosTime); // log the status packet FlashLog(&StatPacket, PosTime); // log the status packet
#endif #endif
*StatusPacket = StatPacket; // copy status packet into the Tx queue *StatusPacket = StatPacket; // copy status packet into the Tx queue
StatusPacket->Packet.Whiten(); // whiten for transmission StatusPacket->Packet.Whiten(); // whiten for transmission

Wyświetl plik

@ -1,11 +1,14 @@
extern uint32_t BatteryVoltage; // [1/256 mV] averaged #include "flight.h"
extern int32_t BatteryVoltageRate; // [1/256 mV] averaged
#ifdef WITH_LOOKOUT // traffic awareness and warnings #ifdef WITH_LOOKOUT // traffic awareness and warnings
#include "lookout.h" #include "lookout.h"
extern LookOut Look; extern LookOut Look;
#endif #endif
extern uint32_t BatteryVoltage; // [1/256 mV] averaged
extern int32_t BatteryVoltageRate; // [1/256 mV] averaged
extern FlightMonitor Flight;
#ifdef WITH_ESP32 #ifdef WITH_ESP32
const uint8_t RelayQueueSize = 32; const uint8_t RelayQueueSize = 32;

Wyświetl plik

@ -37,6 +37,9 @@ class Socket
if(Err!=0) { Disconnect(); return -3; } if(Err!=0) { Disconnect(); return -3; }
return Link; } return Link; }
// int Connect()
// { Link = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); }
void Disconnect(void) void Disconnect(void)
{ if(Link>=0) { close(Link); Link=(-1); } { if(Link>=0) { close(Link); Link=(-1); }
if(Host) { freeaddrinfo(Host); Host=0; } if(Host) { freeaddrinfo(Host); Host=0; }

Wyświetl plik

@ -1,16 +1,15 @@
#include <ctype.h>
#include "hal.h" #include "hal.h"
#include "tcpip_adapter.h" #include "tcpip_adapter.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "esp_event_loop.h" #include "esp_event_loop.h"
#include <ctype.h>
#include "format.h" #include "format.h"
#include "fifo.h"
#include "socket.h" #include "socket.h"
#include "proc.h" #include "proc.h"
#include "stratux.h" #include "stratux.h"
#define DEBUG_PRINT #define DEBUG_PRINT
@ -20,8 +19,9 @@
// ============================================================================================== // ==============================================================================================
wifi_config_t WIFI_Config; // WIFI config: ESSID, etc. wifi_config_t WIFI_Config; // WIFI config: ESSID, etc.
uint32_t WIFI_LocalIP = 0; // WIFI local IP address tcpip_adapter_ip_info_t WIFI_IP = { 0, 0, 0 }; // WIFI local IP address, mask and gateway
bool WIFI_isConnected(void) { return WIFI_LocalIP!=0; }
bool WIFI_isConnected(void) { return WIFI_IP.ip.addr!=0; }
static esp_err_t WIFI_event_handler(void *ctx, system_event_t *event) 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 static uint32_t WIFI_getLocalIP(void) // get local IP, once DHCP phase is done
{ esp_err_t Err; { esp_err_t Err;
tcpip_adapter_ip_info_t Info; Err=tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &WIFI_IP); if(Err!=ESP_OK) return 0;
Err=tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &Info); if(Err!=ESP_OK) return 0; return WIFI_IP.ip.addr; }
return Info.ip.addr; }
uint8_t IP_Print(char *Out, uint32_t IP) uint8_t IP_Print(char *Out, uint32_t IP)
{ uint8_t Len=0; { 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) bool Stratux_isConnected(void)
{ return 0; } { return WIFI_isConnected() && Stratux_Socket.isConnected(); }
int Stratux_Read (uint8_t &Byte) int Stratux_Read (uint8_t &Byte)
{ return 0; } { return Stratux_RxFIFO.Read(Byte); }
void Stratux_Write (char 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" extern "C"
void vTaskWIFI(void* pvParameters) void vTaskSTX(void* pvParameters)
{ esp_err_t Err; { esp_err_t Err;
vTaskDelay(1000); vTaskDelay(1000);
@ -161,7 +176,7 @@ void vTaskWIFI(void* pvParameters)
for( ; ; ) // main (endless) loop for( ; ; ) // main (endless) loop
{ vTaskDelay(1000); { vTaskDelay(1000);
if(Parameters.StratuxPass[0]==0) continue; if(Parameters.StratuxWIFI[0]==0) continue;
Err=WIFI_Connect(Parameters.StratuxWIFI, Parameters.StratuxPass); Err=WIFI_Connect(Parameters.StratuxWIFI, Parameters.StratuxPass);
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
@ -177,24 +192,58 @@ void vTaskWIFI(void* pvParameters)
#endif #endif
if(Err) { vTaskDelay(10000); continue; } 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 for(uint8_t Idx=0; Idx<10; Idx++) // wait to obtain local IP from DHCP
{ vTaskDelay(1000); { vTaskDelay(1000);
WIFI_LocalIP = WIFI_getLocalIP(); if(WIFI_getLocalIP()) break; }
if(WIFI_LocalIP) break; }
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
xSemaphoreTake(CONS_Mutex, portMAX_DELAY); xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
Format_String(CONS_UART_Write, "Local IP: "); Format_String(CONS_UART_Write, "Local IP: ");
IP_Print(CONS_UART_Write, WIFI_LocalIP); IP_Print(CONS_UART_Write, WIFI_IP.ip.addr);
// Format_Hex(CONS_UART_Write, WIFI_LocalIP); Format_String(CONS_UART_Write, " GW: ");
IP_Print(CONS_UART_Write, WIFI_IP.gw.addr);
Format_String(CONS_UART_Write, "\n"); Format_String(CONS_UART_Write, "\n");
xSemaphoreGive(CONS_Mutex); xSemaphoreGive(CONS_Mutex);
#endif #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); vTaskDelay(5000);
WIFI_Disconnect(); WIFI_LocalIP=0; WIFI_Disconnect(); WIFI_IP.ip.addr=0;
vTaskDelay(2000); vTaskDelay(2000);
} }

Wyświetl plik

@ -9,6 +9,8 @@
#include "socket.h" #include "socket.h"
#include "proc.h"
#ifdef WITH_WIFI #ifdef WITH_WIFI
#define DEBUG_PRINT #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_start(&Config, 1); if(Err!=ESP_OK) return Err;
Err = esp_wifi_scan_get_ap_records(&APs, AP); 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; { esp_err_t Err;
wifi_scan_config_t Config = { ssid:0, bssid:0, channel:0, show_hidden:0, wifi_scan_config_t Config = { ssid:0, bssid:0, channel:0, show_hidden:0,
scan_type:WIFI_SCAN_TYPE_PASSIVE, 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; Err = esp_wifi_connect(); if(Err!=ESP_OK) return Err;
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(); { esp_err_t Err=esp_wifi_disconnect();
return Err; } return Err; }