* auto i/o - Added socket interface to allow separate program to access
    - CONNECT
    - DISCONNECT
    - CONNECTION_STATE
    - SEND_TEXT
    - RECEIVE_TEXT
    Allows similarly modified flmsg to send/recv messages using
    flarq / ARQ transport protocol.
  * ARQ reset - force complete reset of all ARQ processes
    - drops link without any indicator to connected station
    - equivalent of stopping and restarting flarq
    - courtesy demands that you inform the CONNECTED station
      to also kill the connection at that end of the link.
    - use Control-Left_click on the "CONNECT / DISCONNECT"
      button to initiate the forced reset.
  * Update ARQ icons
  * Disable auto-open flmsg when flmsg->flarq->fldigi data path
    is active.
pull/4/head
David Freese 2016-04-12 13:38:23 -05:00
rodzic 9c04f07877
commit 76ab77cd0c
13 zmienionych plików z 3077 dodań i 1148 usunięć

2287
data/flarq.pdf 100644

File diff suppressed because one or more lines are too long

Plik diff jest za duży Load Diff

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 12 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 361 KiB

Wyświetl plik

@ -35,19 +35,25 @@ $EXTRA_LIBS $FLXMLRPC_LIBS"
# CPPFLAGS # CPPFLAGS
FLARQ_BUILD_CPPFLAGS="-I\$(srcdir) -I\$(srcdir)/include -I\$(srcdir)/fileselector \ FLARQ_BUILD_CPPFLAGS="-I\$(srcdir) -I\$(srcdir)/include -I\$(srcdir)/fileselector \
-I\$(srcdir)/flarq-src -I\$(srcdir)/flarq-src/include" -I\$(srcdir)/flarq-src -I\$(srcdir)/flarq-src/include"
if test "x$ac_cv_flxmlrpc" != "xyes"; then
FLARQ_BUILD_CPPFLAGS="$FLARQ_BUILD_CPPFLAGS -I\$(srcdir)/xmlrpcpp"
fi
# CXXFLAGS # CXXFLAGS
FLARQ_BUILD_CXXFLAGS="$FLTK_CFLAGS $X_CFLAGS $MAC_UNIVERSAL_CFLAGS $INTL_CFLAGS $PTW32_CFLAGS \ FLARQ_BUILD_CXXFLAGS="$FLTK_CFLAGS $X_CFLAGS $MAC_UNIVERSAL_CFLAGS $INTL_CFLAGS $PTW32_CFLAGS \
$BFD_CFLAGS -pipe -Wall -fexceptions $OPT_CFLAGS $DEBUG_CFLAGS" $BFD_CFLAGS -pipe -Wall -fexceptions $OPT_CFLAGS $DEBUG_CFLAGS"
if test "x$target_mingw32" = "xyes"; then if test "x$target_mingw32" = "xyes"; then
FLARQ_BUILD_CXXFLAGS="-mthreads $FLARQ_BUILD_CXXFLAGS" FLARQ_BUILD_CXXFLAGS="-mthreads $FLARQ_BUILD_CXXFLAGS"
fi fi
if test "x$ac_cv_flxmlrpc" != "xyes"; then
FLARQ_BUILD_CXXFLAGS="$FLARQ_BUILD_CXXFLAGS -I\$(srcdir)/xmlrpcpp"
fi
# LDFLAGS # LDFLAGS
FLARQ_BUILD_LDFLAGS="$MAC_UNIVERSAL_LDFLAGS" FLARQ_BUILD_LDFLAGS="$MAC_UNIVERSAL_LDFLAGS"
if test "x$target_mingw32" = "xyes"; then if test "x$target_mingw32" = "xyes"; then
FLARQ_BUILD_LDFLAGS="-mthreads $FLARQ_BUILD_LDFLAGS" FLARQ_BUILD_LDFLAGS="-mthreads $FLARQ_BUILD_LDFLAGS"
fi fi
# LDADD # LDADD
FLARQ_BUILD_LDADD="$FLTK_LIBS $X_LIBS $INTL_LIBS $PTW32_LIBS $BFD_LIBS $EXTRA_LIBS" FLARQ_BUILD_LDADD="$FLTK_LIBS $X_LIBS $INTL_LIBS $PTW32_LIBS $BFD_LIBS $EXTRA_LIBS $FLXMLRPC_LIBS"
if test "x$ac_cv_debug" = "xyes"; then if test "x$ac_cv_debug" = "xyes"; then
FLDIGI_BUILD_CXXFLAGS="$FLDIGI_BUILD_CXXFLAGS -UNDEBUG" FLDIGI_BUILD_CXXFLAGS="$FLDIGI_BUILD_CXXFLAGS -UNDEBUG"

Wyświetl plik

@ -35,16 +35,25 @@ include/hamlib.h \
rigcontrol/hamlib.cxx \ rigcontrol/hamlib.cxx \
include/rigclass.h \ include/rigclass.h \
rigcontrol/rigclass.cxx rigcontrol/rigclass.cxx
XMLRPC_SRC = \ XMLRPC_SRC = \
include/xmlrpc.h \ include/xmlrpc.h \
misc/xmlrpc.cxx misc/xmlrpc.cxx
FLDIGI_WIN32_RES_SRC = fldigirc.rc FLDIGI_WIN32_RES_SRC = fldigirc.rc
FLARQ_WIN32_RES_SRC = flarq-src/flarqrc.rc FLARQ_WIN32_RES_SRC = flarq-src/flarqrc.rc
COMMON_WIN32_RES_SRC = common.rc COMMON_WIN32_RES_SRC = common.rc
BENCHMARK_SRC = include/benchmark.h misc/benchmark.cxx BENCHMARK_SRC = include/benchmark.h misc/benchmark.cxx
REGEX_SRC = compat/regex.h compat/regex.c REGEX_SRC = compat/regex.h compat/regex.c
STACK_SRC = include/stack.h misc/stack.cxx STACK_SRC = include/stack.h misc/stack.cxx
MINGW32_SRC = include/compat.h compat/getsysinfo.c compat/mingw.c compat/mingw.h MINGW32_SRC = include/compat.h compat/getsysinfo.c compat/mingw.c compat/mingw.h
NLS_SRC = misc/nls.cxx include/nls.h NLS_SRC = misc/nls.cxx include/nls.h
# We distribute these but do not always compile them # We distribute these but do not always compile them
@ -77,7 +86,7 @@ XMLRPCPP_SRC = \
EXTRA_fldigi_SOURCES = $(HAMLIB_SRC) $(XMLRPC_SRC) $(FLDIGI_WIN32_RES_SRC) $(COMMON_WIN32_RES_SRC) \ EXTRA_fldigi_SOURCES = $(HAMLIB_SRC) $(XMLRPC_SRC) $(FLDIGI_WIN32_RES_SRC) $(COMMON_WIN32_RES_SRC) \
$(BENCHMARK_SRC) $(REGEX_SRC) $(STACK_SRC) $(MINGW32_SRC) $(NLS_SRC) $(XMLRPCPP_SRC) $(BENCHMARK_SRC) $(REGEX_SRC) $(STACK_SRC) $(MINGW32_SRC) $(NLS_SRC) $(XMLRPCPP_SRC)
EXTRA_flarq_SOURCES = $(FLARQ_WIN32_RES_SRC) $(COMMON_WIN32_RES_SRC) EXTRA_flarq_SOURCES = $(FLARQ_WIN32_RES_SRC) $(COMMON_WIN32_RES_SRC) $(XMLRPCPP_SRC)
fldigi_SOURCES = fldigi_SOURCES =
flarq_SOURCES = flarq_SOURCES =
@ -86,11 +95,16 @@ fldigi_SOURCES += $(XMLRPC_SRC)
if !ENABLE_FLXMLRPC if !ENABLE_FLXMLRPC
fldigi_SOURCES += $(XMLRPCPP_SRC) fldigi_SOURCES += $(XMLRPCPP_SRC)
flarq_SOURCES += $(XMLRPCPP_SRC)
else else
fldigi_CPPFLAGS += @FLXMLRPC_CFLAGS@ fldigi_CPPFLAGS += @FLXMLRPC_CFLAGS@
fldigi_CXXFLAGS += @FLXMLRPC_CFLAGS@ fldigi_CXXFLAGS += @FLXMLRPC_CFLAGS@
fldigi_CFLAGS += @FLXMLRPC_CFLAGS@ fldigi_CFLAGS += @FLXMLRPC_CFLAGS@
fldigi_LDFLAGS += @FLXMLRPC_LIBS@ fldigi_LDFLAGS += @FLXMLRPC_LIBS@
flarq_CPPFLAGS += @FLXMLRPC_CFLAGS@
flarq_CXXFLAGS += @FLXMLRPC_CFLAGS@
flarq_CFLAGS += @FLXMLRPC_CFLAGS@
flarq_LDFLAGS += @FLXMLRPC_LIBS@
endif endif
if ENABLE_HAMLIB if ENABLE_HAMLIB
@ -734,11 +748,13 @@ flarq_SOURCES += \
flarq-src/b64.cxx \ flarq-src/b64.cxx \
flarq-src/flarq.cxx \ flarq-src/flarq.cxx \
flarq-src/flarqenv.cxx \ flarq-src/flarqenv.cxx \
flarq-src/xml_server.cxx \
flarq-src/include/arq.h \ flarq-src/include/arq.h \
flarq-src/include/arqdialogs.h \ flarq-src/include/arqdialogs.h \
flarq-src/include/b64.h \ flarq-src/include/b64.h \
flarq-src/include/flarq.h \ flarq-src/include/flarq.h \
flarq-src/include/flarqenv.h \ flarq-src/include/flarqenv.h \
flarq-src/include/xml_server.h \
include/Fl_Text_Display_mod.H \ include/Fl_Text_Display_mod.H \
include/Fl_Text_Editor_mod.H \ include/Fl_Text_Editor_mod.H \
include/FTextView.h \ include/FTextView.h \

