DEFINITION MODULE aprsdecode; (* connect to aprs-is gateway and decode data for archive and map by OE5DXL *)

FROM SYSTEM IMPORT INT16, INT8, CARD16, CARD8;
FROM aprsstr IMPORT POSITION, TIME, IPNUM, UDPPORT;
FROM osi IMPORT SOCKET;
FROM xosi IMPORT PROCESSHANDLE;

TYPE SET256=SET OF [0..255];

CONST
      CR=015C;
      LF=012C;
      DEGSYM=177C; 
      DELETSYM=1C;
      WXNIL=1000000.0;
      MSGSIZE=67;
      ACKSIZE=5;
      REPLYACK="}";
      UDPSOCKS=4;
      DESTCALL="APLM01";
      SHOWTEMPWIND=3600;        (* till seconds after last wx info show temp or windvane *)
      MAXTEMP=99;               (* ignore out of range temps *)
      MINTEMP=-99;              (* ignore out of range temps *)
      IGATEMAXDELAY=5;          (* seconds to discard igate frames if mainloop is too slow *)
      BEGINOFTIME=1388534400;   (* oldest possible log date *)
      MAXMULTILINES=40;         (* AE5PL limits to 23 multiline elements *)    
      SYMTABLE=SET256{47,92,65..90,48..57,97..122};
      POIINFOSIZE=4096;
      VERSNUM="0.82";
      DEFAULTPOISYMBOL="//";
      MAXPOIFILES=30;
      FOLLOWX=0;
      FOLLOWWATCH=1;

<* IF TARGET_FAMILY="WIN32" THEN *>
  <* IF __GEN_C__ THEN *>
      VERS="aprsmap(cw) "+VERSNUM;
  <* ELSE *>
      VERS="aprsmap(w) "+VERSNUM;
  <* END *>
<* ELSIF TARGET_FAMILY="UNIX" THEN *>
  <* IF __GEN_C__ THEN *>
      VERS="aprsmap(cu) "+VERSNUM;
  <* ELSE *>
      VERS="aprsmap(u) "+VERSNUM;
  <* END *>
<* END *>


TYPE
      MONCALL=ARRAY[0..8] OF CHAR;
      FRAMEBUF=ARRAY[0..511] OF CHAR;
      WWWB=ARRAY[0..1400] OF CHAR;

      FILENAME=ARRAY[0..1023] OF CHAR;
      POSCALL=RECORD
                call:MONCALL;
                typ:CHAR;
                pos:POSITION;
              END;   

      pWWWBUF=POINTER TO WWWBUF;
      WWWBUF=RECORD
              buf  :WWWB;
              tlen :INTEGER;
              push :BOOLEAN;
              next :pWWWBUF;
            END;

      QWatch=RECORD
               lasttb  :CARDINAL;
               qsize   :INTEGER;
               lastqb  :INTEGER;
               txbyte  :ARRAY[0..59] OF INTEGER;
             END;
      pTCPSOCK=POINTER TO TCPSOCK;
      TCPSOCK=RECORD
               next    : pTCPSOCK;
               fd      : SOCKET;
               watchtime,
               beacont, 
               connt   : TIME;
               gatepri : CARDINAL;    
               ipnum   : ARRAY[0..63] OF CHAR;
               port    : ARRAY[0..5] OF CHAR;
               user    : POSCALL;
               txframes,
               txbytes,
               rxframes,
               rxbytes : CARDINAL;
               rpos, 
               tlen    : INTEGER;
               rbuf, 
               tbuf    : FRAMEBUF;
               qwatch  : QWatch;
               waitpong: CARD8;
               lastpong,
               lastping,
               windoofwatch:TIME; 
             END;

     DUPETIMES=ARRAY[0..65535] OF TIME;
     UDPSOCK=RECORD
               fd         : SOCKET;
               rawread,
               checkip    : BOOLEAN;
               ip         : IPNUM;
               bindport,
               dport      : UDPPORT;
               chan       : INTEGER;                       (* channel number 1.. *)

               lastudprx,
               lastudptx,
               starttime,
               bpstime    : TIME;
               rxframes,
               rxbytes,
               txframes,
               txbytes    : CARDINAL;                      (* for tx bit/s limiter *)
               uip        : IPNUM;
               pdupetimes : POINTER TO DUPETIMES;
             END;

      MSGTEXT=ARRAY[0..MSGSIZE-1] OF CHAR;
      ACKTEXT=ARRAY[0..ACKSIZE-1] OF CHAR;
      ACKREPTEXT=ARRAY[0..1] OF CHAR;

      ERRFLAGS=(eDIST, eSPIKE, eSYMB, eDUPE, eSPEED, eNODRAW, eNOPOS);
      ERRSET=SET OF ERRFLAGS;

      DRAWHINTS=(MIRRORSYM, ISOBJECT, HIDE, MARKED, MOVES);

      sDRAWHINTS=SET OF DRAWHINTS;

      SYMBOL=RECORD tab, pic: CHAR END;
      AREASYMB=RECORD
        typ    : CHAR;
        color  : CARD8;
        dpos   : POSITION;
      END;

      pFRAMEHIST=POINTER TO FRAMEHIST;

      pVARDAT=POINTER TO VARDAT;
      FRAMEHIST=RECORD
               next     :pFRAMEHIST;
               time     :TIME;
               vardat   :pVARDAT;
               nodraw   :ERRSET;
             END;


      VARDAT=RECORD
               lastref  :pFRAMEHIST;
               pos      :POSITION;
               refcnt   :CARDINAL;                    (* starts at 0 *)
