kopia lustrzana https://github.com/sp9skp/spdxl
1961 wiersze
55 KiB
C
1961 wiersze
55 KiB
C
|
/*
|
||
|
* dxlAPRS toolchain
|
||
|
*
|
||
|
* Copyright (C) Christian Rabler <oe5dxl@oevsv.at>
|
||
|
*
|
||
|
* SPDX-License-Identifier: GPL-2.0+
|
||
|
*/
|
||
|
|
||
|
|
||
|
#define X2C_int32
|
||
|
#define X2C_index32
|
||
|
#ifndef X2C_H_
|
||
|
#include "X2C.h"
|
||
|
#endif
|
||
|
#define l2cat_C_
|
||
|
#ifndef Execlogin_H_
|
||
|
#include "Execlogin.h"
|
||
|
#endif
|
||
|
#include <unistd.h>
|
||
|
#include <signal.h>
|
||
|
#ifndef Select_H_
|
||
|
#include "Select.h"
|
||
|
#endif
|
||
|
#ifndef cleanup_H_
|
||
|
#include "cleanup.h"
|
||
|
#endif
|
||
|
#ifndef aprsstr_H_
|
||
|
#include "aprsstr.h"
|
||
|
#endif
|
||
|
#ifndef osi_H_
|
||
|
#include "osi.h"
|
||
|
#endif
|
||
|
#include <osic.h>
|
||
|
#ifndef mlib_H_
|
||
|
#include "mlib.h"
|
||
|
#endif
|
||
|
#ifndef udp_H_
|
||
|
#include "udp.h"
|
||
|
#endif
|
||
|
#ifndef l2_H_
|
||
|
#include "l2.h"
|
||
|
#endif
|
||
|
#ifndef frameio_H_
|
||
|
#include "frameio.h"
|
||
|
#endif
|
||
|
#ifndef deflate_H_
|
||
|
#include "deflate.h"
|
||
|
#endif
|
||
|
|
||
|
/* layer2 to std in/out or start a task*/
|
||
|
/*
|
||
|
FROM mlib IMPORT tcsetattr, tcgetattr, tcflag_t,
|
||
|
TCSAFLUSH, TIOCMGET, TIOCMBIS, TIOCMBIC, TCSANOW, ISIG,
|
||
|
CS8, CLOCAL, CREAD, CRTSCTS, B1200, B2400,
|
||
|
B4800, B9600, B19200, B38400, B57600, B115200, B230400,
|
||
|
B460800, TIOCM_CD, TIOCM_DTR, TIOCSCTTY;
|
||
|
*/
|
||
|
#define l2cat_MAXCMDWORDS 64
|
||
|
|
||
|
#define l2cat_NL "\012"
|
||
|
|
||
|
#define l2cat_PPPFLAG 0x7E
|
||
|
|
||
|
#define l2cat_PPPESC 0x7D
|
||
|
|
||
|
#define l2cat_LF "\012"
|
||
|
|
||
|
#define l2cat_LOOPTIME 10000
|
||
|
|
||
|
#define l2cat_MINRECONTIME 2000000
|
||
|
|
||
|
#define l2cat_MAXRECONTIME 120000000
|
||
|
|
||
|
#define l2cat_RCTIMEBASE 1000
|
||
|
|
||
|
typedef char IOBUF[256];
|
||
|
|
||
|
struct JUNKBUF;
|
||
|
|
||
|
|
||
|
struct JUNKBUF {
|
||
|
IOBUF buf;
|
||
|
int32_t len;
|
||
|
int32_t time0;
|
||
|
};
|
||
|
|
||
|
struct DEFLATBUF;
|
||
|
|
||
|
|
||
|
struct DEFLATBUF {
|
||
|
char outbuf[20001]; /* 20000 */
|
||
|
int32_t outlen;
|
||
|
char xoutbuf[4096];
|
||
|
char pppbuf[4096];
|
||
|
int32_t ppplen;
|
||
|
int32_t xoutlen;
|
||
|
int32_t inp0;
|
||
|
int32_t xinp;
|
||
|
char pppstate;
|
||
|
struct deflate_CONTEXT deflatcontext;
|
||
|
struct deflate_XCONTEXT expandcontext;
|
||
|
char done;
|
||
|
char pppframing;
|
||
|
};
|
||
|
|
||
|
struct TASK;
|
||
|
|
||
|
typedef struct TASK * pTASK;
|
||
|
|
||
|
|
||
|
struct TASK {
|
||
|
pTASK next;
|
||
|
IOBUF inbuf;
|
||
|
IOBUF outbuf;
|
||
|
int32_t inlen;
|
||
|
int32_t outlen;
|
||
|
struct JUNKBUF junkbuf;
|
||
|
struct l2_GETADRESS l2addr;
|
||
|
l2_pLINK link0;
|
||
|
uint16_t events;
|
||
|
int32_t infd;
|
||
|
int32_t outfd;
|
||
|
uint8_t state;
|
||
|
uint32_t crlfmode;
|
||
|
uint32_t detectdone;
|
||
|
uint32_t inignor;
|
||
|
struct DEFLATBUF * pcdeflat;
|
||
|
};
|
||
|
|
||
|
static char terminate;
|
||
|
|
||
|
static char keepconnected;
|
||
|
|
||
|
static char verb;
|
||
|
|
||
|
static char verb2;
|
||
|
|
||
|
static char usedeflat;
|
||
|
|
||
|
static char pppmode;
|
||
|
|
||
|
static char autodet;
|
||
|
|
||
|
static pTASK tasks;
|
||
|
|
||
|
static uint32_t sockc;
|
||
|
|
||
|
static uint32_t convlfcr;
|
||
|
|
||
|
static uint32_t convtopipe;
|
||
|
|
||
|
static uint32_t montyp;
|
||
|
|
||
|
static uint32_t recontime;
|
||
|
|
||
|
static uint32_t minrecontime;
|
||
|
|
||
|
static uint32_t maxrecontime;
|
||
|
|
||
|
static int32_t timesum;
|
||
|
|
||
|
static int32_t pppdiscard;
|
||
|
|
||
|
static char mycall[113];
|
||
|
|
||
|
static char cmdline[4096];
|
||
|
|
||
|
static char pipename[4096];
|
||
|
|
||
|
static char connectto0[256]; /* if active connect to this server */
|
||
|
|
||
|
static struct l2_PARMS0 parms;
|
||
|
|
||
|
struct _0;
|
||
|
|
||
|
|
||
|
struct _0 {
|
||
|
int32_t port;
|
||
|
int32_t parmnum;
|
||
|
int32_t val;
|
||
|
};
|
||
|
|
||
|
static struct _0 numpar[256];
|
||
|
|
||
|
static l2_pLINK pmon;
|
||
|
|
||
|
|
||
|
static void Error(char text[], uint32_t text_len)
|
||
|
{
|
||
|
X2C_PCOPY((void **)&text,text_len);
|
||
|
osi_Werr(text, text_len);
|
||
|
osi_Werr(" error abort\012", 14ul);
|
||
|
X2C_ABORT();
|
||
|
X2C_PFREE(text);
|
||
|
} /* end Error() */
|
||
|
|
||
|
#define l2cat_QUOT "\""
|
||
|
|
||
|
#define l2cat_SEP " "
|
||
|
|
||
|
|
||
|
static void NextArgs(char s[], uint32_t s_len)
|
||
|
{
|
||
|
char h[65536];
|
||
|
int32_t l;
|
||
|
s[0UL] = 0;
|
||
|
l = 0L;
|
||
|
do {
|
||
|
osi_NextArg(h, 65536ul);
|
||
|
if (l==0L) {
|
||
|
if (h[0U]=='\"') aprsstr_Delstr(h, 65536ul, 0UL, 1UL);
|
||
|
else {
|
||
|
aprsstr_Append(s, s_len, h, 65536ul);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
l = (int32_t)aprsstr_Length(h, 65536ul);
|
||
|
if (l==0L) return;
|
||
|
if (h[l-1L]=='\"') {
|
||
|
aprsstr_Delstr(h, 65536ul, (uint32_t)(l-1L), 1UL);
|
||
|
l = 0L;
|
||
|
}
|
||
|
aprsstr_Append(s, s_len, " ", 2ul);
|
||
|
aprsstr_Append(s, s_len, h, 65536ul);
|
||
|
} while (l);
|
||
|
} /* end NextArgs() */
|
||
|
|
||
|
|
||
|
static void Whex(char hd[], uint32_t hd_len, const char bu[],
|
||
|
uint32_t bu_len, int32_t len)
|
||
|
{
|
||
|
int32_t i0;
|
||
|
uint32_t b;
|
||
|
int32_t tmp;
|
||
|
char tmp0;
|
||
|
X2C_PCOPY((void **)&hd,hd_len);
|
||
|
osi_Werr(hd, hd_len);
|
||
|
tmp = len-1L;
|
||
|
i0 = 0L;
|
||
|
if (i0<=tmp) for (;; i0++) {
|
||
|
b = (uint32_t)(uint8_t)bu[i0]/16UL;
|
||
|
if (b>=10UL) {
|
||
|
osi_Werr((char *)(tmp0 = (char)(b+55UL),&tmp0), 1u/1u);
|
||
|
}
|
||
|
else osi_Werr((char *)(tmp0 = (char)(b+48UL),&tmp0), 1u/1u);
|
||
|
b = (uint32_t)(uint8_t)bu[i0]&15UL;
|
||
|
if (b>=10UL) {
|
||
|
osi_Werr((char *)(tmp0 = (char)(b+55UL),&tmp0), 1u/1u);
|
||
|
}
|
||
|
else osi_Werr((char *)(tmp0 = (char)(b+48UL),&tmp0), 1u/1u);
|
||
|
if ((i0&31L)==31L) osi_Werr("\012", 2ul);
|
||
|
else osi_Werr(" ", 2ul);
|
||
|
if (i0==tmp) break;
|
||
|
} /* end for */
|
||
|
osi_Werr("\012", 2ul);
|
||
|
X2C_PFREE(hd);
|
||
|
} /* end Whex() */
|
||
|
|
||
|
|
||
|
static void CallStr(char c[], uint32_t c_len, uint32_t n,
|
||
|
char withssid, char s[], uint32_t s_len)
|
||
|
{
|
||
|
uint32_t p;
|
||
|
uint32_t i0;
|
||
|
X2C_PCOPY((void **)&c,c_len);
|
||
|
n = n*7UL;
|
||
|
p = 0UL;
|
||
|
for (i0 = 0UL; i0<=5UL; i0++) {
|
||
|
if (c[i0+n]!=' ') {
|
||
|
s[p] = c[i0+n];
|
||
|
++p;
|
||
|
}
|
||
|
} /* end for */
|
||
|
s[p] = 0;
|
||
|
if (withssid) {
|
||
|
i0 = (uint32_t)(uint8_t)c[n+6UL]&15UL;
|
||
|
if (i0) {
|
||
|
s[p] = '-';
|
||
|
++p;
|
||
|
if (i0>=10UL) {
|
||
|
s[p] = (char)(i0/10UL+48UL);
|
||
|
++p;
|
||
|
}
|
||
|
s[p] = (char)(i0%10UL+48UL);
|
||
|
++p;
|
||
|
}
|
||
|
s[p] = 0;
|
||
|
}
|
||
|
X2C_PFREE(c);
|
||
|
} /* end CallStr() */
|
||
|
|
||
|
|
||
|
static void WerrCall(pTASK task)
|
||
|
{
|
||
|
char h[256];
|
||
|
if (verb && task) {
|
||
|
CallStr(task->l2addr.adress, 72ul, 0UL, 1, h, 256ul);
|
||
|
osi_Werr(h, 256ul);
|
||
|
}
|
||
|
} /* end WerrCall() */
|
||
|
|
||
|
|
||
|
static void GetCall(const char from[], uint32_t from_len,
|
||
|
uint32_t * p, l2_pSTRING to)
|
||
|
{
|
||
|
uint16_t len;
|
||
|
uint16_t i0;
|
||
|
len = (uint16_t)aprsstr_Length(from, from_len);
|
||
|
while (*p<(uint32_t)len && (uint8_t)from[*p]<=' ') ++*p;
|
||
|
for (i0 = 0U; i0<=5U; i0++) {
|
||
|
if ((*p<(uint32_t)len && from[*p]!='-') && from[*p]!=' ') {
|
||
|
to[i0] = X2C_CAP(from[*p]);
|
||
|
++*p;
|
||
|
}
|
||
|
else to[i0] = ' ';
|
||
|
} /* end for */
|
||
|
i0 = 0U;
|
||
|
if (from[*p]=='-') {
|
||
|
++*p;
|
||
|
if ((uint8_t)from[*p]>='0' && (uint8_t)from[*p]<='9') {
|
||
|
i0 = (uint16_t)((uint32_t)(uint8_t)from[*p]-48UL);
|
||
|
++*p;
|
||
|
}
|
||
|
if ((uint8_t)from[*p]>='0' && (uint8_t)from[*p]<='9') {
|
||
|
i0 = (uint16_t)(((uint32_t)(i0*10U)+(uint32_t)(uint8_t)
|
||
|
from[*p])-48UL);
|
||
|
++*p;
|
||
|
}
|
||
|
}
|
||
|
to[6U] = (char)((i0&15U)+48U);
|
||
|
} /* end GetCall() */
|
||
|
|
||
|
static void Event(char * *, l2_pLINK, uint8_t);
|
||
|
|
||
|
|
||
|
static void Event(char * * atask, l2_pLINK link0, uint8_t event)
|
||
|
{
|
||
|
struct l2_GETADRESS gadr;
|
||
|
pTASK ntask;
|
||
|
struct l2_CONNECT connect;
|
||
|
pTASK ptask;
|
||
|
if (event==l2_eCONNREQ) {
|
||
|
osic_alloc((char * *) &ntask, sizeof(struct TASK));
|
||
|
if (ntask==0) return;
|
||
|
memset((char *)ntask,(char)0,sizeof(struct TASK));
|
||
|
ntask->infd = -1L;
|
||
|
ntask->outfd = -1L;
|
||
|
ntask->link0 = link0;
|
||
|
ntask->state = 1U;
|
||
|
ntask->crlfmode = convlfcr;
|
||
|
ntask->detectdone = (uint32_t)autodet;
|
||
|
l2_GetAdress0(link0, &ntask->l2addr);
|
||
|
memset((char *) &connect,(char)0,sizeof(struct l2_CONNECT));
|
||
|
connect.port = ntask->l2addr.port;
|
||
|
connect.baud = 1U;
|
||
|
connect.cpid = 240U;
|
||
|
connect.l2adr = (l2_pSTRING)ntask->l2addr.adress;
|
||
|
connect.typ = l2_cCONNAK;
|
||
|
ntask->link0 = l2_Connect0((char *)ntask, &connect);
|
||
|
ntask->next = tasks;
|
||
|
tasks = ntask;
|
||
|
if (verb) {
|
||
|
WerrCall(ntask);
|
||
|
osi_Werr(" connreq\012", 10ul);
|
||
|
}
|
||
|
}
|
||
|
else if (event==l2_eFLEXDATA) l2_GetAdress0(link0, &gadr);
|
||
|
else if (event==l2_eCONNECTED) {
|
||
|
/*WrStr(gadr.adress); */
|
||
|
/*WrInt(dbuf^.len, 10); */
|
||
|
/*WrStrLn(" flexdata"); */
|
||
|
if (verb) {
|
||
|
WerrCall((pTASK)*atask);
|
||
|
osi_Werr(" connected!\012", 13ul);
|
||
|
}
|
||
|
if (*atask) {
|
||
|
ptask = (pTASK)*atask;
|
||
|
ptask->state = 1U;
|
||
|
}
|
||
|
}
|
||
|
else if (*atask) {
|
||
|
/* ELSIF event=eDISCONNECTED THEN */
|
||
|
/*WrInt(ORD(event), 1);WrStrLn(":host got event"); */
|
||
|
ptask = (pTASK)*atask;
|
||
|
ptask->events |= (1U<<event);
|
||
|
}
|
||
|
} /* end Event() */
|
||
|
|
||
|
|
||
|
static void GetWord(char s[], uint32_t s_len, char w[],
|
||
|
uint32_t w_len)
|
||
|
{
|
||
|
uint32_t j;
|
||
|
uint32_t i0;
|
||
|
char e;
|
||
|
i0 = 0UL;
|
||
|
j = 0UL;
|
||
|
e = ' ';
|
||
|
if (s[0UL]=='\"') {
|
||
|
e = '\"';
|
||
|
s[0UL] = ' ';
|
||
|
i0 = 1UL;
|
||
|
}
|
||
|
for (;;) {
|
||
|
if (i0>s_len-1 || s[i0]==0) break;
|
||
|
if (s[i0]==e) {
|
||
|
s[i0] = ' ';
|
||
|
break;
|
||
|
}
|
||
|
if (j<w_len-1) {
|
||
|
w[j] = s[i0];
|
||
|
++j;
|
||
|
}
|
||
|
s[i0] = ' ';
|
||
|
++i0;
|
||
|
}
|
||
|
w[j] = 0;
|
||
|
} /* end GetWord() */
|
||
|
|
||
|
|
||
|
static void taskparms(char s[], uint32_t s_len, char argbuf[],
|
||
|
uint32_t argbuf_len, char * argwords[],
|
||
|
uint32_t argwords_len)
|
||
|
{
|
||
|
uint32_t i0;
|
||
|
uint32_t argc;
|
||
|
uint32_t argp;
|
||
|
char h[1024];
|
||
|
X2C_PCOPY((void **)&s,s_len);
|
||
|
memset((char *)argwords,(char)0,argwords_len*sizeof(char *));
|
||
|
argc = 0UL;
|
||
|
argp = 0UL;
|
||
|
for (;;) {
|
||
|
while (s[0UL]==' ') aprsstr_Delstr(s, s_len, 0UL, 1UL);
|
||
|
GetWord(s, s_len, h, 1024ul);
|
||
|
/*WrStrLn(h); */
|
||
|
h[1023U] = 0;
|
||
|
if (h[0U]==0) break;
|
||
|
argwords[argc] = (char *) &argbuf[argp];
|
||
|
i0 = 0UL;
|
||
|
for (;;) {
|
||
|
if (argp>=argbuf_len-1) {
|
||
|
/*argbuffer full*/
|
||
|
argbuf[argbuf_len-1] = 0;
|
||
|
osi_Werr("ArgBuf full!\012", 14ul);
|
||
|
break;
|
||
|
}
|
||
|
argbuf[argp] = h[i0];
|
||
|
++argp;
|
||
|
if (h[i0]==0) break;
|
||
|
++i0;
|
||
|
}
|
||
|
++argc;
|
||
|
if (argc>=argwords_len-1) break;
|
||
|
}
|
||
|
argwords[argc] = 0;
|
||
|
X2C_PFREE(s);
|
||
|
} /* end taskparms() */
|
||
|
|
||
|
#define l2cat_M "%"
|
||
|
|
||
|
|
||
|
static void Makros(char c[], uint32_t c_len, char a[],
|
||
|
uint32_t a_len, char s[], uint32_t s_len)
|
||
|
{
|
||
|
uint32_t i0;
|
||
|
char h[16];
|
||
|
char m;
|
||
|
X2C_PCOPY((void **)&c,c_len);
|
||
|
X2C_PCOPY((void **)&a,a_len);
|
||
|
s[0UL] = 0;
|
||
|
i0 = 0UL;
|
||
|
m = 0;
|
||
|
while (i0<=c_len-1 && c[i0]) {
|
||
|
if (m) {
|
||
|
if (c[i0]=='%') aprsstr_Append(s, s_len, "%", 2ul);
|
||
|
else if (c[i0]=='m') {
|
||
|
CallStr(a, a_len, 1UL, 1, h, 16ul);
|
||
|
aprsstr_Append(s, s_len, h, 16ul);
|
||
|
}
|
||
|
else if (c[i0]=='u') {
|
||
|
CallStr(a, a_len, 0UL, 1, h, 16ul);
|
||
|
aprsstr_Append(s, s_len, h, 16ul);
|
||
|
}
|
||
|
else if (c[i0]=='U') {
|
||
|
CallStr(a, a_len, 0UL, 0, h, 16ul);
|
||
|
aprsstr_Append(s, s_len, h, 16ul);
|
||
|
}
|
||
|
else {
|
||
|
aprsstr_Append(s, s_len, "%", 2ul);
|
||
|
aprsstr_Append(s, s_len, (char *) &c[i0], 1u/1u);
|
||
|
}
|
||
|
m = 0;
|
||
|
}
|
||
|
else if (c[i0]=='%') m = 1;
|
||
|
else aprsstr_Append(s, s_len, (char *) &c[i0], 1u/1u);
|
||
|
++i0;
|
||
|
}
|
||
|
X2C_PFREE(c);
|
||
|
X2C_PFREE(a);
|
||
|
} /* end Makros() */
|
||
|
|
||
|
|
||
|
static void Login(int32_t * fd, char l2adr[], uint32_t l2adr_len)
|
||
|
{
|
||
|
struct Execlogin_tEXEC cmdvec;
|
||
|
char argstr[8192];
|
||
|
char argbuf[8192];
|
||
|
char * argwords[65];
|
||
|
X2C_PCOPY((void **)&l2adr,l2adr_len);
|
||
|
/*args:="/bin/login login"; */
|
||
|
Makros(cmdline, 4096ul, l2adr, l2adr_len, argstr, 8192ul);
|
||
|
taskparms(argstr, 8192ul, argbuf, 8192ul, argwords, 65ul);
|
||
|
/*p:=argwords[0];WrLn;WrInt(CAST(CARDINAL, argwords[0]), 15);
|
||
|
WrInt(CAST(CARDINAL, p), 15);WrLn; */
|
||
|
/*WrStrLn(p^);p:=argwords[1];WrStrLn(p^);WrStrLn(argbuf); */
|
||
|
*fd = -1L;
|
||
|
cmdvec.cmdfn = (char *)argwords[0U];
|
||
|
cmdvec.args = (X2C_pCHAR *) &argwords[1U];
|
||
|
if (verb) {
|
||
|
osi_Werr("start: ", 8ul);
|
||
|
osi_Werr(cmdline, 4096ul);
|
||
|
osi_Werr("\012", 2ul);
|
||
|
}
|
||
|
*fd = Execlogin_StartLogin(&cmdvec);
|
||
|
/*
|
||
|
IF fd>=0 THEN
|
||
|
ret:=tcgetattr(fd, tio);
|
||
|
tio.c_lflag:=CAST(tcflag_t, CAST(BITSET, tio.c_lflag) + CAST(BITSET,
|
||
|
ISIG));
|
||
|
ret:=tcsetattr (fd, TCSAFLUSH, tio);
|
||
|
END;
|
||
|
*/
|
||
|
if (*fd>=2L && *fd<=255L) {
|
||
|
if (verb) {
|
||
|
osi_Werr("login fd=", 10ul);
|
||
|
aprsstr_IntToStr(*fd, 1UL, argbuf, 8192ul);
|
||
|
osi_Werr(argbuf, 8192ul);
|
||
|
osi_Werr("\012", 2ul);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if (verb) osi_Werr("login fd error\012", 16ul);
|
||
|
*fd = -1L;
|
||
|
}
|
||
|
X2C_PFREE(l2adr);
|
||
|
} /* end Login() */
|
||
|
|
||
|
|
||
|
static char GetNum(const char h[], uint32_t h_len, char eot,
|
||
|
uint32_t * p, uint32_t * n)
|
||
|
{
|
||
|
*n = 0UL;
|
||
|
while ((uint8_t)h[*p]>='0' && (uint8_t)h[*p]<='9') {
|
||
|
*n = ( *n*10UL+(uint32_t)(uint8_t)h[*p])-48UL;
|
||
|
++*p;
|
||
|
}
|
||
|
return h[*p]==eot;
|
||
|
} /* end GetNum() */
|
||
|
|
||
|
|
||
|
static void Parms(void)
|
||
|
{
|
||
|
char err;
|
||
|
char hh[1024];
|
||
|
char h[1024];
|
||
|
uint32_t l2parcnt;
|
||
|
uint32_t p;
|
||
|
uint32_t k;
|
||
|
uint32_t j;
|
||
|
uint32_t i0;
|
||
|
struct frameio_UDPSOCK * anonym;
|
||
|
err = 0;
|
||
|
sockc = 0UL;
|
||
|
for (i0 = 0UL; i0<=255UL; i0++) {
|
||
|
numpar[i0].port = 0L;
|
||
|
} /* end for */
|
||
|
l2parcnt = 0UL;
|
||
|
for (;;) {
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
if (h[0U]==0) break;
|
||
|
if (h[0U]=='-' && h[2U]==0) {
|
||
|
if (h[1U]=='C') {
|
||
|
/* -C ax25 destination */
|
||
|
NextArgs(h, 1024ul);
|
||
|
i0 = 0UL;
|
||
|
j = 0UL;
|
||
|
while (j<63UL && i0<aprsstr_Length(h, 1024ul)) {
|
||
|
GetCall(h, 1024ul, &i0, (l2_pSTRING) &connectto0[j]);
|
||
|
j += 7UL;
|
||
|
if (j==7UL) j = 14UL;
|
||
|
}
|
||
|
connectto0[j] = 0;
|
||
|
}
|
||
|
else if (h[1U]=='c') {
|
||
|
/* -c comand line */
|
||
|
NextArgs(cmdline, 4096ul);
|
||
|
keepconnected = 1;
|
||
|
}
|
||
|
else if (h[1U]=='p') {
|
||
|
/* -p pipe */
|
||
|
osi_NextArg(pipename, 4096ul);
|
||
|
}
|
||
|
else if (h[1U]=='i') {
|
||
|
/* -i mycall */
|
||
|
NextArgs(h, 1024ul);
|
||
|
j = 7UL; /* first call is digi call, insert later */
|
||
|
i0 = 0UL;
|
||
|
do {
|
||
|
GetCall(h, 1024ul, &i0, (l2_pSTRING) &mycall[j]);
|
||
|
j += 7UL;
|
||
|
} while (!(j>=112UL || h[i0]!=' '));
|
||
|
if (j<=112UL) mycall[j] = 0;
|
||
|
for (i0 = 0UL; i0<=6UL; i0++) {
|
||
|
mycall[i0] = mycall[i0+7UL]; /* first mycall is digi call*/
|
||
|
} /* end for */
|
||
|
}
|
||
|
else if (h[1U]=='j') {
|
||
|
/* -j <num> convert cr lf to pipe */
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
i0 = 0UL;
|
||
|
if (!GetNum(h, 1024ul, 0, &i0, &convtopipe) || convtopipe>6UL) {
|
||
|
err = 1;
|
||
|
osi_WrStrLn("-j <0..6>", 10ul);
|
||
|
}
|
||
|
}
|
||
|
else if (h[1U]=='m') {
|
||
|
/* -j <num> convert cr lf to pipe */
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
i0 = 0UL;
|
||
|
if (!GetNum(h, 1024ul, 0, &i0, &montyp)) {
|
||
|
err = 1;
|
||
|
osi_WrStrLn("-m <0..1>", 10ul);
|
||
|
}
|
||
|
}
|
||
|
else if (h[1U]=='D') {
|
||
|
/* -D <n> discard frame len */
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
i0 = 0UL;
|
||
|
if (!GetNum(h, 1024ul, 0, &i0, &j)) {
|
||
|
err = 1;
|
||
|
osi_WrStrLn("-D <0..1500>", 13ul);
|
||
|
}
|
||
|
pppdiscard = (int32_t)j;
|
||
|
}
|
||
|
else if (h[1U]=='r') {
|
||
|
/* -j <num> convert cr lf to pipe */
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
i0 = 0UL;
|
||
|
if (!GetNum(h, 1024ul, 0, &i0, &j) || j>4000000UL) {
|
||
|
err = 1;
|
||
|
osi_WrStrLn("-r <ms> (max 4000000)", 22ul);
|
||
|
}
|
||
|
else minrecontime = j*1000UL;
|
||
|
keepconnected = 1;
|
||
|
}
|
||
|
else if (h[1U]=='R') {
|
||
|
/* -r <ms> min reconn time */
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
i0 = 0UL;
|
||
|
if (!GetNum(h, 1024ul, 0, &i0, &j) || j>4000000UL) {
|
||
|
err = 1;
|
||
|
osi_WrStrLn("-R <ms> (max 4000000)", 22ul);
|
||
|
}
|
||
|
else {
|
||
|
maxrecontime = j*1000UL;
|
||
|
}
|
||
|
keepconnected = 1;
|
||
|
}
|
||
|
else if (h[1U]=='n') {
|
||
|
/* -R <ms> max reconn time */
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
if (h[0U]=='a') p = 16UL;
|
||
|
else {
|
||
|
i0 = 0UL;
|
||
|
if (!GetNum(h, 1024ul, 0, &i0, &p) || p>15UL) {
|
||
|
err = 1;
|
||
|
osi_WrStrLn("-n <port> <parameter> <value>", 30ul);
|
||
|
}
|
||
|
}
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
switch ((unsigned)h[0U]) {
|
||
|
case 't': /* txwait */
|
||
|
j = 17UL;
|
||
|
break;
|
||
|
case 'd': /* dwait */
|
||
|
j = 20UL;
|
||
|
break;
|
||
|
case 'o': /* maxframes */
|
||
|
j = 23UL;
|
||
|
break;
|
||
|
case 'f': /* t1 */
|
||
|
j = 24UL;
|
||
|
break;
|
||
|
case 'F': /* t3 */
|
||
|
j = 25UL;
|
||
|
break;
|
||
|
case 'I': /* ipoll */
|
||
|
j = 26UL;
|
||
|
break;
|
||
|
case 'n': /* retr */
|
||
|
j = 27UL;
|
||
|
break;
|
||
|
case 'h': /* halfduplex */
|
||
|
j = 24UL;
|
||
|
break;
|
||
|
default:;
|
||
|
i0 = 0UL;
|
||
|
if (!GetNum(h, 1024ul, 0, &i0, &j) || j>255UL) {
|
||
|
err = 1;
|
||
|
osi_WrStrLn("-n <port> <parameter> <value>", 30ul);
|
||
|
}
|
||
|
break;
|
||
|
} /* end switch */
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
i0 = 0UL;
|
||
|
if (!GetNum(h, 1024ul, 0, &i0, &k)) {
|
||
|
err = 1;
|
||
|
osi_WrStrLn("-n <port> <parameter> <value>", 30ul);
|
||
|
}
|
||
|
if (!err) {
|
||
|
if (l2parcnt>255UL) Error("parameter table full", 21ul);
|
||
|
numpar[l2parcnt].port = (int32_t)p;
|
||
|
numpar[l2parcnt].parmnum = (int32_t)j;
|
||
|
numpar[l2parcnt].val = (int32_t)k;
|
||
|
++l2parcnt;
|
||
|
}
|
||
|
}
|
||
|
else if (h[1U]=='U') {
|
||
|
osi_NextArg(h, 1024ul);
|
||
|
if (sockc>14UL) Error("too many ports", 15ul);
|
||
|
{ /* with */
|
||
|
struct frameio_UDPSOCK * anonym = &frameio_udpsocks0[sockc];
|
||
|
if (aprsstr_GetIp2(h, 1024ul, &anonym->ipnum, &anonym->toport,
|
||
|
&anonym->fromport, &anonym->checkip)<0L) {
|
||
|
Error("-U wrong ip:port:port number", 29ul);
|
||
|
}
|
||
|
anonym->fd = openudp();
|
||
|
if (anonym->fd<0L || bindudp(anonym->fd,
|
||
|
anonym->fromport)<0L) {
|
||
|
strncpy(h,"-U cannot open udp port ",1024u);
|
||
|
aprsstr_IntToStr((int32_t)anonym->fromport, 0UL, hh,
|
||
|
1024ul);
|
||
|
aprsstr_Append(h, 1024ul, hh, 1024ul);
|
||
|
Error(h, 1024ul);
|
||
|
}
|
||
|
}
|
||
|
++sockc;
|
||
|
}
|
||
|
else if (h[1U]=='a') autodet = 1;
|
||
|
else if (h[1U]=='P') {
|
||
|
pppmode = 1;
|
||
|
usedeflat = 1;
|
||
|
}
|
||
|
else if (h[1U]=='d') usedeflat = 1;
|
||
|
else if (h[1U]=='v') {
|
||
|
verb = 1;
|
||
|
}
|
||
|
else if (h[1U]=='V') {
|
||
|
verb = 1;
|
||
|
verb2 = 1;
|
||
|
}
|
||
|
else if (h[1U]=='l') convlfcr = 1UL;
|
||
|
else if (h[1U]=='L') convlfcr = 2UL;
|
||
|
else {
|
||
|
if (h[1U]=='h') {
|
||
|
osic_WrLn();
|
||
|
osi_WrStrLn(" -a autodetect def\
|
||
|
late + ppp on first bytes", 75ul);
|
||
|
osi_WrStrLn(" ppp + deflat\
|
||
|
e:\"!p\",deflate;\"!d\"", 69ul);
|
||
|
osi_WrStrLn(" LF to CR:\"!\
|
||
|
l\", strip LF:\"!L\"", 66ul);
|
||
|
osi_WrStrLn(" -C <destination> slave connect \
|
||
|
destination -C \"OE0AAA-12 OE5XBL\"", 83ul);
|
||
|
osi_WrStrLn(" if no \"-C\"\
|
||
|
run as server waiting for connect", 82ul);
|
||
|
osi_WrStrLn(" -c <cmdline> execute comman\
|
||
|
d on connect -c \"/bin/bash bash %m %u\"", 88ul);
|
||
|
osi_WrStrLn(" %m=mycall %u\
|
||
|
=usercall %U=same no SSID %%=%", 80ul);
|
||
|
osi_WrStrLn(" if no \"-c\"\
|
||
|
data path is stdin/stdout", 74ul);
|
||
|
osi_WrStrLn(" -D <bytes> discard longer\
|
||
|
ppp frames if pr tx buffer full", 82ul);
|
||
|
osi_WrStrLn(" -d deflate on",
|
||
|
46ul);
|
||
|
osi_WrStrLn(" -h this", 40ul);
|
||
|
osi_WrStrLn(" -i <mycall> <mycall> ... connectable ca\
|
||
|
lls -i \"OE0AAA OE0AAA-15\"", 75ul);
|
||
|
osi_WrStrLn(" first mycall\
|
||
|
is digi and used to connect out", 82ul);
|
||
|
osi_WrStrLn(" -j <1..6> 1:del LF, 2:de\
|
||
|
l LF+CR>LF, 3:CR>LF, 4:del CR", 79ul);
|
||
|
osi_WrStrLn(" 5:del CR+LF>\
|
||
|
CR, 6:LF>CR in stream from pr", 79ul);
|
||
|
osi_WrStrLn(" -l convert LF to \
|
||
|
CR in stream to pr", 68ul);
|
||
|
osi_WrStrLn(" -L strip LF in st\
|
||
|
ream to pr", 60ul);
|
||
|
osi_WrStrLn(" -m <0..2> ax25 Monitor t\
|
||
|
o stderr (2 with info)", 72ul);
|
||
|
osi_WrStrLn(" -n <port> <parm> <value> layer 2 parms,\
|
||
|
\"-n a\" set on all ports", 74ul);
|
||
|
osi_WrStrLn(" parm t:txwai\
|
||
|
t d:dwait o:maxfr f:t1 F:t3", 77ul);
|
||
|
osi_WrStrLn(" parm I:ipoll\
|
||
|
n:retr h:halfdup", 67ul);
|
||
|
osi_WrStrLn(" -P ppp + deflate \
|
||
|
on", 52ul);
|
||
|
osi_WrStrLn(" -p <filename> data to/from t\
|
||
|
his device/pipe -p /dev/ttyS0", 79ul);
|
||
|
osi_WrStrLn(" -R <ms> enable slave \\
|
||
|
"keep connected\" with max reconnet delay", 89ul);
|
||
|
osi_WrStr(" (max 4000000ms\
|
||
|
) (", 55ul);
|
||
|
osic_WrINT32(maxrecontime/1000UL, 1UL);
|
||
|
osi_WrStrLn(")", 2ul);
|
||
|
osi_WrStrLn(" -r <ms> enable slave \\
|
||
|
"keep connected\" with min reconnet delay", 89ul);
|
||
|
osi_WrStr(" and doubles de\
|
||
|
lay each conn try till \"-R\" (", 82ul);
|
||
|
osic_WrINT32(minrecontime/1000UL, 1UL);
|
||
|
osi_WrStrLn(")", 2ul);
|
||
|
osi_WrStrLn(" -U <x.x.x.x:destport:listenport> axudp (autodet\
|
||
|
ect axudp2)", 61ul);
|
||
|
osi_WrStrLn(" repeat -U fo\
|
||
|
r more ports", 62ul);
|
||
|
osi_WrStrLn(" -v verbous",
|
||
|
43ul);
|
||
|
osi_WrStrLn(" -V more verbous",
|
||
|
48ul);
|
||
|
osic_WrLn();
|
||
|
X2C_ABORT();
|
||
|
}
|
||
|
if (h[1U]=='-') Error("- - ?", 6ul);
|
||
|
if (h[1U]==0) Error("- ?", 5ul);
|
||
|
err = 1;
|
||
|
}
|
||
|
}
|
||
|
else err = 1;
|
||
|
if (err) break;
|
||
|
}
|
||
|
if (connectto0[0U]) {
|
||
|
/* insert mycall as it is valid after whole cmd line */
|
||
|
if (mycall[7U]==0) Error("need -i <call> for -C ", 23ul);
|
||
|
X2C_MOVE((char *) &mycall[7U],(char *) &connectto0[7U],7UL);
|
||
|
}
|
||
|
} /* end Parms() */
|
||
|
|
||
|
|
||
|
static void Connectto(void)
|
||
|
{
|
||
|
pTASK ntask;
|
||
|
struct l2_CONNECT connect;
|
||
|
osic_alloc((char * *) &ntask, sizeof(struct TASK));
|
||
|
if (ntask==0) return;
|
||
|
memset((char *)ntask,(char)0,sizeof(struct TASK));
|
||
|
ntask->infd = -1L;
|
||
|
ntask->outfd = -1L;
|
||
|
/* GetAdress(link, ADR(ntask^.l2addr)); */
|
||
|
memset((char *) &connect,(char)0,sizeof(struct l2_CONNECT));
|
||
|
connect.port = 1U;
|
||
|
connect.baud = 1U;
|
||
|
connect.cpid = 240U;
|
||
|
connect.l2adr = (l2_pSTRING)connectto0;
|
||
|
connect.l3adr = 0;
|
||
|
connect.typ = l2_cNORMAL;
|
||
|
ntask->link0 = l2_Connect0((char *)ntask, &connect);
|
||
|
ntask->state = 5U;
|
||
|
ntask->next = tasks;
|
||
|
ntask->crlfmode = convlfcr;
|
||
|
tasks = ntask;
|
||
|
} /* end Connectto() */
|
||
|
|
||
|
static void killdisc(int32_t);
|
||
|
|
||
|
|
||
|
static void killdisc(int32_t signum)
|
||
|
{
|
||
|
if (verb) osi_Werr("sigint\012", 8ul);
|
||
|
/* IF (tasks<>NIL) & (tasks^.state=2) THEN WrStrLn("disc!");
|
||
|
Disconnect(tasks^.link, TRUE); */
|
||
|
/* ELSE HALT(signum) END; */
|
||
|
if (terminate) X2C_ABORT();
|
||
|
terminate = 1;
|
||
|
} /* end killdisc() */
|
||
|
|
||
|
|
||
|
static void initcompress(pTASK pt0)
|
||
|
{
|
||
|
/*IntToStr(SIZE(pt^.pcdeflat^), 1, deb); Werr(deb);Werr("=mem"); */
|
||
|
osic_alloc((char * *) &pt0->pcdeflat, sizeof(struct DEFLATBUF));
|
||
|
if (pt0->pcdeflat==0) Error("alloc compres memory", 21ul);
|
||
|
deflate_Initdeflate(&pt0->pcdeflat->deflatcontext);
|
||
|
deflate_Initexpand(&pt0->pcdeflat->expandcontext);
|
||
|
pt0->pcdeflat->outlen = 0L;
|
||
|
pt0->pcdeflat->xoutlen = 0L;
|
||
|
pt0->pcdeflat->inp0 = 0L;
|
||
|
pt0->pcdeflat->xinp = 0L;
|
||
|
pt0->pcdeflat->done = 0;
|
||
|
if (pppmode) pt0->pcdeflat->pppframing = 1;
|
||
|
pt0->pcdeflat->pppstate = 0;
|
||
|
if (verb) osi_Werr("init compression\012", 18ul);
|
||
|
} /* end initcompress() */
|
||
|
|
||
|
|
||
|
static char pppcrc(char b[], uint32_t b_len, int32_t len)
|
||
|
{
|
||
|
char crc2;
|
||
|
char crc1;
|
||
|
char ok0;
|
||
|
/*ShowHex(b, len); */
|
||
|
if (len<2L) return 0;
|
||
|
len -= 2L;
|
||
|
crc1 = b[len];
|
||
|
crc2 = b[len+1L];
|
||
|
aprsstr_AppCRC(b, b_len, len);
|
||
|
ok0 = crc1==b[len] && crc2==b[len+1L];
|
||
|
if (!ok0) osi_Werr(" crc-err \012", 11ul);
|
||
|
return ok0;
|
||
|
} /* end pppcrc() */
|
||
|
|
||
|
|
||
|
static void compress(pTASK pt0)
|
||
|
{
|
||
|
int32_t i0;
|
||
|
struct TASK * anonym;
|
||
|
int32_t tmp;
|
||
|
{ /* with */
|
||
|
struct TASK * anonym = pt0;
|
||
|
if (anonym->pcdeflat->pppframing) {
|
||
|
for (;;) {
|
||
|
if (anonym->pcdeflat->inp0>=anonym->inlen) {
|
||
|
/* out of data */
|
||
|
anonym->pcdeflat->inp0 = 0L;
|
||
|
anonym->inlen = 0L;
|
||
|
break;
|
||
|
}
|
||
|
/*IF verb2 THEN WrHex(ORD(inbuf[pcdeflat^.inp]), 3) END; */
|
||
|
if (anonym->pcdeflat->pppstate==0 && anonym->inbuf[anonym->pcdeflat->inp0]
|
||
|
=='~') {
|
||
|
/* hunt mode */
|
||
|
anonym->pcdeflat->pppstate = '\001'; /* in frame */
|
||
|
anonym->pcdeflat->ppplen = 0L;
|
||
|
}
|
||
|
else if (anonym->pcdeflat->pppstate=='\001') {
|
||
|
if (anonym->inbuf[anonym->pcdeflat->inp0]=='}') {
|
||
|
anonym->pcdeflat->pppstate = '\002';
|
||
|
/* escaped char follows */
|
||
|
}
|
||
|
else {
|
||
|
if (anonym->inbuf[anonym->pcdeflat->inp0]=='~') {
|
||
|
/* frame complete */
|
||
|
if (anonym->pcdeflat->ppplen>0L) {
|
||
|
if (pppcrc(anonym->pcdeflat->pppbuf, 4096ul,
|
||
|
anonym->pcdeflat->ppplen)) {
|
||
|
/* frame good */
|
||
|
/*IntToStr(pcdeflat^.ppplen, 7, deb);Werr(deb);
|
||
|
Werr("=c "); */
|
||
|
if (anonym->pcdeflat->ppplen<=pppdiscard || l2_SendStr(anonym->link0,
|
||
|
0U, 0)) {
|
||
|
tmp = anonym->pcdeflat->ppplen-1L;
|
||
|
i0 = 0L;
|
||
|
if (i0<=tmp) for (;; i0++) {
|
||
|
deflate_Deflatbyte(&anonym->pcdeflat->deflatcontext,
|
||
|
anonym->pcdeflat->pppbuf[i0], 0, anonym->pcdeflat->outbuf,
|
||
|
20001ul, &anonym->pcdeflat->outlen);
|
||
|
if (i0==tmp) break;
|
||
|
} /* end for */
|
||
|
deflate_Deflatbyte(&anonym->pcdeflat->deflatcontext,
|
||
|
0, '\002', anonym->pcdeflat->outbuf, 20001ul,
|
||
|
&anonym->pcdeflat->outlen);
|
||
|
}
|
||
|
else if (verb) {
|
||
|
osi_Werr("ppp frame discarded\012", 21ul);
|
||
|
}
|
||
|
}
|
||
|
else osi_Werr("ppp frame crc error\012", 21ul);
|
||
|
/*IntToStr(pcdeflat^.outlen, 7, deb);Werr(deb);
|
||
|
Werr("=co "); */
|
||
|
anonym->pcdeflat->ppplen = 0L;
|
||
|
}
|
||
|
++anonym->pcdeflat->inp0;
|
||
|
break;
|
||
|
}
|
||
|
anonym->pcdeflat->pppbuf[anonym->pcdeflat->ppplen]
|
||
|
= anonym->inbuf[anonym->pcdeflat->inp0];
|
||
|
if (anonym->pcdeflat->ppplen<4095L) {
|
||
|
++anonym->pcdeflat->ppplen;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (anonym->pcdeflat->pppstate=='\002') {
|
||
|
/* stuffed byte */
|
||
|
anonym->pcdeflat->pppbuf[anonym->pcdeflat->ppplen]
|
||
|
= (char)((uint8_t)(uint8_t)
|
||
|
anonym->inbuf[anonym->pcdeflat->inp0]^0x20U);
|
||
|
if (anonym->pcdeflat->ppplen<4095L) {
|
||
|
++anonym->pcdeflat->ppplen;
|
||
|
}
|
||
|
anonym->pcdeflat->pppstate = '\001';
|
||
|
}
|
||
|
++anonym->pcdeflat->inp0;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
while (anonym->pcdeflat->inp0<anonym->inlen && anonym->pcdeflat->outlen<3601L)
|
||
|
{
|
||
|
deflate_Deflatbyte(&anonym->pcdeflat->deflatcontext,
|
||
|
anonym->inbuf[anonym->pcdeflat->inp0], 0,
|
||
|
anonym->pcdeflat->outbuf, 20001ul,
|
||
|
&anonym->pcdeflat->outlen);
|
||
|
++anonym->pcdeflat->inp0;
|
||
|
}
|
||
|
if (anonym->pcdeflat->inp0>=anonym->inlen) {
|
||
|
/* inbuffer empty so send compressed block */
|
||
|
deflate_Deflatbyte(&anonym->pcdeflat->deflatcontext, 0, '\002',
|
||
|
anonym->pcdeflat->outbuf, 20001ul,
|
||
|
&anonym->pcdeflat->outlen); /* flush */
|
||
|
anonym->pcdeflat->inp0 = 0L;
|
||
|
anonym->inlen = 0L;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
/*ShowHex(pcdeflat^.outbuf, pcdeflat^.outlen); WrStrLn(""); */
|
||
|
} /* end compress() */
|
||
|
|
||
|
|
||
|
static void expand(pTASK pt0)
|
||
|
{
|
||
|
char done;
|
||
|
char pb[3001];
|
||
|
int32_t j;
|
||
|
int32_t i0;
|
||
|
struct TASK * anonym;
|
||
|
/*ShowHex(outbuf, outlen); */
|
||
|
int32_t tmp;
|
||
|
{ /* with */
|
||
|
struct TASK * anonym = pt0;
|
||
|
for (;;) {
|
||
|
/*IF pcdeflat^.xoutlen>=SIZE(pcdeflat^.xoutbuf)
|
||
|
-300 THEN Werr(" outfull ") END; */
|
||
|
if ((anonym->pcdeflat->xinp>=anonym->outlen || anonym->pcdeflat->xoutlen>=3796L)
|
||
|
|| anonym->pcdeflat->xoutlen<0L) break;
|
||
|
/*WrHex(ORD(outbuf[pcdeflat^.xinp]), 3);INC(deb1); */
|
||
|
deflate_Expandbyte(&anonym->pcdeflat->expandcontext,
|
||
|
anonym->outbuf[anonym->pcdeflat->xinp],
|
||
|
anonym->pcdeflat->xoutbuf, 4096ul,
|
||
|
&anonym->pcdeflat->xoutlen, &done);
|
||
|
/*IF pcdeflat^.xoutlen<0 THEN Werr(" expand error"+NL) END; */
|
||
|
/*Werr("(");IntToStr(pcdeflat^.xoutlen, 1, deb);Werr(deb);Werr(")");
|
||
|
*/
|
||
|
++anonym->pcdeflat->xinp;
|
||
|
if (done && anonym->pcdeflat->pppframing) {
|
||
|
/* rebuild ppp frame */
|
||
|
/*IntToStr(deb1, 7, deb);Werr(deb);Werr("=xi ");deb1:=0; */
|
||
|
/*IntToStr(pcdeflat^.xoutlen, 7, deb);Werr(deb);Werr("=x "); */
|
||
|
/*WrStrLn("done");ShowHex(pcdeflat^.xoutbuf, pcdeflat^.xoutlen);
|
||
|
*/
|
||
|
if (pppcrc(anonym->pcdeflat->xoutbuf, 4096ul,
|
||
|
anonym->pcdeflat->xoutlen)) {
|
||
|
/*WrStrLn("");WrStr("Y:");
|
||
|
ShowHex(pcdeflat^.xoutbuf, pcdeflat^.xoutlen); WrStrLn("");
|
||
|
*/
|
||
|
pb[0U] = '~';
|
||
|
j = 1L;
|
||
|
tmp = anonym->pcdeflat->xoutlen-1L;
|
||
|
i0 = 0L;
|
||
|
if (i0<=tmp) for (;; i0++) {
|
||
|
if ((anonym->pcdeflat->xoutbuf[i0]
|
||
|
=='~' || anonym->pcdeflat->xoutbuf[i0]=='}') || (uint8_t)
|
||
|
anonym->pcdeflat->xoutbuf[i0]<' ') {
|
||
|
/* stuff */
|
||
|
pb[j] = '}';
|
||
|
if (j<3000L) ++j;
|
||
|
pb[j] = (char)((uint8_t)(uint8_t)
|
||
|
anonym->pcdeflat->xoutbuf[i0]^0x20U);
|
||
|
}
|
||
|
else pb[j] = anonym->pcdeflat->xoutbuf[i0];
|
||
|
if (j<3000L) ++j;
|
||
|
if (i0==tmp) break;
|
||
|
} /* end for */
|
||
|
pb[j] = '~';
|
||
|
++j;
|
||
|
i0 = 0L;
|
||
|
while (i0<4095L && i0<j) {
|
||
|
anonym->pcdeflat->xoutbuf[i0] = pb[i0];
|
||
|
++i0;
|
||
|
}
|
||
|
anonym->pcdeflat->xoutlen = i0;
|
||
|
anonym->pcdeflat->done = 1;
|
||
|
/*WrStrLn("");WrStr("X:");
|
||
|
ShowHex(pcdeflat^.xoutbuf, pcdeflat^.xoutlen); WrStrLn("");
|
||
|
*/
|
||
|
break;
|
||
|
}
|
||
|
anonym->pcdeflat->xoutlen = -1L; /* crc error */
|
||
|
}
|
||
|
}
|
||
|
if (anonym->pcdeflat->xinp>=anonym->outlen) {
|
||
|
/* outbuffer empty */
|
||
|
anonym->pcdeflat->xinp = 0L;
|
||
|
anonym->outlen = 0L;
|
||
|
}
|
||
|
}
|
||
|
} /* end expand() */
|
||
|
|
||
|
|
||
|
static void wrpipe(int32_t fd, char b[], uint32_t b_len,
|
||
|
int32_t * blen)
|
||
|
{
|
||
|
int32_t i0;
|
||
|
int32_t len;
|
||
|
int32_t tmp;
|
||
|
/*WrStrLn("");WrStr("P:"); ShowHex(b, blen); WrStrLn(""); */
|
||
|
len = write(fd, (char *)b, (uint32_t)*blen);
|
||
|
if (len>*blen) len = *blen;
|
||
|
if (len>0L) {
|
||
|
*blen -= len;
|
||
|
tmp = *blen-1L;
|
||
|
i0 = 0L;
|
||
|
if (i0<=tmp) for (;; i0++) {
|
||
|
b[i0] = b[i0+len];
|
||
|
if (i0==tmp) break;
|
||
|
} /* end for */
|
||
|
}
|
||
|
/* IF blen>0 THEN MOVE(ADR(b[len]), ADR(b), blen) END; */
|
||
|
} /* end wrpipe() */
|
||
|
|
||
|
|
||
|
static void sendjunk(l2_pLINK link0, struct JUNKBUF * junk)
|
||
|
{
|
||
|
if (junk->len==256L || junk->len>=0L && junk->time0<=0L) {
|
||
|
if (l2_SendStr(link0, (uint16_t)junk->len, (l2_pSTRING)junk->buf)) {
|
||
|
junk->len = 0L;
|
||
|
}
|
||
|
}
|
||
|
} /* end sendjunk() */
|
||
|
|
||
|
|
||
|
static void wrl2(l2_pLINK link0, char b[], uint32_t b_len,
|
||
|
int32_t * blen, struct JUNKBUF * junk)
|
||
|
{
|
||
|
int32_t j;
|
||
|
int32_t i0;
|
||
|
int32_t len;
|
||
|
/*WrStr("L:"); WrInt(blen, 1); WrStr(" "); */
|
||
|
if (*blen==0L) return;
|
||
|
if (junk->len<256L) {
|
||
|
len = 0L;
|
||
|
while (junk->len<256L && len<*blen) {
|
||
|
junk->buf[junk->len] = b[len];
|
||
|
++junk->len;
|
||
|
++len;
|
||
|
}
|
||
|
j = len;
|
||
|
i0 = 0L;
|
||
|
while (j<*blen) {
|
||
|
b[i0] = b[j];
|
||
|
++j;
|
||
|
++i0;
|
||
|
}
|
||
|
*blen -= len;
|
||
|
junk->time0 = 4L;
|
||
|
}
|
||
|
sendjunk(link0, junk);
|
||
|
} /* end wrl2() */
|
||
|
|
||
|
|
||
|
static void wrclose(pTASK pt0, int32_t fd, char c[], uint32_t c_len)
|
||
|
{
|
||
|
char s[100];
|
||
|
X2C_PCOPY((void **)&c,c_len);
|
||
|
WerrCall(pt0);
|
||
|
aprsstr_IntToStr(fd, 1UL, s, 100ul);
|
||
|
osi_Werr(c, c_len);
|
||
|
osi_Werr(s, 100ul);
|
||
|
osi_Werr("\012", 2ul);
|
||
|
X2C_PFREE(c);
|
||
|
} /* end wrclose() */
|
||
|
|
||
|
|
||
|
static void crlf(char b[], uint32_t b_len, int32_t * len,
|
||
|
uint32_t mode)
|
||
|
{
|
||
|
int32_t j;
|
||
|
int32_t i0;
|
||
|
if (mode>0UL) {
|
||
|
/* convert LF to pr */
|
||
|
i0 = 0L;
|
||
|
j = 0L;
|
||
|
while (i0<*len) {
|
||
|
if (b[i0]=='\012') {
|
||
|
if (mode==1UL) {
|
||
|
b[j] = '\015';
|
||
|
++j;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
b[j] = b[i0];
|
||
|
++j;
|
||
|
}
|
||
|
++i0;
|
||
|
}
|
||
|
*len = j;
|
||
|
}
|
||
|
} /* end crlf() */
|
||
|
|
||
|
|
||
|
static void crlfp(char b[], uint32_t b_len, int32_t * len,
|
||
|
uint32_t mode)
|
||
|
/*1 del lf, 2 del lf cr>lf, 3 cr>lf, 4 del cr, 5 del cr lf>cr, 6 lf>cr */
|
||
|
{
|
||
|
int32_t j;
|
||
|
int32_t i0;
|
||
|
if (mode>0UL) {
|
||
|
/* convert LF to pr */
|
||
|
i0 = 0L;
|
||
|
j = 0L;
|
||
|
while (i0<*len) {
|
||
|
if (mode==1UL) {
|
||
|
if (b[i0]!='\012') {
|
||
|
b[j] = b[i0];
|
||
|
++j;
|
||
|
}
|
||
|
}
|
||
|
else if (mode==2UL) {
|
||
|
if (b[i0]=='\015') {
|
||
|
b[j] = '\012';
|
||
|
++j;
|
||
|
}
|
||
|
else if (b[i0]!='\012') {
|
||
|
b[j] = b[i0];
|
||
|
++j;
|
||
|
}
|
||
|
}
|
||
|
else if (mode==3UL) {
|
||
|
if (b[i0]=='\015') b[j] = '\012';
|
||
|
else b[j] = b[i0];
|
||
|
++j;
|
||
|
}
|
||
|
else if (mode==4UL) {
|
||
|
if (b[i0]!='\015') {
|
||
|
b[j] = b[i0];
|
||
|
++j;
|
||
|
}
|
||
|
}
|
||
|
else if (mode==5UL) {
|
||
|
if (b[i0]=='\012') {
|
||
|
b[j] = '\015';
|
||
|
++j;
|
||
|
}
|
||
|
else if (b[i0]!='\015') {
|
||
|
b[j] = b[i0];
|
||
|
++j;
|
||
|
}
|
||
|
}
|
||
|
else if (mode==6UL) {
|
||
|
if (b[i0]=='\012') b[j] = '\015';
|
||
|
else b[j] = b[i0];
|
||
|
++j;
|
||
|
}
|
||
|
++i0;
|
||
|
}
|
||
|
*len = j;
|
||
|
}
|
||
|
} /* end crlfp() */
|
||
|
|
||
|
|
||
|
static void detect(pTASK pt0)
|
||
|
/* startet task first sends command on stdout */
|
||
|
{
|
||
|
int32_t j;
|
||
|
int32_t i0;
|
||
|
struct TASK * anonym;
|
||
|
{ /* with */
|
||
|
struct TASK * anonym = pt0;
|
||
|
while (anonym->inlen>0L && anonym->detectdone>0UL) {
|
||
|
i0 = 0L;
|
||
|
if (anonym->detectdone==1UL) {
|
||
|
if (anonym->inbuf[0U]=='!') {
|
||
|
anonym->detectdone = 2UL;
|
||
|
i0 = 1L;
|
||
|
}
|
||
|
else anonym->detectdone = 0UL;
|
||
|
}
|
||
|
else if (anonym->detectdone==2UL) {
|
||
|
if (anonym->inbuf[0U]=='d') {
|
||
|
initcompress(pt0);
|
||
|
i0 = 1L;
|
||
|
if (verb) osi_Werr("task switched deflate on\012", 26ul);
|
||
|
}
|
||
|
else if (anonym->inbuf[0U]=='p') {
|
||
|
initcompress(pt0);
|
||
|
anonym->pcdeflat->pppframing = 1;
|
||
|
i0 = 1L;
|
||
|
if (verb) {
|
||
|
osi_Werr("task switched ppp + deflate on\012", 32ul);
|
||
|
}
|
||
|
}
|
||
|
else if (anonym->inbuf[0U]=='l') {
|
||
|
anonym->crlfmode = 1UL;
|
||
|
i0 = 1L;
|
||
|
if (verb) osi_Werr("task switched LF to CR on\012", 27ul);
|
||
|
}
|
||
|
else if (anonym->inbuf[0U]=='L') {
|
||
|
anonym->crlfmode = 2UL;
|
||
|
i0 = 1L;
|
||
|
if (verb) osi_Werr("task switched delete LF on\012", 28ul);
|
||
|
}
|
||
|
anonym->detectdone = 0UL;
|
||
|
}
|
||
|
else anonym->detectdone = 0UL;
|
||
|
if (i0>0L) {
|
||
|
/* delete command */
|
||
|
j = 0L;
|
||
|
while (i0<anonym->inlen) {
|
||
|
anonym->inbuf[j] = anonym->inbuf[i0];
|
||
|
++i0;
|
||
|
++j;
|
||
|
}
|
||
|
anonym->inlen = j;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} /* end detect() */
|
||
|
|
||
|
|
||
|
static void AppendTime(char s[], uint32_t s_len)
|
||
|
{
|
||
|
char h[31];
|
||
|
aprsstr_TimeToStr(osic_time()%86400UL, h, 31ul);
|
||
|
aprsstr_Append(s, s_len, " - ", 4ul);
|
||
|
aprsstr_Append(s, s_len, h, 31ul);
|
||
|
} /* end AppendTime() */
|
||
|
|
||
|
static uint16_t l2cat_UA = 0x63U;
|
||
|
|
||
|
static uint16_t l2cat_DM = 0xFU;
|
||
|
|
||
|
static uint16_t l2cat_SABM = 0x2FU;
|
||
|
|
||
|
static uint16_t l2cat_DISC = 0x43U;
|
||
|
|
||
|
static uint16_t l2cat_FRMR = 0x87U;
|
||
|
|
||
|
static uint16_t l2cat_UI = 0x3U;
|
||
|
|
||
|
static uint16_t l2cat_RR = 0x1U;
|
||
|
|
||
|
static uint16_t l2cat_REJ = 0x9U;
|
||
|
|
||
|
static uint16_t l2cat_RNR = 0x5U;
|
||
|
|
||
|
#define l2cat_LF0 "\015"
|
||
|
|
||
|
#define l2cat_LINELEN 78
|
||
|
|
||
|
static char l2cat_oneline = 0;
|
||
|
|
||
|
|
||
|
static void Nibble(int32_t * p, char rxbuf[2048], uint16_t n)
|
||
|
{
|
||
|
rxbuf[*p] = (char)((uint32_t)(48U+n)+7UL*(uint32_t)(n>9U));
|
||
|
++*p;
|
||
|
} /* end Nibble() */
|
||
|
|
||
|
|
||
|
static void WriteHex(char rxbuf[2048], int32_t * p, char c)
|
||
|
{
|
||
|
Nibble(p, rxbuf, (uint16_t)((uint32_t)(uint8_t)c/16UL));
|
||
|
Nibble(p, rxbuf, (uint16_t)((uint32_t)(uint8_t)c&15UL));
|
||
|
} /* end WriteHex() */
|
||
|
|
||
|
|
||
|
static void ShowCall(int32_t * p, char rxbuf[2048],
|
||
|
struct l2_GETADRESS * getadress, uint16_t cp,
|
||
|
char hbit)
|
||
|
{
|
||
|
uint32_t i0;
|
||
|
char c;
|
||
|
uint32_t tmp;
|
||
|
tmp = (uint32_t)(cp+5U);
|
||
|
i0 = (uint32_t)cp;
|
||
|
if (i0<=tmp) for (;; i0++) {
|
||
|
c = getadress->adress[i0];
|
||
|
if (c!=' ') {
|
||
|
if ((uint8_t)c>' ') {
|
||
|
rxbuf[*p] = c;
|
||
|
++*p;
|
||
|
}
|
||
|
else WriteHex(rxbuf, p, c);
|
||
|
}
|
||
|
if (i0==tmp) break;
|
||
|
} /* end for */
|
||
|
i0 = (uint32_t)(uint8_t)getadress->adress[cp+6U]&15UL;
|
||
|
if (i0) {
|
||
|
rxbuf[*p] = '-';
|
||
|
++*p;
|
||
|
if (i0>9UL) {
|
||
|
rxbuf[*p] = (char)(48UL+i0/10UL);
|
||
|
++*p;
|
||
|
}
|
||
|
rxbuf[*p] = (char)(48UL+i0%10UL);
|
||
|
++*p;
|
||
|
}
|
||
|
if (hbit && (0x40U & (uint16_t)(uint32_t)(uint8_t)
|
||
|
getadress->adress[cp+6U])) {
|
||
|
rxbuf[*p] = '*';
|
||
|
++*p;
|
||
|
}
|
||
|
} /* end ShowCall() */
|
||
|
|
||
|
|
||
|
static void MonHead(char rxbuf[2048], struct l2_GETADRESS * getadress,
|
||
|
l2_pLINK l, int32_t ilen, const char info[],
|
||
|
uint32_t info_len)
|
||
|
{
|
||
|
int32_t p;
|
||
|
int32_t i0;
|
||
|
uint32_t com;
|
||
|
uint16_t cmd;
|
||
|
char cr;
|
||
|
char pf;
|
||
|
char PF0[4];
|
||
|
char s[21];
|
||
|
/* udp2:ARRAY[0..99] OF CHAR; */
|
||
|
int32_t tmp;
|
||
|
l2_GetAdress0(l, getadress);
|
||
|
aprsstr_IntToStr((int32_t)getadress->port, 1UL, rxbuf, 2048ul);
|
||
|
aprsstr_Append(rxbuf, 2048ul, ":fm ", 5ul);
|
||
|
p = (int32_t)aprsstr_Length(rxbuf, 2048ul);
|
||
|
ShowCall(&p, rxbuf, getadress, 7U, 0);
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
rxbuf[p] = 't';
|
||
|
++p;
|
||
|
rxbuf[p] = 'o';
|
||
|
++p;
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
ShowCall(&p, rxbuf, getadress, 0U, 0);
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
i0 = 14L;
|
||
|
while (i0+7L<71L && getadress->adress[i0]) {
|
||
|
if (i0==14L) {
|
||
|
rxbuf[p] = 'v';
|
||
|
++p;
|
||
|
rxbuf[p] = 'i';
|
||
|
++p;
|
||
|
rxbuf[p] = 'a';
|
||
|
++p;
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
}
|
||
|
ShowCall(&p, rxbuf, getadress, (uint16_t)i0, 1);
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
i0 += 7L;
|
||
|
}
|
||
|
rxbuf[p] = 'c';
|
||
|
++p;
|
||
|
rxbuf[p] = 't';
|
||
|
++p;
|
||
|
rxbuf[p] = 'l';
|
||
|
++p;
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
cmd = (uint16_t)getadress->my;
|
||
|
com = (uint32_t)((0x40U & (uint16_t)(uint32_t)(uint8_t)
|
||
|
getadress->adress[6U])!=0)+2UL*(uint32_t)
|
||
|
((0x40U & (uint16_t)(uint32_t)(uint8_t)
|
||
|
getadress->adress[13U])!=0);
|
||
|
pf = (0x10U & cmd)!=0;
|
||
|
cmd = cmd&~0x10U;
|
||
|
if ((cmd&0xFU)==0x1U) {
|
||
|
strncpy(PF0,"RR ",4u);
|
||
|
PF0[2U] = (char)(48U+(uint16_t)cmd/32U);
|
||
|
}
|
||
|
else if ((cmd&0xFU)==0x5U) {
|
||
|
strncpy(PF0,"RNR ",4u);
|
||
|
PF0[3U] = (char)(48U+(uint16_t)cmd/32U);
|
||
|
}
|
||
|
else if ((cmd&0xFU)==0x9U) {
|
||
|
strncpy(PF0,"REJ ",4u);
|
||
|
PF0[3U] = (char)(48U+(uint16_t)cmd/32U);
|
||
|
}
|
||
|
else if ((cmd&0x1U)==0U) {
|
||
|
strncpy(PF0,"I ",4u);
|
||
|
PF0[2U] = (char)(48U+((uint16_t)cmd/2U&7U));
|
||
|
PF0[1U] = (char)(48U+(uint16_t)cmd/32U);
|
||
|
}
|
||
|
else if (cmd==0x3U) strncpy(PF0,"UI ",4u);
|
||
|
else if (cmd==0xFU) strncpy(PF0,"DM ",4u);
|
||
|
else if (cmd==0x2FU) strncpy(PF0,"SABM",4u);
|
||
|
else if (cmd==0x43U) strncpy(PF0,"DISC",4u);
|
||
|
else if (cmd==0x63U) strncpy(PF0,"UA ",4u);
|
||
|
else if (cmd==0x87U) strncpy(PF0,"FRMR",4u);
|
||
|
else WriteHex(rxbuf, &p, (char)getadress->my);
|
||
|
for (i0 = 0L; i0<=3L; i0++) {
|
||
|
if (PF0[i0]!=' ') {
|
||
|
rxbuf[p] = PF0[i0];
|
||
|
++p;
|
||
|
}
|
||
|
} /* end for */
|
||
|
strncpy(PF0,"v^-+",4u);
|
||
|
cr = 1;
|
||
|
if (com==0UL || com==3UL) {
|
||
|
rxbuf[p] = 'v';
|
||
|
++p;
|
||
|
rxbuf[p] = '1';
|
||
|
++p;
|
||
|
}
|
||
|
else {
|
||
|
rxbuf[p] = PF0[(com&1UL)+2UL*(uint32_t)pf];
|
||
|
++p;
|
||
|
}
|
||
|
if (getadress->cpid<=255U) {
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
rxbuf[p] = 'p';
|
||
|
++p;
|
||
|
rxbuf[p] = 'i';
|
||
|
++p;
|
||
|
rxbuf[p] = 'd';
|
||
|
++p;
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
WriteHex(rxbuf, &p, (char)getadress->cpid);
|
||
|
}
|
||
|
if ((0x10U & (uint16_t)(uint32_t)(uint8_t)getadress->adress[13U])
|
||
|
==0) {
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
rxbuf[p] = 'd';
|
||
|
++p;
|
||
|
rxbuf[p] = 'a';
|
||
|
++p;
|
||
|
rxbuf[p] = 'm';
|
||
|
++p;
|
||
|
rxbuf[p] = 'a';
|
||
|
++p;
|
||
|
rxbuf[p] = ' ';
|
||
|
++p;
|
||
|
}
|
||
|
/*
|
||
|
Getudp2info(l, udp2);
|
||
|
IF udp2[0]<>0C THEN
|
||
|
rxbuf[p]:=" ";
|
||
|
INC(p);
|
||
|
i:=0;
|
||
|
WHILE (p<HIGH(rxbuf)) & (udp2[i]<>0C) DO rxbuf[p]:=udp2[i]; INC(p);
|
||
|
INC(i) END;
|
||
|
END;
|
||
|
*/
|
||
|
rxbuf[p] = 0;
|
||
|
if (ilen>0L && montyp==1UL) {
|
||
|
aprsstr_IntToStr(ilen, 1UL, s, 21ul);
|
||
|
aprsstr_Append(rxbuf, 2048ul, " ", 2ul);
|
||
|
aprsstr_Append(rxbuf, 2048ul, s, 21ul);
|
||
|
aprsstr_Append(rxbuf, 2048ul, "B", 2ul);
|
||
|
}
|
||
|
AppendTime(rxbuf, 2048ul);
|
||
|
if (ilen>0L && montyp>1UL) {
|
||
|
p = (int32_t)aprsstr_Length(rxbuf, 2048ul);
|
||
|
rxbuf[p] = '\012';
|
||
|
++p;
|
||
|
tmp = ilen-1L;
|
||
|
i0 = 0L;
|
||
|
if (i0<=tmp) for (;; i0++) {
|
||
|
if ((uint8_t)info[i0]>=' ' && (uint8_t)info[i0]<'\177') {
|
||
|
rxbuf[p] = info[i0];
|
||
|
}
|
||
|
else rxbuf[p] = '.';
|
||
|
++p;
|
||
|
if (i0==tmp) break;
|
||
|
} /* end for */
|
||
|
rxbuf[p] = 0;
|
||
|
}
|
||
|
osi_Werr(rxbuf, 2048ul);
|
||
|
osi_Werr("\012", 2ul);
|
||
|
} /* end MonHead() */
|
||
|
|
||
|
|
||
|
static void Monitor(void)
|
||
|
{
|
||
|
char rxbuf[2048];
|
||
|
struct l2_GETADRESS getadress;
|
||
|
int32_t ilen;
|
||
|
char ibuf[300];
|
||
|
if (pmon==0) pmon = l2_GetMon();
|
||
|
if (pmon) {
|
||
|
ilen = (int32_t)l2_GetStr(pmon, 256U, (l2_pSTRING)ibuf);
|
||
|
MonHead(rxbuf, &getadress, pmon, ilen, ibuf, 300ul);
|
||
|
l2_Disconnect(&pmon, 1); /*release buffer*/
|
||
|
}
|
||
|
} /* end Monitor() */
|
||
|
|
||
|
|
||
|
static void sleeprecon(void)
|
||
|
{
|
||
|
char s[21];
|
||
|
if (!terminate) {
|
||
|
if (verb) {
|
||
|
aprsstr_IntToStr((int32_t)(recontime/1000UL), 1UL, s, 21ul);
|
||
|
osi_Werr(" delay ", 8ul);
|
||
|
osi_Werr(s, 21ul);
|
||
|
osi_Werr("ms before next connect\012", 24ul);
|
||
|
}
|
||
|
usleep(recontime);
|
||
|
}
|
||
|
if (recontime>maxrecontime/2UL) recontime = maxrecontime;
|
||
|
else recontime = recontime*2UL;
|
||
|
} /* end sleeprecon() */
|
||
|
|
||
|
static uint32_t i;
|
||
|
|
||
|
static uint32_t ts;
|
||
|
|
||
|
static uint32_t timeout;
|
||
|
|
||
|
static int32_t ret;
|
||
|
|
||
|
static l2_CALLBACKPROC eventproc;
|
||
|
|
||
|
static pTASK pt;
|
||
|
|
||
|
static pTASK pth;
|
||
|
|
||
|
static int32_t pp0;
|
||
|
|
||
|
static int32_t pp1;
|
||
|
|
||
|
static uint16_t sockset;
|
||
|
|
||
|
|
||
|
X2C_STACK_LIMIT(100000l)
|
||
|
extern int main(int argc, char **argv)
|
||
|
{
|
||
|
uint32_t tmp;
|
||
|
X2C_BEGIN(&argc,argv,1,4000000l,8000000l);
|
||
|
if (sizeof(IOBUF)!=256) X2C_ASSERT(0);
|
||
|
deflate_BEGIN();
|
||
|
frameio_BEGIN();
|
||
|
l2_BEGIN();
|
||
|
osi_BEGIN();
|
||
|
aprsstr_BEGIN();
|
||
|
Execlogin_BEGIN();
|
||
|
memset((char *)frameio_udpsocks0,(char)0,
|
||
|
sizeof(struct frameio_UDPSOCK [15]));
|
||
|
cmdline[0] = 0;
|
||
|
pipename[0] = 0;
|
||
|
connectto0[0] = 0;
|
||
|
memset((char *)mycall,(char)0,113UL);
|
||
|
convlfcr = 0UL;
|
||
|
convtopipe = 0UL;
|
||
|
terminate = 0;
|
||
|
keepconnected = 0;
|
||
|
usedeflat = 0;
|
||
|
verb2 = 0;
|
||
|
verb = 0;
|
||
|
pppmode = 0;
|
||
|
autodet = 0;
|
||
|
pppdiscard = X2C_max_longint;
|
||
|
montyp = 0UL;
|
||
|
minrecontime = 2000000UL;
|
||
|
maxrecontime = 120000000UL;
|
||
|
Parms();
|
||
|
pmon = 0;
|
||
|
eventproc = Event;
|
||
|
sockset = 0U;
|
||
|
tmp = sockc;
|
||
|
i = 0UL;
|
||
|
if (i<=tmp) for (;; i++) {
|
||
|
sockset |= (1U<<i);
|
||
|
if (i==tmp) break;
|
||
|
} /* end for */
|
||
|
l2_L2Init(1000U, sockset, eventproc);
|
||
|
signal(SIGCHLD, cleanup); /*CleanWho*/
|
||
|
/*
|
||
|
MOVE(ADR(mycall), ADR(hc[0*7]), 7); (* via call *)
|
||
|
MOVE(ADR(mycall), ADR(hc[1*7]), 7); (* connect call *)
|
||
|
hc[2*7]:=0C;
|
||
|
*/
|
||
|
parms.test = 0;
|
||
|
parms.parm = 0U; /* mycalls */
|
||
|
parms.port = 1U;
|
||
|
parms.str = (l2_pSTRING)mycall;
|
||
|
l2_Parm(&parms);
|
||
|
for (i = 0UL; i<=255UL; i++) {
|
||
|
parms.test = 0;
|
||
|
parms.port = (uint16_t)i;
|
||
|
parms.parm = 10U;
|
||
|
parms.val = montyp;
|
||
|
l2_Parm(&parms);
|
||
|
if (numpar[i].port>0L) {
|
||
|
/* port configured */
|
||
|
pp0 = numpar[i].port;
|
||
|
pp1 = pp0;
|
||
|
if (pp0>15L) {
|
||
|
/* set parameter to all ports */
|
||
|
pp0 = 1L;
|
||
|
pp1 = 15L;
|
||
|
}
|
||
|
do {
|
||
|
parms.test = 0;
|
||
|
parms.port = (uint16_t)pp0;
|
||
|
parms.parm = (uint16_t)numpar[i].parmnum;
|
||
|
parms.val = (uint32_t)numpar[i].val;
|
||
|
if (verb2) {
|
||
|
osi_WrStr("set port ", 10ul);
|
||
|
osic_WrINT32((uint32_t)parms.port, 1UL);
|
||
|
osi_WrStr(" parmnum ", 10ul);
|
||
|
osic_WrINT32((uint32_t)parms.parm, 1UL);
|
||
|
osi_WrStr(" to value ", 11ul);
|
||
|
osic_WrINT32(parms.val, 1UL);
|
||
|
osi_WrStrLn("", 1ul);
|
||
|
}
|
||
|
l2_Parm(&parms);
|
||
|
++pp0;
|
||
|
} while (pp0<=pp1);
|
||
|
}
|
||
|
} /* end for */
|
||
|
if (connectto0[0U]) {
|
||
|
signal(SIGTERM, killdisc);
|
||
|
signal(SIGINT, killdisc);
|
||
|
signal(SIGPIPE, killdisc);
|
||
|
}
|
||
|
recontime = minrecontime;
|
||
|
tasks = 0;
|
||
|
timesum = 0L;
|
||
|
for (;;) {
|
||
|
if (tasks==0) {
|
||
|
if (terminate) X2C_ABORT();
|
||
|
if (connectto0[0U]) {
|
||
|
for (;;) {
|
||
|
Connectto();
|
||
|
if (terminate || tasks) break;
|
||
|
sleeprecon();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fdclr();
|
||
|
pt = tasks;
|
||
|
while (pt) {
|
||
|
if (pt->state==1U) {
|
||
|
/* recontime:=minrecontime; */
|
||
|
if (cmdline[0U]) {
|
||
|
/* start task */
|
||
|
Login(&pt->infd, pt->l2addr.adress, 72ul);
|
||
|
pt->outfd = pt->infd;
|
||
|
/*WrInt(pt^.fd, 1); WrStrLn(" fd"); */
|
||
|
if (pt->infd>=0L) {
|
||
|
/*ioctl(pt^.fd, TIOCSCTTY, ADR(iocbuf)); */
|
||
|
pt->state = 2U;
|
||
|
}
|
||
|
else {
|
||
|
pt->state = 3U;
|
||
|
if (verb) osi_Werr("task start failed\012", 19ul);
|
||
|
}
|
||
|
}
|
||
|
else if (pipename[0U]) {
|
||
|
/* use pipe */
|
||
|
pt->infd = osi_OpenRW(pipename, 4096ul);
|
||
|
pt->outfd = pt->infd;
|
||
|
if (pt->infd>=0L) pt->state = 2U;
|
||
|
else {
|
||
|
pt->state = 3U;
|
||
|
if (verb) osi_Werr("pipe open error\012", 17ul);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
pt->state = 2U; /* use stdin stdout */
|
||
|
pt->infd = 0L;
|
||
|
pt->outfd = 1L;
|
||
|
}
|
||
|
if (usedeflat) initcompress(pt);
|
||
|
else pt->pcdeflat = 0;
|
||
|
}
|
||
|
else if (pt->state==2U) {
|
||
|
if ((terminate || (0x2U & pt->events)) || (0x4U & pt->events)) {
|
||
|
pt->state = 3U;
|
||
|
if (verb) {
|
||
|
WerrCall(pt);
|
||
|
osi_Werr(" layer2 disconnect\012", 20ul);
|
||
|
}
|
||
|
if (cmdline[0U]==0 && connectto0[0U]==0) X2C_ABORT();
|
||
|
}
|
||
|
if ((pt->infd>=0L && pt->inlen==0L) && pt->inignor==0UL) {
|
||
|
fdsetr((uint32_t)pt->infd);
|
||
|
}
|
||
|
if (pt->inignor>0UL) --pt->inignor;
|
||
|
}
|
||
|
else if (pt->state==3U) {
|
||
|
if (verb) {
|
||
|
WerrCall(pt);
|
||
|
osi_Werr(" disconnect\012", 13ul);
|
||
|
}
|
||
|
if (cmdline[0U]) {
|
||
|
if (pt->infd>=0L && pt->infd!=pt->outfd) {
|
||
|
if (verb) wrclose(pt, pt->infd, " close in pipe ", 16ul);
|
||
|
osic_Close(pt->infd);
|
||
|
}
|
||
|
if (pt->outfd>=0L) {
|
||
|
if (verb) wrclose(pt, pt->outfd, " close out pipe ", 17ul);
|
||
|
osic_Close(pt->outfd);
|
||
|
}
|
||
|
pt->infd = -1L;
|
||
|
pt->outfd = -1L;
|
||
|
fdclr();
|
||
|
}
|
||
|
l2_Disconnect(&pt->link0, 0);
|
||
|
pt->state = 4U;
|
||
|
}
|
||
|
if (pt->state==4U || pt->state==5U) {
|
||
|
if ((terminate || (0x2U & pt->events)) || (0x4U & pt->events)) {
|
||
|
if (verb) {
|
||
|
WerrCall(pt);
|
||
|
osi_Werr(" deallocate link\012", 18ul);
|
||
|
}
|
||
|
l2_Disconnect(&pt->link0, 1);
|
||
|
if (verb) {
|
||
|
WerrCall(pt);
|
||
|
osi_Werr(" disconnect close layer2\012", 26ul);
|
||
|
}
|
||
|
if (tasks==pt) tasks = pt->next;
|
||
|
else {
|
||
|
pth = tasks;
|
||
|
while (pth->next!=pt) pth = pth->next;
|
||
|
pth->next = pt->next;
|
||
|
}
|
||
|
if (pt->pcdeflat) {
|
||
|
osic_free((char * *) &pt->pcdeflat,
|
||
|
sizeof(struct DEFLATBUF));
|
||
|
}
|
||
|
osic_free((char * *) &pt, sizeof(struct TASK));
|
||
|
pt = 0;
|
||
|
if (tasks==0) {
|
||
|
if (!keepconnected) terminate = 1;
|
||
|
else if (connectto0[0U]) sleeprecon();
|
||
|
}
|
||
|
}
|
||
|
else pt = pt->next;
|
||
|
}
|
||
|
else pt = pt->next;
|
||
|
}
|
||
|
ts = 0UL;
|
||
|
timeout = 10000UL;
|
||
|
ret = selectrwt(&ts, &timeout);
|
||
|
timesum += (int32_t)(10000UL-timeout);
|
||
|
if (timesum>=10000L) {
|
||
|
/* IF timeout<=0 THEN */
|
||
|
l2_Layer2();
|
||
|
if (montyp>0UL) Monitor();
|
||
|
timesum -= 10000L;
|
||
|
}
|
||
|
pt = tasks;
|
||
|
while (pt) {
|
||
|
if (pt->state==2U && pt->infd>=0L) {
|
||
|
/*WrInt(pt^.state, 1); WrStrLn(" st"); */
|
||
|
if (issetr((uint32_t)pt->infd)) {
|
||
|
if (pt->inlen==0L) {
|
||
|
if (!terminate) {
|
||
|
/* read blocks after a SIGINT - why ever */
|
||
|
pt->inlen = osi_RdBin(pt->infd, (char *)pt->inbuf,
|
||
|
256u/1u, 256UL);
|
||
|
if (pt->inlen==0L) {
|
||
|
pt->inignor = 20UL; /* read from pipe why ever */
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (verb2 && pt->inlen>0L) {
|
||
|
Whex("IN ", 4ul, pt->inbuf, 256ul, pt->inlen);
|
||
|
}
|
||
|
}
|
||
|
/*WrStrLn("");WrStr("I:"); ShowHex(pt^.inbuf, pt^.inlen); */
|
||
|
if (pt->inlen>0L) {
|
||
|
if (~pt->detectdone>0UL) {
|
||
|
detect(pt); /* switch option with first bytes in stdin */
|
||
|
}
|
||
|
if (pt->pcdeflat) {
|
||
|
/* compress */
|
||
|
if (pt->pcdeflat->outlen==0L) compress(pt);
|
||
|
wrl2(pt->link0, pt->pcdeflat->outbuf, 20001ul,
|
||
|
&pt->pcdeflat->outlen, &pt->junkbuf);
|
||
|
}
|
||
|
else {
|
||
|
crlf(pt->inbuf, 256ul, &pt->inlen, pt->crlfmode);
|
||
|
wrl2(pt->link0, pt->inbuf, 256ul, &pt->inlen,
|
||
|
&pt->junkbuf);
|
||
|
}
|
||
|
}
|
||
|
else if (pt->inlen<0L) {
|
||
|
if (pt->junkbuf.len>0L) {
|
||
|
/* send rest */
|
||
|
pt->junkbuf.time0 = 0L;
|
||
|
sendjunk(pt->link0, &pt->junkbuf);
|
||
|
}
|
||
|
else {
|
||
|
pt->state = 3U;
|
||
|
if (verb) osi_Werr("read pipe from task broken\012", 28ul);
|
||
|
}
|
||
|
}
|
||
|
if (pt->state==2U) {
|
||
|
for (;;) {
|
||
|
if (pt->outlen>0L) {
|
||
|
if (verb2) {
|
||
|
Whex("OUT ", 5ul, pt->outbuf, 256ul, pt->outlen);
|
||
|
}
|
||
|
if (pt->pcdeflat) {
|
||
|
/* decompress */
|
||
|
if (!pt->pcdeflat->done) {
|
||
|
expand(pt);
|
||
|
if (pt->pcdeflat->xoutlen<0L) {
|
||
|
/* expand or crc error */
|
||
|
pt->state = 3U;
|
||
|
if (verb) {
|
||
|
osi_Werr("deflate or crc error\012", 22ul);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (!pt->pcdeflat->pppframing || pt->pcdeflat->done) {
|
||
|
if (pt->pcdeflat->xoutlen>0L) {
|
||
|
wrpipe(pt->outfd, pt->pcdeflat->xoutbuf,
|
||
|
4096ul, &pt->pcdeflat->xoutlen);
|
||
|
}
|
||
|
if (pt->pcdeflat->xoutlen==0L) {
|
||
|
pt->pcdeflat->done = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
crlfp(pt->outbuf, 256ul, &pt->outlen, convtopipe);
|
||
|
wrpipe(pt->outfd, pt->outbuf, 256ul, &pt->outlen);
|
||
|
}
|
||
|
}
|
||
|
if (pt->outlen==0L) {
|
||
|
pt->outlen = (int32_t)l2_GetStr(pt->link0, 256U,
|
||
|
(l2_pSTRING)pt->outbuf);
|
||
|
if (pt->outlen<=0L) break;
|
||
|
}
|
||
|
else break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (pt->junkbuf.len>0L) {
|
||
|
if (pt->junkbuf.time0>0L) --pt->junkbuf.time0;
|
||
|
else sendjunk(pt->link0, &pt->junkbuf);
|
||
|
}
|
||
|
pt = pt->next;
|
||
|
}
|
||
|
}
|
||
|
X2C_EXIT();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
X2C_MAIN_DEFINITION
|