Wyświetl plik

@ -38,9 +38,9 @@ string RXIDENT = "RX: Link Still Active";
string RXCONREQ = "RX: Connect Request"; string RXCONREQ = "RX: Connect Request";
string RXCONACK = "RX: Connect OK"; string RXCONACK = "RX: Connect OK";
string RXDISCONN = "RX: Disconnect Request"; string RXDISCONN = "RX: Disconnect Request";
string RXDISCONACK = "RX: Disconnect OK"; string RXDISCONACK = "RX: Disconnect OK";
string RXSTATUS = "RX: Status Report"; string RXSTATUS = "RX: Status Report";
string RXPOLL = "RX: Send Blocks Report"; string RXPOLL = "RX: Send Blocks Report";
string TXSTATUS = "TX: Blocks Received OK"; string TXSTATUS = "TX: Blocks Received OK";
string TXDISCONN = "TX: Disconnect Request"; string TXDISCONN = "TX: Disconnect Request";
string TXDISACK = "TX: Disconnect OK"; string TXDISACK = "TX: Disconnect OK";
@ -69,12 +69,12 @@ arq::arq()
printRX_DEBUG = NULL; printRX_DEBUG = NULL;
printTX_DEBUG = NULL; printTX_DEBUG = NULL;
rxUrCall = NULL; rxUrCall = NULL;
Header.erase(); Header.erase();
MyStreamID = '0'; MyStreamID = '0';
UrStreamID = '0'; UrStreamID = '0';
UrCall.erase(); UrCall.erase();
MyCall.erase(); MyCall.erase();
@ -89,7 +89,7 @@ arq::arq()
TXflag = false; TXflag = false;
SessionNumber = 0; SessionNumber = 0;
exponent = EXPONENT; exponent = EXPONENT;
maxheaders = MAXHEADERS; maxheaders = MAXHEADERS;
RetryTime = RETRYTIME; RetryTime = RETRYTIME;
@ -100,7 +100,7 @@ arq::arq()
primary = false; primary = false;
setBufferlength(); setBufferlength();
// status variables // // status variables //
// totalRx = 0; // totalRx = 0;
@ -122,7 +122,7 @@ arq::arq()
UrLastHeader = MAXCOUNT - 1; // Other station's Header last sent UrLastHeader = MAXCOUNT - 1; // Other station's Header last sent
UrEndHeader = MAXCOUNT - 1; // Other station's last received Header UrEndHeader = MAXCOUNT - 1; // Other station's last received Header
blkcount = -1; blkcount = -1;
TXflag = false; // TX on TXflag = false; // TX on
LinkState = DOWN; // ARQ link is initially down LinkState = DOWN; // ARQ link is initially down
Sending = 0; Sending = 0;
@ -131,7 +131,7 @@ arq::arq()
MyMissing.clear(); MyMissing.clear();
MissingRxBlocks = ""; MissingRxBlocks = "";
TxBlocks.clear(); TxBlocks.clear();
TxMissing.clear(); TxMissing.clear();
TxPending.clear(); TxPending.clear();
@ -139,17 +139,17 @@ arq::arq()
RxPending.clear(); RxPending.clear();
arqstop = false; arqstop = false;
retries = baseRetries = Retries; retries = baseRetries = Retries;
baseRetryTime = RetryTime; baseRetryTime = RetryTime;
baseTimeout = Timeout; baseTimeout = Timeout;
retrytime = RetryTime / ARQLOOPTIME; retrytime = RetryTime / ARQLOOPTIME;
timeout = Timeout / ARQLOOPTIME; timeout = Timeout / ARQLOOPTIME;
loopcount = 0; loopcount = 0;
tx2txdelay = 0;//TxDelay / ARQLOOPTIME; tx2txdelay = 0;//TxDelay / ARQLOOPTIME;
// srand(time(NULL)); // srand(time(NULL));
} }
@ -196,14 +196,14 @@ void arq::reset()
// new session number // new session number
// unknown stream id = 0 // unknown stream id = 0
// known id's from 1 to 63 // known id's from 1 to 63
void arq::newsession() void arq::newsession()
{ {
if (++SessionNumber == 64) SessionNumber = 1; if (++SessionNumber == 64) SessionNumber = 1;
MyStreamID = SessionNumber + '0'; MyStreamID = SessionNumber + '0';
} }
// get new blocknumber // get new blocknumber
void arq::newblocknumber() void arq::newblocknumber()
{ {
Lastqueued++; Lastqueued++;
Lastqueued %= MAXCOUNT; Lastqueued %= MAXCOUNT;
@ -252,7 +252,7 @@ void arq::addToTxQue(string s)
// c Header = Client:port Server:port <streamnr. (0)> <max. Headerlen> // c Header = Client:port Server:port <streamnr. (0)> <max. Headerlen>
// e.g.: '00cW1HKJ:1025 KH6TY:24 4' // e.g.: '00cW1HKJ:1025 KH6TY:24 4'
// //
void arq::connectFrame() void arq::connectFrame()
{ {
char szGlobals[24]; char szGlobals[24];
reset(); reset();
@ -280,9 +280,9 @@ void arq::connectFrame()
addToTxQue(Frame); addToTxQue(Frame);
LinkState = CONNECTING; LinkState = ARQ_CONNECTING;
printSTATUS(TXCONNECT, 5.0); printSTATUS(TXCONNECT, 5.0);
} }
// Connect acknowledge (server:port, client:port) // Connect acknowledge (server:port, client:port)
@ -294,7 +294,7 @@ void arq::ackFrame ()
reset(); reset();
IdHeader(); IdHeader();
Header += CONACK; Header += CONACK;
Payload.erase(); Payload.erase();
Payload.append(MyCall); Payload.append(MyCall);
Payload.append(":24"); Payload.append(":24");
@ -304,7 +304,7 @@ void arq::ackFrame ()
Payload += MyStreamID; Payload += MyStreamID;
Payload += ' '; Payload += ' ';
Payload += MyBlockLengthChar; Payload += MyBlockLengthChar;
Frame = Header + Payload; Frame = Header + Payload;
Frame = Frame + checksum(Frame); Frame = Frame + checksum(Frame);
Frame += EOT; Frame += EOT;
@ -317,11 +317,11 @@ void arq::ackFrame ()
// c Header = Caller:port static:port <streamnr. (0)> <max. Headerlen> // c Header = Caller:port static:port <streamnr. (0)> <max. Headerlen>
// e.g.: '00cW1HKJ:87 KH6TY:87 4' // e.g.: '00cW1HKJ:87 KH6TY:87 4'
// //
void arq::ttyconnectFrame() void arq::ttyconnectFrame()
{ {
UnkHeader(); UnkHeader();
Header += CONREQ; Header += CONREQ;
Payload.erase(); Payload.erase();
Payload.append(MyCall); Payload.append(MyCall);
Payload.append(":87"); Payload.append(":87");
@ -332,24 +332,24 @@ void arq::ttyconnectFrame()
Payload += MyStreamID; Payload += MyStreamID;
Payload += ' '; Payload += ' ';
Payload += MyBlockLengthChar; Payload += MyBlockLengthChar;
Frame = Header + Payload; Frame = Header + Payload;
Frame = Frame + checksum(Frame); Frame = Frame + checksum(Frame);
Frame += EOT; Frame += EOT;
addToTxQue(Frame); addToTxQue(Frame);
} }
// Connect acknowledge (server:port, client:port) // Connect acknowledge (server:port, client:port)
// k Header = Server:port Client:port <streamnr.> <max. Headerlen> // k Header = Server:port Client:port <streamnr.> <max. Headerlen>
// e.g: '00kKH6TY:87 W1HKJ 4' // e.g: '00kKH6TY:87 W1HKJ 4'
// Service id # 87 is keyboard-to-keyboard // Service id # 87 is keyboard-to-keyboard
// //
void arq::ttyackFrame() void arq::ttyackFrame()
{ {
IdHeader(); IdHeader();
Header += CONACK; Header += CONACK;
Payload.erase(); Payload.erase();
Payload.append(MyCall); Payload.append(MyCall);
Payload.append(":87"); Payload.append(":87");
@ -357,7 +357,7 @@ void arq::ttyackFrame()
Payload.append(UrCall); Payload.append(UrCall);
Payload += ' '; Payload += ' ';
Payload += MyBlockLengthChar; Payload += MyBlockLengthChar;
Frame = Header + Payload; Frame = Header + Payload;
Frame = Frame + checksum(Frame); Frame = Frame + checksum(Frame);
Frame += EOT; Frame += EOT;
@ -371,12 +371,12 @@ void arq::identFrame()
{ {
IdHeader(); IdHeader();
Header += IDENT; Header += IDENT;
Payload.erase(); Payload.erase();
Payload.append(UrCall); Payload.append(UrCall);
Payload.append(" de "); Payload.append(" de ");
Payload.append(MyCall); Payload.append(MyCall);
Frame = Header + Payload; Frame = Header + Payload;
Frame = Frame + checksum(Frame); Frame = Frame + checksum(Frame);
Frame += EOT; Frame += EOT;
@ -386,7 +386,7 @@ void arq::identFrame()
char szIDENT[80]; char szIDENT[80];
snprintf(szIDENT,sizeof(szIDENT), TXIDENT.c_str(), retries); snprintf(szIDENT,sizeof(szIDENT), TXIDENT.c_str(), retries);
printSTATUS(szIDENT, 5.0); printSTATUS(szIDENT, 5.0);
} }
// e.g. Ping frame // e.g. Ping frame
@ -396,27 +396,27 @@ void arq::pingFrame()
{ {
IdHeader(); IdHeader();
Header += _UNPROTO; Header += _UNPROTO;
Payload.erase(); Payload.erase();
Payload.append(MyCall); Payload.append(MyCall);
Payload.append(":7"); Payload.append(":7");
Payload += ' '; Payload += ' ';
Frame = Header + Payload; Frame = Header + Payload;
Frame = Frame + checksum(Frame); Frame = Frame + checksum(Frame);
Frame += EOT; Frame += EOT;
addToTxQue(Frame); addToTxQue(Frame);
} }
// talk frame // talk frame
// similar to UNPROTO frame // similar to UNPROTO frame
// but only sent if CONNECTED // but only sent if ARQ_CONNECTED
void arq::talkFrame(string txt) void arq::talkFrame(string txt)
{ {
IdHeader(); IdHeader();
Header += _TALK; Header += _TALK;
Payload.erase(); Payload.erase();
Payload.append(MyCall); Payload.append(MyCall);
Payload.append(":73"); Payload.append(":73");
@ -442,11 +442,11 @@ void arq::ackAbortFrame()
Payload += (GoodHeader + 0x20); Payload += (GoodHeader + 0x20);
Payload += (EndHeader + 0x20); Payload += (EndHeader + 0x20);
Payload.append(MissingRxBlocks); Payload.append(MissingRxBlocks);
Frame = Header + Payload; Frame = Header + Payload;
Frame = Frame + checksum(Frame); Frame = Frame + checksum(Frame);
Frame += EOT; Frame += EOT;
addToTxQue(Frame); addToTxQue(Frame);
printSTATUS(TXSTATUS, 5.0); printSTATUS(TXSTATUS, 5.0);
} }
@ -455,7 +455,7 @@ void arq::ackAbortFrame()
//p frame = <last Header tx><last Header rx ok><last Header rx> <missing Headers> //p frame = <last Header tx><last Header rx ok><last Header rx> <missing Headers>
//e.g.: '00sXHCAB' //e.g.: '00sXHCAB'
// //
void arq::statFrame() void arq::statFrame()
{ {
IdHeader(); IdHeader();
Header += STATUS; Header += STATUS;
@ -465,11 +465,11 @@ void arq::statFrame()
Payload += (GoodHeader + 0x20); Payload += (GoodHeader + 0x20);
Payload += (EndHeader + 0x20); Payload += (EndHeader + 0x20);
Payload.append(MissingRxBlocks); Payload.append(MissingRxBlocks);
Frame = Header + Payload; Frame = Header + Payload;
Frame = Frame + checksum(Frame); Frame = Frame + checksum(Frame);
Frame += EOT; Frame += EOT;
addToTxQue(Frame); addToTxQue(Frame);
printSTATUS(TXSTATUS, 5.0); printSTATUS(TXSTATUS, 5.0);
} }
@ -498,7 +498,7 @@ void arq::disackFrame()
{ {
IdHeader(); IdHeader();
Header += _DISACK; Header += _DISACK;
Payload.erase(); Payload.erase();
Payload.append(MyCall); Payload.append(MyCall);
Payload.append(":91"); Payload.append(":91");
@ -531,7 +531,7 @@ void arq::abortFrame()
// u Header = From:port data // u Header = From:port data
// e.g: '00uKH6TY:72 Beacon text ' // e.g: '00uKH6TY:72 Beacon text '
// //
void arq::beaconFrame(string txt) void arq::beaconFrame(string txt)
{ {
UnkHeader(); UnkHeader();
Header += _UNPROTO; Header += _UNPROTO;
@ -555,7 +555,7 @@ void arq::beaconFrame(string txt)
// poll // poll
//p frame = <last Header tx><last Header rx ok><last Header rx> <missing Headers> //p frame = <last Header tx><last Header rx ok><last Header rx> <missing Headers>
//e.g.: '00pXHCAB' //e.g.: '00pXHCAB'
void arq::pollFrame() void arq::pollFrame()
{ {
IdHeader(); IdHeader();
@ -603,8 +603,8 @@ void arq::parseCONREQ()
size_t p1 = 0, p2 = rcvPayload.find(':'); size_t p1 = 0, p2 = rcvPayload.find(':');
if (p2 == string::npos) if (p2 == string::npos)
return; return;
// if (LinkState == CONNECTED || LinkState == WAITFORACK) return; // disallow multiple connects // if (LinkState == ARQ_CONNECTED || LinkState == WAITFORACK) return; // disallow multiple connects
// requesting stations callsign // requesting stations callsign
UrCall = upcase(rcvPayload.substr(p1, p2 - p1)); UrCall = upcase(rcvPayload.substr(p1, p2 - p1));
p1 = rcvPayload.find(' ', p2+1); p1 = rcvPayload.find(' ', p2+1);
@ -631,7 +631,7 @@ void arq::parseCONREQ()
UrStreamID = rcvPayload[p1]; UrStreamID = rcvPayload[p1];
p1++; // *p1 ==> requested block size p1++; // *p1 ==> requested block size
UrBlockLengthChar = rcvPayload[p1]; UrBlockLengthChar = rcvPayload[p1];
p1 += 3; // *p1 ==>" TnnnRnnnWnnn" p1 += 3; // *p1 ==>" TnnnRnnnWnnn"
if (p1 < rcvPayload.length()) { if (p1 < rcvPayload.length()) {
char num[7]; char num[7];
@ -655,7 +655,7 @@ void arq::parseCONREQ()
Timeout += Retries * RetryTime; Timeout += Retries * RetryTime;
} }
} }
/* /*
char line[80]; char line[80];
string NewValues = "Temporary control parameters set to\n"; string NewValues = "Temporary control parameters set to\n";
snprintf(line, 79, " Retries = %d\n", Retries); snprintf(line, 79, " Retries = %d\n", Retries);
@ -668,15 +668,15 @@ void arq::parseCONREQ()
*/ */
} }
} }
reset(); reset();
LinkState = WAITFORACK; LinkState = WAITFORACK;
newsession(); newsession();
if (rxUrCall) rxUrCall(UrCall); if (rxUrCall) rxUrCall(UrCall);
TxTextQueue.clear();//erase(); TxTextQueue.clear();
ackFrame(); ackFrame();
immediate = true; immediate = true;
printSTATUS(RXCONREQ, 5.0); printSTATUS(RXCONREQ, 5.0);
@ -685,10 +685,10 @@ void arq::parseCONREQ()
void arq::parseCONACK() void arq::parseCONACK()
{ {
if (LinkState < CONNECTING ) { //!= CONNECTING) { if (LinkState < ARQ_CONNECTING ) { //!= ARQ_CONNECTING) {
return; // Connect Acknowledge only valid during a connect return; // Connect Acknowledge only valid during a connect
} }
size_t p1 = 0, p2 = rcvPayload.find(':'); size_t p1 = 0, p2 = rcvPayload.find(':');
// LinkState = DOWN; // LinkState = DOWN;
if (p2 == string::npos) if (p2 == string::npos)
@ -708,7 +708,7 @@ void arq::parseCONACK()
UrCall.erase(); UrCall.erase();
return; return;
} }
p1++; // *p1 ==> StreamID for requesting station p1++; // *p1 ==> StreamID for requesting station
UrStreamID = rcvPayload[p1]; UrStreamID = rcvPayload[p1];
p1++; // *p1 ==> requested block size p1++; // *p1 ==> requested block size
@ -716,9 +716,9 @@ void arq::parseCONACK()
RxTextQueue.clear();//erase(); RxTextQueue.clear();//erase();
LinkState = CONNECTED; LinkState = ARQ_CONNECTED;
timeout = Timeout / ARQLOOPTIME; timeout = Timeout / ARQLOOPTIME;
statFrame(); statFrame();
immediate = true; immediate = true;
primary = true; primary = true;
@ -753,14 +753,14 @@ void arq::parseABORT()
if (abortfnc) abortfnc(); if (abortfnc) abortfnc();
ackAbortFrame(); ackAbortFrame();
immediate = true; immediate = true;
LinkState = CONNECTED; LinkState = ARQ_CONNECTED;
} }
void arq::parseACKABORT() void arq::parseACKABORT()
{ {
reset(); reset();
if (abortfnc) abortfnc(); if (abortfnc) abortfnc();
LinkState = CONNECTED; LinkState = ARQ_CONNECTED;
} }
void arq::parseUNPROTO() void arq::parseUNPROTO()
@ -787,7 +787,7 @@ void arq::parseSTATUS()
{ {
// create the missing list // create the missing list
// all reported missing blocks // all reported missing blocks
if (LinkState >= CONNECTED) { if (LinkState >= ARQ_CONNECTED) {
UrLastHeader = rcvPayload[0] - 0x20; // Other station's Header last sent UrLastHeader = rcvPayload[0] - 0x20; // Other station's Header last sent
UrGoodHeader = rcvPayload[1] - 0x20; // Other station's Good Header UrGoodHeader = rcvPayload[1] - 0x20; // Other station's Good Header
UrEndHeader = rcvPayload[2] - 0x20; // Other station's last received Header UrEndHeader = rcvPayload[2] - 0x20; // Other station's last received Header
@ -809,10 +809,10 @@ void arq::parseSTATUS()
} }
missing.push_back(LastHeader); missing.push_back(LastHeader);
} }
if (missing.empty()) if (missing.empty())
TxMissing.clear(); TxMissing.clear();
if (TxMissing.empty() == false) { if (TxMissing.empty() == false) {
list<cTxtBlk> keep; list<cTxtBlk> keep;
list<cTxtBlk>::iterator p = TxMissing.begin(); list<cTxtBlk>::iterator p = TxMissing.begin();
@ -846,19 +846,19 @@ void arq::parseSTATUS()
switch (LinkState) { switch (LinkState) {
case WAITFORACK : case WAITFORACK :
LinkState = CONNECTED; LinkState = ARQ_CONNECTED;
break; break;
case DISCONNECTING : case DISCONNECTING :
if (rxUrCall) rxUrCall(""); if (rxUrCall) rxUrCall("");
LinkState = DOWN; LinkState = DOWN;
break; break;
case WAITING : case WAITING :
LinkState = CONNECTED; LinkState = ARQ_CONNECTED;
break; break;
// case ABORTING : // case ABORTING :
// reset(); // reset();
// if (abortfnc) abortfnc(); // if (abortfnc) abortfnc();
// LinkState = CONNECTED; // LinkState = ARQ_CONNECTED;
// break; // break;
// case ABORT : // case ABORT :
// break; // break;
@ -871,12 +871,12 @@ void arq::parseSTATUS()
void arq::parsePOLL() void arq::parsePOLL()
{ {
if (LinkState == DISCONNECTING || LinkState == DOWN || if (LinkState == DISCONNECTING || LinkState == DOWN ||
LinkState == TIMEDOUT || LinkState == ABORT ) LinkState == TIMEDOUT || LinkState == ABORT )
return; return;
statFrame(); statFrame();
immediate = true; immediate = true;
LinkState = CONNECTED; LinkState = ARQ_CONNECTED;
printSTATUS(RXPOLL, 5.0); printSTATUS(RXPOLL, 5.0);
} }
@ -884,18 +884,18 @@ void arq::parseDATA()
{ {
vector<cTxtBlk>::iterator p1, p2; vector<cTxtBlk>::iterator p1, p2;
int n1, n2; int n1, n2;
if (LinkState < CONNECTED) return; // do not respond if DOWN or TIMEDOUT if (LinkState < ARQ_CONNECTED) return; // do not respond if DOWN or TIMEDOUT
for (p1 = RxPending.begin(); p1 < RxPending.end(); p1++) for (p1 = RxPending.begin(); p1 < RxPending.end(); p1++)
if (blknbr == p1->nbr()) { if (blknbr == p1->nbr()) {
return; return;
} }
char szStatus[80]; char szStatus[80];
snprintf(szStatus, sizeof(szStatus),"RX: data block %d", blknbr); snprintf(szStatus, sizeof(szStatus),"RX: data block %d", blknbr);
printSTATUS(szStatus, 5.0); printSTATUS(szStatus, 5.0);
cTxtBlk tempblk(blknbr, rcvPayload); cTxtBlk tempblk(blknbr, rcvPayload);
RxPending.push_back (tempblk); RxPending.push_back (tempblk);
@ -920,7 +920,7 @@ void arq::parseDATA()
} }
// add RxPending blocks that are consecutive to GoodHeader // add RxPending blocks that are consecutive to GoodHeader
p1 = RxPending.begin(); p1 = RxPending.begin();
while (!RxPending.empty()) { while (!RxPending.empty()) {
if ((p1->nbr() != (GoodHeader +1) % MAXCOUNT)) if ((p1->nbr() != (GoodHeader +1) % MAXCOUNT))
break; break;
@ -988,14 +988,14 @@ int arq::parseFrame(string txt)
// treat unproto TALK as a special case // treat unproto TALK as a special case
// no effort made to confirm the data by the CRC value // no effort made to confirm the data by the CRC value
if (fID == _TALK) { if (fID == _TALK) {
if (LinkState >= CONNECTED) { if (LinkState >= ARQ_CONNECTED) {
timeout = Timeout / ARQLOOPTIME; timeout = Timeout / ARQLOOPTIME;
parseTALK(); parseTALK();
retries = Retries; retries = Retries;
} }
return -1; return -1;
} }
string sRcvdCRC = testcrc.scrc16( txt.substr(0, len - 4)); string sRcvdCRC = testcrc.scrc16( txt.substr(0, len - 4));
if (sRcvdCRC != txt.substr(len - 4) ) { if (sRcvdCRC != txt.substr(len - 4) ) {
@ -1007,7 +1007,7 @@ int arq::parseFrame(string txt)
retries = Retries; retries = Retries;
switch (fID) { switch (fID) {
case IDENT : case IDENT :
if (!isUrcall()) if (!isUrcall())
break; break;
blknbr = fID - 0x20; blknbr = fID - 0x20;
@ -1016,8 +1016,8 @@ int arq::parseFrame(string txt)
printRX_DEBUG("IDENT:"); printRX_DEBUG("IDENT:");
} }
break; break;
case CONREQ : case CONREQ :
if (LinkState > TIMEDOUT) if (LinkState > TIMEDOUT)
break; // disallow multiple connects break; // disallow multiple connects
blknbr = fID - 0x20; blknbr = fID - 0x20;
parseCONREQ(); parseCONREQ();
@ -1104,11 +1104,11 @@ int arq::parseFrame(string txt)
} }
} }
if (printRX_DEBUG) { if (printRX_DEBUG) {
printRX_DEBUG(txt); printRX_DEBUG("\n"); printRX_DEBUG(txt); printRX_DEBUG("\n");
} }
if (LinkState == CONNECTED) if (LinkState == ARQ_CONNECTED)
timeout = Timeout / ARQLOOPTIME; timeout = Timeout / ARQLOOPTIME;
return fID; return fID;
@ -1124,10 +1124,10 @@ void arq::rcvChar( char c )
tx2txdelay = TxDelay / ARQLOOPTIME; tx2txdelay = TxDelay / ARQLOOPTIME;
return; return;
} }
if (lastRxChar == SOH && c == SOH) // consecutive <SOH> characters if (lastRxChar == SOH && c == SOH) // consecutive <SOH> characters
return; return;
if (lastRxChar == EOT && c == EOT) // consecutive <EOT> characters if (lastRxChar == EOT && c == EOT) // consecutive <EOT> characters
return; return;
@ -1142,7 +1142,7 @@ void arq::rcvChar( char c )
} else } else
RxFrameQueue += c; RxFrameQueue += c;
} }
lastRxChar = c; lastRxChar = c;
} }
@ -1152,8 +1152,8 @@ void arq::sendText (string txt)
{ {
size_t offset = 0; size_t offset = 0;
cTxtBlk tempblk; cTxtBlk tempblk;
if (LinkState < CONNECTED) return; if (LinkState < ARQ_CONNECTED) return;
Blocks2Send = 0; Blocks2Send = 0;
while (offset < txt.length()) { while (offset < txt.length()) {
newblocknumber(); newblocknumber();
@ -1171,7 +1171,7 @@ void arq::sendblocks()
int missedblks = 0, newblks = 0; int missedblks = 0, newblks = 0;
int framecount = 0; int framecount = 0;
cTxtBlk tempblk; cTxtBlk tempblk;
if (TxMissing.empty() == false) { if (TxMissing.empty() == false) {
list<cTxtBlk>::iterator p = TxMissing.begin(); list<cTxtBlk>::iterator p = TxMissing.begin();
while (p != TxMissing.end()) { while (p != TxMissing.end()) {
@ -1205,7 +1205,7 @@ void arq::sendblocks()
if (LinkState != ABORT && LinkState != ABORTING) if (LinkState != ABORT && LinkState != ABORTING)
LinkState = WAITING; LinkState = WAITING;
} }
void arq::connect(string callsign) void arq::connect(string callsign)
{ {
UrCall = callsign; UrCall = callsign;
@ -1215,7 +1215,7 @@ void arq::connect(string callsign)
if (rxUrCall) rxUrCall(UrCall); if (rxUrCall) rxUrCall(UrCall);
TxTextQueue.clear(); TxTextQueue.clear();
connectFrame(); connectFrame();
LinkState = CONNECTING; LinkState = ARQ_CONNECTING;
immediate = true; immediate = true;
} }
@ -1226,7 +1226,7 @@ void arq::disconnect()
RetryTime = baseRetryTime; RetryTime = baseRetryTime;
totalTx = 0; totalTx = 0;
nbrbadTx = 0; nbrbadTx = 0;
LinkState = DISCONNECT; LinkState = DISCONNECT;
} }
@ -1289,7 +1289,7 @@ void arqloop(void *who)
{ {
arq *me = (arq *)who; arq *me = (arq *)who;
char c; char c;
// check for received chars including 0x06 for Sending = 0 // check for received chars including 0x06 for Sending = 0
if (me->getc1(c) == true) { if (me->getc1(c) == true) {
me->rcvChar(c); me->rcvChar(c);
@ -1310,7 +1310,7 @@ void arqloop(void *who)
me->immediate = false; me->immediate = false;
} else { } else {
switch (me->LinkState) { switch (me->LinkState) {
case CONNECTING : case ARQ_CONNECTING :
break; break;
case DISCONNECT : case DISCONNECT :
me->LinkState = DISCONNECTING; me->LinkState = DISCONNECTING;
@ -1320,7 +1320,7 @@ void arqloop(void *who)
me->TxPlainTextQueue.clear(); me->TxPlainTextQueue.clear();
me->disconnectFrame(); me->disconnectFrame();
me->immediate = true; me->immediate = true;
break; break;
case DISCONNECTING : case DISCONNECTING :
if (me->retrytime-- == 0) { if (me->retrytime-- == 0) {
me->retrytime = me->rtry(); me->retrytime = me->rtry();
@ -1383,8 +1383,8 @@ void arqloop(void *who)
} }
} }
break; break;
case CONNECTED : case ARQ_CONNECTED :
default: default:
if (me->TxTextQueue.empty() == false) { if (me->TxTextQueue.empty() == false) {
me->transmitdata(); me->transmitdata();
@ -1399,7 +1399,7 @@ void arqloop(void *who)
} }
me->timeout--; me->timeout--;
if (me->timeout == 0 // 10000 / ARQLOOPTIME // 10 seconds remaining if (me->timeout == 0 // 10000 / ARQLOOPTIME // 10 seconds remaining
&& me->LinkState == CONNECTED // link is connected && me->LinkState == ARQ_CONNECTED // link is connected
&& me->primary == true ) { // this is the connecting station && me->primary == true ) { // this is the connecting station
if (--me->retries) { // repeat Retries and then allow timeout if (--me->retries) { // repeat Retries and then allow timeout
me->TxTextQueue.clear(); me->TxTextQueue.clear();
@ -1409,14 +1409,14 @@ void arqloop(void *who)
} }
} }
if (me->timeout == 0) { if (me->timeout == 0) {
if (me->LinkState == CONNECTED) if (me->LinkState == ARQ_CONNECTED)
me->LinkState = TIMEDOUT; me->LinkState = TIMEDOUT;
else else
me->LinkState = DOWN; me->LinkState = DOWN;
me->Retries = me->baseRetries; me->Retries = me->baseRetries;
me->Timeout = me->baseTimeout; me->Timeout = me->baseTimeout;
me->RetryTime = me->baseRetryTime; me->RetryTime = me->baseRetryTime;
me->retries = me->Retries; me->retries = me->Retries;
me->retrytime = me->rtry(); me->retrytime = me->rtry();
me->TxMissing.clear(); me->TxMissing.clear();
@ -1446,8 +1446,29 @@ void arqloop(void *who)
} }
} }
if (me->arqstop) if (me->arqstop) {
me->LinkState = STOPPED;
me->arqstop = false;
me->LinkState = DOWN;
me->Retries = me->baseRetries;
me->Timeout = me->baseTimeout;
me->RetryTime = me->baseRetryTime;
me->retries = me->Retries;
me->retrytime = me->rtry();
me->TxMissing.clear();
me->TxBlocks.clear();
me->TxTextQueue.clear();
me->TxPlainTextQueue.clear();
me->timeout = me->Timeout / ARQLOOPTIME;
if (me->rxUrCall) me->rxUrCall("");
me->printSTATUS(STIMEDOUT, 10.0);
Fl::repeat_timeout( 1.0, arqloop, me);
return; return;
}
Fl::repeat_timeout( ARQLOOPTIME/1000.0, arqloop, me); Fl::repeat_timeout( ARQLOOPTIME/1000.0, arqloop, me);
} }
@ -1458,4 +1479,8 @@ void arq::start_arq()
Fl::add_timeout(1.0, arqloop, this); Fl::add_timeout(1.0, arqloop, this);
} }
void arq::restart_arq() {
arqstop = true;
}
//--------------------------------------------------------------------- //---------------------------------------------------------------------