(*             altitude :INT16;*)
               igatepos,
               igatelen :CARD8;
               raw      :ARRAY[0..499] OF CHAR;       (* last part allocatet with real size *)
             END;

       
      CLBTYP=INT8;
      pOPHIST=POINTER TO OPHIST; 
      OPHIST=RECORD
               next       :pOPHIST;                   (* symbol call chain *)
               frames,                                (* beacons with this call *)
               lastfrp    :pFRAMEHIST;                (* log import quick write pointer, no compress *)
               margin0,                               (* movement frame for quick draw *)
               margin1,
               lastpos    :POSITION;
               lasttime,
               temptime   :TIME;
               lastkmh,                               (* drive kmh, wx kmh *)                
               lasttempalt:INT16;                     (* drive altitude, wx temp *)
               framerate  :REAL;                      (* thruput frames/s *) 
               call       :MONCALL;
               sym        :SYMBOL;
               drawhints  :sDRAWHINTS;
               clb        :CLBTYP;
               trackcol,
               textpos,
               valuepos   :INT8;
               lastinftyp :CARD8;  (*0 no inf, 10..99 drive dir, 100 wx no dir 110..199 wind dir*)
               lastrxport :CHAR;                      (* for msg routing, in future remove if port is seen in rawframes *)  
               areasymb   :AREASYMB;                  (* area object data *)
               poligon,
               dirty      :BOOLEAN;                   (* Checktrack not done *) 
             END;


      STORM=(WXNOWX, WXNORMAL, WXTS, WXHC, WXTD);
      WX=RECORD
           gust,
           temp,     
           hygro,    
           baro,     
           rain1,    
           rain24,   
           raintoday,
           lum,
           sievert:REAL;
           dust10,
           dust2,
           dust1,
           dust01:INT16;
           storm:STORM; 
           sustaind,
           radiushurr,
           radiusstorm,
           wholegale       :REAL;
         END;  

      TYPES=(UNKNOWN, MICE, POS, WETH, PWETH, MSG, OBJ, ITEM, SCAP, STAT, TELE, QUERY);
      TYPSET=SET OF TYPES;
      ACKREJ=(MSGMSG, MSGACK, MSGREJ);
      HRTPOS=RECORD
               dlong, dlat, dalt:REAL;
               dtime:TIME;
               notinterpolated:BOOLEAN;
             END;
      MULTILINE=RECORD
        size    :CARDINAL;
        linetyp :CHAR;
        filltyp :CHAR;
        vec     :ARRAY[0..MAXMULTILINES] OF POSITION;
      END;

      TELEMETRY=ARRAY[0..6] OF CARD16; 
      DAT=RECORD
            srcall,
            symcall,
            dstcall    : MONCALL;
            viacalls   : ARRAY[0..9] OF MONCALL;
            msgto,
            objectfrom : MONCALL;
            hbitp,
            igaterawp,
            igatelen,
            igatep,
            payload    : CARDINAL;
            postyp,
            typc       : CHAR;
            areasymb   : AREASYMB;
            pos        : POSITION;
            speed      : CARDINAL;
            course     : CARDINAL;
            climb,
            altitude   : INTEGER; 
            sym,   
            symt,
            timestamp,   
            objkill,
            lastrxport : CHAR;    
            wx         : WX;      
            type       : TYPES;   
            moved      : REAL;    
