kopia lustrzana https://github.com/sp9skp/spdxl
1295 wiersze
36 KiB
C
1295 wiersze
36 KiB
C
/*
|
|
* dxlAPRS toolchain
|
|
*
|
|
* Copyright (C) Christian Rabler <oe5dxl@oevsv.at>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
|
|
#define X2C_int32
|
|
#define X2C_index32
|
|
#ifndef sondeaprs_H_
|
|
#include "sondeaprs.h"
|
|
#endif
|
|
#define sondeaprs_C_
|
|
#ifndef aprsstr_H_
|
|
#include "aprsstr.h"
|
|
#endif
|
|
#ifndef osi_H_
|
|
#include "osi.h"
|
|
#endif
|
|
#include <osic.h>
|
|
#ifndef udp_H_
|
|
#include "udp.h"
|
|
#endif
|
|
|
|
char sondeaprs_via[100];
|
|
char sondeaprs_destcall[100];
|
|
char sondeaprs_objname[100];
|
|
char sondeaprs_commentfn[1025];
|
|
char sondeaprs_sym[2];
|
|
uint32_t sondeaprs_beacontime;
|
|
uint32_t sondeaprs_lowaltbeacontime;
|
|
uint32_t sondeaprs_lowalt;
|
|
uint32_t sondeaprs_toport;
|
|
uint32_t sondeaprs_ipnum;
|
|
char sondeaprs_verb;
|
|
char sondeaprs_verb2;
|
|
char sondeaprs_nofilter;
|
|
int32_t sondeaprs_comptyp;
|
|
int32_t sondeaprs_micessid;
|
|
int32_t sondeaprs_udpsock;
|
|
char sondeaprs_anyip;
|
|
char sondeaprs_sendmon;
|
|
char sondeaprs_dao;
|
|
/* encode demodulated sonde to aprs axudp by OE5DXL */
|
|
/*FROM TimeConv IMPORT time; */
|
|
/*FROM RealMath IMPORT ln; */
|
|
/*FROM Storage IMPORT ALLOCATE; */
|
|
#define sondeaprs_CR "\015"
|
|
|
|
#define sondeaprs_LF "\012"
|
|
|
|
#define sondeaprs_KNOTS 1.851984
|
|
|
|
#define sondeaprs_FEET 3.2808398950131
|
|
|
|
#define sondeaprs_LINESBUF 60
|
|
/* seconds pos history */
|
|
|
|
#define sondeaprs_PI 3.1415926535898
|
|
|
|
#define sondeaprs_DAYSEC 86400
|
|
|
|
#define sondeaprs_RAD 1.7453292519943E-2
|
|
|
|
#define sondeaprs_MAXHRMS 50.0
|
|
/* not send if gps h pos spreads more meters */
|
|
|
|
#define sondeaprs_MAXVRMS 500.0
|
|
/* not send if gps v pos spreads more meters */
|
|
|
|
#define sondeaprs_MAXAGE 86400
|
|
/* context lifetime */
|
|
|
|
enum ERRS {sondeaprs_ePRES, sondeaprs_eTEMP, sondeaprs_eHYG,
|
|
sondeaprs_eSPEED, sondeaprs_eDIR, sondeaprs_eLAT,
|
|
sondeaprs_eLONG, sondeaprs_eALT, sondeaprs_eMISS,
|
|
sondeaprs_eRMS};
|
|
|
|
|
|
struct DATLINE;
|
|
|
|
|
|
struct DATLINE {
|
|
double hpa;
|
|
double temp;
|
|
double hyg;
|
|
double alt;
|
|
double speed;
|
|
double dir;
|
|
double lat;
|
|
double long0;
|
|
/*- climb, */
|
|
double clb;
|
|
uint32_t time0;
|
|
uint32_t uptime;
|
|
};
|
|
|
|
struct POSITION;
|
|
|
|
|
|
struct POSITION {
|
|
double long0;
|
|
double lat;
|
|
};
|
|
|
|
typedef struct DATLINE DATS[60];
|
|
|
|
struct CONTEXT;
|
|
|
|
typedef struct CONTEXT * pCONTEXT;
|
|
|
|
|
|
struct CONTEXT {
|
|
pCONTEXT next;
|
|
char name[12];
|
|
DATS dat;
|
|
double speedsum;
|
|
uint32_t speedcnt;
|
|
uint32_t lastused;
|
|
uint32_t lastbeacon;
|
|
uint32_t commentline;
|
|
};
|
|
|
|
/*CRCL, CRCH: ARRAY[0..255] OF SET8;*/
|
|
static pCONTEXT contexts;
|
|
/* dat :ARRAY[0..LINESBUF-1] OF DATLINE; */
|
|
|
|
/* speedsum:LONGREAL; */
|
|
/* speedcnt:CARDINAL; */
|
|
static uint16_t chk;
|
|
|
|
/* systime, lastbeacon:TIME; */
|
|
/* commentline:CARDINAL; */
|
|
|
|
static uint32_t truncc(double r)
|
|
{
|
|
if (r<=0.0) return 0UL;
|
|
else if (r>=2.E+9) return 2000000000UL;
|
|
else return (uint32_t)X2C_TRUNCC(r,0UL,X2C_max_longcard);
|
|
return 0;
|
|
} /* end truncc() */
|
|
|
|
|
|
extern int32_t sondeaprs_GetIp(char h[], uint32_t h_len,
|
|
uint32_t * p, uint32_t * ip, uint32_t * port)
|
|
{
|
|
uint32_t n;
|
|
uint32_t i;
|
|
char ok0;
|
|
int32_t sondeaprs_GetIp_ret;
|
|
X2C_PCOPY((void **)&h,h_len);
|
|
*p = 0UL;
|
|
h[h_len-1] = 0;
|
|
*ip = 0UL;
|
|
for (i = 0UL; i<=4UL; i++) {
|
|
n = 0UL;
|
|
ok0 = 0;
|
|
while ((uint8_t)h[*p]>='0' && (uint8_t)h[*p]<='9') {
|
|
ok0 = 1;
|
|
n = (n*10UL+(uint32_t)(uint8_t)h[*p])-48UL;
|
|
++*p;
|
|
}
|
|
if (!ok0) {
|
|
sondeaprs_GetIp_ret = -1L;
|
|
goto label;
|
|
}
|
|
if (i<3UL) {
|
|
if (h[*p]!='.' || n>255UL) {
|
|
sondeaprs_GetIp_ret = -1L;
|
|
goto label;
|
|
}
|
|
*ip = *ip*256UL+n;
|
|
}
|
|
else if (i==3UL) {
|
|
*ip = *ip*256UL+n;
|
|
if (h[*p]!=':' || n>255UL) {
|
|
sondeaprs_GetIp_ret = -1L;
|
|
goto label;
|
|
}
|
|
}
|
|
else if (n>65535UL) {
|
|
sondeaprs_GetIp_ret = -1L;
|
|
goto label;
|
|
}
|
|
*port = n;
|
|
++*p;
|
|
} /* end for */
|
|
sondeaprs_GetIp_ret = 0L;
|
|
label:;
|
|
X2C_PFREE(h);
|
|
return sondeaprs_GetIp_ret;
|
|
} /* end GetIp() */
|
|
|
|
|
|
static void comment0(char buf[], uint32_t buf_len, uint32_t uptime,
|
|
uint32_t sats, double hrms, uint32_t * linec)
|
|
{
|
|
int32_t len;
|
|
int32_t lc;
|
|
int32_t eol;
|
|
int32_t bol;
|
|
int32_t i;
|
|
int32_t f;
|
|
char fb[32768];
|
|
char h[100];
|
|
buf[0UL] = 0;
|
|
len = 0L;
|
|
if (sondeaprs_commentfn[0UL]) {
|
|
f = osi_OpenRead(sondeaprs_commentfn, 1025ul);
|
|
if (f>=0L) {
|
|
len = osi_RdBin(f, (char *)fb, 32768u/1u, 32767UL);
|
|
osic_Close(f);
|
|
while (len>0L && (uint8_t)fb[len-1L]<=' ') --len;
|
|
if (len>0L && len<32767L) {
|
|
fb[len] = '\012';
|
|
++len;
|
|
}
|
|
do {
|
|
lc = (int32_t)*linec;
|
|
eol = 0L;
|
|
for (;;) {
|
|
bol = eol;
|
|
while (eol<len && fb[eol]!='\012') ++eol;
|
|
if (eol>=len) {
|
|
bol = eol;
|
|
if (*linec) {
|
|
lc = 1L;
|
|
*linec = 0UL;
|
|
}
|
|
break;
|
|
}
|
|
if (fb[bol]!='#') {
|
|
if (lc==0L) {
|
|
++*linec;
|
|
break;
|
|
}
|
|
--lc;
|
|
}
|
|
++eol;
|
|
}
|
|
} while (lc);
|
|
if (eol+2L>=bol && fb[bol]=='%') {
|
|
if (fb[bol+1L]=='u') {
|
|
/* insert uptime */
|
|
if (uptime>0UL) {
|
|
strncpy(fb," powerup h:m:s ",32768u);
|
|
aprsstr_TimeToStr(uptime, h, 100ul);
|
|
aprsstr_Append(fb, 32768ul, h, 100ul);
|
|
}
|
|
else fb[0] = 0;
|
|
}
|
|
else if (fb[bol+1L]=='v') {
|
|
/* insert version */
|
|
strncpy(fb," sondemod(c) 2.0",32768u);
|
|
}
|
|
else if (fb[bol+1L]=='s') {
|
|
/* insert sat count */
|
|
if (sats>0UL) {
|
|
strncpy(fb," Sats ",32768u);
|
|
aprsstr_IntToStr((int32_t)sats, 1UL, h, 100ul);
|
|
aprsstr_Append(fb, 32768ul, h, 100ul);
|
|
}
|
|
else fb[0] = 0;
|
|
}
|
|
else if (fb[bol+1L]=='r') {
|
|
/* hrms +3m from tropomodel */
|
|
if (sats>4UL) {
|
|
strncpy(fb," hdil=",32768u);
|
|
aprsstr_FixToStr((float)(hrms+3.0), 2UL, h, 100ul);
|
|
aprsstr_Append(fb, 32768ul, h, 100ul);
|
|
aprsstr_Append(fb, 32768ul, "m", 2ul);
|
|
}
|
|
else fb[0] = 0;
|
|
}
|
|
else fb[0] = 0;
|
|
bol = 0L;
|
|
eol = (int32_t)aprsstr_Length(fb, 32768ul);
|
|
}
|
|
i = 0L;
|
|
while (bol<eol && i<(int32_t)(buf_len-1)) {
|
|
buf[i] = fb[bol];
|
|
++i;
|
|
++bol;
|
|
}
|
|
buf[i] = 0;
|
|
}
|
|
else if (sondeaprs_verb) osi_WrStrLn("beacon file not found", 22ul);
|
|
}
|
|
} /* end comment() */
|
|
|
|
|
|
static void sendudp(char buf[], uint32_t buf_len, int32_t len)
|
|
{
|
|
int32_t i;
|
|
/* crc:CARDINAL; */
|
|
X2C_PCOPY((void **)&buf,buf_len);
|
|
/*
|
|
IF withcrc THEN
|
|
crc:=UDPCRC(buf, len);
|
|
buf[len]:=CHR(crc MOD 256);
|
|
buf[len+1]:=CHR(crc DIV 256);
|
|
INC(len, 2);
|
|
END;
|
|
AppCRC(buf, len);
|
|
*/
|
|
i = udpsend(sondeaprs_udpsock, buf, len, sondeaprs_toport,
|
|
sondeaprs_ipnum);
|
|
X2C_PFREE(buf);
|
|
/*
|
|
FOR i:=0 TO upos-2 DO IO.WrHex(ORD(buf[i]), 3) END; IO.WrLn;
|
|
*/
|
|
} /* end sendudp() */
|
|
|
|
|
|
static char num(uint32_t n)
|
|
{
|
|
return (char)(n%10UL+48UL);
|
|
} /* end num() */
|
|
|
|
|
|
static uint32_t dao91(double x)
|
|
/* radix91(xx/1.1) of dddmm.mmxx */
|
|
{
|
|
double a;
|
|
a = fabs(x);
|
|
return ((truncc((a-(double)(float)truncc(a))*6.E+5)%100UL)
|
|
*20UL+11UL)/22UL;
|
|
} /* end dao91() */
|
|
|
|
|
|
static void sendaprs(uint32_t comp0, uint32_t micessid, char dao,
|
|
uint32_t time0, uint32_t uptime, char mycall[],
|
|
uint32_t mycall_len, char destcall[],
|
|
uint32_t destcall_len, char via[], uint32_t via_len,
|
|
char sym[], uint32_t sym_len, char obj[],
|
|
uint32_t obj_len, double lat, double long0,
|
|
double alt, double course, double speed,
|
|
uint32_t goodsats, double hrms, char comm[],
|
|
uint32_t comm_len, uint32_t * commentcnt)
|
|
{
|
|
char ds[201];
|
|
char h[201];
|
|
char b[201];
|
|
char raw[361];
|
|
int32_t rp;
|
|
uint32_t micdest;
|
|
uint32_t nl;
|
|
uint32_t n;
|
|
uint32_t i;
|
|
double a;
|
|
char tmp;
|
|
X2C_PCOPY((void **)&mycall,mycall_len);
|
|
X2C_PCOPY((void **)&destcall,destcall_len);
|
|
X2C_PCOPY((void **)&via,via_len);
|
|
X2C_PCOPY((void **)&sym,sym_len);
|
|
X2C_PCOPY((void **)&obj,obj_len);
|
|
X2C_PCOPY((void **)&comm,comm_len);
|
|
b[0] = 0;
|
|
aprsstr_Append(b, 201ul, mycall, mycall_len);
|
|
micdest = aprsstr_Length(b, 201ul)+1UL;
|
|
aprsstr_Append(b, 201ul, ">", 2ul);
|
|
aprsstr_Append(b, 201ul, destcall, destcall_len);
|
|
if (micessid>0UL) {
|
|
aprsstr_Append(b, 201ul, "-", 2ul);
|
|
aprsstr_Append(b, 201ul, (char *)(tmp = (char)(micessid+48UL),
|
|
&tmp), 1u/1u);
|
|
}
|
|
if (via[0UL]) {
|
|
aprsstr_Append(b, 201ul, ",", 2ul);
|
|
aprsstr_Append(b, 201ul, via, via_len);
|
|
}
|
|
if (comp0==0UL) {
|
|
/* uncompressed */
|
|
aprsstr_Append(b, 201ul, ":;", 3ul);
|
|
aprsstr_Assign(h, 201ul, obj, obj_len);
|
|
aprsstr_Append(h, 201ul, " ", 10ul);
|
|
h[9U] = 0;
|
|
aprsstr_Append(b, 201ul, h, 201ul);
|
|
aprsstr_Append(b, 201ul, "*", 2ul);
|
|
aprsstr_DateToStr(time0, ds, 201ul);
|
|
ds[0U] = ds[11U];
|
|
ds[1U] = ds[12U];
|
|
ds[2U] = ds[14U];
|
|
ds[3U] = ds[15U];
|
|
ds[4U] = ds[17U];
|
|
ds[5U] = ds[18U];
|
|
ds[6U] = 0;
|
|
aprsstr_Append(b, 201ul, ds, 201ul);
|
|
aprsstr_Append(b, 201ul, "h", 2ul);
|
|
i = aprsstr_Length(b, 201ul);
|
|
a = fabs(lat);
|
|
n = osi_realcard((float)a);
|
|
b[i] = num(n/10UL);
|
|
++i;
|
|
b[i] = num(n);
|
|
++i;
|
|
n = osi_realcard((float)((a-(double)(float)n)*6000.0));
|
|
b[i] = num(n/1000UL);
|
|
++i;
|
|
b[i] = num(n/100UL);
|
|
++i;
|
|
b[i] = '.';
|
|
++i;
|
|
b[i] = num(n/10UL);
|
|
++i;
|
|
b[i] = num(n);
|
|
++i;
|
|
if (lat>=0.0) b[i] = 'N';
|
|
else b[i] = 'S';
|
|
++i;
|
|
b[i] = sym[0UL];
|
|
++i;
|
|
a = fabs(long0);
|
|
n = osi_realcard((float)a);
|
|
b[i] = num(n/100UL);
|
|
++i;
|
|
b[i] = num(n/10UL);
|
|
++i;
|
|
b[i] = num(n);
|
|
++i;
|
|
n = osi_realcard((float)((a-(double)(float)n)*6000.0));
|
|
b[i] = num(n/1000UL);
|
|
++i;
|
|
b[i] = num(n/100UL);
|
|
++i;
|
|
b[i] = '.';
|
|
++i;
|
|
b[i] = num(n/10UL);
|
|
++i;
|
|
b[i] = num(n);
|
|
++i;
|
|
if (long0>=0.0) b[i] = 'E';
|
|
else b[i] = 'W';
|
|
++i;
|
|
b[i] = sym[1UL];
|
|
++i;
|
|
if (speed>0.5) {
|
|
n = osi_realcard((float)(course+1.5));
|
|
b[i] = num(n/100UL);
|
|
++i;
|
|
b[i] = num(n/10UL);
|
|
++i;
|
|
b[i] = num(n);
|
|
++i;
|
|
b[i] = '/';
|
|
++i;
|
|
n = osi_realcard((float)(speed*5.3996146834962E-1+0.5));
|
|
b[i] = num(n/100UL);
|
|
++i;
|
|
b[i] = num(n/10UL);
|
|
++i;
|
|
b[i] = num(n);
|
|
++i;
|
|
}
|
|
if (alt>0.5) {
|
|
b[i] = '/';
|
|
++i;
|
|
b[i] = 'A';
|
|
++i;
|
|
b[i] = '=';
|
|
++i;
|
|
n = osi_realcard((float)fabs(alt*3.2808398950131+0.5));
|
|
if (alt>=0.0) b[i] = num(n/100000UL);
|
|
else b[i] = '-';
|
|
++i;
|
|
b[i] = num(n/10000UL);
|
|
++i;
|
|
b[i] = num(n/1000UL);
|
|
++i;
|
|
b[i] = num(n/100UL);
|
|
++i;
|
|
b[i] = num(n/10UL);
|
|
++i;
|
|
b[i] = num(n);
|
|
++i;
|
|
}
|
|
}
|
|
else if (comp0==1UL) {
|
|
/* compressed */
|
|
aprsstr_Append(b, 201ul, ":!", 3ul);
|
|
i = aprsstr_Length(b, 201ul);
|
|
b[i] = sym[0UL];
|
|
++i;
|
|
if (lat<90.0) n = osi_realcard((float)((90.0-lat)*3.80926E+5));
|
|
else n = 0UL;
|
|
b[i] = (char)(33UL+n/753571UL);
|
|
++i;
|
|
b[i] = (char)(33UL+(n/8281UL)%91UL);
|
|
++i;
|
|
b[i] = (char)(33UL+(n/91UL)%91UL);
|
|
++i;
|
|
b[i] = (char)(33UL+n%91UL);
|
|
++i;
|
|
if (long0>(-180.0)) {
|
|
n = osi_realcard((float)((180.0+long0)*1.90463E+5));
|
|
}
|
|
else n = 0UL;
|
|
b[i] = (char)(33UL+n/753571UL);
|
|
++i;
|
|
b[i] = (char)(33UL+(n/8281UL)%91UL);
|
|
++i;
|
|
b[i] = (char)(33UL+(n/91UL)%91UL);
|
|
++i;
|
|
b[i] = (char)(33UL+n%91UL);
|
|
++i;
|
|
b[i] = sym[1UL];
|
|
++i;
|
|
if (speed>0.5) {
|
|
b[i] = (char)(33UL+osi_realcard((float)course)/4UL);
|
|
++i;
|
|
b[i] = (char)(33UL+osi_realcard(osic_ln((float)
|
|
(speed*5.3996146834962E-1+1.0))*1.29935872129E+1f));
|
|
++i;
|
|
b[i] = '_';
|
|
++i;
|
|
}
|
|
else if (alt>0.5) {
|
|
if (alt*3.2808398950131>1.0) {
|
|
n = osi_realcard(osic_ln((float)(alt*3.2808398950131))*500.5f)
|
|
;
|
|
}
|
|
else n = 0UL;
|
|
if (n>=8281UL) n = 8280UL;
|
|
b[i] = (char)(33UL+n/91UL);
|
|
++i;
|
|
b[i] = (char)(33UL+n%91UL);
|
|
++i;
|
|
b[i] = 'W';
|
|
++i;
|
|
}
|
|
else {
|
|
b[i] = ' ';
|
|
++i;
|
|
b[i] = ' ';
|
|
++i;
|
|
b[i] = '_';
|
|
++i;
|
|
}
|
|
if (speed>0.5) {
|
|
b[i] = '/';
|
|
++i;
|
|
b[i] = 'A';
|
|
++i;
|
|
b[i] = '=';
|
|
++i;
|
|
n = osi_realcard((float)(alt*3.2808398950131+0.5));
|
|
if (alt>=0.0) b[i] = num(n/10000UL);
|
|
else b[i] = '-';
|
|
++i;
|
|
b[i] = num(n/10000UL);
|
|
++i;
|
|
b[i] = num(n/1000UL);
|
|
++i;
|
|
b[i] = num(n/100UL);
|
|
++i;
|
|
b[i] = num(n/10UL);
|
|
++i;
|
|
b[i] = num(n);
|
|
++i;
|
|
}
|
|
}
|
|
else if (comp0==2UL) {
|
|
/* mic-e */
|
|
aprsstr_Append(b, 201ul, ":`", 3ul);
|
|
i = micdest;
|
|
nl = osi_realcard((float)fabs(long0));
|
|
n = osi_realcard((float)fabs(lat));
|
|
b[i] = (char)(80UL+n/10UL);
|
|
++i;
|
|
b[i] = (char)(80UL+n%10UL);
|
|
++i;
|
|
n = osi_realcard((float)((fabs(lat)-(double)(float)n)
|
|
*6000.0));
|
|
b[i] = (char)(80UL+n/1000UL);
|
|
++i;
|
|
b[i] = (char)(48UL+32UL*(uint32_t)(lat>=0.0)+(n/100UL)%10UL);
|
|
++i;
|
|
b[i] = (char)(48UL+32UL*(uint32_t)(nl<10UL || nl>=100UL)+(n/10UL)
|
|
%10UL);
|
|
++i;
|
|
b[i] = (char)(48UL+32UL*(uint32_t)(long0<0.0)+n%10UL);
|
|
i = aprsstr_Length(b, 201ul);
|
|
if (nl<10UL) b[i] = (char)(nl+118UL);
|
|
else if (nl>=100UL) {
|
|
if (nl<110UL) b[i] = (char)(nl+8UL);
|
|
else b[i] = (char)(nl-72UL);
|
|
}
|
|
else b[i] = (char)(nl+28UL);
|
|
++i;
|
|
nl = osi_realcard((float)((fabs(long0)-(double)(float)nl)
|
|
*6000.0)); /* long min*100 */
|
|
n = nl/100UL;
|
|
if (n<10UL) n += 60UL;
|
|
b[i] = (char)(n+28UL);
|
|
++i;
|
|
b[i] = (char)(nl%100UL+28UL);
|
|
++i;
|
|
n = osi_realcard((float)(speed*5.3996146834962E-1+0.5));
|
|
b[i] = (char)(n/10UL+28UL);
|
|
++i;
|
|
nl = osi_realcard((float)course);
|
|
b[i] = (char)(32UL+(n%10UL)*10UL+nl/100UL);
|
|
++i;
|
|
b[i] = (char)(28UL+nl%100UL);
|
|
++i;
|
|
b[i] = sym[1UL];
|
|
++i;
|
|
b[i] = sym[0UL];
|
|
++i;
|
|
if (alt>0.5) {
|
|
if (alt>(-1.E+4)) n = osi_realcard((float)(alt+10000.5));
|
|
else n = 0UL;
|
|
b[i] = (char)(33UL+(n/8281UL)%91UL);
|
|
++i;
|
|
b[i] = (char)(33UL+(n/91UL)%91UL);
|
|
++i;
|
|
b[i] = (char)(33UL+n%91UL);
|
|
++i;
|
|
b[i] = '}';
|
|
++i;
|
|
}
|
|
}
|
|
if (dao) {
|
|
b[i] = '!';
|
|
++i;
|
|
b[i] = 'w';
|
|
++i;
|
|
b[i] = (char)(33UL+dao91(lat));
|
|
++i;
|
|
b[i] = (char)(33UL+dao91(long0));
|
|
++i;
|
|
b[i] = '!';
|
|
++i;
|
|
}
|
|
b[i] = 0;
|
|
aprsstr_Append(b, 201ul, comm, comm_len);
|
|
comment0(h, 201ul, uptime, goodsats, hrms, commentcnt);
|
|
aprsstr_Append(b, 201ul, h, 201ul);
|
|
/* Append(b, CR+LF); */
|
|
if (aprsstr_Length(mycall, mycall_len)>=3UL) {
|
|
if (!sondeaprs_sendmon) {
|
|
aprsstr_mon2raw(b, 201ul, raw, 361ul, &rp);
|
|
if (rp>0L) sendudp(raw, 361ul, rp);
|
|
}
|
|
else sendudp(b, 201ul, (int32_t)(aprsstr_Length(b, 201ul)+1UL));
|
|
}
|
|
if (sondeaprs_verb) osi_WrStrLn(b, 201ul);
|
|
X2C_PFREE(mycall);
|
|
X2C_PFREE(destcall);
|
|
X2C_PFREE(via);
|
|
X2C_PFREE(sym);
|
|
X2C_PFREE(obj);
|
|
X2C_PFREE(comm);
|
|
} /* end sendaprs() */
|
|
|
|
#define sondeaprs_Z 48
|
|
|
|
|
|
static void degtostr(double d, char lat, char form,
|
|
char s[], uint32_t s_len)
|
|
{
|
|
uint32_t i;
|
|
uint32_t n;
|
|
if (s_len-1<11UL) {
|
|
s[0UL] = 0;
|
|
return;
|
|
}
|
|
if (form=='2') i = 7UL;
|
|
else if (form=='3') i = 8UL;
|
|
else i = 9UL;
|
|
if (d<0.0) {
|
|
d = -d;
|
|
if (lat) s[i] = 'S';
|
|
else s[i+1UL] = 'W';
|
|
}
|
|
else if (lat) s[i] = 'N';
|
|
else s[i+1UL] = 'E';
|
|
if (form=='2') {
|
|
/* DDMM.MMNDDMM.MME */
|
|
n = osi_realcard((float)(d*3.4377467707849E+5+0.5));
|
|
s[0UL] = (char)((n/600000UL)%10UL+48UL);
|
|
i = (uint32_t)!lat;
|
|
s[i] = (char)((n/60000UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/6000UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/1000UL)%6UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/100UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = '.';
|
|
++i;
|
|
s[i] = (char)((n/10UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = (char)(n%10UL+48UL);
|
|
++i;
|
|
}
|
|
else if (form=='3') {
|
|
/* DDMM.MMMNDDMM.MMME */
|
|
n = osi_realcard((float)(d*3.4377467707849E+6+0.5));
|
|
s[0UL] = (char)((n/6000000UL)%10UL+48UL);
|
|
i = (uint32_t)!lat;
|
|
s[i] = (char)((n/600000UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/60000UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/10000UL)%6UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/1000UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = '.';
|
|
++i;
|
|
s[i] = (char)((n/100UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/10UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = (char)(n%10UL+48UL);
|
|
++i;
|
|
}
|
|
else {
|
|
/* DDMMSS */
|
|
n = osi_realcard((float)(d*2.062648062471E+5+0.5));
|
|
s[0UL] = (char)((n/360000UL)%10UL+48UL);
|
|
i = (uint32_t)!lat;
|
|
s[i] = (char)((n/36000UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/3600UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = 'o';
|
|
++i;
|
|
s[i] = (char)((n/600UL)%6UL+48UL);
|
|
++i;
|
|
s[i] = (char)((n/60UL)%10UL+48UL);
|
|
++i;
|
|
s[i] = '\'';
|
|
++i;
|
|
s[i] = (char)((n/10UL)%6UL+48UL);
|
|
++i;
|
|
s[i] = (char)(n%10UL+48UL);
|
|
++i;
|
|
s[i] = '\"';
|
|
++i;
|
|
}
|
|
++i;
|
|
s[i] = 0;
|
|
} /* end degtostr() */
|
|
|
|
|
|
static void postostr(struct POSITION pos, char form, char s[],
|
|
uint32_t s_len)
|
|
{
|
|
char h[32];
|
|
degtostr(pos.lat, 1, form, s, s_len);
|
|
aprsstr_Append(s, s_len, "/", 2ul);
|
|
degtostr(pos.long0, 0, form, h, 32ul);
|
|
aprsstr_Append(s, s_len, h, 32ul);
|
|
} /* end postostr() */
|
|
|
|
#define sondeaprs_RAD0 1.7453292519943E-2
|
|
|
|
|
|
static void WrDeg(double la, double lo)
|
|
{
|
|
char s[31];
|
|
struct POSITION pos;
|
|
pos.lat = la*1.7453292519943E-2;
|
|
pos.long0 = lo*1.7453292519943E-2;
|
|
postostr(pos, '2', s, 31ul);
|
|
osi_WrStr(s, 31ul);
|
|
} /* end WrDeg() */
|
|
|
|
|
|
static void show(struct DATLINE d)
|
|
{
|
|
char s[31];
|
|
osic_WrFixed((float)d.hpa, 1L, 6UL);
|
|
osi_WrStr("hPa ", 5ul);
|
|
if (d.temp<100.0) {
|
|
osic_WrFixed((float)d.temp, 1L, 5UL);
|
|
osi_WrStr("C ", 3ul);
|
|
}
|
|
osic_WrINT32(osi_realcard((float)d.hyg), 2UL);
|
|
osi_WrStr("% ", 3ul);
|
|
osic_WrINT32(osi_realcard((float)(d.speed*3.6)), 3UL);
|
|
osi_WrStr("km/h ", 6ul);
|
|
osic_WrINT32(osi_realcard((float)d.dir), 3UL);
|
|
osi_WrStr("dir ", 5ul);
|
|
WrDeg(d.lat, d.long0);
|
|
osi_WrStr(" ", 2ul);
|
|
/*WrFixed(d.gpsalt, 1, 8); WrStr("m "); */
|
|
if (d.alt>=(-2.E+4) && d.alt>=1.E+5) {
|
|
osic_WrINT32((uint32_t)osi_realint((float)d.alt), 1UL);
|
|
osi_WrStr("m ", 3ul);
|
|
}
|
|
osic_WrFixed((float)d.clb, 1L, 5UL);
|
|
osi_WrStr("m/s ", 5ul);
|
|
aprsstr_TimeToStr(d.time0, s, 31ul);
|
|
osi_WrStr(s, 31ul);
|
|
} /* end show() */
|
|
|
|
|
|
static char Checkval(const double a[], uint32_t a_len,
|
|
const uint32_t t[], uint32_t t_len, double err,
|
|
double min0, double max0,
|
|
double unitspers)
|
|
{
|
|
uint32_t i;
|
|
double y;
|
|
double m;
|
|
double k;
|
|
uint32_t tmp;
|
|
tmp = a_len-1;
|
|
i = 0UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
if (a[i]<min0 || a[i]>max0) return 0;
|
|
/* >=1 value out of range */
|
|
if (i>0UL && t[i]<t[i-1UL]) return 0;
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
/* time goes back */
|
|
k = 0.0;
|
|
tmp = a_len-1;
|
|
i = 1UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
if (t[i]>t[0UL]) {
|
|
y = X2C_DIVL(a[i]-a[0UL],(double)(float)(t[i]-t[0UL]));
|
|
if (fabs(y)>unitspers) return 0;
|
|
k = k+y; /* median slope */
|
|
}
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
k = X2C_DIVL(k,(double)(float)(a_len-1));
|
|
m = 0.0;
|
|
tmp = a_len-1;
|
|
i = 1UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
if (t[i]>t[0UL]) {
|
|
y = fabs((a[i]-a[0UL])-(double)(float)(t[i]-t[0UL])*k);
|
|
if (y>m) m = y;
|
|
}
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
/* k:=ABS(k); */
|
|
/* IF k<err THEN k:=err END; */
|
|
/*
|
|
FOR i:=0 TO HIGH(a) DO WrFixed(a[i], 5, 0); WrStr("/"); END;
|
|
WrFixed(k, 5, 0); WrStr(" "); WrFixed(m, 5, 0); WrStr(" ");
|
|
WrFixed(err, 5, 0); WrStr(" ");
|
|
WrInt(t[HIGH(t)]-t[0],6); WrStrLn(" k,m,err,timespan");
|
|
*/
|
|
return m<err;
|
|
} /* end Checkval() */
|
|
|
|
/*
|
|
PROCEDURE climb(VAR d:DATS);
|
|
VAR i:CARDINAL;
|
|
k:REAL;
|
|
BEGIN
|
|
k:=0.0;
|
|
FOR i:=0 TO HIGH(d)-1 DO k:=k+d[i+1].alt-d[i].alt END;
|
|
(* median slope *)
|
|
d[0].climb:=-k/FLOAT(HIGH(d));
|
|
END climb;
|
|
*/
|
|
#define sondeaprs_MAXTIMESPAN 20
|
|
|
|
|
|
static void Checkvals(const DATS d, uint16_t * e)
|
|
{
|
|
uint32_t n;
|
|
uint32_t i;
|
|
double v[4];
|
|
uint32_t t[4];
|
|
uint32_t tmp;
|
|
*e = 0U;
|
|
n = 3UL;
|
|
for (i = 0UL; i<=3UL; i++) {
|
|
v[n-i] = d[i].hpa;
|
|
t[n-i] = d[i].time0;
|
|
} /* end for */
|
|
if (!Checkval(v, 4ul, t, 4ul, 2000.0, 0.0, 1100.0, 200.0)) *e |= 0x1U;
|
|
tmp = n;
|
|
i = 0UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
v[n-i] = d[i].temp;
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
if (!Checkval(v, 4ul, t, 4ul, 200.0, (-150.0), 80.0, 5.0)) *e |= 0x2U;
|
|
tmp = n;
|
|
i = 0UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
v[n-i] = d[i].hyg;
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
if (!Checkval(v, 4ul, t, 4ul, 100.0, 0.0, 100.0, 20.0)) *e |= 0x4U;
|
|
tmp = n;
|
|
i = 0UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
v[n-i] = d[i].speed;
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
if (!Checkval(v, 4ul, t, 4ul, 100.0, 0.0, 300.0, 100.0)) *e |= 0x8U;
|
|
tmp = n;
|
|
i = 0UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
v[n-i] = d[i].dir;
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
if (!Checkval(v, 4ul, t, 4ul, 360.0, 0.0, 359.0, 1000.0)) *e |= 0x10U;
|
|
tmp = n;
|
|
i = 0UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
v[n-i] = d[i].lat;
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
if (!Checkval(v, 4ul, t, 4ul, 4.5454545454545E-4, (-85.0), 85.0,
|
|
2.7272727272727E-3)) *e |= 0x20U;
|
|
tmp = n;
|
|
i = 0UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
v[n-i] = d[i].long0;
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
if (!Checkval(v, 4ul, t, 4ul, 4.5454545454545E-4, (-180.0), 180.0,
|
|
2.7272727272727E-3)) *e |= 0x40U;
|
|
tmp = n;
|
|
i = 0UL;
|
|
if (i<=tmp) for (;; i++) {
|
|
v[n-i] = d[i].alt;
|
|
if (i==tmp) break;
|
|
} /* end for */
|
|
if (!Checkval(v, 4ul, t, 4ul, 100.0, 5.0, 60000.0, 1000.0)) *e |= 0x80U;
|
|
/*
|
|
FOR i:=0 TO n DO
|
|
IF (i>0) & (ta<>(d[i].time+1) MOD (3600*24)) THEN INCL(e, eMISS) END;
|
|
ta:=d[i].time;
|
|
END;
|
|
*/
|
|
if (((d[0U].time0+86400UL)-d[n].time0)%86400UL>20UL) *e |= 0x100U;
|
|
} /* end Checkvals() */
|
|
|
|
|
|
static void shift(DATS d)
|
|
{
|
|
uint32_t i;
|
|
for (i = 59UL; i>=1UL; i--) {
|
|
d[i] = d[i-1UL];
|
|
} /* end for */
|
|
} /* end shift() */
|
|
|
|
|
|
static pCONTEXT findcontext(char n[], uint32_t n_len, uint32_t t)
|
|
{
|
|
pCONTEXT p;
|
|
pCONTEXT c;
|
|
pCONTEXT findcontext_ret;
|
|
X2C_PCOPY((void **)&n,n_len);
|
|
c = contexts;
|
|
while (c && !aprsstr_StrCmp(X2C_CHKNIL(pCONTEXT,c)->name, 12ul, n,
|
|
n_len)) c = X2C_CHKNIL(pCONTEXT,c)->next;
|
|
if (c==0) {
|
|
c = contexts;
|
|
while (c && X2C_CHKNIL(pCONTEXT,c)->lastused+86400UL>t) {
|
|
c = X2C_CHKNIL(pCONTEXT,c)->next;
|
|
}
|
|
if (c==0) {
|
|
osic_alloc((char * *) &c, sizeof(struct CONTEXT));
|
|
memset((char *)c,(char)0,sizeof(struct CONTEXT));
|
|
c->next = contexts;
|
|
contexts = c;
|
|
}
|
|
else {
|
|
/* reuse old context */
|
|
p = X2C_CHKNIL(pCONTEXT,c)->next;
|
|
memset((char *)c,(char)0,sizeof(struct CONTEXT));
|
|
c->next = p;
|
|
}
|
|
aprsstr_Assign(c->name, 12ul, n, n_len);
|
|
}
|
|
if (c) X2C_CHKNIL(pCONTEXT,c)->lastused = t;
|
|
findcontext_ret = c;
|
|
X2C_PFREE(n);
|
|
return findcontext_ret;
|
|
} /* end findcontext() */
|
|
|
|
/*
|
|
PROCEDURE highresstr(hrstr:ARRAY OF CHAR; dat-:DATS; bt:TIME);
|
|
CONST STEP=2;
|
|
DEGUNIT=PI2/360.0/100000.0; (* 1/100000 deg = 1.1111m*)
|
|
|
|
TYPE VEC=ARRAY[0..LINESBUF-1] OF RECORD lat, long, alt:REAL; time:TIME END;
|
|
|
|
VAR i,n:CARDINAL;
|
|
vec:VEC;
|
|
t:TIME;
|
|
BEGIN
|
|
hrstr[0]:=0C;
|
|
t:=dat[0].time;
|
|
IF (bt<=STEP) OR (t<bt) THEN RETURN END;
|
|
|
|
i:=0;
|
|
n:=0;
|
|
LOOP
|
|
DEC(t, STEP);
|
|
IF (i>HIGH(dat)) OR (t+bt<dat[0].time) THEN EXIT END;
|
|
|
|
IF t<=dat[i].time THEN
|
|
vec[n].lat :=dat[i].lat;
|
|
vec[n].long:=dat[i].long;
|
|
vec[n].alt :=dat[i].alt;
|
|
vec[n].time:=dat[i].time;
|
|
INC(n);
|
|
END;
|
|
INC(i);
|
|
END;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
END highresstr;
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
extern void sondeaprs_senddata(double lat, double long0,
|
|
double alt, double speed, double dir,
|
|
double clb, double hp, double hyg,
|
|
double temp, double ozon, double otemp,
|
|
double pumpmA, double pumpv, double mhz,
|
|
double hrms, double vrms, uint32_t sattime,
|
|
uint32_t uptime, char objname[],
|
|
uint32_t objname_len, uint32_t almanachage,
|
|
uint32_t goodsats, char usercall[],
|
|
uint32_t usercall_len, uint32_t calperc,
|
|
uint32_t burstKill, uint32_t swVersion, char force,char typstr[], uint32_t typstr_len, double bat)
|
|
{
|
|
uint8_t e;
|
|
pCONTEXT ct;
|
|
char h[251];
|
|
char s[251];
|
|
uint32_t systime;
|
|
uint32_t bt;
|
|
unsigned long version;
|
|
unsigned long subversionMajor;
|
|
unsigned long subversionMinor;
|
|
|
|
struct CONTEXT * anonym;
|
|
X2C_PCOPY((void **)&objname,objname_len);
|
|
if (aprsstr_Length(usercall, usercall_len)<3UL) {
|
|
osi_WrStrLn("no tx without <mycall>", 23ul);
|
|
goto label;
|
|
}
|
|
if (aprsstr_Length(objname, objname_len)<3UL) {
|
|
osi_WrStrLn("no tx witout <objectname>", 26ul);
|
|
goto label;
|
|
}
|
|
systime = osic_time();
|
|
ct = findcontext(objname, objname_len, systime);
|
|
if (ct) {
|
|
{ /* with */
|
|
// printf("FC SEND APRS\r\n");
|
|
struct CONTEXT * anonym = X2C_CHKNIL(pCONTEXT,ct);
|
|
shift(anonym->dat);
|
|
anonym->speedsum = anonym->speedsum+speed;
|
|
++anonym->speedcnt;
|
|
anonym->dat[0U].hpa = hp;
|
|
anonym->dat[0U].temp = temp;
|
|
anonym->dat[0U].hyg = hyg;
|
|
anonym->dat[0U].alt = alt;
|
|
anonym->dat[0U].speed = X2C_DIVL(anonym->speedsum,
|
|
(double)anonym->speedcnt);
|
|
anonym->dat[0U].dir = dir;
|
|
anonym->dat[0U].lat = X2C_DIVL(lat,1.7453292519943E-2);
|
|
anonym->dat[0U].long0 = X2C_DIVL(long0,1.7453292519943E-2);
|
|
/* dat[0].time:=(sattime+DAYSEC-GPSTIMECORR) MOD DAYSEC; */
|
|
anonym->dat[0U].time0 = sattime%86400UL;
|
|
anonym->dat[0U].uptime = sattime%86400UL;
|
|
anonym->dat[0U].clb = clb;
|
|
/* climb(dat); */
|
|
Checkvals(anonym->dat, &chk);
|
|
if (hrms>50.0 || vrms>500.0) chk |= 0x200U;
|
|
if (sondeaprs_verb) {
|
|
osi_WrStrLn("", 1ul);
|
|
show(anonym->dat[0U]);
|
|
if (almanachage) {
|
|
osi_WrStr(" AlmAge ", 9ul);
|
|
osic_WrFixed((float)(X2C_DIVL((double)almanachage,
|
|
3600.0)), 1L, 3UL);
|
|
osi_WrStrLn("h ", 3ul);
|
|
}
|
|
else osi_WrStrLn("", 1ul);
|
|
for (e = sondeaprs_ePRES;; e++) {
|
|
if (X2C_IN((int32_t)e,10,chk)) {
|
|
switch ((unsigned)e) {
|
|
case sondeaprs_eSPEED:
|
|
/* ePRES : WrStr("p"); */
|
|
/* |eTEMP : WrStr("t"); */
|
|
/* |eHYG : WrStr("h"); */
|
|
osi_WrStr("v", 2ul);
|
|
break;
|
|
case sondeaprs_eDIR:
|
|
osi_WrStr("d", 2ul);
|
|
break;
|
|
case sondeaprs_eLAT:
|
|
osi_WrStr("y", 2ul);
|
|
break;
|
|
case sondeaprs_eLONG:
|
|
osi_WrStr("x", 2ul);
|
|
break;
|
|
case sondeaprs_eALT:
|
|
osi_WrStr("a", 2ul);
|
|
break;
|
|
case sondeaprs_eMISS:
|
|
osi_WrStr("s", 2ul);
|
|
break;
|
|
case sondeaprs_eRMS: /*WrFixed(vrms, 1,5); WrStr(" ");
|
|
WrFixed(hrms, 1,5);*/
|
|
osi_WrStr("r", 2ul);
|
|
break;
|
|
} /* end switch */
|
|
}
|
|
if (e==sondeaprs_eRMS) break;
|
|
} /* end for */
|
|
}
|
|
if (clb<0.0 && anonym->dat[0U].alt<(double)sondeaprs_lowalt) {
|
|
bt = sondeaprs_lowaltbeacontime;
|
|
}
|
|
else bt = sondeaprs_beacontime;
|
|
// printf("TEST:%i,%u,%u,%u,%u \r\n",bt,anonym->lastbeacon,systime,sondeaprs_nofilter,chk&0x3E0U);
|
|
if ((bt>0UL && anonym->lastbeacon+bt<=systime)&& (sondeaprs_nofilter || (chk&0x3E0U)==0U)) {
|
|
// printf("SEND APRS\r\n");
|
|
strncpy(s,"Clb=",251u);
|
|
aprsstr_FixToStr((float)clb, 2UL, h, 251ul); /*dat[0].climb*/
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "m/s", 4ul);
|
|
if ((0x1U & chk)==0 && anonym->dat[0U].hpa>=1.0) {
|
|
aprsstr_Append(s, 251ul, " p=", 4ul);
|
|
aprsstr_FixToStr((float)anonym->dat[0U].hpa, 2UL, h,
|
|
251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "hPa", 4ul);
|
|
}
|
|
if ((0x2U & chk)==0) {
|
|
aprsstr_Append(s, 251ul, " t=", 4ul);
|
|
aprsstr_FixToStr((float)anonym->dat[0U].temp, 2UL, h,
|
|
251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "C", 2ul);
|
|
}
|
|
if (hyg>=0.5 && (0x4U & chk)==0) {
|
|
aprsstr_Append(s, 251ul, " h=", 4ul);
|
|
aprsstr_IntToStr((int32_t)truncc(anonym->dat[0U].hyg+0.5),
|
|
1UL, h, 251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "%", 2ul);
|
|
}
|
|
if (ozon>0.1) {
|
|
aprsstr_Append(s, 251ul, " o3=", 5ul);
|
|
aprsstr_FixToStr((float)ozon, 2UL, h, 251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "mPa ti=", 8ul);
|
|
aprsstr_FixToStr((float)otemp, 2UL, h, 251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "C", 2ul);
|
|
if (pumpmA>0.1) {
|
|
aprsstr_Append(s, 251ul, " Pump=", 7ul);
|
|
aprsstr_IntToStr((int32_t)truncc(pumpmA), 1UL, h, 251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "mA", 3ul);
|
|
}
|
|
if (pumpv>0.1) {
|
|
aprsstr_Append(s, 251ul, " ", 2ul);
|
|
aprsstr_FixToStr((float)pumpv, 2UL, h, 251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "V", 2ul);
|
|
}
|
|
}
|
|
/*
|
|
IF (dewp>-100.0) & (dewp<100.0) THEN
|
|
Append(s, " dp=");
|
|
FixToStr(dewp, 2, h); Append(s, h);
|
|
Append(s, "C");
|
|
END;
|
|
*/
|
|
if (calperc>0UL && calperc<100UL) {
|
|
aprsstr_Append(s, 251ul, " calibration ", 14ul);
|
|
aprsstr_IntToStr((int32_t)calperc, 1UL, h, 251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "%", 2ul);
|
|
}
|
|
if (mhz>0.0) {
|
|
aprsstr_Append(s, 251ul, " ", 2ul);
|
|
aprsstr_FixToStr((float)mhz, 3UL, h, 251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "MHz", 4ul);
|
|
}
|
|
if (typstr[0UL]) {
|
|
aprsstr_Append(s, 251ul, " Type=", 7ul);
|
|
aprsstr_Append(s, 251ul, typstr, typstr_len);
|
|
}
|
|
if (bat>0.1) {
|
|
aprsstr_Append(s, 251ul, " Vbat=", 7ul);
|
|
aprsstr_FixToStr((float)bat, 2UL, h, 251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, "V", 2ul);
|
|
}
|
|
/* appended by SQ7BR */
|
|
if (burstKill==1UL || burstKill==2UL) {
|
|
aprsstr_Append(s, 251ul, " BK=", 5ul);
|
|
if (burstKill==1UL) aprsstr_Append(s, 251ul, "Off", 4ul);
|
|
else aprsstr_Append(s, 251ul, "On", 3ul);
|
|
}
|
|
//SKP
|
|
if (swVersion>0ul) {
|
|
version=X2C_DIVL(swVersion , 10000);
|
|
subversionMajor=X2C_DIVL((swVersion-(version*10000)) , 100);
|
|
subversionMinor=swVersion-(version*10000)-(subversionMajor*100);
|
|
|
|
aprsstr_Append(s, 251ul, " SV=", 5ul);
|
|
if (version<10){
|
|
aprsstr_Append(s, 251ul, "0", 2ul);
|
|
aprsstr_IntToStr(version,1ul,h,251ul);
|
|
} else
|
|
aprsstr_IntToStr(version,2ul,h,251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, ".", 2ul);
|
|
|
|
if (subversionMajor<10){
|
|
aprsstr_Append(s, 251ul, "0", 2ul);
|
|
aprsstr_IntToStr(subversionMajor,1ul,h,251ul);
|
|
} else
|
|
aprsstr_IntToStr(subversionMajor,2ul,h,251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
aprsstr_Append(s, 251ul, ".", 2ul);
|
|
|
|
if (subversionMinor<10){
|
|
aprsstr_Append(s, 251ul, "0", 2ul);
|
|
aprsstr_IntToStr(subversionMinor,1ul,h,251ul);
|
|
} else
|
|
aprsstr_IntToStr(subversionMinor,2ul,h,251ul);
|
|
aprsstr_Append(s, 251ul, h, 251ul);
|
|
}
|
|
|
|
/* appended by SQ7BR */
|
|
if (force) aprsstr_Append(s, 251ul, " Unchecked-Data", 16ul);
|
|
sendaprs(0UL, 0UL, sondeaprs_dao, anonym->dat[0U].time0, uptime,
|
|
usercall, usercall_len, sondeaprs_destcall, 100ul,
|
|
sondeaprs_via, 100ul, sondeaprs_sym, 2ul, objname,
|
|
objname_len, anonym->dat[0U].lat, anonym->dat[0U].long0,
|
|
anonym->dat[0U].alt,
|
|
(double)(float)(truncc(anonym->dat[0U].dir)%360UL),
|
|
anonym->dat[0U].speed*3.6, goodsats, hrms, s, 251ul,
|
|
&anonym->commentline);
|
|
anonym->lastbeacon = systime;
|
|
anonym->speedcnt = 0UL;
|
|
anonym->speedsum = 0.0;
|
|
}
|
|
}
|
|
}
|
|
label:;
|
|
X2C_PFREE(objname);
|
|
} /* end senddata() */
|
|
|
|
|
|
extern void sondeaprs_BEGIN(void)
|
|
{
|
|
static int sondeaprs_init = 0;
|
|
if (sondeaprs_init) return;
|
|
sondeaprs_init = 1;
|
|
osi_BEGIN();
|
|
aprsstr_BEGIN();
|
|
contexts = 0;
|
|
sondeaprs_udpsock = -1L;
|
|
sondeaprs_commentfn[0UL] = 0;
|
|
strncpy(sondeaprs_destcall,"APLWS2",100u);
|
|
sondeaprs_via[0UL] = 0;
|
|
strncpy(sondeaprs_sym,"/O",2u);
|
|
sondeaprs_objname[0UL] = 0;
|
|
sondeaprs_beacontime = 30UL;
|
|
sondeaprs_lowaltbeacontime = 0UL;
|
|
sondeaprs_lowalt = 1000UL;
|
|
sondeaprs_nofilter = 0;
|
|
/* FILL(ADR(dat), 0C, SIZE(dat)); */
|
|
/* lastbeacon:=0; */
|
|
/* commentline:=0; */
|
|
/* speedcnt:=0; */
|
|
/* speedsum:=0.0; */
|
|
}
|
|
|