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");
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
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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() ");

Wyświetl plik

@ -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"

Wyświetl plik

@ -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);

Wyświetl plik

@ -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");

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)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())

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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; }

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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; }