Skip to content

Commit

Permalink
Update from other projects
Browse files Browse the repository at this point in the history
  • Loading branch information
pjalocha committed May 23, 2023
1 parent 10a2845 commit b99cf5b
Show file tree
Hide file tree
Showing 14 changed files with 1,708 additions and 402 deletions.
2 changes: 1 addition & 1 deletion main/ognconv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ uint8_t AcftType_ADSBtoOGN(uint8_t AcftCat)
{ if(Low==1) return 8;
if(Low==7) return 3;
return 9; }
if(Upp=0xB)
if(Upp==0xB)
{ const uint8_t Map[8] = { 0, 0xB, 1, 4, 7, 0, 0xD, 0 };
return Map[Low]; }
if(Upp==0xC)
Expand Down
412 changes: 412 additions & 0 deletions utils/adsl.h

Large diffs are not rendered by default.

145 changes: 128 additions & 17 deletions utils/fanet.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ class FANET_Packet

uint8_t getAddrType(void) const // address-type based on prefix
{ uint8_t Pref=getAddrPref();
if(Pref==0x11 || Pref==0x20 || Pref==0xDD || Pref==0xDE || Pref==0xDF) return 2;
if(Pref==0x08 || Pref==0x11 || Pref==0x20 || Pref==0xDD || Pref==0xDE || Pref==0xDF) return 2;
return 3; }

void setAddress(uint32_t Addr) { setAddrPref(Addr>>16); setAddrLow(Addr); }
void setAddrPref(uint8_t Prefix) { Byte[1]=Prefix; }
void setAddrLow(uint16_t Addr ) { Byte[2]=Addr; Byte[3]=Addr>>8; }
void setAddress(uint32_t Addr) { setAddrPref(Addr>>16); setAddrLow(Addr); } // full 24-bit address
void setAddrPref(uint8_t Prefix) { Byte[1]=Prefix; } // address prefix
void setAddrLow(uint16_t Addr ) { Byte[2]=Addr; Byte[3]=Addr>>8; } // lower 16-bits of the address
void setHeader(uint8_t Type) { Byte[0] = 0x40 | (Type&0x3F); }
void setType(uint8_t Type) { Byte[0] = (Byte[0]&0xC0) | (Type&0x3F); }
void setType(uint8_t Type) { Byte[0] = (Byte[0]&0xC0) | (Type&0x3F); } // packet-type: 1=air-position

