/* Generated by XDS Modula-2 to ANSI C v4.20 translator */ #define X2C_int32 #define X2C_index32 #ifndef X2C_H_ #include "X2C.h" #endif #define udpflex_C_ #ifndef aprsstr_H_ #include "aprsstr.h" #endif #ifndef osi_H_ #include "osi.h" #endif #include "Windows.h" #ifndef TimeConv_H_ #include "TimeConv.h" #endif /* interface rmnc-flex-kiss <> axudp by oe5dxl */ #define udpflex_DEFTTY "com1" #define udpflex_SLEEPWINLOOP 20 /* win poll data loop ms */ #define udpflex_SLEEPCONNTCP 2000 /* wait before new tcp network kiss connect ms */ enum MODE {udpflex_KISS, udpflex_FLEXKISS, udpflex_SMACK}; static X2C_CARD16 udpflex_POLYNOM[256] = {3975U,7694U,11413U,15644U,18851U, 22570U,27313U,31544U,33743U,37446U,41181U,45396U,50667U, 54370U,59129U,63344U,7942U,3727U,15380U,11677U,22818U,18603U, 31280U,27577U,37710U,33479U,45148U,41429U,54634U,50403U, 63096U,59377U,11909U,16140U,3479U,7198U,26785U,31016U,19379U, 23098U,41677U,45892U,33247U,36950U,58601U,62816U,51195U, 54898U,15876U,12173U,7446U,3231U,30752U,27049U,23346U,19131U, 45644U,41925U,37214U,32983U,62568U,58849U,55162U,50931U, 19843U,23562U,28305U,32536U,2983U,6702U,10421U,14652U,49611U, 53314U,58073U,62288U,34799U,38502U,42237U,46452U,23810U, 19595U,32272U,28569U,6950U,2735U,14388U,10685U,53578U,49347U, 62040U,58321U,38766U,34535U,46204U,42485U,27777U,32008U, 20371U,24090U,10917U,15148U,2487U,6206U,57545U,61760U,50139U, 53842U,42733U,46948U,34303U,38006U,31744U,28041U,24338U, 20123U,14884U,11181U,6454U,2239U,61512U,57793U,54106U,49875U, 46700U,42981U,38270U,34039U,35727U,39430U,43165U,47380U, 52651U,56354U,61113U,65328U,1991U,5710U,9429U,13660U,16867U, 20586U,25329U,29560U,39694U,35463U,47132U,43413U,56618U, 52387U,65080U,61361U,5958U,1743U,13396U,9693U,20834U,16619U, 29296U,25593U,43661U,47876U,35231U,38934U,60585U,64800U, 53179U,56882U,9925U,14156U,1495U,5214U,24801U,29032U,17395U, 21114U,47628U,43909U,39198U,34967U,64552U,60833U,57146U, 52915U,13892U,10189U,5462U,1247U,28768U,25065U,21362U,17147U, 51595U,55298U,60057U,64272U,36783U,40486U,44221U,48436U, 17859U,21578U,26321U,30552U,999U,4718U,8437U,12668U,55562U, 51331U,64024U,60305U,40750U,36519U,48188U,44469U,21826U, 17611U,30288U,26585U,4966U,751U,12404U,8701U,59529U,63744U, 52123U,55826U,44717U,48932U,36287U,39990U,25793U,30024U, 18387U,22106U,8933U,13164U,503U,4222U,63496U,59777U,56090U, 51859U,48684U,44965U,40254U,36023U,29760U,26057U,22354U, 18139U,12900U,9197U,4470U,255U}; static X2C_CARD16 udpflex_SMACKCRC[256] = {0U,49345U,49537U,320U,49921U,960U, 640U,49729U,50689U,1728U,1920U,51009U,1280U,50625U,50305U, 1088U,52225U,3264U,3456U,52545U,3840U,53185U,52865U,3648U, 2560U,51905U,52097U,2880U,51457U,2496U,2176U,51265U,55297U, 6336U,6528U,55617U,6912U,56257U,55937U,6720U,7680U,57025U, 57217U,8000U,56577U,7616U,7296U,56385U,5120U,54465U,54657U, 5440U,55041U,6080U,5760U,54849U,53761U,4800U,4992U,54081U, 4352U,53697U,53377U,4160U,61441U,12480U,12672U,61761U,13056U, 62401U,62081U,12864U,13824U,63169U,63361U,14144U,62721U, 13760U,13440U,62529U,15360U,64705U,64897U,15680U,65281U, 16320U,16000U,65089U,64001U,15040U,15232U,64321U,14592U, 63937U,63617U,14400U,10240U,59585U,59777U,10560U,60161U, 11200U,10880U,59969U,60929U,11968U,12160U,61249U,11520U, 60865U,60545U,11328U,58369U,9408U,9600U,58689U,9984U,59329U, 59009U,9792U,8704U,58049U,58241U,9024U,57601U,8640U,8320U, 57409U,40961U,24768U,24960U,41281U,25344U,41921U,41601U, 25152U,26112U,42689U,42881U,26432U,42241U,26048U,25728U, 42049U,27648U,44225U,44417U,27968U,44801U,28608U,28288U, 44609U,43521U,27328U,27520U,43841U,26880U,43457U,43137U, 26688U,30720U,47297U,47489U,31040U,47873U,31680U,31360U, 47681U,48641U,32448U,32640U,48961U,32000U,48577U,48257U, 31808U,46081U,29888U,30080U,46401U,30464U,47041U,46721U, 30272U,29184U,45761U,45953U,29504U,45313U,29120U,28800U, 45121U,20480U,37057U,37249U,20800U,37633U,21440U,21120U, 37441U,38401U,22208U,22400U,38721U,21760U,38337U,38017U, 21568U,39937U,23744U,23936U,40257U,24320U,40897U,40577U, 24128U,23040U,39617U,39809U,23360U,39169U,22976U,22656U, 38977U,34817U,18624U,18816U,35137U,19200U,35777U,35457U, 19008U,19968U,36545U,36737U,20288U,36097U,19904U,19584U, 35905U,17408U,33985U,34177U,17728U,34561U,18368U,18048U, 34369U,33281U,17088U,17280U,33601U,16640U,33217U,32897U, 16448U}; #define udpflex_FEND 192 #define udpflex_FESC 219 #define udpflex_TFEND 220 #define udpflex_TFESC 221 static X2C_CHAR udpflex_FLEXKISSBYTE = ' '; static X2C_CHAR udpflex_SMACKBYTE = '\200'; #define udpflex_ESC "\033" #define udpflex_CR "\015" #define udpflex_DEFAULTPORT "8001" static X2C_CARD8 CRCL[256]; static X2C_CARD8 CRCH[256]; static X2C_CHAR ifn[701]; static X2C_CHAR ubuf[701]; static X2C_CHAR tbuf[701]; static X2C_CHAR kbuf[701]; static X2C_CHAR ttynamee[701]; static X2C_CARD32 inilen; static X2C_CARD32 kissm; static X2C_CARD32 baud; static X2C_CARD32 fend; static X2C_CARD8 flexmod; struct _0; struct _0 { unsigned sock; X2C_CARD32 ipnum; X2C_CARD32 fromport; X2C_CARD32 toport; X2C_BOOLEAN anyip; }; static struct _0 udpsocks[8]; static HANDLE tty; static X2C_CARD32 dlen; static X2C_BOOLEAN void0; static X2C_CARD32 sleepwinloop; static X2C_INT32 len; static X2C_INT32 rp; static X2C_INT32 upos; static X2C_INT32 tpos; static X2C_INT32 i; static X2C_CHAR c; static X2C_BOOLEAN auto0; static X2C_BOOLEAN verb; static X2C_BOOLEAN hexdump; static X2C_BOOLEAN kisson; static X2C_BOOLEAN usbrobust; static X2C_BOOLEAN direwolf; static X2C_BOOLEAN direwolfserver; static X2C_CARD32 errtime; static unsigned tcplistenfd; static unsigned tcpfd; static X2C_CHAR direwolfurl[2048]; static X2C_CHAR direwolfport[11]; static void Error(X2C_CHAR text[], X2C_CARD32 text_len) { X2C_PCOPY((void **)&text,text_len); osi_WrStr("udpflex: ", 10ul); osi_WrStr(text, text_len); osi_WrStrLn(" error abort", 13ul); X2C_ABORT(); X2C_PFREE(text); } /* end Error() */ static void initfile(X2C_CHAR fn[], X2C_CARD32 fn_len) { X2C_CHAR b[4001]; HANDLE fd; X2C_INT32 len0; X2C_CARD32 dlen0; X2C_PCOPY((void **)&fn,fn_len); if (fn[0UL]) { fd = osi_OpenRead(fn, fn_len); if (fd!=osi_InvalidFd) { len0 = osi_RdBin(fd, (X2C_LOC *)b, 4001u/1u, 4001UL); void0 = (X2C_BOOLEAN)WriteFile(tty, (LPCVOID)b, (X2C_CARD32)len0, &dlen0, 0); osi_Close(fd); } else Error("initfile not found", 19ul); } X2C_PFREE(fn); } /* end initfile() */ static void inittnc(void) { X2C_CARD32 dlen0; if (fend!=192UL) return; /* TAPR mode */ errtime = TimeConv_time(); initfile(ifn, 701ul); if (kisson) { strncpy(tbuf,"\015\033@K\015",701u); Sleep(500UL); void0 = (X2C_BOOLEAN)WriteFile(tty, (LPCVOID)tbuf, 5UL, &dlen0, 0); } if (inilen>0UL) { Sleep(500UL); void0 = (X2C_BOOLEAN)WriteFile(tty, (LPCVOID)kbuf, inilen, &dlen0, 0); Sleep(500UL); } if (verb) osi_WrStrLn("send init to tnc", 17ul); } /* end inittnc() */ static void opentty(void) { COMMTIMEOUTS CommTimeouts; DCB dcb; /* tty:=CreateFile(ttyname,); */ /* tty:=Create(ttyname); */ tty = CreateFileA(ttynamee, 0xC0000000UL, 0x1U, 0, OPEN_EXISTING, 0x80UL, 0); if ((verb || !usbrobust) && tty==0) Error("com open error", 15ul); if (tty) { if (GetCommState(tty, &dcb)) { /* WrInt(dcb.BaudRate, 10); WrStrLn(" baud"); */ /* WrInt(dcb.ByteSize, 10); WrStrLn(" bits"); */ /* WrInt(CAST(CARDINAL, dcb.Flags), 10); WrStrLn(" flags"); */ dcb.Parity = NOPARITY; dcb.ByteSize = 8U; dcb.BaudRate = baud; dcb.Flags = 0x1011U; void0 = (X2C_BOOLEAN)SetCommState(tty, &dcb); /* IF GetCommTimeouts (tty, CommTimeouts) THEN */ memset((X2C_ADDRESS) &CommTimeouts,(X2C_LOC)0,sizeof(COMMTIMEOUTS)); CommTimeouts.ReadIntervalTimeout = X2C_max_longcard; void0 = (X2C_BOOLEAN)SetCommTimeouts(tty, &CommTimeouts); } else { if (!usbrobust) Error("com config", 11ul); if (verb) osi_WrStrLn("com config error", 17ul); } } } /* end opentty() */ static void testtty(X2C_INT32 len0) { DCB dcb; if (!GetCommState(tty, &dcb)) { CloseHandle(tty); Sleep(1000UL); opentty(); if (verb) osi_WrStrLn("tty reopen", 11ul); inittnc(); } } /* end testtty() */ #define udpflex_ERRWAIT 4 static void kisserr(void) { if (errtime+4UL='0' && (X2C_CARD8)h[*p]<='9') { *n = ( *n*10UL+(X2C_CARD32)(X2C_CARD8)h[*p])-48UL; ++*p; } return h[*p]==eot; } /* end GetNum() */ static void app(X2C_CARD32 c0, X2C_BOOLEAN esc) { if (esc) { if (c0==192UL) { kbuf[inilen] = '\333'; ++inilen; c0 = 220UL; } else if (c0==219UL) { kbuf[inilen] = '\333'; ++inilen; c0 = 221UL; } } kbuf[inilen] = (X2C_CHAR)c0; ++inilen; } /* end app() */ static void urlport(X2C_CHAR url[], X2C_CARD32 url_len, X2C_CHAR port[], X2C_CARD32 port_len, X2C_CHAR s[], X2C_CARD32 s_len) { X2C_INT32 ii; X2C_INT32 i0; X2C_PCOPY((void **)&s,s_len); s[s_len-1] = 0; if (s[0UL]=='[') { ii = 1L; while (s[ii] && s[ii]!=']') ++ii; if (s[ii]!=']' || s[ii+1L]!=':') Error("-g [url]:port", 14ul); s[ii] = 0; i0 = 1L; while (i0<=(X2C_INT32)(s_len-1)) { s[i0-1L] = s[i0]; ++i0; } } else ii = aprsstr_InStr(s, s_len, ":", 2ul); if (ii>=0L) s[ii] = 0; if (ii==0L) aprsstr_Assign(url, url_len, "127.0.0.1", 10ul); else aprsstr_Assign(url, url_len, s, s_len); port[0UL] = 0; if (ii>=0L) { /* port number */ ++ii; i0 = 0L; while (ii<=(X2C_INT32)(s_len-1) && i0<(X2C_INT32)(port_len-1)) { port[i0] = s[ii]; ++i0; ++ii; } port[i0] = 0; } if (port[0UL]==0) aprsstr_Assign(port, port_len, "8001", 5ul); X2C_PFREE(s); } /* end urlport() */ static void Parms(void) { X2C_BOOLEAN err; X2C_CHAR h[1024]; X2C_CARD32 sockc; X2C_CARD32 val; X2C_CARD32 cmd; X2C_CARD32 i0; struct _0 * anonym; err = 0; sockc = 0UL; for (;;) { osi_NextArg(h, 1024ul); if (h[0U]==0) break; if ((h[0U]=='-' && h[1U]) && h[2U]==0) { if (h[1U]=='c') { } else if (h[1U]=='r') { /* dummy for compatibility */ flexmod = udpflex_FLEXKISS; /* RMNC crc type */ } else if (h[1U]=='s') flexmod = udpflex_SMACK; else if (h[1U]=='a') { auto0 = 1; if (sockc>1UL) Error("-a only with 1 UDP socket, ", 28ul); } else if (h[1U]=='A') { auto0 = 0; fend = 13UL; if (sockc>1UL) Error("-A only with 1 UDP socket, ", 28ul); } else if (h[1U]=='k') kisson = 1; else if (h[1U]=='p') { osi_NextArg(h, 1024ul); i0 = 0UL; if (!GetNum(h, 1024ul, ':', &i0, &cmd)) { Error("-p cmd:value", 13ul); } ++i0; if (!GetNum(h, 1024ul, 0, &i0, &val)) { Error("-p cmd:value", 13ul); } app(192UL, 0); app(cmd, 1); app(val, 1); app(192UL, 0); } else if (h[1U]=='U') { if (auto0 && sockc>0UL) { Error("-U only 1 UDP with -a Mode", 27ul); } osi_NextArg(h, 1024ul); { /* with */ struct _0 * anonym = &udpsocks[sockc]; if (aprsstr_GetIp2(h, 1024ul, &anonym->ipnum, &anonym->toport, &anonym->fromport, &anonym->anyip)<0L) { Error("-U wrong ip:port:port number", 29ul); } anonym->sock = osi_openudp(); if (anonym->sock<0U || osi_bindudp(anonym->sock, anonym->fromport)<0L) { /* say with port */ Error("-U cannot open udp socket", 26ul); } } ++sockc; } else if (h[1U]=='u') usbrobust = 1; else if (h[1U]=='t') { osi_NextArg(h, 1024ul); i0 = 0UL; while ((h[i0] && h[i0]!=':') && i0<700UL) { ttynamee[i0] = h[i0]; ++i0; } ttynamee[i0] = 0; if (h[i0]) { ++i0; if (!GetNum(h, 1024ul, 0, &i0, &baud)) { Error("need ttydevice:baud", 20ul); } } } else if (h[1U]=='T') { osi_NextArg(h, 1024ul); urlport(direwolfurl, 2048ul, direwolfport, 11ul, h, 1024ul); direwolf = 1; direwolfserver = aprsstr_StrCmp(direwolfurl, 2048ul, "0.0.0.0", 8ul); } else if (h[1U]=='v') verb = 1; else if (h[1U]=='V') { verb = 1; hexdump = 1; } else if (h[1U]=='W') { osi_NextArg(h, 1024ul); i0 = 0UL; if (!GetNum(h, 1024ul, 0, &i0, &sleepwinloop) || i0==0UL) { Error("-W ", 18ul); } } else { if (h[1U]=='h') { osi_WrLn(); osi_WrStrLn("bidirectional AXUDP <-> KISS/SMACK(tty/com/pipe) \ or TCP-KISS(dire-wolf) Interface", 82ul); osi_WrLn(); osi_WrStrLn(" -A ASCII (TAPR) M\ ode", 53ul); osi_WrStrLn(" -a automatic swit\ ch to KISS/FLEX/SMACK mode", 76ul); osi_WrStrLn(" (only with 1 P\ ort)", 54ul); osi_WrStrLn(" -h this", 40ul); osi_WrStrLn(" -i send this file\ to tty to switch on kiss", 75ul); osi_WrStrLn(" -k tnc2 tf switch\ on kiss", 58ul); osi_WrStrLn(" -p : tnc2 parameter\ 1=txd, 2=p", 61ul); osi_WrStrLn(" 3=slottime, 25\ 5:13 kiss exit", 64ul); osi_WrStrLn(" (add 16, 32 ..\ . to cmd for next Port)", 73ul); osi_WrStrLn(" -r use rmnc-crc", 48ul); osi_WrStrLn(" -s SMACK (crc) on\ ", 50ul); osi_WrStrLn(" -t : com1:9600 or P\ ipe Filename", 62ul); osi_WrStrLn(" -T [ip]:[port] TCP-KISS -T 12\ 7.0.0.1:8001 (default)", 72ul); osi_WrStrLn(" local dire-wol\ f soundmodem -T :", 67ul); osi_WrStrLn(" -U axudp \"ip:des\ tport/listenport\" to check ipnum", 81ul); osi_WrStrLn(" (repeat for mo\ re Ports)", 59ul); osi_WrStrLn(" -u retry until (r\ e)pluged (USB) tty", 68ul); osi_WrStrLn(" and on kiss er\ ror reinitialize kiss mode", 76ul); osi_WrStrLn(" -v verbous error \ messages", 58ul); osi_WrStrLn(" -V verbous errors\ and monitor data to stdout", 77ul); osi_WrLn(); X2C_ABORT(); } if (h[1U]=='i') osi_NextArg(ifn, 701ul); else err = 1; } } else { /* h[0]:=0C; */ err = 1; } if (err) break; } if (flexmod==udpflex_FLEXKISS && sockc>1UL) { Error("only 1 UDP with flexnet", 24ul); } if (err) { osi_WrStr(">", 2ul); osi_WrStr(h, 1024ul); osi_WrStrLn("< use -h", 9ul); X2C_ABORT(); } } /* end Parms() */ #define udpflex_POLINOM 0x8408 static void Gencrctab(void) { X2C_CARD32 c0; X2C_CARD32 crc0; X2C_CARD32 i0; for (c0 = 0UL; c0<=255UL; c0++) { crc0 = 255UL-c0; for (i0 = 0UL; i0<=7UL; i0++) { if ((crc0&1)) crc0 = (X2C_CARD32)((X2C_CARD32)(crc0>>1)^0x8408UL); else crc0 = crc0>>1; } /* end for */ CRCL[c0] = (X2C_CARD8)crc0; CRCH[c0] = (X2C_CARD8)(255UL-(crc0>>8)); } /* end for */ } /* end Gencrctab() */ static X2C_CARD32 UDPCRC(const X2C_CHAR frame[], X2C_CARD32 frame_len, X2C_INT32 size) { X2C_CARD8 h; X2C_CARD8 l; X2C_CARD8 b; X2C_INT32 i0; X2C_INT32 tmp; l = 0U; h = 0U; tmp = size-1L; i0 = 0L; if (i0<=tmp) for (;; i0++) { b = (X2C_CARD8)((X2C_CARD8)(X2C_CARD8)frame[i0]^l); l = CRCL[b]^h; h = CRCH[b]; if (i0==tmp) break; } /* end for */ return (X2C_CARD32)(X2C_CARD8)(X2C_CHAR)l+256UL*(X2C_CARD32)(X2C_CARD8) (X2C_CHAR)h; } /* end UDPCRC() */ static X2C_CARD16 _cnst[256] = {3975U,7694U,11413U,15644U,18851U,22570U, 27313U,31544U,33743U,37446U,41181U,45396U,50667U,54370U, 59129U,63344U,7942U,3727U,15380U,11677U,22818U,18603U,31280U, 27577U,37710U,33479U,45148U,41429U,54634U,50403U,63096U, 59377U,11909U,16140U,3479U,7198U,26785U,31016U,19379U,23098U, 41677U,45892U,33247U,36950U,58601U,62816U,51195U,54898U, 15876U,12173U,7446U,3231U,30752U,27049U,23346U,19131U,45644U, 41925U,37214U,32983U,62568U,58849U,55162U,50931U,19843U, 23562U,28305U,32536U,2983U,6702U,10421U,14652U,49611U,53314U, 58073U,62288U,34799U,38502U,42237U,46452U,23810U,19595U, 32272U,28569U,6950U,2735U,14388U,10685U,53578U,49347U,62040U, 58321U,38766U,34535U,46204U,42485U,27777U,32008U,20371U, 24090U,10917U,15148U,2487U,6206U,57545U,61760U,50139U,53842U, 42733U,46948U,34303U,38006U,31744U,28041U,24338U,20123U, 14884U,11181U,6454U,2239U,61512U,57793U,54106U,49875U,46700U, 42981U,38270U,34039U,35727U,39430U,43165U,47380U,52651U, 56354U,61113U,65328U,1991U,5710U,9429U,13660U,16867U,20586U, 25329U,29560U,39694U,35463U,47132U,43413U,56618U,52387U, 65080U,61361U,5958U,1743U,13396U,9693U,20834U,16619U,29296U, 25593U,43661U,47876U,35231U,38934U,60585U,64800U,53179U, 56882U,9925U,14156U,1495U,5214U,24801U,29032U,17395U,21114U, 47628U,43909U,39198U,34967U,64552U,60833U,57146U,52915U, 13892U,10189U,5462U,1247U,28768U,25065U,21362U,17147U,51595U, 55298U,60057U,64272U,36783U,40486U,44221U,48436U,17859U, 21578U,26321U,30552U,999U,4718U,8437U,12668U,55562U,51331U, 64024U,60305U,40750U,36519U,48188U,44469U,21826U,17611U, 30288U,26585U,4966U,751U,12404U,8701U,59529U,63744U,52123U, 55826U,44717U,48932U,36287U,39990U,25793U,30024U,18387U, 22106U,8933U,13164U,503U,4222U,63496U,59777U,56090U,51859U, 48684U,44965U,40254U,36023U,29760U,26057U,22354U,18139U, 12900U,9197U,4470U,255U}; static X2C_CARD32 flexcrc(const X2C_CHAR buf[], X2C_CARD32 buf_len, X2C_CARD32 a, X2C_CARD32 b) { X2C_CARD16 crc0; crc0 = 0xFFFFU; while (a<=b) { crc0 = X2C_LSH(crc0,16,8)^(X2C_CARD16)_cnst[(X2C_CARD32)(X2C_LSH(crc0, 16,-8)^(X2C_CARD16)(X2C_CARD32)(X2C_CARD8)buf[a])]; ++a; } return (X2C_CARD32)crc0; } /* end flexcrc() */ static X2C_CARD16 _cnst0[256] = {0U,49345U,49537U,320U,49921U,960U,640U, 49729U,50689U,1728U,1920U,51009U,1280U,50625U,50305U,1088U, 52225U,3264U,3456U,52545U,3840U,53185U,52865U,3648U,2560U, 51905U,52097U,2880U,51457U,2496U,2176U,51265U,55297U,6336U, 6528U,55617U,6912U,56257U,55937U,6720U,7680U,57025U,57217U, 8000U,56577U,7616U,7296U,56385U,5120U,54465U,54657U,5440U, 55041U,6080U,5760U,54849U,53761U,4800U,4992U,54081U,4352U, 53697U,53377U,4160U,61441U,12480U,12672U,61761U,13056U, 62401U,62081U,12864U,13824U,63169U,63361U,14144U,62721U, 13760U,13440U,62529U,15360U,64705U,64897U,15680U,65281U, 16320U,16000U,65089U,64001U,15040U,15232U,64321U,14592U, 63937U,63617U,14400U,10240U,59585U,59777U,10560U,60161U, 11200U,10880U,59969U,60929U,11968U,12160U,61249U,11520U, 60865U,60545U,11328U,58369U,9408U,9600U,58689U,9984U,59329U, 59009U,9792U,8704U,58049U,58241U,9024U,57601U,8640U,8320U, 57409U,40961U,24768U,24960U,41281U,25344U,41921U,41601U, 25152U,26112U,42689U,42881U,26432U,42241U,26048U,25728U, 42049U,27648U,44225U,44417U,27968U,44801U,28608U,28288U, 44609U,43521U,27328U,27520U,43841U,26880U,43457U,43137U, 26688U,30720U,47297U,47489U,31040U,47873U,31680U,31360U, 47681U,48641U,32448U,32640U,48961U,32000U,48577U,48257U, 31808U,46081U,29888U,30080U,46401U,30464U,47041U,46721U, 30272U,29184U,45761U,45953U,29504U,45313U,29120U,28800U, 45121U,20480U,37057U,37249U,20800U,37633U,21440U,21120U, 37441U,38401U,22208U,22400U,38721U,21760U,38337U,38017U, 21568U,39937U,23744U,23936U,40257U,24320U,40897U,40577U, 24128U,23040U,39617U,39809U,23360U,39169U,22976U,22656U, 38977U,34817U,18624U,18816U,35137U,19200U,35777U,35457U, 19008U,19968U,36545U,36737U,20288U,36097U,19904U,19584U, 35905U,17408U,33985U,34177U,17728U,34561U,18368U,18048U, 34369U,33281U,17088U,17280U,33601U,16640U,33217U,32897U, 16448U}; static X2C_CARD32 smackcrc(const X2C_CHAR buf[], X2C_CARD32 buf_len, X2C_CARD32 a, X2C_CARD32 b) { X2C_CARD16 crc0; crc0 = 0U; while (a<=b) { /* crc = ((crc >> 8) & 0xff) ^ crc_table[(crc ^ *buf++) & 0xff]; */ crc0 = X2C_LSH(crc0,16,-8)^(X2C_CARD16)_cnst0[(X2C_CARD32)((crc0^(X2C_CARD16)(X2C_CARD32)(X2C_CARD8)buf[a])&0xFFU)]; ++a; } /*WrHex(CAST(CARDINAL, crc) DIV 256, 3); WrHex(CAST(CARDINAL, crc) MOD 256, 3); WrStrLn("=crc"); */ return (X2C_CARD32)(X2C_LSH(crc0,16,-8)|X2C_LSH(crc0&0xFFU,16,8)); } /* end smackcrc() */ static void sendudp(X2C_CHAR buf[], X2C_CARD32 buf_len, X2C_INT32 len0, X2C_CARD32 port) { X2C_INT32 i0; X2C_CARD32 crc0; struct _0 * anonym; X2C_PCOPY((void **)&buf,buf_len); crc0 = UDPCRC(buf, buf_len, len0); buf[len0] = (X2C_CHAR)(crc0&255UL); buf[len0+1L] = (X2C_CHAR)(crc0/256UL); { /* with */ struct _0 * anonym = &udpsocks[port]; if (anonym->sock>=0U) { i0 = osi_udpsend((X2C_INT32)anonym->sock, buf, buf_len, len0+2L, anonym->toport, anonym->ipnum); } } X2C_PFREE(buf); /* FOR i:=0 TO upos-2 DO IO.WrHex(ORD(buf[i]), 3) END; WrLn; */ } /* end sendudp() */ static X2C_INT32 getudp(X2C_INT32 fd, X2C_CHAR buf[], X2C_CARD32 buf_len, X2C_CARD32 inip, X2C_BOOLEAN any) { X2C_CARD32 fromport; X2C_CARD32 ip; X2C_INT32 len0; X2C_CHAR udp2[100]; len0 = osi_udpreceive((unsigned)fd, buf, buf_len, (X2C_INT32)(buf_len), &fromport, &ip); if (len0==-1L) return 0L; if ((len0<=2L || len0>=(X2C_INT32)(buf_len)) || any && inip!=ip) { return -1L; } if ((X2C_CARD32)(X2C_CARD8)buf[len0-2L]+256UL*(X2C_CARD32)(X2C_CARD8) buf[len0-1L]!=UDPCRC(buf, buf_len, len0-2L)) return -2L; if (buf[0UL]=='\001') aprsstr_extrudp2(buf, buf_len, udp2, 100ul, &len0); return len0; } /* end getudp() */ static void conntcp(unsigned * fd, X2C_CHAR url[], X2C_CARD32 url_len, X2C_CHAR port[], X2C_CARD32 port_len) { X2C_INT32 res; X2C_PCOPY((void **)&url,url_len); X2C_PCOPY((void **)&port,port_len); *fd = osi_connectto(url, url_len, port, port_len); if ((X2C_INT32)*fd>=0L) res = osi_socknonblock(*fd); X2C_PFREE(url); X2C_PFREE(port); } /* end conntcp() */ static void WCh(X2C_CHAR c0) { if (c0!='\015') { if ((X2C_CARD8)c0<' ' || (X2C_CARD8)c0>='\177') osi_WrStr(".", 2ul); else osi_WrStr((X2C_CHAR *) &c0, 1u/1u); } } /* end WCh() */ static void ShowCall(X2C_CHAR f[], X2C_CARD32 f_len, X2C_CARD32 pos) { X2C_CARD32 e; X2C_CARD32 i0; X2C_CARD32 tmp; X2C_CHAR tmp0; e = pos; tmp = pos+5UL; i0 = pos; if (i0<=tmp) for (;; i0++) { if (f[i0]!='@') e = i0; if (i0==tmp) break; } /* end for */ tmp = e; i0 = pos; if (i0<=tmp) for (;; i0++) { WCh((X2C_CHAR)((X2C_CARD32)(X2C_CARD8)f[i0]>>1)); if (i0==tmp) break; } /* end for */ i0 = (X2C_CARD32)(X2C_CARD8)f[pos+6UL]>>1&15UL; if (i0) { osi_WrStr("-", 2ul); if (i0>=10UL) { osi_WrStr((X2C_CHAR *)(tmp0 = (X2C_CHAR)(i0/10UL+48UL),&tmp0), 1u/1u); } osi_WrStr((X2C_CHAR *)(tmp0 = (X2C_CHAR)(i0%10UL+48UL),&tmp0), 1u/1u); } } /* end ShowCall() */ static X2C_CARD32 udpflex_UA = 0x63UL; static X2C_CARD32 udpflex_DM = 0xFUL; static X2C_CARD32 udpflex_SABM = 0x2FUL; static X2C_CARD32 udpflex_DISC = 0x43UL; static X2C_CARD32 udpflex_FRMR = 0x87UL; static X2C_CARD32 udpflex_UI = 0x3UL; static X2C_CARD32 udpflex_RR = 0x1UL; static X2C_CARD32 udpflex_REJ = 0x9UL; static X2C_CARD32 udpflex_RNR = 0x5UL; static void Showctl(X2C_CARD32 com, X2C_CARD32 cmd) { X2C_CARD32 cm; X2C_CHAR PF[4]; X2C_CHAR tmp; osi_WrStr(" ctl ", 6ul); cm = (X2C_CARD32)cmd&~0x10UL; if ((cm&0xFUL)==0x1UL) { osi_WrStr("RR", 3ul); osi_WrStr((X2C_CHAR *)(tmp = (X2C_CHAR)(48UL+(cmd>>5)),&tmp), 1u/1u); } else if ((cm&0xFUL)==0x5UL) { osi_WrStr("RNR", 4ul); osi_WrStr((X2C_CHAR *)(tmp = (X2C_CHAR)(48UL+(cmd>>5)),&tmp), 1u/1u); } else if ((cm&0xFUL)==0x9UL) { osi_WrStr("REJ", 4ul); osi_WrStr((X2C_CHAR *)(tmp = (X2C_CHAR)(48UL+(cmd>>5)),&tmp), 1u/1u); } else if ((cm&0x1UL)==0UL) { osi_WrStr("I", 2ul); osi_WrStr((X2C_CHAR *)(tmp = (X2C_CHAR)(48UL+(cmd>>5)),&tmp), 1u/1u); osi_WrStr((X2C_CHAR *)(tmp = (X2C_CHAR)(48UL+(cmd>>1&7UL)),&tmp), 1u/1u); } else if (cm==0x3UL) osi_WrStr("UI", 3ul); else if (cm==0xFUL) osi_WrStr("DM", 3ul); else if (cm==0x2FUL) osi_WrStr("SABM", 5ul); else if (cm==0x43UL) osi_WrStr("DISC", 5ul); else if (cm==0x63UL) osi_WrStr("UA", 3ul); else if (cm==0x87UL) osi_WrStr("FRMR", 5ul); else osi_WrHex(cmd, 1UL); strncpy(PF,"v^-+",4u); if (com==0UL || com==3UL) osi_WrStr("v1", 3ul); else { osi_WrStr((X2C_CHAR *) &PF[(com&1UL)+2UL*(X2C_CARD32) ((0x10UL & (X2C_CARD32)cmd)!=0)], 1u/1u); } } /* end Showctl() */ static void ShowFrame(X2C_CHAR f[], X2C_CARD32 f_len, X2C_CARD32 len0, X2C_CHAR port) { X2C_CARD32 i0; X2C_BOOLEAN d; X2C_BOOLEAN v; osi_WrStr((X2C_CHAR *) &port, 1u/1u); i0 = 0UL; while (!((X2C_CARD32)(X2C_CARD8)f[i0]&1)) { ++i0; if (i0>len0) { osi_WrStrLn(" no axudp (no address end mark)", 32ul); return; } } /* no address end mark found */ if (i0%7UL!=6UL) { osi_WrStrLn(" no axudp (address field size not modulo 7)", 44ul); return; } /* address end not modulo 7 error */ osi_WrStr(":fm ", 5ul); ShowCall(f, f_len, 7UL); osi_WrStr(" to ", 5ul); ShowCall(f, f_len, 0UL); i0 = 14UL; v = 1; while (i0+6UL=128UL && (((X2C_CARD32) (X2C_CARD8)f[i0+6UL]&1) || (X2C_CARD32)(X2C_CARD8) f[i0+13UL]<128UL)) osi_WrStr("*", 2ul); i0 += 7UL; } Showctl((X2C_CARD32)((0x80U & (X2C_CARD8)(X2C_CARD8)f[6UL])!=0) +2UL*(X2C_CARD32)((0x80U & (X2C_CARD8)(X2C_CARD8)f[13UL])!=0) , (X2C_CARD32)(X2C_CARD8)f[i0]); ++i0; if (i0=2L) *len0 -= 2L; X2C_PFREE(t); } /* end tapr2u() */ static void disctcp(unsigned * fd) { osi_CloseSock(*fd); *fd = X2C_max_longcard; Sleep(2000UL); } /* end disctcp() */ static X2C_CARD32 tncport; static X2C_CARD32 crc; /*testloop:CARDINAL; */ static aprsstr_GHOSTSET _cnst1 = {0x00000000UL,0x00000000UL,0x00000000UL, 0x00000000UL,0x00000000UL,0x00000000UL,0x00000000UL, 0x00000000UL,0x00000000UL}; X2C_STACK_LIMIT(100000l) extern int main(int argc, char **argv) { X2C_INT32 tmp; X2C_INT32 tmp0; X2C_BEGIN(&argc,argv,1,2000000l,4000000l); osi_BEGIN(); aprsstr_BEGIN(); osi_STDIO(1); sleepwinloop = 20UL; auto0 = 0; kisson = 0; verb = 0; hexdump = 0; flexmod = udpflex_KISS; usbrobust = 0; direwolf = 0; direwolfserver = 0; baud = 9600UL; ttynamee[0] = 0; ifn[0] = 0; tcpfd = X2C_max_longcard; tcplistenfd = X2C_max_longcard; for (tncport = 0UL; tncport<=7UL; tncport++) { udpsocks[tncport].sock = X2C_max_longcard; } /* end for */ inilen = 0UL; tty = osi_InvalidFd; fend = 192UL; Parms(); Gencrctab(); if (ttynamee[0U]) opentty(); /*IF udpsock<0 THEN Error("udpport open") END; */ /*WrInt(udpsock, 10); WrStrLn(" sock"); */ errtime = 0UL; upos = 0L; kissm = 0UL; if (fend!=192UL) kissm = 1UL; for (;;) { if (errtime==0UL) inittnc(); if (direwolf) { if ((X2C_INT32)tcpfd>=0L) { len = osi_readsock(tcpfd, tbuf, 701ul, 701L-i); if (len<0L) { disctcp(&tcpfd); len = 0L; } else if (len==0L && osi_sendsock(tcpfd, kbuf, 701ul, 0L)<0L) { /* send 0 byte test if connected */ disctcp(&tcpfd); } } else { /* disconnected */ len = 0L; if (verb) { osi_WrStr("connect ", 9ul); osi_WrStr(direwolfurl, 2048ul); osi_WrStr(":", 2ul); osi_WrStrLn(direwolfport, 11ul); } conntcp(&tcpfd, direwolfurl, 2048ul, direwolfport, 11ul); } } else { if (tty==osi_InvalidFd || !ReadFile(tty, (PVOID)tbuf, 701UL, &dlen, 0)) dlen = 0UL; len = (X2C_INT32)dlen; } Sleep(sleepwinloop); /*INC(testloop); */ /*IF testloop MOD 1000=0 THEN WrInt(testloop DIV 1000, 1); WrLn; END; */ if (!direwolf && usbrobust) testtty(len); /*WrInt(len, 5); WrLn; */ tmp = len-1L; rp = 0L; if (rp<=tmp) for (;; rp++) { c = tbuf[rp]; /*WrStr(c); */ if (kissm==0UL) { if (c==(X2C_CHAR)fend) { upos = 0L; kissm = 1UL; } else kisserr(); } else if (kissm==1UL) { if (c==(X2C_CHAR)fend) { if ((upos==0L || flexmod==udpflex_FLEXKISS) || fend!=192UL) { tncport = 0UL; } else tncport = (X2C_CARD32)(X2C_CARD8)ubuf[0U]/16UL&7UL; if (upos>4L) { if (auto0) { if (ubuf[0U]==' ') { if (verb && flexmod!=udpflex_FLEXKISS) { osi_WrStrLn("switching to FLEXKISS", 22ul); } flexmod = udpflex_FLEXKISS; } else if (ubuf[0U]=='\200') { if (verb && flexmod!=udpflex_SMACK) { osi_WrStrLn("switching to SMACK", 19ul); } flexmod = udpflex_SMACK; } else { if (verb && flexmod) { osi_WrStrLn("switching to KISS", 18ul); } flexmod = udpflex_KISS; } } if ((flexmod==udpflex_KISS || flexmod==udpflex_FLEXKISS && flexcrc(ubuf, 701ul, 0UL, (X2C_CARD32)(upos-1L))==28784UL) || flexmod==udpflex_SMACK && smackcrc(ubuf, 701ul, 0UL, (X2C_CARD32)(upos-1L))==0UL) { if (flexmod>udpflex_KISS) upos -= 2L; if (fend==192UL) { /* not TAPR */ c = ubuf[0U]; tmp0 = upos-2L; i = 0L; if (i<=tmp0) for (;; i++) { ubuf[i] = ubuf[i+1L]; /* remove port byte */ if (i==tmp0) break; } /* end for */ --upos; } else tapr2u(ubuf, 701ul, upos, ubuf, 701ul, &upos); if (upos>0L) { if (hexdump) { if (fend==192UL) { /* not TAPR */ if (flexmod==udpflex_FLEXKISS && c==' ') { osi_WrStr("FLEX", 5ul); } else if ((X2C_CARD8)c>=(X2C_CARD8)'\200') { osi_WrStr("SMACK", 6ul); } else osi_WrStr("KISS", 5ul); } else osi_WrStr("TAPR", 5ul); ShowFrame(ubuf, 701ul, (X2C_CARD32)upos, (X2C_CHAR)(tncport+48UL)); } sendudp(ubuf, 701ul, upos, tncport); } } else if (verb) osi_WrStrLn("serialport-crc error", 21ul); } /* FOR i:=0 TO upos-1 DO WrHex(ORD(ubuf[i]), 3) END; */ /* WrLn; */ upos = 0L; kissm = 1UL; } else if (c=='\333' && fend==192UL) kissm = 2UL; else if (upos<700L) { ubuf[upos] = c; ++upos; } else kisserr(); } else if (kissm==2UL) { if (c=='\334') c = '\300'; else if (c=='\335') c = '\333'; if (upos<700L) { ubuf[upos] = c; ++upos; } else kisserr(); kissm = 1UL; } if (rp==tmp) break; } /* end for */ for (tncport = 0UL; tncport<=7UL; tncport++) { if (udpsocks[tncport].sock!=X2C_max_longcard) { { /* with */ struct _0 * anonym = &udpsocks[tncport]; len = getudp((X2C_INT32)anonym->sock, ubuf, 701ul, anonym->ipnum, anonym->anyip); } if (len>=2L && len<698L) { if (hexdump) { osi_WrStr("UDP", 4ul); ShowFrame(ubuf, 701ul, (X2C_CARD32)(len-2L), (X2C_CHAR)(tncport+48UL)); } tpos = 0L; if (fend==192UL) { /* not TAPR */ for (i = len; i>=1L; i--) { ubuf[i] = ubuf[i-1L]; } /* end for */ if (flexmod==udpflex_FLEXKISS) ubuf[0U] = ' '; else if (flexmod==udpflex_SMACK) { ubuf[0U] = (X2C_CHAR)(128UL+16UL*tncport); } else ubuf[0U] = (X2C_CHAR)(16UL*tncport); --len; if (flexmod>udpflex_KISS) { if (flexmod==udpflex_FLEXKISS) { crc = flexcrc(ubuf, 701ul, 0UL, (X2C_CARD32)(len-1L)); } else { crc = smackcrc(ubuf, 701ul, 0UL, (X2C_CARD32)(len-1L)); } ubuf[len+1L] = (X2C_CHAR)(crc&255UL); ubuf[len] = (X2C_CHAR)(crc/256UL); len += 2L; } kbuf[0U] = '\300'; tpos = 1L; tmp = len-1L; rp = 0L; if (rp<=tmp) for (;; rp++) { c = ubuf[rp]; if (c=='\300') { kbuf[tpos] = '\333'; ++tpos; c = '\334'; } else if (c=='\333') { kbuf[tpos] = '\333'; ++tpos; c = '\335'; } kbuf[tpos] = c; ++tpos; if (rp==tmp) break; } /* end for */ kbuf[tpos] = '\300'; } else if (len>2L) { aprsstr_raw2mon(ubuf, 701ul, kbuf, 701ul, (X2C_CARD32)(len-2L), &crc, _cnst1); tpos = (X2C_INT32)aprsstr_Length(kbuf, 701ul); if (tpos>0L) kbuf[tpos] = '\015'; } else tpos = 0L; if (tpos>0L) { /* frame valid */ if (direwolf) { if ((X2C_INT32)tcpfd>=0L) { if (osi_sendsock(tcpfd, kbuf, 701ul, tpos+1L)<0L) { /* disconnected */ osi_CloseSock(tcpfd); tcpfd = X2C_max_longcard; } } } else if (tty!=osi_InvalidFd) { void0 = (X2C_BOOLEAN)WriteFile(tty, (LPCVOID)kbuf, (X2C_CARD32)(tpos+1L), &dlen, 0); } } } else if (verb) { if (len==-2L) osi_WrStrLn("axudp crc error", 16ul); else if (len==-1L) { osi_WrStrLn("axudp from wrong source ip", 27ul); } else if (len) osi_WrStrLn("axudp length error", 19ul); } } } /* end for */ } X2C_EXIT(); return 0; } X2C_MAIN_DEFINITION