kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
Prepare to download log files as IGC from HTTP interface
rodzic
bf5f77a000
commit
fb7c0f004d
|
@ -16,6 +16,7 @@
|
|||
#include "gps.h"
|
||||
#include "log.h"
|
||||
#include "http.h"
|
||||
#include "ognconv.h"
|
||||
|
||||
// #define DEBUG_PRINT
|
||||
|
||||
|
@ -691,6 +692,33 @@ static int LogFileName(char *Name, time_t Time, const char *Ext=0)
|
|||
if(Ext) Len+=Format_String(Name+Len, Ext);
|
||||
Name[Len]=0; return Len; }
|
||||
|
||||
// send give log file in the IGC format
|
||||
static esp_err_t SendLog_IGC(httpd_req_t *Req, const char *FileName, uint32_t FileTime)
|
||||
{ char ContDisp[64];
|
||||
char Line[1000]; int Len=0;
|
||||
Len=Format_String(ContDisp, "attachement; filename=\""); Len+=LogFileName(ContDisp+Len, FileTime, ".IGC"); ContDisp[Len++]='\"'; ContDisp[Len]=0;
|
||||
httpd_resp_set_hdr(Req, "Content-Disposition", ContDisp);
|
||||
httpd_resp_set_type(Req, "text/plain");
|
||||
FILE *File = fopen(FileName, "rb"); if(File==0) { httpd_resp_send_chunk(Req, 0, 0); return ESP_OK; }
|
||||
// here we should write the IGC header
|
||||
OGN_LogPacket<OGN_Packet> Packet;
|
||||
for( ; ; )
|
||||
{ if(fread(&Packet, Packet.Bytes, 1, File)!=1) break; // read the next packet
|
||||
if(!Packet.isCorrect()) continue;
|
||||
uint32_t Time = Packet.getTime(FileTime); // [sec] get exact time from short time in the packet and the file start time
|
||||
Len+=Format_String(Line+Len, "LGNE "); // attach APRS as LGNE record
|
||||
char *APRS=Line+Len;
|
||||
Len+=Packet.Packet.WriteAPRS(Line+Len, Time); // packet in the APRS format
|
||||
bool Own = Packet.Packet.Header.Address==Parameters.Address && Packet.Packet.Header.AddrType==Parameters.AddrType;
|
||||
if(Own && !Packet.Packet.Header.NonPos && !Packet.Packet.Header.Encrypted)
|
||||
Len+=APRS2IGC(Line+Len, APRS, GPS_GeoidSepar); // IGC B-record
|
||||
if(Len>=800) { httpd_resp_send_chunk(Req, Line, Len); Len=0; } // when more than 800 bytes then write this part to the socket
|
||||
vTaskDelay(1); }
|
||||
fclose(File);
|
||||
if(Len) { httpd_resp_send_chunk(Req, Line, Len); Len=0; }
|
||||
httpd_resp_send_chunk(Req, 0, 0);
|
||||
return ESP_OK; }
|
||||
|
||||
// send give log file in the APRS format
|
||||
static esp_err_t SendLog_APRS(httpd_req_t *Req, const char *FileName, uint32_t FileTime)
|
||||
{ char ContDisp[64];
|
||||
|
@ -748,6 +776,7 @@ static esp_err_t log_get_handler(httpd_req_t *Req)
|
|||
uint32_t Time=FlashLog_ReadShortFileTime(Name);
|
||||
if(Time)
|
||||
{ if(strcmp(Format, "APRS")==0) return SendLog_APRS(Req, FullName, Time);
|
||||
if(strcmp(Format, "IGC" )==0) return SendLog_IGC(Req, FullName, Time);
|
||||
return SendLog_TLG(Req, FullName, Time); }
|
||||
}
|
||||
}
|
||||
|
@ -779,7 +808,7 @@ static esp_err_t log_get_handler(httpd_req_t *Req)
|
|||
closedir(Dir);
|
||||
std::sort(FileList.begin(), FileList.end());
|
||||
|
||||
httpd_resp_sendstr_chunk(Req, "<table>\n<tr><th>File</th><th></th><th>[KB]</th><th>Date</th></tr>\n");
|
||||
httpd_resp_sendstr_chunk(Req, "<table>\n<tr><th>File</th><th></th><th></th><th>[KB]</th><th>Date</th></tr>\n");
|
||||
for(size_t Idx=0; Idx<FileList.size(); Idx++)
|
||||
{ uint32_t Time=FileList[Idx];
|
||||
char Name[16];
|
||||
|
@ -794,7 +823,10 @@ static esp_err_t log_get_handler(httpd_req_t *Req)
|
|||
Len+=Format_String(Line+Len, Name);
|
||||
Len+=Format_String(Line+Len, "</a></td><td><a href=\"/log.html?Format=APRS&File=");
|
||||
Len+=Format_String(Line+Len, Name);
|
||||
Len+=Format_String(Line+Len, "\">APRS</a></td><td align=\"center\">");
|
||||
Len+=Format_String(Line+Len, "\">APRS</a></td>");
|
||||
Len+=Format_String(Line+Len, "<td><a href=\"/log.html?Format=IGC&File=");
|
||||
Len+=Format_String(Line+Len, Name);
|
||||
Len+=Format_String(Line+Len, "\">IGC</a></td><td align=\"center\">");
|
||||
Len+=Format_UnsDec(Line+Len, (Size+512)>>10);
|
||||
Len+=Format_String(Line+Len, "</td><td>");
|
||||
Len+=Format_DateTime(Line+Len, Time);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "format.h"
|
||||
#include "ognconv.h"
|
||||
|
||||
// ==============================================================================================
|
||||
|
||||
uint32_t FeetToMeters(uint32_t Altitude) { return (Altitude*312+512)>>10; } // [feet] => [m]
|
||||
uint32_t MetersToFeet(uint32_t Altitude) { return (Altitude*3360+512)>>10; } // [m] => [feet]
|
||||
int32_t FeetToMeters(int32_t Altitude) { return (Altitude*312+512)>>10; } // [feet] => [m]
|
||||
int32_t MetersToFeet(int32_t Altitude) { return (Altitude*3360+512)>>10; } // [m] => [feet]
|
||||
|
||||
// ==============================================================================================
|
||||
|
||||
|
@ -269,3 +271,39 @@ uint8_t DecodeAscii85(uint32_t &Word, const char *Ascii)
|
|||
|
||||
// ==============================================================================================
|
||||
|
||||
int APRS2IGC(char *Out, const char *Inp, int GeoidSepar) // convert APRS positon message into IGC B-record
|
||||
{ int Len=0;
|
||||
const char *Msg = strchr(Inp, ':'); if(Msg==0) return 0; // colon: separates header and message
|
||||
Msg++; // where message starts
|
||||
if(Msg[0]!='/' || Msg[7]!='h') return 0;
|
||||
const char *Pos = Msg+8; if(Pos[4]!='.' || Pos[14]!='.') return 0; // where position starts
|
||||
const char *ExtPos = strstr(Pos+18, " !W"); if(ExtPos[5]=='!') ExtPos+=3; else ExtPos=0;
|
||||
Out[Len++]='B'; // B-record
|
||||
memcpy(Out+Len, Msg+1, 6); Len+=6; // copy UTC time
|
||||
memcpy(Out+Len, Pos, 4); Len+=4; // copy DDMM
|
||||
memcpy(Out+Len, Pos+5, 2); Len+=2; // copy fractional MM
|
||||
Out[Len++] = ExtPos?ExtPos[0]:'0'; // extended precision
|
||||
Out[Len++] = Pos[7]; // copy N/S sign
|
||||
memcpy(Out+Len, Pos+9, 5); Len+=5; // copy DDMM
|
||||
memcpy(Out+Len, Pos+15,2); Len+=2; // copy fractional MM
|
||||
Out[Len++] = ExtPos?ExtPos[1]:'0'; // extended precision
|
||||
Out[Len++] = Pos[17]; // copy E/W sign
|
||||
Out[Len++] = 'A';
|
||||
memcpy(Out+Len, " ", 10);
|
||||
const char *FL = strstr(Pos+18, " FL");
|
||||
int32_t AltH=0; int32_t AltL=0;
|
||||
if(FL && FL[6]=='.' && Read_Int(AltH, FL+3)==3 && Read_Int(AltL, FL+7)==2) // pressure altitude
|
||||
{ int Alt = AltH*100+AltL; Alt=FeetToMeters(Alt);
|
||||
if(Alt<0) { Alt = (-Alt); Out[Len] = '-'; Format_UnsDec(Out+Len+1, (uint32_t)Alt, 4); }
|
||||
else { Format_UnsDec(Out+Len, (uint32_t)Alt, 5); }
|
||||
}
|
||||
Len+=5; int32_t Alt=0;
|
||||
if(Pos[27]=='A' && Pos[28]=='=' && Read_Int(Alt, Pos+29)==6) // geometrical altitude
|
||||
{ Alt=FeetToMeters(Alt); Alt+=GeoidSepar; // convert to meters and add GeoidSepar for HAE
|
||||
if(Alt<0) { Alt = (-Alt); Out[Len] = '-'; Format_UnsDec(Out+Len+1, (uint32_t)Alt, 4); }
|
||||
else { Format_UnsDec(Out+Len, (uint32_t)Alt, 5); }
|
||||
}
|
||||
Len+=5;
|
||||
Out[Len]=0; return Len; }
|
||||
|
||||
// ==============================================================================================
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t FeetToMeters(uint32_t Altitude); //
|
||||
uint32_t MetersToFeet(uint32_t Altitude); //
|
||||
int32_t FeetToMeters(int32_t Altitude); //
|
||||
int32_t MetersToFeet(int32_t Altitude); //
|
||||
|
||||
uint16_t EncodeUR2V8(uint16_t Value); // Encode unsigned 12bit (0..3832) as 10bit
|
||||
uint16_t DecodeUR2V8(uint16_t Value); // Decode 10bit 0..0x3FF
|
||||
|
@ -82,4 +82,6 @@ void xorshift64(uint64_t &Seed);
|
|||
uint8_t EncodeAscii85( char *Ascii, uint32_t Word ); // Encode 32-bit Word into 5-char Ascii-85 string
|
||||
uint8_t DecodeAscii85(uint32_t &Word, const char *Ascii); // Decode 5-char Ascii-85 to 32-bit Word
|
||||
|
||||
int APRS2IGC(char *Out, const char *Inp, int GeoidSepar); // convert APRS message to IGC B-record
|
||||
|
||||
#endif // __OGNCONV_H__
|
||||
|
|
|
@ -174,7 +174,7 @@ static int IGC_LogLine(const char *Line, int Len)
|
|||
static int IGC_LogLine(const char *Line)
|
||||
{ return IGC_LogLine(Line, strlen(Line)); }
|
||||
|
||||
static char Line[192];
|
||||
static char Line[512];
|
||||
|
||||
static int IGC_HeadParm(const char *Name, const char *Parm1, const char *Parm2=0, const char *Parm3=0)
|
||||
{ int Len=Format_String(Line, Name);
|
||||
|
@ -211,8 +211,22 @@ static int IGC_Header(const GPS_Position &Pos) // write the
|
|||
Line[Len++]='\n'; Line[Len]=0;
|
||||
IGC_LogLine(Line, Len); }
|
||||
IGC_LogLine("HFRFWFirmwareVersion:ESP32-OGN-TRACKER " __DATE__ " " __TIME__ "\n"); // firmware version, compile date/time
|
||||
#ifdef WITH_FollowMe
|
||||
IGC_LogLine("HFGPSReceiver:L80\n"); // GPS sensor
|
||||
#else
|
||||
#ifdef WITH_GPS_UBX
|
||||
IGC_LogLine("HFGPSReceiver:UBX\n"); // GPS sensor
|
||||
#endif
|
||||
#ifdef WITH_GPS_MTK
|
||||
IGC_LogLine("HFGPSReceiver:MTK\n"); // GPS sensor
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WITH_BMP280
|
||||
IGC_LogLine("HFPRSPressAltSensor:BMP280\n"); // pressure sensor
|
||||
#endif
|
||||
#ifdef WITH_BME280
|
||||
IGC_LogLine("HFPRSPressAltSensor:BME280\n"); // pressure sensor
|
||||
#endif
|
||||
return 0; }
|
||||
|
||||
int IGC_ID(void)
|
||||
|
|
|
@ -73,6 +73,11 @@ esp_err_t WIFI_StartAP(const char *SSID, const char *Pass, int MaxConnections)
|
|||
else WIFI_Config.ap.password[0]=0;
|
||||
WIFI_Config.ap.max_connection = MaxConnections;
|
||||
WIFI_Config.ap.authmode = (Pass && Pass[0]) ? WIFI_AUTH_WPA_WPA2_PSK:WIFI_AUTH_OPEN;
|
||||
// tcpip_adapter_ip_info_t IPinfo; // attempt to change the IP range to 192.168.1.1 but does not work
|
||||
// IP4_ADDR(&IPinfo.ip, 192,168,1,1);
|
||||
// IP4_ADDR(&IPinfo.gw, 192,168,1,1);
|
||||
// IP4_ADDR(&IPinfo.netmask, 255,255,255,0);
|
||||
// tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &IPinfo);
|
||||
Err = esp_wifi_set_config(ESP_IF_WIFI_AP, &WIFI_Config); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_wifi_set_mode(WIFI_MODE_AP); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_wifi_start();
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "format.h"
|
||||
#include "ognconv.h"
|
||||
|
||||
// ==============================================================================================
|
||||
|
||||
uint32_t FeetToMeters(uint32_t Altitude) { return (Altitude*312+512)>>10; } // [feet] => [m]
|
||||
uint32_t MetersToFeet(uint32_t Altitude) { return (Altitude*3360+512)>>10; } // [m] => [feet]
|
||||
int32_t FeetToMeters(int32_t Altitude) { return (Altitude*312+512)>>10; } // [feet] => [m]
|
||||
int32_t MetersToFeet(int32_t Altitude) { return (Altitude*3360+512)>>10; } // [m] => [feet]
|
||||
|
||||
// ==============================================================================================
|
||||
|
||||
|
@ -293,14 +291,15 @@ int APRS2IGC(char *Out, const char *Inp, int GeoidSepar) // convert
|
|||
Out[Len++] = 'A';
|
||||
memcpy(Out+Len, " ", 10);
|
||||
const char *FL = strstr(Pos+18, " FL");
|
||||
if(FL) // pressure altitude
|
||||
{ float PressAlt=atof(FL+3); PressAlt*=30.4; int32_t Alt=floor(PressAlt+0.5);
|
||||
int32_t AltH=0; int32_t AltL=0;
|
||||
if(FL && FL[6]=='.' && Read_Int(AltH, FL+3)==3 && Read_Int(AltL, FL+7)==2) // pressure altitude
|
||||
{ int Alt = AltH*100+AltL; Alt=FeetToMeters(Alt);
|
||||
if(Alt<0) { Alt = (-Alt); Out[Len] = '-'; Format_UnsDec(Out+Len+1, (uint32_t)Alt, 4); }
|
||||
else { Format_UnsDec(Out+Len, (uint32_t)Alt, 5); }
|
||||
}
|
||||
Len+=5;
|
||||
if(Pos[27]=='A' && Pos[28]=='=') // geometrical altitude
|
||||
{ int32_t Alt=atol(Pos+29); Alt=(Alt*3+5)/10; Alt+=GeoidSepar; // convert to meters and add GeoidSepar for HAE
|
||||
Len+=5; int32_t Alt=0;
|
||||
if(Pos[27]=='A' && Pos[28]=='=' && Read_Int(Alt, Pos+29)==6) // geometrical altitude
|
||||
{ Alt=FeetToMeters(Alt); Alt+=GeoidSepar; // convert to meters and add GeoidSepar for HAE
|
||||
if(Alt<0) { Alt = (-Alt); Out[Len] = '-'; Format_UnsDec(Out+Len+1, (uint32_t)Alt, 4); }
|
||||
else { Format_UnsDec(Out+Len, (uint32_t)Alt, 5); }
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t FeetToMeters(uint32_t Altitude); //
|
||||
uint32_t MetersToFeet(uint32_t Altitude); //
|
||||
int32_t FeetToMeters(int32_t Altitude); //
|
||||
int32_t MetersToFeet(int32_t Altitude); //
|
||||
|
||||
uint16_t EncodeUR2V8(uint16_t Value); // Encode unsigned 12bit (0..3832) as 10bit
|
||||
uint16_t DecodeUR2V8(uint16_t Value); // Decode 10bit 0..0x3FF
|
||||
|
|
Ładowanie…
Reference in New Issue