uint8_t ExtHeaderLen(void) const // length ot the extended header (zero in most cases)
{ if(!ExtHeader()) return 0;
Expand All @@ -62,7 +62,8 @@ class FANET_Packet

uint8_t MsgOfs(void) const { return 4+ExtHeaderLen(); } // offset to the actual message (past the header and ext. header)
uint8_t MsgLen(void) const { return Len-4-ExtHeaderLen(); } // length of the actual message
const uint8_t *Msg(void) const { return Byte+MsgOfs(); }
const uint8_t *Msg(void) const { return Byte+MsgOfs(); } // pointer to the message, past the header
uint8_t *Msg(void) { return Byte+MsgOfs(); }

void setName(const char *Name)
{ setHeader(2);
Expand Down Expand Up @@ -192,6 +193,20 @@ class FANET_Packet
uint8_t WriteFNNGB(char *Out)
{ return 0; }

int DecodePosition(float &Lat, float &Lon, int &Alt)
{ uint8_t Idx=MsgOfs();
if(Type()==1)
{ Lat = FloatCoord(getLat(Byte+Idx));
Lon = FloatCoord(getLon(Byte+Idx+3));
Alt = getAltitude(Byte+Idx+6);
return 3; }
if(Type()==7)
{ Lat = FloatCoord(getLat(Byte+Idx));
Lon = FloatCoord(getLon(Byte+Idx+3));
Alt = 0;
return 2; }
return 0; }

void Print(const char *Name=0) const
{ if(Name) printf("%s ", Name);
printf("[%2d:%d:%2d] FNT%06X", Len, Type(), MsgLen(), getAddr());
Expand Down Expand Up @@ -262,7 +277,7 @@ class FANET_Packet
Byte[Len] = (Upp<<4) | Low; Inp+=2; } // new byte, count input
return Len; } // return number of bytes read = packet length

static int32_t CoordUBX(int32_t Coord) { return ((int64_t)900007296*Coord+0x20000000)>>30; } // convert FANET-cordic to UBX 10e-7deg units
static int32_t CoordUBX(int32_t Coord) { return ((int64_t)900007296*Coord+0x20000000)>>30; } // convert FANET-cordic to UBX 1e-7deg units
// ((int64_t)900000000*Coord+0x20000000)>>30; // this is the exact formula, but FANET is not exact here

static int Format_Lat(char *Str, int32_t Lat, char &HighRes) // format latitude after APRS
Expand Down Expand Up @@ -313,19 +328,85 @@ class FANET_RxPacket: public FANET_Packet
int8_t RSSI; // [dBm]
uint8_t BitErr; // number of bit errors
uint8_t CodeErr; // number of block errors
uint8_t Sync; // sync symbols used: 0xF1 for sx127x but 0x12 for sx1262 ?

public:
void setTime(double RxTime) { sTime=floor(RxTime); msTime=floor(1000.0*(RxTime-sTime)); }
double getTime(void) const { return (double)sTime+0.001*msTime; }
uint32_t SlotTime(void) const { uint32_t Slot=sTime; if(msTime<=300) Slot--; return Slot; }
uint32_t SlotTime(void) const { uint32_t Slot=sTime; if(msTime<100) Slot--; return Slot; }

void Print(char *Name=0) const
{ char HHMMSS[8];
Format_HHMMSS(HHMMSS, SlotTime()); HHMMSS[6]='h'; HHMMSS[7]=0;
printf("%s CR%c%c%c %3.1fdB/%de %+3.1fkHz ", HHMMSS, '0'+CR, hasCRC?'c':'_', badCRC?'-':'+', 0.25*SNR, BitErr, 1e-2*FreqOfs);
FANET_Packet::Print(Name); }

int WriteJSON(char *JSON) const
int PrintJSON(char *JSON, uint8_t AddrType=0) const
{ const uint8_t *Msg = this->Msg();
uint8_t MsgLen = this->MsgLen();
uint8_t Type = this->Type();
if(Type!=1 && Type!=7) { JSON[0]=0; return 0; }
int Len=0;
JSON[Len++]='{';
uint32_t Address = getAddr();
if(AddrType==0) AddrType = getAddrType();
Len+=Format_String(JSON+Len, "\"Address\":\"");
Len+=Format_Hex(JSON+Len, Byte[1]);
Len+=Format_Hex(JSON+Len, Byte[3]);
Len+=Format_Hex(JSON+Len, Byte[2]);
Len+=Format_String(JSON+Len, "\", \"AddrType\":");
JSON[Len++] = '0'+AddrType;
Len+=Format_String(JSON+Len, "\", \"ID\":\"");
Len+=Format_Hex(JSON+Len, Address | ((uint32_t)AddrType<<24));
uint32_t Time = SlotTime(); // sTime; if(msTime<100) Time--;
Len+=Format_String(JSON+Len, "\", \"Time\":");
Len+=Format_UnsDec(JSON+Len, Time);
if(Type==1)
{ const uint8_t OGNtype[8] = { 0, 7, 6, 0xB, 1, 8, 3, 0xD } ; // OGN aircraft types
uint8_t AcftType=Msg[7]>>4; // get the aircraft-type and online-track flag
Len+=Format_String(JSON+Len, ", \"AcftType\":");
Len+=Format_UnsDec(JSON+Len, OGNtype[AcftType&0x7]);
uint32_t Alt=getAltitude(Msg+6); // [m] decode the altitude
uint32_t Speed=getSpeed(Msg[8]); // [0.5km/h] ground speed
Speed = (Speed*355+0x80)>>8; // [0.5km/h] => [0.1m/s] convert
int32_t Climb=getClimb(Msg[9]); // [0.1m/s] climb rate
uint16_t Dir=getDir(Msg[10]); // [deg]
Len+=Format_String(JSON+Len, ", \"Alt\":");
Len+=Format_UnsDec(JSON+Len, Alt);
Len+=Format_String(JSON+Len, ", \"Track\":");
Len+=Format_UnsDec(JSON+Len, Dir);
Len+=Format_String(JSON+Len, ", \"Speed\":");
Len+=Format_UnsDec(JSON+Len, Speed, 2, 1);
Len+=Format_String(JSON+Len, ", \"Climb\":");
Len+=Format_SignDec(JSON+Len, Climb, 2, 1, 1);
if(MsgLen>11)
{ int16_t Turn=getTurnRate(Msg[11]);
Len+=Format_String(JSON+Len, ", \"Turn\":");
Len+=Format_SignDec(JSON+Len, Turn*10/4, 2, 1, 1); }
if(MsgLen>12)
{ int32_t AltStd=Alt; Alt+=getQNE(Msg[12]);
Len+=Format_String(JSON+Len, ", \"StdAlt\":");
Len+=Format_SignDec(JSON+Len, AltStd, 1, 0, 1); }
}
if(Type==1 || Type==7)
{ int32_t Lat = getLat(Msg); // [cordic] decode the latitude
int32_t Lon = getLon(Msg+3); // [cordic] decode the longitude
Len+=Format_String(JSON+Len, ", \"Lat\":");
Len+=Format_SignDec(JSON+Len, CoordUBX(Lat), 8, 7, 1);
Len+=Format_String(JSON+Len, ", \"Lon\":");
Len+=Format_SignDec(JSON+Len, CoordUBX(Lon), 8, 7, 1); }
Len+=Format_String(JSON+Len, ", \"RxProt\":\"FNT\"");
if(SNR>0)
{ Len+=Format_String(JSON+Len, ", \"RxSNR\":");
Len+=Format_SignDec(JSON+Len, ((int16_t)SNR*10+2-843)>>2, 2, 1, 1); }
Len+=Format_String(JSON+Len, ", \"RxErr\":");
Len+=Format_UnsDec(JSON+Len, BitErr);
Len+=Format_String(JSON+Len, ", \"RxFreqOfs\":");
Len+=Format_SignDec(JSON+Len, FreqOfs/10, 1, 1);
JSON[Len++]=' '; JSON[Len++]='}';
JSON[Len]=0; return Len; }

int WriteStxJSON(char *JSON, uint8_t AddrType=0) const
{ int Len=0;
Len+=Format_String(JSON+Len, "\"addr\":\"");
Len+=Format_Hex(JSON+Len, Byte[1]);
Expand All @@ -334,11 +415,12 @@ class FANET_RxPacket: public FANET_Packet
JSON[Len++]='\"';
JSON[Len++]=',';
Len+=Format_String(JSON+Len, "\"addr_type\":");
JSON[Len++] = HexDigit(getAddrType());
if(AddrType==0) AddrType = getAddrType();
JSON[Len++] = '0'+AddrType;
const uint8_t *Msg = this->Msg();
uint8_t MsgLen = this->MsgLen();
uint8_t Type = this->Type();
uint32_t Time=sTime; if(msTime<300) Time--;
uint32_t Time = SlotTime(); // sTime; if(msTime<100) Time--;
Len+=Format_String(JSON+Len, ",\"time\":");
Len+=Format_UnsDec(JSON+Len, Time);
int64_t RxTime=(int64_t)sTime-Time; RxTime*=1000; RxTime+=msTime;
Expand Down Expand Up @@ -378,7 +460,29 @@ class FANET_RxPacket: public FANET_Packet
Len+=Format_String(JSON+Len, ",\"lat_deg\":");
Len+=Format_SignDec(JSON+Len, CoordUBX(Lat), 8, 7, 1);
Len+=Format_String(JSON+Len, ",\"lon_deg\":");
Len+=Format_SignDec(JSON+Len, CoordUBX(Lon), 8, 7, 1); }
Len+=Format_SignDec(JSON+Len, CoordUBX(Lon), 8, 7, 1);
int Idx=7;
if(Service&0x40)
{ Len+=Format_String(JSON+Len, ",\"temp_deg\":");
Len+=Format_SignDec(JSON+Len, (int16_t)5*((int8_t)Msg[Idx++]), 2, 1, 1); }
if(Service&0x20)
{ uint16_t Dir = Msg[Idx++]; // [cordic]
Len+=Format_String(JSON+Len, ",\"wind_deg\":");
Len+=Format_UnsDec(JSON+Len, (45*Dir+16)>>5, 2, 1);
uint16_t Wind = getSpeed(Msg[Idx++]); // [0.2km/h]
Len+=Format_String(JSON+Len, ",\"wind_kmh\":");
Len+=Format_UnsDec(JSON+Len, 2*Wind, 2, 1);
uint16_t Gust = getSpeed(Msg[Idx++]);
Len+=Format_String(JSON+Len, ",\"gust_kmh\":");
Len+=Format_UnsDec(JSON+Len, 2*Gust, 2, 1); }
if(Service&0x10)
{ Len+=Format_String(JSON+Len, ",\"hum_perc\":");
Len+=Format_UnsDec(JSON+Len, (uint16_t)4*Msg[Idx++], 2, 1); }
if(Service&0x08)
{ Len+=Format_String(JSON+Len, ",\"press_hpa\":");
Len+=Format_UnsDec(JSON+Len, getPressure(Msg+Idx), 2, 1);
Idx+=2; }
}
if(Type==1 || Type==7) // airborne or ground position
{ int32_t Lat = getLat(Msg); // [cordic] decode the latitude
int32_t Lon = getLon(Msg+3); // [cordic] decode the longitude
Expand Down Expand Up @@ -416,8 +520,9 @@ class FANET_RxPacket: public FANET_Packet
Len+=Format_String(JSON+Len, ",\"on_ground\":1"); }
return Len; }