(*
            stack      : CARDINAL;
*)
            msgtext    : MSGTEXT;
            acktext    : ACKTEXT;
            ackrej     : ACKREJ;
            hrtposes   : ARRAY[0..31] OF HRTPOS;
            hrtlen     : CARDINAL;
            hrttime    : TIME;                                (* if non zero is hrt defined *)
            multiline  : MULTILINE;
            tlmvalues  : TELEMETRY;                           (* 5 analog and if all 5 valid the sixth is bitset, 0 undef, incremented by 1 *)
            comment    : ARRAY[0..255] OF CHAR;
          END;

       WXSET=(wTEMP, wBARO, wHYG, wWIND, wWINDDIR, wRAIN, wLUMI, wSIEV, wFINEDUST,
                     wSHIST, wBHIST, wAHIST);
       sWXSET=SET OF WXSET;

       CLICKTYPS=(tTEXT, tTRACK, tSYMBOL, tMAP, tOBJECT, tOBJECTTEXT, tRFPATH, tKMHOBJ, tKMH,
                  tDEGREE, tDEGREEOBJ, tMETEOCOLOR);


       pTXMESSAGE=POINTER TO TXMESSAGE;
       TXMESSAGE=RECORD
         next       : pTXMESSAGE;
         txtime,
         acktime    : TIME;
         txcnt      : CARDINAL;
         port       : CHAR;
         to         : MONCALL;
         msgtext    : MSGTEXT;
         acknum     : CARDINAL;
         heard,
         rej        : BOOLEAN;
       END;       

     pMSGFIFO=POINTER TO MSGFIFO;
     MSGFIFO=RECORD
       next:pMSGFIFO;
       time:TIME;
       port:CHAR; 
       itemname,
       from,
       to:  MONCALL;
       txt:MSGTEXT; 
       ack:ACKTEXT;
       query, deleteitem, isaa:BOOLEAN;
       itempos:POSITION;
     END;
       
     ZOOMFRAME=RECORD x0, y0, x1, y1:INTEGER END;
     COLTYP=RECORD r,g,b:CARDINAL END;

     pMOUNTAININFO=POINTER TO ARRAY[0..65535] OF CHAR;
     pMOUNTAIN=POINTER TO MOUNTAIN;
     MOUNTAIN=RECORD
       next:pMOUNTAIN;
       pinfo:pMOUNTAININFO;
       pos:POSITION;
       alt:INT16;
       index:CARD16;
       name:ARRAY[0..31] OF CHAR;
       category:ARRAY[0..9] OF CHAR;
     END;

     CLICKOBJECT=RECORD
                   opf       :pOPHIST;
                   pff, pff0 :pFRAMEHIST;
                   typf      :CLICKTYPS;
                 END;
     MAPNAME = ARRAY[0..40] OF CHAR;

     SYMBOLSET = SET OF [0..191];

     MAPGAMMATAB = ARRAY[0..256] OF CARDINAL;

     POIFILELINE = RECORD
       count    :CARDINAL;
       on       :BOOLEAN;
       symbol   :ARRAY[0..1] OF CHAR;
       name     :ARRAY[0..9] OF CHAR;
       fullname :ARRAY[0..4095] OF CHAR;
     END;


