Prepare to download log files as IGC from HTTP interface

pull/36/head
Pawel Jalocha 2021-03-06 17:06:50 +00:00
rodzic bf5f77a000
commit fb7c0f004d
7 zmienionych plików z 108 dodań i 18 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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