int WriteAPRS(char *Out)
int WriteAPRS(char *Out, uint8_t AddrType=0)
{ bool Report=0;
if(AddrType==0) AddrType = getAddrType(); // 2 (FLARM) or 3 (OGN)
int Len=0;
bool isPosition = Type()==1 || Type()==4 || Type()==7;
Len+=Format_String(Out+Len, "FNT");
Expand Down Expand Up @@ -469,7 +574,8 @@ class FANET_RxPacket: public FANET_Packet
} else Len+=Format_String(Out+Len, ".../...g...");
Out[Len++]='t';
if(Service&0x40)
{ int16_t Fahr=Temp; Fahr+=4*Temp/5; Fahr+=32;
{ // int16_t Fahr=Temp; Fahr+=4*Temp/5; Fahr/=2; Fahr+=32; //
int16_t Fahr = (((int16_t)Temp*115+64)>>7) + 32; // [0.5degC] => [degF]
if(Fahr>=0) Len+=Format_UnsDec(Out+Len, Fahr, 3);
else Len+=Format_SignDec(Out+Len, Fahr, 2);
} else Len+=Format_String(Out+Len, "...");
Expand All @@ -486,7 +592,6 @@ class FANET_RxPacket: public FANET_Packet
const uint8_t OGNtype[8] = { 0, 7, 6, 0xB, 1, 8, 3, 0xD } ; // OGN aircraft types
uint8_t AcftType=Msg[7]>>4; // aircraft-type and online-tracking flag
const char *Icon = AcftIcon[AcftType&7]; // APRS icon
uint8_t AddrType = getAddrType(); // 2 (FLARM) or 3 (OGN)
uint32_t ID = (OGNtype[AcftType&7]<<2) | AddrType; // acft-type and addr-type
bool Track = AcftType&0x08; // online tracking flag
if(!Track) ID|=0x80; // if no online tracking the set as stealth flag
Expand Down Expand Up @@ -542,7 +647,6 @@ class FANET_RxPacket: public FANET_Packet
const char *Icon = "\\n"; // static object
if(Status>=13) Icon = "\\!"; // Emergency
// const char *StatMsg = StatusMsg[Status];
uint8_t AddrType = getAddrType(); //
uint8_t AcftType = 15; //
uint32_t ID = (AcftType<<2) | AddrType; // acft-type and addr-type
if(!Track) ID|=0x80; // stealth flag
Expand All @@ -565,9 +669,11 @@ class FANET_RxPacket: public FANET_Packet
Len+=Format_String(Out+Len, " FNT7"); Out[Len++]=HexDigit(Status);
Report=1; break; }
}
Out[Len++]=' '; Out[Len++]='s';
Len+=Format_Hex(Out+Len, Sync);
if(SNR>0)
{ Out[Len++]=' ';
Len+=Format_UnsDec(Out+Len, ((uint16_t)SNR*10+2)/4, 2, 1);
Len+=Format_SignDec(Out+Len, ((int16_t)SNR*10+2-843)>>2, 2, 1, 1);
Out[Len++]='d'; Out[Len++]='B'; }
Out[Len++]=' ';
Len+=Format_SignDec(Out+Len, FreqOfs/10, 2, 1);
Expand All @@ -581,6 +687,8 @@ class FANET_RxPacket: public FANET_Packet