VAR systime, realtime, lastlooped, updateintervall:TIME;
    rxidle:CARDINAL;
    quit:BOOLEAN;
    WITHX11,
    verb: BOOLEAN;
    logdone:BOOLEAN;
     
    click:RECORD
      dryrun,
      withradio,
      chkmaps,
      panorama,
      altimap,
      watchmhop, 
      lastpoi,
      insreplaceline,
      watchlast,
      abort    : BOOLEAN;
      x,
      y,
      min      : INTEGER;
      mhop     : MONCALL;
      onesymbol: SYMBOL;
      onesymbolset:SYMBOLSET;
      ops      : pOPHIST;
      pf, pf0  : pFRAMEHIST;
      zoomtox,
      zoomtoy  : INTEGER;
      typ      : CLICKTYPS;
      cmd,
      cmdatt   : CHAR;
      pullpos,
      clickpos,
      squerpos0,
      squerpos1,
      squerspos0,
      squerspos1,
      measurepos,
      markpos  : POSITION;
      markpost : TIME;                                (* waypoint time to markpos to make uniqe *)
      marktime : TIME;                                (* delete marker if no set by set marker *) 
      markalti : INTEGER;                             (* for geoprofile *)
      sumpos   : POSITION;                            (* store last clickpos for waysum *)
      waysum   : REAL;                                (* sum up marker set distances *)
      graphset : sWXSET;                              (* update graphs if marked last waypoint *)
      selected,
      entries  : CARDINAL; 
      bubblpos : POSITION;                            (* found position of POI *) 
      bubblstr : ARRAY[0..49] OF CHAR;                (* found text of POI *) 
      bubblinfo: ARRAY[0..4095] OF CHAR;              (* found additional info of POI *) 
      table    : ARRAY[0..9] OF CLICKOBJECT;
      polilinecursor:CARDINAL;                        (* edit which edge of polinine object *)
    END;  

    mappos                : POSITION;
    inittilex, inittiley,
    initxsize, initysize,
    parmzoom,
    initzoom              : INTEGER;
    finezoom, parmfinezoom: REAL;
    mapdir:ARRAY[0..1024] OF CHAR;
    mountains:pMOUNTAIN;
    poifiles:ARRAY[0..MAXPOIFILES] OF POIFILELINE;
    autoshots:TIME;                                   (* every s make screenshot *)

    lums: RECORD
      moving, moded, errorstep, logmode, headmenuy:BOOLEAN;
      mapname :MAPNAME;
      mapnum  :CARDINAL;
      configfn:ARRAY[0..256] OF CHAR;
      maplumcorr:MAPGAMMATAB;
      map,
      rf,
      rfbri,
      track,
      waypoint,
      sym,
      obj,
      text,
      nomov,
      centering,
      fps,
      actfps    : INTEGER;
      symsize, 
      fontxsize,
      fontysize,
      fontsymbolpercent : CARDINAL;
      wxcol     : CHAR;
      movestep,

      dupemaxtime,
      kmhtime,
      purgetime,
      purgetimeobj,
      firstdim,
      maxdim    :TIME;

      gamma     :REAL;
      menutransp:BOOLEAN;
      menubackcol,
      menucol:COLTYP;
      followwhat:BITSET;

    END; 

    tracenew: RECORD
      winpos0,
      winpos1   :POSITION;
      call      :MONCALL;
      winevent  :CARDINAL;
      follow,
      beep      :BOOLEAN;
    END;   

    txmessages:pTXMESSAGE;
    msgfifo:pMSGFIFO;
    spikesens,
    maxhop      :REAL;
    ophist2,
    ophist                : pOPHIST;

    gateways              : ARRAY[0..9] OF RECORD
                              url:ARRAY[0..255] OF CHAR;
                              port:ARRAY[0..5] OF CHAR;
                              filterst:ARRAY[0..255] OF CHAR;
                            END;  