Wyświetl plik

@ -77,9 +77,13 @@
#include "b64.h" #include "b64.h"
#include "gettext.h" #include "gettext.h"
#include "xml_server.h"
#define FLDIGI_port "7322" #define FLDIGI_port "7322"
#define MPSK_port "3122" #define MPSK_port "3122"
#define FLARQ_XML_PORT 7422
#define MPSK_TX "TX" #define MPSK_TX "TX"
#define MPSK_RX "RX" #define MPSK_RX "RX"
#define MPSK_TX2RX "RX_AFTER_TX" #define MPSK_TX2RX "RX_AFTER_TX"
@ -946,6 +950,7 @@ void arqCLOSE()
{ {
tcpip->close(); tcpip->close();
saveConfig(); saveConfig();
exit_server();
exit(0); exit(0);
} }
@ -974,7 +979,14 @@ void restart()
void arqCONNECT() void arqCONNECT()
{ {
if (digi_arq->state() < CONNECTED) { int state = Fl::event_state();
if ((state & FL_CTRL) == FL_CTRL) {
digi_arq->restart_arq();
txtURCALL->value("");
restart();
return;
}
if (digi_arq->state() < ARQ_CONNECTED) {
if (strlen(txtURCALL->value()) > 0) if (strlen(txtURCALL->value()) > 0)
digi_arq->connect(txtURCALL->value()); digi_arq->connect(txtURCALL->value());
} else { } else {
@ -1140,7 +1152,6 @@ void payloadText(string s)
} }
if (incomingText.find(arqemail) != string::npos) if (incomingText.find(arqemail) != string::npos)
haveemail = true; haveemail = true;
incomingText = "";
startpos = string::npos; startpos = string::npos;
endpos = string::npos; endpos = string::npos;
fnamepos = string::npos; fnamepos = string::npos;
@ -1151,6 +1162,9 @@ void payloadText(string s)
rxARQfile = false; rxARQfile = false;
rxARQhavesize = false; rxARQhavesize = false;
rxTextReady = true; rxTextReady = true;
if (incomingText.find("FLMSG_XFR") != std::string::npos)
xml_rx_text_ready = true;
incomingText = "";
txtStatus->value(""); txtStatus->value("");
prgStatus->value(0.0); prgStatus->value(0.0);
prgStatus->label(""); prgStatus->label("");
@ -1220,7 +1234,7 @@ void moveEmailFile()
void sendEmailFile() void sendEmailFile()
{ {
if (arqstate < CONNECTED) { if (arqstate < ARQ_CONNECTED) {
fl_alert2("Not connected"); fl_alert2("Not connected");
return; return;
} }
@ -1284,7 +1298,7 @@ void sendEmailFile()
void sendAsciiFile() void sendAsciiFile()
{ {
if (arqstate < CONNECTED) { if (arqstate < ARQ_CONNECTED) {
fl_alert2("Not connected"); fl_alert2("Not connected");
return; return;
} }
@ -1336,7 +1350,7 @@ void sendAsciiFile()
void sendImageFile() void sendImageFile()
{ {
if (arqstate < CONNECTED) { if (arqstate < ARQ_CONNECTED) {
fl_alert2("Not connected"); fl_alert2("Not connected");
return; return;
} }
@ -1385,7 +1399,7 @@ void sendImageFile()
void sendBinaryFile() void sendBinaryFile()
{ {
if (arqstate < CONNECTED) { if (arqstate < ARQ_CONNECTED) {
fl_alert2("Not connected"); fl_alert2("Not connected");
return; return;
} }
@ -1432,6 +1446,43 @@ void sendBinaryFile()
sendingfile = false; sendingfile = false;
} }
void send_xml_text(std::string fname, std::string txt)
{
if (arqstate < ARQ_CONNECTED) {
fl_alert2("Not connected");
return;
}
size_t txtsize;
char sizemsg[40];
if (!txt.empty()) {
TX.erase();
TX.append(arqfile);
TX.append(fname);
TX.append("\n");
TX.append(arqascii);
txtsize = txt.length();
arqPayloadSize = txtsize;
blocksSent = 0;
snprintf(sizemsg, sizeof(sizemsg), "ARQ:SIZE::%d\n",
static_cast<int>(txtsize));
TX.append(sizemsg);
TX.append(arqstart);
TX.append(txt);
TX.append(arqend);
traffic = true;
sendingfile = true;
statusmsg = "Sending XML payload: ";
statusmsg.append(fname);
txtStatus->value(statusmsg.c_str());
cbClearText();
return;
}
traffic = false;
sendingfile = false;
}
char statemsg[80]; char statemsg[80];
void dispState() void dispState()
@ -1450,7 +1501,7 @@ void dispState()
// mnuSend->deactivate(); // mnuSend->deactivate();
mnu->redraw(); mnu->redraw();
} }
else if (arqstate == CONNECTED || arqstate == WAITING) { else if (arqstate == ARQ_CONNECTED || arqstate == WAITING) {
if (btnCONNECT->active()) if (btnCONNECT->active())
btnCONNECT->label("Disconnect"); btnCONNECT->label("Disconnect");
if (!autobeacon) if (!autobeacon)
@ -1467,7 +1518,7 @@ void dispState()
if (currstate <= 0x7F) // receiving if (currstate <= 0x7F) // receiving
switch (currstate) { switch (currstate) {
case CONNECTING : case ARQ_CONNECTING :
snprintf(statemsg, sizeof(statemsg), "CONNECTING: %d", digi_arq->getTimeLeft()); snprintf(statemsg, sizeof(statemsg), "CONNECTING: %d", digi_arq->getTimeLeft());
txtState->value(statemsg); txtState->value(statemsg);
txtState->redraw(); txtState->redraw();
@ -1486,7 +1537,7 @@ void dispState()
autobeacon = false; autobeacon = false;
break; break;
case WAITING : case WAITING :
case CONNECTED : case ARQ_CONNECTED :
char szState[80]; char szState[80];
snprintf(szState, sizeof(szState),"CONNECTED - Quality = %4.2f", snprintf(szState, sizeof(szState),"CONNECTED - Quality = %4.2f",
digi_arq->quality()); digi_arq->quality());
@ -1573,7 +1624,7 @@ void mainloop(void *)
if (rxTextReady) { if (rxTextReady) {
if (haveemail) if (haveemail)
saveEmailFile(); saveEmailFile();
else else if (!xml_rx_text_ready)
saveRxFile(); saveRxFile();
} }
Fl::repeat_timeout(0.1, mainloop); Fl::repeat_timeout(0.1, mainloop);
@ -1893,6 +1944,8 @@ int main (int argc, char *argv[] )
arqwin->icon((char *)flarq_icon_pixmap); arqwin->icon((char *)flarq_icon_pixmap);
#endif #endif
start_xml_server(FLARQ_XML_PORT);
arqwin->show(argc, argv); arqwin->show(argc, argv);
return Fl::run(); return Fl::run();
} }

Wyświetl plik

@ -27,13 +27,13 @@
// generic Frame format: // generic Frame format:
// <SOH>dcl[info])12EF<EOT|SOH> // <SOH>dcl[info])12EF<EOT|SOH>
// | ||| | | | // | ||| | | |
// | ||| | | +--ASCII <SOH> or <EOT> (0x04) character // | ||| | | +--ASCII <SOH> or <EOT> (0x04) character
// | ||| | +-------checksum (4xAlphaNum) // | ||| | +-------checksum (4xAlphaNum)
// | ||| +-------------Payload (1 ... 2^N chars, N 4, 5, 6, 7 8) // | ||| +-------------Payload (1 ... 2^N chars, N 4, 5, 6, 7 8)
// | ||+---------------Block type // | ||+---------------Block type
// | |+----------------Stream id // | |+----------------Stream id
// | +-----------------Protocol version number // | +-----------------Protocol version number
// +---------------------ASCII <SOH> (0x01) character // +---------------------ASCII <SOH> (0x01) character
// BLOCKSIZE = 2^n // BLOCKSIZE = 2^n
// //
@ -88,19 +88,33 @@ using namespace std;
#define ARQLOOPTIME 100 // # msec for loop timing #define ARQLOOPTIME 100 // # msec for loop timing
//===================================================================== //=====================================================================
//link states //link states
#define DOWN 0 enum LINK_STATES {
#define TIMEDOUT 1 DOWN = 0,
#define ABORT 3 TIMEDOUT,
#define CONNECTING 4 ABORT,
#define CONNECTED 5 ARQ_CONNECTING,
#define WAITING 6 ARQ_CONNECTED,
#define WAITFORACK 7 WAITING,
#define DISCONNECT 8 WAITFORACK,
#define DISCONNECTING 9 DISCONNECT,
#define ABORTING 10 DISCONNECTING,
ABORTING,
STOPPED
};
//#define DOWN 0
//#define TIMEDOUT 1
//#define ABORT 3
//#define ARQ_CONNECTING 4
//#define ARQ_CONNECTED 5
//#define WAITING 6
//#define WAITFORACK 7
//#define DISCONNECT 8
//#define DISCONNECTING 9
//#define ABORTING 10
#define SENDING 0x80; #define SENDING 0x80;
//===================================================================== //=====================================================================
extern char *ARQASCII[]; extern char *ARQASCII[];
@ -129,8 +143,8 @@ public:
crcval = (crcval >> 1); crcval = (crcval >> 1);
} }
} }
unsigned int crc16(char c) { unsigned int crc16(char c) {
update(c); update(c);
return crcval; return crcval;
} }
unsigned int crc16(string s) { unsigned int crc16(string s) {
@ -166,7 +180,7 @@ public:
class arq { class arq {
private: private:
bool arqstop; bool arqstop;
string MyCall; string MyCall;
string UrCall; string UrCall;
@ -175,18 +189,18 @@ private:
string Frame; string Frame;
string Payload; string Payload;
string rcvPayload; string rcvPayload;
string logfile; string logfile;
char MyStreamID; char MyStreamID;
char UrStreamID; char UrStreamID;
char MyBlockLengthChar; char MyBlockLengthChar;
char UrBlockLengthChar; char UrBlockLengthChar;
char BlockNumberChar; char BlockNumberChar;
char fID; char fID;
int blknbr; int blknbr;
// queues // // queues //
string TxTextQueue; // Text out to mail engine string TxTextQueue; // Text out to mail engine
string TxPlainTextQueue; // plain text transmit queu string TxPlainTextQueue; // plain text transmit queu
@ -219,14 +233,14 @@ private:
int tx2txdelay; int tx2txdelay;
int TxDelay; int TxDelay;
int loopcount; int loopcount;
int baseRetryTime; int baseRetryTime;
int baseTimeout; int baseTimeout;
int baseRetries; int baseRetries;
bool immediate; bool immediate;
bool primary; bool primary;
Ccrc16 framecrc; Ccrc16 framecrc;
// My status // My status
@ -242,7 +256,7 @@ private:
vector<int> MyMissing; // missing Rx blocks vector<int> MyMissing; // missing Rx blocks
string MissingRxBlocks; string MissingRxBlocks;
vector<cTxtBlk> RxPending; // RxPending Rx blocks (not consecutive) vector<cTxtBlk> RxPending; // RxPending Rx blocks (not consecutive)
list<cTxtBlk> TxBlocks; // fifo of transmit buffers list<cTxtBlk> TxBlocks; // fifo of transmit buffers
list<cTxtBlk> TxMissing; // fifo of sent; RxPending Status report list<cTxtBlk> TxMissing; // fifo of sent; RxPending Status report
list<cTxtBlk> TxPending; // fifo of transmitted buffers pending print list<cTxtBlk> TxPending; // fifo of transmitted buffers pending print
@ -255,20 +269,19 @@ private:
int LinkState; // status of ARQ link int LinkState; // status of ARQ link
int Sending; int Sending;
bool bABORT; bool bABORT;
// Link quality for sending *** used for testing only !! *** // Link quality for sending *** used for testing only !! ***
// double sendquality; // double sendquality;
void reset(); void reset();
void resetTx(); void resetTx();
void resetRx(); void resetRx();
int rtry(); int rtry();
void setBufferlength(); void setBufferlength();
void checkblocks(); void checkblocks();
string upcase(string s); string upcase(string s);
void newblocknumber(); void newblocknumber();
@ -291,12 +304,12 @@ private:
void beaconFrame(string txt); void beaconFrame(string txt);
void textFrame(cTxtBlk block); void textFrame(cTxtBlk block);
void talkFrame(string txt); void talkFrame(string txt);
void addToTxQue(string s); void addToTxQue(string s);
void sendblocks(); void sendblocks();
void transmitdata(); void transmitdata();
string frame() {return Frame;} string frame() {return Frame;}
bool isUrcall(); bool isUrcall();
@ -315,8 +328,8 @@ private:
void parseTALK(); void parseTALK();
int parseFrame(string txt); int parseFrame(string txt);
// external functions called by arq class // external functions called by arq class
void (*sendfnc)(const string& s); void (*sendfnc)(const string& s);
bool (*getc1)(char &); bool (*getc1)(char &);
void (*rcvfnc)(); void (*rcvfnc)();
@ -330,7 +343,7 @@ private:
void (*rxUrCall)(string s); void (*rxUrCall)(string s);
void (*qualityfnc)(string s); void (*qualityfnc)(string s);
void (*printSTATUS)(string s, double disptime); void (*printSTATUS)(string s, double disptime);
public: public:
arq(); arq();
~arq() {}; ~arq() {};
@ -338,33 +351,35 @@ public:
friend void arqloop(void *me); friend void arqloop(void *me);
void start_arq(); void start_arq();
void restart_arq();
string checksum(string &s); string checksum(string &s);
void myCall(string s) { MyCall = upcase(s);} void myCall(string s) { MyCall = upcase(s);}
string myCall() { return MyCall;} string myCall() { return MyCall;}
void urCall(string s) { UrCall = s;} void urCall(string s) { UrCall = s;}
string urCall() { return UrCall;} string urCall() { return UrCall;}
void newsession(); void newsession();
void setSendFunc( void (*f)(const string& s)) { sendfnc = f;} void setSendFunc( void (*f)(const string& s)) { sendfnc = f;}
void setGetCFunc( bool (*f)(char &)) { getc1 = f;} void setGetCFunc( bool (*f)(char &)) { getc1 = f;}
void setRcvFunc( void (*f)()) { rcvfnc = f;} void setRcvFunc( void (*f)()) { rcvfnc = f;}
void setPrintRX( void (*f)(string s)) { printRX = f;} void setPrintRX( void (*f)(string s)) { printRX = f;}
void setPrintTX( void (*f)(string s)) { printTX = f;} void setPrintTX( void (*f)(string s)) { printTX = f;}
void setPrintTALK (void (*f)(string s)) {printTALK = f;} void setPrintTALK (void (*f)(string s)) {printTALK = f;}
void setPrintRX_DEBUG (void (*f)(string s)){printRX_DEBUG = f;} void setPrintRX_DEBUG (void (*f)(string s)){printRX_DEBUG = f;}
void setPrintTX_DEBUG (void (*f)(string s)) {printTX_DEBUG = f;} void setPrintTX_DEBUG (void (*f)(string s)) {printTX_DEBUG = f;}
void setPrintSTATUS (void (*f)(string s, double disptime)) { printSTATUS = f;} void setPrintSTATUS (void (*f)(string s, double disptime)) { printSTATUS = f;}
void setMaxHeaders( int mh ) { maxheaders = mh; } void setMaxHeaders( int mh ) { maxheaders = mh; }
void setExponent( int exp ) { exponent = exp; setBufferlength(); } void setExponent( int exp ) { exponent = exp; setBufferlength(); }
int getExponent() { return (int) exponent;} int getExponent() { return (int) exponent;}
void setWaitTime( int rtime ) { RetryTime = rtime; baseRetryTime = rtime; } void setWaitTime( int rtime ) { RetryTime = rtime; baseRetryTime = rtime; }
int getWaitTime() { return (int) RetryTime; } int getWaitTime() { return (int) RetryTime; }
void setRetries ( int rtries ) { void setRetries ( int rtries ) {
retries = Retries = baseRetries = rtries; } retries = Retries = baseRetries = rtries; }
int getRetries() { return (int) Retries; } int getRetries() { return (int) Retries; }
void setTimeout ( int tout ) { Timeout = tout; baseTimeout = tout; } void setTimeout ( int tout ) { Timeout = tout; baseTimeout = tout; }
@ -378,41 +393,41 @@ public:
void setQualityValue( void (*f)(string s)) { qualityfnc = f;} void setQualityValue( void (*f)(string s)) { qualityfnc = f;}
void setAbortedTransfer( void (*f)()) { abortfnc = f;}; void setAbortedTransfer( void (*f)()) { abortfnc = f;};
void setDisconnected( void (*f)()) { disconnectfnc = f;}; void setDisconnected( void (*f)()) { disconnectfnc = f;};
void rcvChar( char c ); void rcvChar( char c );
void connect(string callsign);//, int blocksize = 6, int retries = 4); void connect(string callsign);//, int blocksize = 6, int retries = 4);
void sendblocks( string txt ); void sendblocks( string txt );
void sendBeacon (string txt); void sendBeacon (string txt);
void sendPlainText( string txt ); void sendPlainText( string txt );
string getText() { return RxTextQueue;} string getText() { return RxTextQueue;}
void sendText(string txt); void sendText(string txt);
bool connected() { return (LinkState == CONNECTED); } bool connected() { return (LinkState == ARQ_CONNECTED); }
void disconnect(); void disconnect();
void abort(); void abort();
int state() { return (LinkState + Sending);} int state() { return (LinkState + Sending);}
int TXblocks() { return totalTx;} int TXblocks() { return totalTx;}
int TXbad() { return nbrbadTx;} int TXbad() { return nbrbadTx;}
int RXblocks() { return totalRx;} int RXblocks() { return totalRx;}
int RXbad() { return nbrbadRx;} int RXbad() { return nbrbadRx;}
double quality() { double quality() {
if (totalTx == 0) return 1.0; if (totalTx == 0) return 1.0;
return ( 1.0 * (totalTx - nbrbadTx) / totalTx ); return ( 1.0 * (totalTx - nbrbadTx) / totalTx );
} }
float percentSent() { float percentSent() {
if (Blocks2Send == 0) return 0.0; if (Blocks2Send == 0) return 0.0;
if ((TxBlocks.empty() && TxMissing.empty())) return 1.0; if ((TxBlocks.empty() && TxMissing.empty())) return 1.0;
return (1.0 * (Blocks2Send - TxBlocks.size() - TxMissing.size()) / Blocks2Send); return (1.0 * (Blocks2Send - TxBlocks.size() - TxMissing.size()) / Blocks2Send);
} }
bool transferComplete() { bool transferComplete() {
if (TxMissing.empty() == false) return false; if (TxMissing.empty() == false) return false;
if (TxBlocks.empty() == false) return false; if (TxBlocks.empty() == false) return false;

Wyświetl plik

@ -47,10 +47,19 @@ extern long iwaittime;
extern long itimeout; extern long itimeout;
extern int bcnInterval; extern int bcnInterval;
// used by xmlrpc interface
extern int arqstate;
extern bool sendingfile;
extern bool rxTextReady;
extern bool rxARQfile;
extern std::string txtarqload;
extern void cb_SaveComposeMail(); extern void cb_SaveComposeMail();
extern void cb_CancelComposeMail(); extern void cb_CancelComposeMail();
extern void cb_UseTemplate(); extern void cb_UseTemplate();
extern void cb_OpenComposeMail(); extern void cb_OpenComposeMail();
extern void ComposeMail(); extern void ComposeMail();
extern void send_xml_text(std::string, std::string);
#endif #endif

Wyświetl plik

@ -0,0 +1,51 @@
// ---------------------------------------------------------------------
//
// xml_server.h, a part of flarq
//
// Copyflarqht (C) 2016
// Dave Freese, W1HKJ
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the program; if not, write to the
//
// Free Software Foundation, Inc.
// 51 Franklin Street, Fifth Floor
// Boston, MA 02110-1301 USA.
//
// ---------------------------------------------------------------------
#ifndef XML_SERVER_H
#define XML_SERVER_H
#include <fstream>
#include <vector>
#include <string>
#include <math.h>
#ifndef WIN32
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#endif
#include "status.h"
#include <FL/fl_show_colormap.H>
#include <FL/fl_ask.H>
extern void start_xml_server(int port = 12345);
extern void exit_server();
extern bool xml_rx_text_ready;
#endif

Wyświetl plik

@ -0,0 +1,216 @@
// ---------------------------------------------------------------------
//
// xml_server.cxx, a part of flarq
//
// Copyflarqht (C) 2016
// Dave Freese, W1HKJ
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the program; if not, write to the
//
// Free Software Foundation, Inc.
// 51 Franklin Street, Fifth Floor
// Boston, MA 02110-1301 USA.
//
// ---------------------------------------------------------------------
#include <config.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <pthread.h>
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Enumerations.H>
//#include "support.h"
//#include "debug.h"
#include "arq.h"
#include "flarq.h"
#include "xml_server.h"
#include "xmlrpcpp/XmlRpc.h"
using namespace XmlRpc;
// The server
XmlRpcServer flarq_server;
//----------------------------------------------------------------------
// get interface
//----------------------------------------------------------------------
bool xml_rx_text_ready = false;
//----------------------------------------------------------------------
// Request for flarq version
//----------------------------------------------------------------------
class flarq_get_version : public XmlRpcServerMethod {
public:
flarq_get_version(XmlRpcServer* s) : XmlRpcServerMethod("flarq.get_version", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) {
result = VERSION;
}
std::string help() { return std::string("returns version number of flarq"); }
} flarq_get_version(&flarq_server);
//----------------------------------------------------------------------
// Request for ARQ state
//----------------------------------------------------------------------
class flarq_get_state : public XmlRpcServerMethod {
public:
flarq_get_state(XmlRpcServer* s) : XmlRpcServerMethod("flarq.get_state", s) {}
// x00 - unconnected
// x81 - connected
// x82 - sending
// x83 - receiving
// x84 - send completed
// x85 - recv completed
void execute(XmlRpcValue& params, XmlRpcValue& result) {
int state = 0;
if (arqstate != ARQ_CONNECTED)
state = 0;
else if (sendingfile)
state = 0x82;
else if (rxARQfile)
state = 0x83;
else if (xml_rx_text_ready)
state = 0x85;
else
state = 0x81;
result = state;
}
std::string help() { return std::string("returns state of connection"); }
} flarq_get_state(&flarq_server);
//----------------------------------------------------------------------
// Request for received text
//----------------------------------------------------------------------
class flarq_rcvd_text : public XmlRpcServerMethod {
public:
flarq_rcvd_text(XmlRpcServer* s) : XmlRpcServerMethod("flarq.rcvd_text", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) {
std::string result_string = "none";
if (xml_rx_text_ready) result_string = txtarqload;
xml_rx_text_ready = false;
result = result_string;
txtarqload = "";
}
std::string help() { return std::string("returns received text"); }
} flarq_rcvd_text(&flarq_server);
//----------------------------------------------------------------------
// set interface
//----------------------------------------------------------------------
//------------------------------------------------------------------------------
// Send text
//------------------------------------------------------------------------------
class flarq_send_text : public XmlRpcServerMethod {
public:
flarq_send_text(XmlRpcServer* s) : XmlRpcServerMethod("flarq.send_text", s) {}
void execute(XmlRpcValue& params, XmlRpcValue &result) {
std::string txt_to_send = string(params[0]);
send_xml_text("FLMSG_XFR", txt_to_send);
}
std::string help() { return std::string("send_text"); }
} flarq_send_text(&flarq_server);
struct MLIST {
string name; string signature; string help;
} mlist[] = {
{ "flarq.rcvd_text", "s:n", "return MODE of current VFO" },
{ "flarq.get_state", "s:n", "return PTT state" },
{ "flarq.send_text", "i:i", "set MODE iaw MODE table" }
};
class flarq_list_methods : public XmlRpcServerMethod {
public:
flarq_list_methods(XmlRpcServer *s) : XmlRpcServerMethod("flarq.list_methods", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) {
vector<XmlRpcValue> methods;
for (size_t n = 0; n < sizeof(mlist) / sizeof(*mlist); ++n) {
XmlRpcValue::ValueStruct item;
item["name"] = mlist[n].name;
item["signature"] = mlist[n].signature;
item["help"] = mlist[n].help;
methods.push_back(item);
}
result = methods;
}
std::string help() { return std::string("get flarq methods"); }
} flarq_list_methods(&flarq_server);
//------------------------------------------------------------------------------
// support thread xmlrpc clients
//------------------------------------------------------------------------------
pthread_t *xml_thread = 0;
void * xml_thread_loop(void *d)
{
for(;;) {
flarq_server.work(-1.0);
}
return NULL;
}
void start_xml_server(int port)
{
XmlRpc::setVerbosity(0);
// Create the server socket on the specified port
flarq_server.bindAndListen(port);
// Enable introspection
flarq_server.enableIntrospection(true);
xml_thread = new pthread_t;
if (pthread_create(xml_thread, NULL, xml_thread_loop, NULL)) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
}
void exit_server()
{
flarq_server.exit();
}

Wyświetl plik

@ -62,13 +62,14 @@ Save tags and all enclosed text to date-time stamped file, ie:\n\
~/.nbems/WRAP/recv/extract-20090127-092515.wrap"); ~/.nbems/WRAP/recv/extract-20090127-092515.wrap");
#endif #endif
#define bufsize 16 #define bufsize 32
char rx_extract_buff[bufsize + 1]; char rx_extract_buff[bufsize + 1];
string rx_buff; string rx_buff;
string rx_extract_msg; string rx_extract_msg;
bool extract_wrap = false; bool extract_wrap = false;
bool extract_flamp = false; bool extract_flamp = false;
bool extract_arq = false;
bool bInit = false; bool bInit = false;
@ -81,6 +82,7 @@ void rx_extract_reset()
rx_extract_buff[bufsize] = 0; rx_extract_buff[bufsize] = 0;
extract_wrap = false; extract_wrap = false;
extract_flamp = false; extract_flamp = false;
extract_arq = false;
put_status(""); put_status("");
} }
@ -286,16 +288,40 @@ void rx_extract_add(int c)
memmove(rx_extract_buff, &rx_extract_buff[1], bufsize - 1); memmove(rx_extract_buff, &rx_extract_buff[1], bufsize - 1);
rx_extract_buff[bufsize - 1] = ch; rx_extract_buff[bufsize - 1] = ch;
if ( strstr(rx_extract_buff, wrap_beg) && !extract_flamp) { if (!extract_arq && strstr(rx_extract_buff, "ARQ:FILE::FLMSG_XFR")) {
extract_arq = true;
REQ(rx_remove_timer);
REQ(rx_add_timer);
memset(rx_extract_buff, ' ', bufsize);
rx_extract_msg = "Extracting ARQ msg";
put_status(rx_extract_msg.c_str());
return;
} else if (extract_arq) {
REQ(rx_remove_timer);
REQ(rx_add_timer);
if (strstr(rx_extract_buff, "ARQ::ETX"))
rx_extract_reset();
return;
} else if (!extract_flamp && strstr(rx_extract_buff, flamp_beg)) {
extract_flamp = true;
memset(rx_extract_buff, ' ', bufsize);
rx_extract_msg = "Extracting FLAMP";
put_status(rx_extract_msg.c_str());
return;
} else if (extract_flamp) {
REQ(rx_remove_timer);
REQ(rx_add_timer);
if (strstr(rx_extract_buff, flamp_end) != NULL)
rx_extract_reset();
return;
} else if (!extract_wrap && strstr(rx_extract_buff, wrap_beg)) {
rx_buff.assign(wrap_beg); rx_buff.assign(wrap_beg);
rx_extract_msg = "Extracting WRAP/FLMSG"; rx_extract_msg = "Extracting WRAP/FLMSG";
put_status(rx_extract_msg.c_str()); put_status(rx_extract_msg.c_str());
memset(rx_extract_buff, ' ', bufsize);
extract_wrap = true; extract_wrap = true;
REQ(rx_remove_timer); REQ(rx_remove_timer);
REQ(rx_add_timer); REQ(rx_add_timer);
return;
} else if (extract_wrap) { } else if (extract_wrap) {
rx_buff += ch; rx_buff += ch;
REQ(rx_remove_timer); REQ(rx_remove_timer);
@ -304,16 +330,6 @@ void rx_extract_add(int c)
invoke_flmsg(); invoke_flmsg();
rx_extract_reset(); rx_extract_reset();
} }
} else if (strstr(rx_extract_buff, flamp_beg) && ! extract_wrap) {
extract_flamp = true;
rx_extract_msg = "Extracting FLAMP";
put_status(rx_extract_msg.c_str());
} else if (extract_flamp == true) {
REQ(rx_remove_timer);
REQ(rx_add_timer);
if (strstr(rx_extract_buff, flamp_end) != NULL) {
rx_extract_reset();
}
} }
} }