// =========================================================================================

#ifndef ARDUINO

class FANET_Name
{ public:
static const int MaxSize = 32;
Expand All @@ -598,6 +706,8 @@ class FANET_Name

} ;

#include <map>

class FANET_NameList
{ public:
std::map<uint32_t, FANET_Name> List;
Expand All @@ -612,6 +722,7 @@ class FANET_NameList
return 1; }

} ;
#endif

// ===============================================================================================

Expand Down
52 changes: 48 additions & 4 deletions utils/format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,20 @@ uint8_t Format_String(char *Out, const char *String, uint8_t MinLen, uint8_t Max
void Format_Hex( void (*Output)(char), uint8_t Byte )
{ (*Output)(HexDigit(Byte>>4)); (*Output)(HexDigit(Byte&0x0F)); }

void Format_HexBytes( void (*Output)(char), const uint8_t *Byte, uint8_t Bytes)
{ for(uint8_t Idx=0; Idx<Bytes; Idx++) Format_Hex(Output, Byte[Idx]); }

void Format_Hex( void (*Output)(char), uint16_t Word )
{ Format_Hex(Output, (uint8_t)(Word>>8)); Format_Hex(Output, (uint8_t)Word); }

void Format_Hex( void (*Output)(char), uint32_t Word )
{ Format_Hex(Output, (uint8_t)(Word>>24)); Format_Hex(Output, (uint8_t)(Word>>16));
Format_Hex(Output, (uint8_t)(Word>>8)); Format_Hex(Output, (uint8_t)Word); }

void Format_Hex( void (*Output)(char), uint64_t Word )
{ Format_Hex(Output, (uint32_t)(Word>>32));
Format_Hex(Output, (uint32_t)(Word )); }

void Format_MAC( void (*Output)(char), uint8_t *MAC, uint8_t Len)
{ for(uint8_t Idx=0; Idx<Len; Idx++)
{ if(Idx) (*Output)(':');
Expand Down Expand Up @@ -105,6 +112,24 @@ void Format_HHMMSS(void (*Output)(char), uint32_t Time)
uint32_t HHMMSS = 10000*Hour + 100*Min + Sec;
Format_UnsDec(Output, HHMMSS, 6); }

void Format_Period(void (*Output)(char), int32_t Time)
{ if(Time<0) { (*Output)('-'); Time=(-Time); }
else { (*Output)(' '); }
if(Time<60) { (*Output)(' '); Format_UnsDec(Output, (uint32_t)Time, 2); (*Output)('s'); return; }
if(Time<3600) { Format_UnsDec(Output, (uint32_t)Time/60, 2); (*Output)('m'); Format_UnsDec(Output, (uint32_t)Time%60, 2); return; }
if(Time<86400) { Format_UnsDec(Output, (uint32_t)Time/3600, 2); (*Output)('h'); Format_UnsDec(Output, ((uint32_t)Time%3600)/60, 2); return; }
Format_UnsDec(Output, (uint32_t)Time/86400, 2); (*Output)('d'); Format_UnsDec(Output, ((uint32_t)Time%86400)/3600, 2); }

uint8_t Format_Period(char *Out, int32_t Time)
{ uint8_t Len=0;
if(Time<0) { Out[Len++]='-'; Time=(-Time); }
else { Out[Len++]=' '; }
if(Time<60) { Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (uint32_t)Time, 2); Out[Len++]='s'; return Len; }
if(Time<3600) { Len+=Format_UnsDec(Out+Len, (uint32_t)Time/60, 2); Out[Len++]='m'; Len+=Format_UnsDec(Out+Len, (uint32_t)Time%60, 2); return Len; }
if(Time<86400) { Len+=Format_UnsDec(Out+Len, (uint32_t)Time/3600, 2); Out[Len++]='h'; Len+=Format_UnsDec(Out+Len, ((uint32_t)Time%3600)/60, 2); return Len; }
Len+=Format_UnsDec(Out+Len, (uint32_t)Time/86400, 2); Out[Len++]='d'; Len+=Format_UnsDec(Out+Len, ((uint32_t)Time%86400)/3600, 2);
return Len; }

void Format_UnsDec( void (*Output)(char), uint16_t Value, uint8_t MinDigits, uint8_t DecPoint)
{ uint16_t Base; uint8_t Pos;
for( Pos=5, Base=10000; Base; Base/=10, Pos--)
Expand Down Expand Up @@ -188,12 +213,26 @@ uint8_t Format_SignDec(char *Out, int32_t Value, uint8_t MinDigits, uint8_t DecP
uint8_t Format_Hex( char *Output, uint8_t Byte )
{ (*Output++) = HexDigit(Byte>>4); (*Output++)=HexDigit(Byte&0x0F); return 2; }

uint8_t Format_HexBytes(char *Output, const uint8_t *Byte, uint8_t Bytes)
{ uint8_t Len=0;
for(uint8_t Idx=0; Idx<Bytes; Idx++)
Len+=Format_Hex(Output+Len, Byte[Idx]);
return Len; }

uint8_t Format_Hex( char *Output, uint16_t Word )
{ Format_Hex(Output, (uint8_t)(Word>>8)); Format_Hex(Output+2, (uint8_t)Word); return 4; }
{ Format_Hex(Output, (uint8_t)(Word>>8));
Format_Hex(Output+2, (uint8_t)Word);
return 4; }

uint8_t Format_Hex( char *Output, uint32_t Word )
{ Format_Hex(Output , (uint8_t)(Word>>24)); Format_Hex(Output+2, (uint8_t)(Word>>16));
Format_Hex(Output+4, (uint8_t)(Word>> 8)); Format_Hex(Output+6, (uint8_t) Word ); return 8; }
{ Format_Hex(Output , (uint16_t)(Word>>16));
Format_Hex(Output+4, (uint16_t)(Word ));
return 8; }

uint8_t Format_Hex( char *Output, uint64_t Word )
{ Format_Hex(Output , (uint32_t)(Word>>32));
Format_Hex(Output+8, (uint32_t)(Word ));
return 16; }

uint8_t Format_Hex( char *Output, uint32_t Word, uint8_t Digits)
{ for(uint8_t Idx=Digits; Idx>0; )
Expand Down Expand Up @@ -249,11 +288,16 @@ int16_t Read_Dec3(const char *Inp) // convert three digit decimal nu
int8_t Low=Read_Dec1(Inp[2]); if(Low<0) return -1;
return (int16_t)Low + (int16_t)10*(int16_t)Mid + (int16_t)100*(int16_t)High; }

int16_t Read_Dec4(const char *Inp) // convert three digit decimal number into an integer
int16_t Read_Dec4(const char *Inp) // convert four digit decimal number into an integer
{ int16_t High=Read_Dec2(Inp ); if(High<0) return -1;
int16_t Low =Read_Dec2(Inp+2); if(Low<0) return -1;
return Low + (int16_t)100*(int16_t)High; }

int32_t Read_Dec5(const char *Inp) // convert four digit decimal number into an integer
{ int16_t High=Read_Dec2(Inp ); if(High<0) return -1;
int16_t Low =Read_Dec3(Inp+2); if(Low<0) return -1;
return (int32_t)Low + (int32_t)1000*(int32_t)High; }

// ------------------------------------------------------------------------------------------

int8_t Read_Coord(int32_t &Lat, const char *Inp)
Expand Down
Loading

0 comments on commit b99cf5b

Please sign in to comment.