(*
    servercall            : MONCALL;
*)
    tcpsocks              : pTCPSOCK;
    udpsocks:ARRAY[0..UDPSOCKS-1] OF UDPSOCK; 
    lasttcptx,
    lastanyudprx,
    lastpurge, 
    lasttcprx             : TIME;
    testbeaconbuf         : FRAMEBUF;            (* fill with port:time:beacon then sent once *)
    checkversion,
    serialpid,
    serialpid2,
    maploadpid:PROCESSHANDLE;

PROCEDURE Decode(buf:ARRAY OF CHAR; VAR dat:DAT):INTEGER;
PROCEDURE Stoframe(VAR optab:pOPHIST; rawbuf:ARRAY OF CHAR; stime:TIME;
                   logmode:BOOLEAN; VAR oldtime:TIME; dat:DAT):INTEGER;
(*
PROCEDURE Checktrack(op:pOPHIST; lastf:pFRAMEHIST);
*)
PROCEDURE Checktracks;
PROCEDURE purge(VAR ops:pOPHIST; oldt, oldobj:TIME);
PROCEDURE knottokmh(kn:INTEGER):INTEGER;
PROCEDURE trunc(r:REAL):CARDINAL;
PROCEDURE floor(r:REAL):REAL;
PROCEDURE tcpout(acttcp:pTCPSOCK):INTEGER;
PROCEDURE tcpin(acttcp:pTCPSOCK);
PROCEDURE udpin(uport:CARDINAL);
PROCEDURE tcpclose(acttcp:pTCPSOCK; fin:BOOLEAN);
PROCEDURE tcpjobs;
PROCEDURE initparms;
PROCEDURE delwaypoint(op:pOPHIST; VAR frame:pFRAMEHIST);
PROCEDURE finddup(pf, frame:pFRAMEHIST):TIME;
PROCEDURE savetrack;
PROCEDURE makemsg(ack:BOOLEAN);
PROCEDURE deltxmsg(cmd, n:CARDINAL);
PROCEDURE acknumstr(VAR aa:ARRAY OF CHAR; n:CARDINAL);
PROCEDURE getactack(call:MONCALL; VAR ack:ARRAY OF CHAR);
PROCEDURE objsender(op:pOPHIST; VAR s:ARRAY OF CHAR);
PROCEDURE selop():pOPHIST;
PROCEDURE tcpconnstat(VAR s:ARRAY OF CHAR);
PROCEDURE udpconnstat(port:CARDINAL; VAR s:ARRAY OF CHAR);
PROCEDURE beeplim(lev:INTEGER; hz:CARDINAL; ms:CARDINAL);
PROCEDURE importbeacon;
PROCEDURE extractbeacon(raw:ARRAY OF CHAR; withparm, macros:BOOLEAN);
PROCEDURE getbeaconname(raw:ARRAY OF CHAR; VAR name:ARRAY OF CHAR; VAR symb:ARRAY OF CHAR;
                        VAR isobj, isdel, isbad:BOOLEAN);
PROCEDURE drawbeacon(raw:ARRAY OF CHAR);
PROCEDURE makelogfn(VAR s:ARRAY OF CHAR);
(*
PROCEDURE checksymb(symt, symb:CHAR):BOOLEAN;          (* true for bad symbol *)
*)
PROCEDURE appendmultiline(pos:POSITION);
PROCEDURE GetMultiline(buf:ARRAY OF CHAR; VAR delfrom:CARDINAL; VAR md:MULTILINE);
PROCEDURE ismultiline(editing:BOOLEAN):BOOLEAN;
PROCEDURE modmultiline(n:CARDINAL);
PROCEDURE Stopticker;
PROCEDURE Watchclock(VAR t:TIME; intervall:TIME):BOOLEAN;

END aprsdecode.
