New upstream version 6.0.25.06+repack

This commit is contained in:
Hibby 2025-10-10 23:37:31 +01:00
parent 7c796758d1
commit 96ac3e4a36
27 changed files with 1097 additions and 316 deletions

View file

@ -509,6 +509,14 @@ UCHAR * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen, int DoNo
return Output; return Output;
} }
if (ADJBUFFER->L2DATA[0] == 0xfe) // Paula's Nodes Poll
{
memcpy(Alias, ++ptr, 6);
Output += sprintf((char *)Output, " NODES POLL from %s\r", Alias);
return Output;
}
// Display normal NET/ROM transmissions // Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r "); Output += sprintf((char *)Output, " NET/ROM\r ");

12
ARDOP.c
View file

@ -567,7 +567,7 @@ static int ProcessLine(char * buf, int Port)
} }
void ARDOPThread(struct TNCINFO * TNC); void ARDOPThread(VOID * Param);
VOID ARDOPProcessDataSocketData(int port); VOID ARDOPProcessDataSocketData(int port);
int ConnecttoARDOP(struct TNCINFO * TNC); int ConnecttoARDOP(struct TNCINFO * TNC);
static VOID ARDOPProcessReceivedData(struct TNCINFO * TNC); static VOID ARDOPProcessReceivedData(struct TNCINFO * TNC);
@ -2312,12 +2312,13 @@ int ConnecttoARDOP(struct TNCINFO * TNC)
return 0; return 0;
} }
VOID ARDOPThread(struct TNCINFO * TNC) VOID ARDOPThread(VOID * Param)
{ {
// Opens sockets and looks for data on control and data sockets. // Opens sockets and looks for data on control and data sockets.
// Socket may be TCP/IP or Serial // Socket may be TCP/IP or Serial
struct TNCINFO * TNC = (struct TNCINFO *) Param;
char Msg[255]; char Msg[255];
int err, i, ret; int err, i, ret;
u_long param=1; u_long param=1;
@ -5758,8 +5759,7 @@ VOID ARDOPSCSPoll(struct TNCINFO * TNC)
// Probably only for Teensy with ESP01. Runs SCS Emulator over a TCP Link // Probably only for Teensy with ESP01. Runs SCS Emulator over a TCP Link
VOID SerialConnecttoTCPThread(VOID * Param);
VOID SerialConnecttoTCPThread(struct TNCINFO * TNC);
int SerialConnecttoTCP(struct TNCINFO * TNC) int SerialConnecttoTCP(struct TNCINFO * TNC)
{ {
@ -5767,9 +5767,9 @@ int SerialConnecttoTCP(struct TNCINFO * TNC)
return 0; return 0;
} }
VOID SerialConnecttoTCPThread(VOID * Param)
VOID SerialConnecttoTCPThread(struct TNCINFO * TNC)
{ {
struct TNCINFO * TNC = (struct TNCINFO *) Param;
char Msg[255]; char Msg[255];
int i; int i;
u_long param = 1; u_long param = 1;

324
BPQINP3.c
View file

@ -35,7 +35,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include <fcntl.h> #include <fcntl.h>
//#include "vmm.h" //#include "vmm.h"
uint64_t timeLoadedMS = 0; uint64_t INP3timeLoadedMS = 0;
extern int DEBUGINP3;
VOID SendNegativeInfo(); VOID SendNegativeInfo();
VOID SortRoutes(struct DEST_LIST * Dest); VOID SortRoutes(struct DEST_LIST * Dest);
@ -62,8 +64,8 @@ typedef struct _RTTMSG
UCHAR ALIAS[7]; UCHAR ALIAS[7];
UCHAR VERSION[12]; UCHAR VERSION[12];
UCHAR SWVERSION[9]; UCHAR SWVERSION[9];
UCHAR FLAGS[10]; UCHAR FLAGS[20];
UCHAR PADDING[147]; UCHAR PADDING[137];
} RTTMSG; } RTTMSG;
@ -102,14 +104,14 @@ int RTTTimeout = 6; // 1 Min (Horizon is 1 min)
VOID InitialiseRTT() VOID InitialiseRTT()
{ {
UCHAR temp[sizeof(RTTMsg.FLAGS) + 4]; UCHAR temp[256] = "";
memset(&RTTMsg, ' ', sizeof(struct _RTTMSG)); memset(&RTTMsg, ' ', sizeof(struct _RTTMSG));
memcpy(RTTMsg.ID, "L3RTT: ", 7); memcpy(RTTMsg.ID, "L3RTT: ", 7);
memcpy(RTTMsg.VERSION, "LEVEL3_V2.1 ", 12); memcpy(RTTMsg.VERSION, "LEVEL3_V2.1 ", 12);
memcpy(RTTMsg.SWVERSION, "BPQ32001 ", 9); memcpy(RTTMsg.SWVERSION, "BPQ32002 ", 9);
_snprintf(temp, sizeof(temp), "$M%d $N ", MAXRTT); // trailing spaces extend to ensure padding if the length of characters for MAXRTT changes. _snprintf(temp, sizeof(temp), "$M%d $N $H%d ", MAXRTT, MaxHops); // trailing spaces extend to ensure padding if the length of characters for MAXRTT changes.
memcpy(RTTMsg.FLAGS, temp, 10); // But still limit the actual characters copied. memcpy(RTTMsg.FLAGS, temp, 20); // But still limit the actual characters copied.
memcpy(RTTMsg.ALIAS, &MYALIASTEXT, 6); memcpy(RTTMsg.ALIAS, &MYALIASTEXT, 6);
RTTMsg.ALIAS[6] = ' '; RTTMsg.ALIAS[6] = ' ';
} }
@ -141,7 +143,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
Call1[ConvFromAX25(Route->NEIGHBOUR_CALL, Call1)] = 0; Call1[ConvFromAX25(Route->NEIGHBOUR_CALL, Call1)] = 0;
Debugprintf("Deleting INP3 routes via %s", Call1); if (DEBUGINP3) Debugprintf("Deleting INP3 routes via %s", Call1);
// Delete any INP3 Dest entries via this Route // Delete any INP3 Dest entries via this Route
@ -177,7 +179,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
// If we are cleaning up after a sabm on an existing link (frmr or other end reloaded) then we don't need to tell anyone - the routes should be reestablished very quickly // If we are cleaning up after a sabm on an existing link (frmr or other end reloaded) then we don't need to tell anyone - the routes should be reestablished very quickly
Debugprintf("Deleting First INP3 Route to %s", Call2); if (DEBUGINP3) Debugprintf("Deleting First INP3 Route to %s", Call2);
if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == 0) if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == 0)
{ {
@ -186,7 +188,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
Dest->INP3ROUTE[0].SRTT = 60000; Dest->INP3ROUTE[0].SRTT = 60000;
Dest->INP3ROUTE[0].Hops = 255; Dest->INP3ROUTE[0].Hops = 255;
Debugprintf("Was the only INP3 route"); if (DEBUGINP3) Debugprintf("Was the only INP3 route");
if (Dest->DEST_ROUTE == 4) // we were using it if (Dest->DEST_ROUTE == 4) // we were using it
Dest->DEST_ROUTE = 0; Dest->DEST_ROUTE = 0;
@ -206,7 +208,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == Route) if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == Route)
{ {
Debugprintf("Deleting 2nd INP3 Route to %s", Call2); if (DEBUGINP3) Debugprintf("Deleting 2nd INP3 Route to %s", Call2);
memcpy(&Dest->INP3ROUTE[1], &Dest->INP3ROUTE[2], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memcpy(&Dest->INP3ROUTE[1], &Dest->INP3ROUTE[2], sizeof(struct INP3_DEST_ROUTE_ENTRY));
memset(&Dest->INP3ROUTE[2], 0, sizeof(struct INP3_DEST_ROUTE_ENTRY)); memset(&Dest->INP3ROUTE[2], 0, sizeof(struct INP3_DEST_ROUTE_ENTRY));
@ -215,7 +217,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route)
if (Dest->INP3ROUTE[2].ROUT_NEIGHBOUR == Route) if (Dest->INP3ROUTE[2].ROUT_NEIGHBOUR == Route)
{ {
Debugprintf("Deleting 3rd INP3 Route to %s", Call2); if (DEBUGINP3) Debugprintf("Deleting 3rd INP3 Route to %s", Call2);
memset(&Dest->INP3ROUTE[2], 0, sizeof(struct INP3_DEST_ROUTE_ENTRY)); memset(&Dest->INP3ROUTE[2], 0, sizeof(struct INP3_DEST_ROUTE_ENTRY));
continue; continue;
} }
@ -339,10 +341,10 @@ VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff)
Route->Timeout = 0; // Got Response Route->Timeout = 0; // Got Response
sscanf(&Buff->L4DATA[6], "%d", &OrigTime); sscanf(&Buff->L4DATA[6], "%d", &OrigTime);
RTT = (GetTickCount() - timeLoadedMS) - OrigTime; RTT = (int)((GetTickCount() - INP3timeLoadedMS) / 10 - (OrigTime)); // We work internally in mS
if (RTT > 60000) if (RTT > 60000)
return; // Ignore if more than 60 secs return; // Ignore if more than 60 secs (why ??)
Route->RTT = RTT; Route->RTT = RTT;
@ -351,11 +353,13 @@ VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff)
else else
Route->SRTT = ((Route->SRTT * 80)/100) + ((RTT * 20)/100); Route->SRTT = ((Route->SRTT * 80)/100) + ((RTT * 20)/100);
Route->RTTIncrement = Route->SRTT / 2; // Half for one way time.
if ((Route->Status & GotRTTResponse) == 0) if ((Route->Status & GotRTTResponse) == 0)
{ {
// Link is just starting // Link is just starting
Debugprintf("INP3 got first RTT reply from %s - Link is (Re)staring", Normcall); if (DEBUGINP3) Debugprintf("INP3 got first RTT reply from %s - Link is (Re)staring", Normcall);
Route->Status |= GotRTTResponse; Route->Status |= GotRTTResponse;
} }
@ -374,10 +378,10 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
char Normcall[10]; char Normcall[10];
Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0; Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0;
Debugprintf("Processing RIF from %s INP3Node %d Route SRTT %d", Normcall, Route->INP3Node, Route->SRTT); if (DEBUGINP3) Debugprintf("Processing RIF from %s INP3Node %d Route SRTT %d", Normcall, Route->INP3Node, Route->SRTT);
if (Route->SRTT == 0) if (Route->SRTT == 0)
Debugprintf("INP3 Zero SRTT"); if (DEBUGINP3) Debugprintf("INP3 Zero SRTT");
#ifdef NOINP3 #ifdef NOINP3
@ -403,7 +407,7 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
{ {
if (msglen < 10) if (msglen < 10)
{ {
Debugprintf("Corrupt INP3 Message"); if (DEBUGINP3) Debugprintf("Corrupt INP3 Message");
return; return;
} }
@ -421,7 +425,12 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
// rtt is value from remote node. Add our RTT to that node // rtt is value from remote node. Add our RTT to that node
rtt += Route->SRTT; // if other end is old bpq then value is mS otherwise 10 mS unita
if (Route->OldBPQ)
rtt /= 10;
// rtt += Route->SRTT; // Don't do this - other end has added linkrtt
msglen -= 10; msglen -= 10;
@ -439,7 +448,7 @@ VOID ProcessINP3RIF(struct ROUTE * Route, UCHAR * ptr1, int msglen, int Port)
memcpy(alias, ptr1+2, len-2); memcpy(alias, ptr1+2, len-2);
else else
{ {
Debugprintf("Corrupt INP3 Message"); if (DEBUGINP3) Debugprintf("Corrupt INP3 Message");
return; return;
} }
} }
@ -477,13 +486,13 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
if (CompareCalls(axcall, NETROMCALL)) if (CompareCalls(axcall, NETROMCALL))
{ {
Debugprintf("INP3 for our Nodecall - discarding"); if (DEBUGINP3) Debugprintf("INP3 for our Nodecall - discarding");
return; return;
} }
if (CheckExcludeList(axcall) == 0) if (CheckExcludeList(axcall) == 0)
{ {
Debugprintf("INP3 excluded - discarding"); if (DEBUGINP3) Debugprintf("INP3 excluded - discarding");
return; return;
} }
@ -493,7 +502,7 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
if (CompareCalls(axcall, APPL->APPLCALL)) if (CompareCalls(axcall, APPL->APPLCALL))
{ {
Debugprintf("INP3 for an APPLCALL - discarding"); if (DEBUGINP3) Debugprintf("INP3 for an APPLCALL - discarding");
return; return;
} }
} }
@ -502,20 +511,20 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
if (hops > MaxHops && hops < 255) if (hops > MaxHops && hops < 255)
{ {
ConvFromAX25(axcall, call); ConvFromAX25(axcall, call);
Debugprintf("INP3 Node %s Hops %d RTT %d Ignored - Hop Count too high", call, hops, rtt); if (DEBUGINP3) Debugprintf("INP3 Node %s Hops %d RTT %d Ignored - Hop Count too high", call, hops, rtt);
return; return;
} }
if (rtt > MAXRTT && rtt < 60000) if (rtt > MAXRTT && rtt < 60000)
{ {
ConvFromAX25(axcall, call); ConvFromAX25(axcall, call);
Debugprintf("INP3 Node %s Hops %d RTT %d Ignored - rtt too high", call, hops, rtt); if (DEBUGINP3) Debugprintf("INP3 Node %s Hops %d RTT %d Ignored - rtt too high", call, hops, rtt);
return; return;
} }
if (rtt >= 60000) if (rtt >= 60000)
{ {
Debugprintf("INP3 RTT > 60000 - discarding"); if (DEBUGINP3) Debugprintf("INP3 RTT > 60000 - discarding");
return; return;
} }
@ -524,7 +533,7 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
if (Dest == NULL) if (Dest == NULL)
{ {
Debugprintf("INP3 Table Full - discarding"); if (DEBUGINP3) Debugprintf("INP3 Table Full - discarding");
return; // Table Full return; // Table Full
} }
@ -548,7 +557,7 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops,
NUMBEROFNODES++; NUMBEROFNODES++;
ConvFromAX25(Dest->DEST_CALL, call); ConvFromAX25(Dest->DEST_CALL, call);
Debugprintf("INP3 Adding New Node %s Hops %d RTT %d", call, hops, rtt); if (DEBUGINP3) Debugprintf("INP3 Adding New Node %s Hops %d RTT %d", call, hops, rtt);
return; return;
@ -556,14 +565,14 @@ Found:
if (Dest->DEST_STATE & 0x80) // Application Entry if (Dest->DEST_STATE & 0x80) // Application Entry
{ {
Debugprintf("INP3 Application Entry - discarding"); if (DEBUGINP3) Debugprintf("INP3 Application Entry - discarding");
return; return;
} }
// Update ALIAS // Update ALIAS
ConvFromAX25(Dest->DEST_CALL, call); ConvFromAX25(Dest->DEST_CALL, call);
Debugprintf("INP3 Updating Node %s Hops %d RTT %d", call, hops, rtt); if (DEBUGINP3) Debugprintf("INP3 Updating Node %s Hops %d RTT %d", call, hops, rtt);
if (alias[0] > ' ') if (alias[0] > ' ')
memcpy(Dest->DEST_ALIAS, alias, 6); memcpy(Dest->DEST_ALIAS, alias, 6);
@ -574,7 +583,7 @@ Found:
if (ROUTEPTR->ROUT_NEIGHBOUR == Route) if (ROUTEPTR->ROUT_NEIGHBOUR == Route)
{ {
Debugprintf("INP3 Already have as route[0] - updating"); if (DEBUGINP3) Debugprintf("INP3 Already have as route[0] - updating");
UpdateRoute(Dest, ROUTEPTR, hops, rtt); UpdateRoute(Dest, ROUTEPTR, hops, rtt);
return; return;
} }
@ -583,7 +592,7 @@ Found:
if (ROUTEPTR->ROUT_NEIGHBOUR == Route) if (ROUTEPTR->ROUT_NEIGHBOUR == Route)
{ {
Debugprintf("INP3 Already have as route[1] - updating"); if (DEBUGINP3) Debugprintf("INP3 Already have as route[1] - updating");
UpdateRoute(Dest, ROUTEPTR, hops, rtt); UpdateRoute(Dest, ROUTEPTR, hops, rtt);
return; return;
} }
@ -592,7 +601,7 @@ Found:
if (ROUTEPTR->ROUT_NEIGHBOUR == Route) if (ROUTEPTR->ROUT_NEIGHBOUR == Route)
{ {
Debugprintf("INP3 Already have as route[2] - updating"); if (DEBUGINP3) Debugprintf("INP3 Already have as route[2] - updating");
UpdateRoute(Dest, ROUTEPTR, hops, rtt); UpdateRoute(Dest, ROUTEPTR, hops, rtt);
return; return;
} }
@ -608,7 +617,7 @@ Found:
{ {
// Add here // Add here
Debugprintf("INP3 adding as route[%d]", i); if (DEBUGINP3) Debugprintf("INP3 adding as route[%d]", i);
AddHere(ROUTEPTR, Route, hops, rtt); AddHere(ROUTEPTR, Route, hops, rtt);
SortRoutes(Dest); SortRoutes(Dest);
return; return;
@ -616,7 +625,7 @@ Found:
ROUTEPTR++; ROUTEPTR++;
} }
Debugprintf("INP3 All entries in use - see if this is better than existing"); if (DEBUGINP3) Debugprintf("INP3 All entries in use - see if this is better than existing");
// Full, see if this is better // Full, see if this is better
@ -626,7 +635,7 @@ Found:
{ {
// We are better. Move others down and add on front // We are better. Move others down and add on front
Debugprintf("INP3 Replacing route 0"); if (DEBUGINP3) Debugprintf("INP3 Replacing route 0");
memcpy(&Dest->INP3ROUTE[2], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memcpy(&Dest->INP3ROUTE[2], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY));
memcpy(&Dest->INP3ROUTE[1], &Dest->INP3ROUTE[0], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memcpy(&Dest->INP3ROUTE[1], &Dest->INP3ROUTE[0], sizeof(struct INP3_DEST_ROUTE_ENTRY));
@ -638,7 +647,7 @@ Found:
{ {
// We are better. Move 2nd down and add // We are better. Move 2nd down and add
Debugprintf("INP3 Replacing route 1"); if (DEBUGINP3) Debugprintf("INP3 Replacing route 1");
memcpy(&Dest->INP3ROUTE[2], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memcpy(&Dest->INP3ROUTE[2], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY));
AddHere(&Dest->INP3ROUTE[1], Route, hops, rtt); AddHere(&Dest->INP3ROUTE[1], Route, hops, rtt);
return; return;
@ -648,13 +657,13 @@ Found:
{ {
// We are better. Add here // We are better. Add here
Debugprintf("INP3 Replacing route 2"); if (DEBUGINP3) Debugprintf("INP3 Replacing route 2");
AddHere(&Dest->INP3ROUTE[2], Route, hops, rtt); AddHere(&Dest->INP3ROUTE[2], Route, hops, rtt);
return; return;
} }
Debugprintf("INP3 Worse that any existing route"); if (DEBUGINP3) Debugprintf("INP3 Worse that any existing route");
// Worse than any - ignore // Worse than any - ignore
@ -735,7 +744,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == 0) if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == 0)
{ {
Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0; Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0;
Debugprintf("INP3 1 route %d %s", Dest->INP3ROUTE[0].SRTT, Call1); if (DEBUGINP3) Debugprintf("INP3 1 route %d %s", Dest->INP3ROUTE[0].SRTT, Call1);
return; // Only One, so cant be out of order return; // Only One, so cant be out of order
} }
if (Dest->INP3ROUTE[2].ROUT_NEIGHBOUR == 0) if (Dest->INP3ROUTE[2].ROUT_NEIGHBOUR == 0)
@ -745,7 +754,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0; Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0;
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2); if (DEBUGINP3) Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2);
if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT) if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT)
return; return;
@ -759,7 +768,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0; Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0;
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2); if (DEBUGINP3) Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2);
return; return;
} }
@ -770,7 +779,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0; Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0;
Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3); if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
// In order? // In order?
@ -791,7 +800,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0; Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0;
Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3); if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
// if 3 is better than 2 swap them. As two is worse than one. three will then be worst // if 3 is better than 2 swap them. As two is worse than one. three will then be worst
@ -807,7 +816,7 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0; Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0;
Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3); if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
// 3 is now slowest. 2 could still be better than 1 // 3 is now slowest. 2 could still be better than 1
@ -824,14 +833,14 @@ VOID SortRoutes(struct DEST_LIST * Dest)
Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0;
Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0; Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0;
Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3); if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3);
if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT && Dest->INP3ROUTE[1].SRTT <= Dest->INP3ROUTE[2].SRTT)// In order? if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT && Dest->INP3ROUTE[1].SRTT <= Dest->INP3ROUTE[2].SRTT)// In order?
return; return;
// Something went wrong // Something went wrong
Debugprintf("INP3 Sort Failed"); if (DEBUGINP3) Debugprintf("INP3 Sort Failed");
} }
@ -871,6 +880,8 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
{ {
int OtherRTT; int OtherRTT;
int Dummy; int Dummy;
char * ptr;
struct _RTTMSG * RTTMsg = (struct _RTTMSG *)&Buff->L4DATA[0];
char Normcall[10]; char Normcall[10];
@ -885,20 +896,40 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
return; return;
} }
if (Route->NEIGHBOUR_LINK->LINKPORT->ALLOWINP3) if (Route->NEIGHBOUR_LINK->LINKPORT->ALLOWINP3 || Route->NEIGHBOUR_LINK->LINKPORT->ENABLEINP3)
Route->INP3Node = 1; Route->INP3Node = 1;
if (Route->INP3Node == 0) if (Route->INP3Node == 0)
{ {
Debugprintf("Ignoring RTT Msg from %s - not using INP3", Normcall); if (DEBUGINP3) Debugprintf("Ignoring RTT Msg from %s - not using INP3", Normcall);
ReleaseBuffer(Buff); ReleaseBuffer(Buff);
return; // We don't want to use INP3 return; // We don't want to use INP3
} }
// Extract other end's SRTT // Extract other end's SRTT
// Get SWVERSION to see if other end is old (Buggy) BPQ
if (memcmp(RTTMsg->SWVERSION, "BPQ32001 ", 9) == 0)
Route->OldBPQ = 1;
else
Route->OldBPQ = 0;
sscanf(&Buff->L4DATA[6], "%d %d", &Dummy, &OtherRTT); sscanf(&Buff->L4DATA[6], "%d %d", &Dummy, &OtherRTT);
Route->NeighbourSRTT = OtherRTT * 10; // We store in mS
Route->NeighbourSRTT = OtherRTT;
// Look for $M and $H (MAXRTT MAXHOPS)
ptr = strstr(RTTMsg->FLAGS, "$M");
if (ptr)
Route->RemoteMAXRTT = atoi(ptr + 2);
ptr = strstr(RTTMsg->FLAGS, "$H");
if (ptr)
Route->RemoteMAXHOPS = atoi(ptr + 2);
// Echo Back to sender // Echo Back to sender
@ -908,20 +939,8 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
{ {
// Link is just starting // Link is just starting
Debugprintf("INP3 Processing first RTT frame from %s - link is (re)starting", Normcall); if (DEBUGINP3) Debugprintf("INP3 Processing first RTT frame from %s - link is (re)starting", Normcall);
Route->Status |= GotRTTRequest; Route->Status |= GotRTTRequest;
// I don't think we should send RIF until we get an RTT response.
if ((Route->Status & SentRTTRequest) == 0) // Not sent one yet so send it
SendRTTMsg(Route);
// No, it's the other end that must have an rrt response and we've just sent it
Route->Status |= SentOurRIF;
SendOurRIF(Route);
SendRIPToNeighbour(Route);
} }
} }
@ -931,6 +950,8 @@ VOID SendRTTMsg(struct ROUTE * Route)
struct _L3MESSAGEBUFFER * Msg; struct _L3MESSAGEBUFFER * Msg;
char Stamp[50]; char Stamp[50];
char Normcall[10]; char Normcall[10];
unsigned char temp[256];
uint64_t sendTime;
Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0; Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0;
@ -950,13 +971,25 @@ VOID SendRTTMsg(struct ROUTE * Route)
Msg->L4TXNO = 0; Msg->L4TXNO = 0;
Msg->L4FLAGS = L4INFO; Msg->L4FLAGS = L4INFO;
// The timestamp can possibly exceed 10 digits. INP3 only works on differece between send and received, so base can be reset safely.
sprintf(Stamp, "%10llu %10d %10d %10d ", (GetTickCount() - timeLoadedMS), Route->SRTT/10, Route->RTT/10, 0); sendTime = ((uint64_t)GetTickCount() - INP3timeLoadedMS) / 10; // 10mS units
if (sendTime > 9999999999)
sendTime = INP3timeLoadedMS = 0;
sprintf(Stamp, "%10llu %10d %10d %10d ", sendTime, Route->SRTT, Route->RTT, 0);
memcpy(RTTMsg.TXTIME, Stamp, 44); memcpy(RTTMsg.TXTIME, Stamp, 44);
// We now allow MAXRTT and MAXHOPS to be reconfigured so should update header each time
sprintf(temp, "$M%d $N $H%d ", MAXRTT, MaxHops); // trailing spaces extend to ensure padding if the length of characters for MAXRTT changes.
memcpy(RTTMsg.FLAGS, temp, 20); // But still limit the actual characters copied.
memcpy(Msg->L4DATA, &RTTMsg, 236); memcpy(Msg->L4DATA, &RTTMsg, 236);
Msg->LENGTH = 256 + 1 + 7; Msg->LENGTH = 256 + 1 + MSGHDDRLEN;
Route->Timeout = RTTTimeout; Route->Timeout = RTTTimeout;
@ -967,7 +1000,7 @@ VOID SendRTTMsg(struct ROUTE * Route)
Route->Status |= SentRTTRequest; Route->Status |= SentRTTRequest;
Debugprintf("INP3 Sending first RTT Msg to %s", Normcall); if (DEBUGINP3) Debugprintf("INP3 Sending first RTT Msg to %s", Normcall);
} }
@ -1031,12 +1064,13 @@ int BuildRIF(UCHAR * RIF, UCHAR * Call, UCHAR * Alias, int Hops, int RTT)
RIF[12+AliasLen] = 0; RIF[12+AliasLen] = 0;
RIFLen = 13 + AliasLen; RIFLen = 13 + AliasLen;
Debugprintf("INP3 sending RIF Entry %s:%s %d %d", AliasCopy, Normcall, Hops, RTT); if (DEBUGINP3) Debugprintf("INP3 sending RIF Entry %s:%s %d %d", AliasCopy, Normcall, Hops, RTT);
return RIFLen; return RIFLen;
} }
RIF[10] = 0; RIF[10] = 0;
Debugprintf("INP3 sending RIF Entry %s %d %d", Normcall, Hops, RTT); if (DEBUGINP3) Debugprintf("INP3 sending RIF Entry %s %d %d", Normcall, Hops, RTT);
return (11); return (11);
} }
@ -1057,14 +1091,18 @@ VOID SendOurRIF(struct ROUTE * Route)
Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0; Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0;
Debugprintf("INP3 Sending Initial RIF to %s ", Normcall); if (DEBUGINP3) Debugprintf("INP3 Sending Initial RIF to %s ", Normcall);
Msg->L3SRCE[0] = 0xff; Msg->L3SRCE[0] = 0xff;
// send a RIF for our Node and all our APPLCalls // send a RIF for our Node and all our APPLCalls
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], MYCALL, MYALIASTEXT, 1, 0); if (Route->OldBPQ)
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], MYCALL, MYALIASTEXT, 1, Route->RTTIncrement * 10);
else
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], MYCALL, MYALIASTEXT, 1, Route->RTTIncrement);
totLen += RIFLen; totLen += RIFLen;
for (App = 0; App < NumberofAppls; App++) for (App = 0; App < NumberofAppls; App++)
@ -1073,7 +1111,11 @@ VOID SendOurRIF(struct ROUTE * Route)
if (APPL->APPLQUAL > 0) if (APPL->APPLQUAL > 0)
{ {
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], APPL->APPLCALL, APPL->APPLALIAS_TEXT, 1, 0); if (Route->OldBPQ)
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], APPL->APPLCALL, APPL->APPLALIAS_TEXT, 1, Route->RTTIncrement * 10);
else
RIFLen = BuildRIF(&Msg->L3SRCE[totLen], APPL->APPLCALL, APPL->APPLALIAS_TEXT, 1, Route->RTTIncrement);
totLen += RIFLen; totLen += RIFLen;
} }
} }
@ -1131,11 +1173,10 @@ int SendRIPTimer()
else else
INP3Delay = 600; INP3Delay = 600;
if (Route->LastConnectAttempt && if (Route->LastConnectAttempt && (REALTIMETICKS - Route->LastConnectAttempt) < INP3Delay)
(REALTIMETICKS - Route->LastConnectAttempt) < INP3Delay)
{ {
Route++; Route++;
continue; // No room for link continue; // Not yet
} }
// Try to activate link // Try to activate link
@ -1143,7 +1184,7 @@ int SendRIPTimer()
if (Route->INP3Node) if (Route->INP3Node)
{ {
Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0; Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0;
Debugprintf("INP3 Activating link to %s", Normcall); if (DEBUGINP3) Debugprintf("INP3 Activating link to %s", Normcall);
} }
L2SETUPCROSSLINKEX(Route, 2); // Only try SABM twice L2SETUPCROSSLINKEX(Route, 2); // Only try SABM twice
@ -1207,7 +1248,7 @@ int SendRIPTimer()
char Call [11] = ""; char Call [11] = "";
ConvFromAX25(Route->NEIGHBOUR_CALL, Call); ConvFromAX25(Route->NEIGHBOUR_CALL, Call);
Debugprintf("BPQ32 INP3 Neighbour %s Lost", Call); if (DEBUGINP3) Debugprintf("BPQ32 INP3 Neighbour %s Lost", Call);
Route->Status = 0; // Down Route->Status = 0; // Down
} }
@ -1222,7 +1263,7 @@ int SendRIPTimer()
} }
else else
{ {
Route->BCTimer = RTTInterval; Route->BCTimer = RTTInterval + rand() % 4;
Route->Retries = RTTRetries; Route->Retries = RTTRetries;
SendRTTMsg(Route); SendRTTMsg(Route);
} }
@ -1261,7 +1302,7 @@ VOID SendRIF(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Msg)
Msg->LENGTH += MSGHDDRLEN + 1; // PID Msg->LENGTH += MSGHDDRLEN + 1; // PID
Debugprintf("Sending INP3 RIF length %d to %s", Msg->LENGTH, Normcall); if (DEBUGINP3) Debugprintf("Sending INP3 RIF length %d to %s", Msg->LENGTH, Normcall);
SendNetFrame(Route, Msg); SendNetFrame(Route, Msg);
} }
@ -1271,10 +1312,11 @@ VOID SendRIPToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_RO
struct _L3MESSAGEBUFFER * Msg; struct _L3MESSAGEBUFFER * Msg;
int count, MaxRoutes = MAXNEIGHBOURS; int count, MaxRoutes = MAXNEIGHBOURS;
char Normcall[10]; char Normcall[10];
int sendHops, sendTT;
Normcall[ConvFromAX25(axcall, Normcall)] = 0; Normcall[ConvFromAX25(axcall, Normcall)] = 0;
Debugprintf("INP3 SendRIPToOtherNeighbours for %s", Normcall); if (DEBUGINP3) Debugprintf("INP3 SendRIPToOtherNeighbours for %s", Normcall);
for (count=0; count<MaxRoutes; count++) for (count=0; count<MaxRoutes; count++)
{ {
@ -1282,26 +1324,39 @@ VOID SendRIPToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_RO
(Routes->Status) && (Routes->Status) &&
(Routes != Entry->ROUT_NEIGHBOUR)) // Dont send to originator of route (Routes != Entry->ROUT_NEIGHBOUR)) // Dont send to originator of route
{ {
Msg = Routes->Msg; sendHops = Entry->Hops + 1;
sendTT = Entry->SRTT + Entry->ROUT_NEIGHBOUR->RTTIncrement;
if (Msg == NULL)
{
Normcall[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall)] = 0;
Debugprintf("INP3 Building RIF to send to %s", Normcall);
Msg = Routes->Msg = CreateRIFHeader(Routes);
}
if (Msg) // send, but only if within their constraints
if ((Routes->RemoteMAXHOPS == 0 || Routes->RemoteMAXHOPS >= Entry->Hops) &&
(Routes->RemoteMAXRTT == 0 || Routes->RemoteMAXRTT >= Entry->SRTT || Entry->SRTT == 60000))
{ {
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], Msg = Routes->Msg;
axcall, alias, Entry->Hops + 1, Entry->SRTT + Entry->ROUT_NEIGHBOUR->SRTT/10);
if (Msg->LENGTH > 250 - 15) if (Msg == NULL)
// if (Msg->LENGTH > Routes->NBOUR_PACLEN - 11)
{ {
SendRIF(Routes, Msg); Normcall[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall)] = 0;
Routes->Msg = NULL; if (DEBUGINP3) Debugprintf("INP3 Building RIF to send to %s", Normcall);
Msg = Routes->Msg = CreateRIFHeader(Routes);
}
if (Msg)
{
if (Routes->OldBPQ)
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH],
axcall, alias, sendHops, sendTT + 10);
else
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH],
axcall, alias, sendHops, sendTT);
if (Msg->LENGTH > 250 - 15)
// if (Msg->LENGTH > Routes->NBOUR_PACLEN - 11)
{
SendRIF(Routes, Msg);
Routes->Msg = NULL;
}
} }
} }
} }
@ -1315,11 +1370,12 @@ VOID SendRIPToNeighbour(struct ROUTE * Route)
struct DEST_LIST * Dest = DESTS; struct DEST_LIST * Dest = DESTS;
struct INP3_DEST_ROUTE_ENTRY * Entry; struct INP3_DEST_ROUTE_ENTRY * Entry;
struct _L3MESSAGEBUFFER * Msg; struct _L3MESSAGEBUFFER * Msg;
int sendHops, sendTT;
char Normcall[10]; char Normcall[10];
Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0; Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0;
Debugprintf("INP3 Sending Our Table to %s ", Normcall); if (DEBUGINP3) Debugprintf("INP3 Sending Our Table to %s ", Normcall);
Dest--; Dest--;
@ -1331,26 +1387,35 @@ VOID SendRIPToNeighbour(struct ROUTE * Route)
Entry = &Dest->INP3ROUTE[0]; Entry = &Dest->INP3ROUTE[0];
if (Entry->ROUT_NEIGHBOUR && Entry->Hops && Route != Entry->ROUT_NEIGHBOUR) if (Entry->ROUT_NEIGHBOUR && Entry->Hops && Route != Entry->ROUT_NEIGHBOUR)
{ {
// Best Route not via this neighbour - send // Best Route not via this neighbour - send, but only if within their constraints
Msg = Route->Msg;
if (Msg == NULL)
Msg = Route->Msg = CreateRIFHeader(Route);
if (Msg == NULL)
return;
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH],
Dest->DEST_CALL, Dest->DEST_ALIAS,
Entry->Hops + 1, Entry->SRTT + Entry->ROUT_NEIGHBOUR->SRTT/10);
if (Msg->LENGTH > 250 - 15) sendHops = Entry->Hops + 1;
sendTT = Entry->SRTT + Entry->ROUT_NEIGHBOUR->RTTIncrement;
if ((Route->RemoteMAXHOPS == 0 || Route->RemoteMAXHOPS >= Entry->Hops) &&
(Route->RemoteMAXRTT == 0 || Route->RemoteMAXRTT >= Entry->SRTT || Entry->SRTT == 60000))
{ {
SendRIF(Route, Msg); Msg = Route->Msg;
Route->Msg = NULL;
if (Msg == NULL)
Msg = Route->Msg = CreateRIFHeader(Route);
if (Msg == NULL)
return;
if (Route->OldBPQ)
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], Dest->DEST_CALL, Dest->DEST_ALIAS, sendHops, sendTT * 10); // old bpq bug - send mS not 10 mS units
else
Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], Dest->DEST_CALL, Dest->DEST_ALIAS, sendHops, sendTT);
if (Msg->LENGTH > 250 - 15)
{
SendRIF(Route, Msg);
Route->Msg = NULL;
}
} }
} }
} }
@ -1368,6 +1433,15 @@ VOID FlushRIFs()
for (count=0; count<MaxRoutes; count++) for (count=0; count<MaxRoutes; count++)
{ {
// Make sure we've sent our local calls
if ((Routes->Status & GotRTTRequest) && (Routes->Status & GotRTTResponse) && ((Routes->Status & SentOurRIF) == 0))
{
Routes->Status |= SentOurRIF;
SendOurRIF(Routes);
SendRIPToNeighbour(Routes);
}
if (Routes->Msg) if (Routes->Msg)
{ {
char Normcall[10]; char Normcall[10];
@ -1375,7 +1449,7 @@ VOID FlushRIFs()
Normcall[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall)] = 0; Normcall[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall)] = 0;
SendRIF(Routes, Routes->Msg); SendRIF(Routes, Routes->Msg);
Routes->Msg = NULL; Routes->Msg = NULL;
Debugprintf("INP3 Flushing RIF to %s", Normcall); if (DEBUGINP3) Debugprintf("INP3 Flushing RIF to %s", Normcall);
} }
Routes+=1; Routes+=1;
} }
@ -1426,7 +1500,7 @@ VOID SendNegativeInfo()
{ {
char call[11]=""; char call[11]="";
ConvFromAX25(Dest->DEST_CALL, call); ConvFromAX25(Dest->DEST_CALL, call);
Debugprintf("INP3 Deleting Node %s", call); if (DEBUGINP3) Debugprintf("INP3 Deleting Node %s", call);
REMOVENODE(Dest); // Clear buffers, Remove from Sorted Nodes chain, and zap entry REMOVENODE(Dest); // Clear buffers, Remove from Sorted Nodes chain, and zap entry
} }
else else
@ -1585,7 +1659,9 @@ UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen)
msglen -= 10; msglen -= 10;
while (*ptr1 && msglen > 0) // Process optional fields
while (*ptr1 && msglen > 0) // Have an option
{ {
len = *ptr1; len = *ptr1;
opcode = *(ptr1+1); opcode = *(ptr1+1);
@ -1599,18 +1675,20 @@ UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen)
{ {
memcpy(&alias[6 - (len - 2)], ptr1+2, len-2); // Right Justiify memcpy(&alias[6 - (len - 2)], ptr1+2, len-2); // Right Justiify
} }
else else if (opcode == 1 && len < 8)
if (opcode == 1 && len < 8) {
{ memcpy(IP, ptr1+2, len-2);
memcpy(IP, ptr1+2, len-2); }
}
ptr2+=sprintf(ptr2, " %s:%s %d %4.2d\r", alias, call, hops, rtt);
ptr1++; ptr1 += len;
msglen--; // EOP msglen -= len;
} }
return ptr2; ptr2+=sprintf(ptr2, " %s:%s %d %4.2d\r", alias, call, hops, rtt);
ptr1++;
msglen--; // Over EOP
} }
return ptr2; return ptr2;
} }

Binary file not shown.

View file

@ -45,6 +45,8 @@ extern VOID Q_ADD();
VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Debugprintf(const char * format, ...);
TRANSPORTENTRY * NRRSession; TRANSPORTENTRY * NRRSession;
time_t NRRTime;
/* /*
datagrams (and other things) to be transported in Netrom L3 frames. datagrams (and other things) to be transported in Netrom L3 frames.
@ -76,6 +78,7 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
UCHAR * BUFFER = GetBuff(); UCHAR * BUFFER = GetBuff();
UCHAR * ptr1; UCHAR * ptr1;
struct _MESSAGE * Msg; struct _MESSAGE * Msg;
time_t Now = time(NULL);
if (BUFFER == NULL) if (BUFFER == NULL)
return; return;
@ -84,7 +87,7 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
*ptr1++ = 0xf0; // PID *ptr1++ = 0xf0; // PID
ptr1 += sprintf(ptr1, "NRR Response:"); ptr1 += sprintf(ptr1, "NRR Response in (probably) %d Secs :", (int)(Now - NRRTime));
Buff += 21 + MSGHDDRLEN; Buff += 21 + MSGHDDRLEN;
Len -= (21 + MSGHDDRLEN); Len -= (21 + MSGHDDRLEN);
@ -172,6 +175,7 @@ VOID SendNRRecordRoute(struct DEST_LIST * DEST, TRANSPORTENTRY * Session)
return; return;
NRRSession = Session; // Save Session Pointer for reply NRRSession = Session; // Save Session Pointer for reply
NRRTime = time(NULL);
Msg->Port = 0; Msg->Port = 0;
Msg->L3PID = NRPID; Msg->L3PID = NRPID;

19
Bpq32.c
View file

@ -1180,7 +1180,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix processing of the Winlink API /account/exists response (82) // Fix processing of the Winlink API /account/exists response (82)
// Fix sending CTEXT to L4 connects to Node when FULL_CTEXT is not set // Fix sending CTEXT to L4 connects to Node when FULL_CTEXT is not set
// Version 6.0.25.? // Version 6.0.25.1 Sept 2025
// Fix 64 bit compatibility problems in SCSTracker and UZ7HO drivers // Fix 64 bit compatibility problems in SCSTracker and UZ7HO drivers
// Add Chat PACLEN config (5) // Add Chat PACLEN config (5)
@ -1284,6 +1284,16 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix Webmail autorefresh extra threads problem (websock connection lost handling) (82) // Fix Webmail autorefresh extra threads problem (websock connection lost handling) (82)
// Fix overwriting application alias (83) // Fix overwriting application alias (83)
// Version 6.0.26.?
// Fix for compiling with gcc15 (2)
// Fix possble stuck L2 session caused by window being set to zero (3)
// Improvments to INP3 (4, 5)
// Add Node API /api/tcpqueues (5)
// Add sending link events to OARC API (disabled by default) (6)
#define CKernel #define CKernel
#include "Versions.h" #include "Versions.h"
@ -1444,7 +1454,8 @@ extern char MYCALL[]; // 7 chars, ax.25 format
extern HWND hIPResWnd; extern HWND hIPResWnd;
extern BOOL IPMinimized; extern BOOL IPMinimized;
extern int NODESINPROGRESS; extern int NODESINPROGRESS;
extern int NODESToOnePort;
extern VOID * CURRENTNODE; extern VOID * CURRENTNODE;
@ -1514,7 +1525,7 @@ extern char ReportDest[7];
extern UCHAR ConfigDirectory[260]; extern UCHAR ConfigDirectory[260];
extern uint64_t timeLoadedMS; extern uint64_t INP3timeLoadedMS;
VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Debugprintf(const char * format, ...);
VOID __cdecl Consoleprintf(const char * format, ...); VOID __cdecl Consoleprintf(const char * format, ...);
@ -2403,7 +2414,7 @@ FirstInit()
EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses"); EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses");
} }
timeLoadedMS = GetTickCount(); INP3timeLoadedMS = GetTickCount();
srand(time(NULL)); srand(time(NULL));

139
Cmd.c
View file

@ -73,7 +73,7 @@ int seeifInterlockneeded(struct PORTCONTROL * PORT);
int CompareNode(const void *a, const void *b); int CompareNode(const void *a, const void *b);
int CompareAlias(const void *a, const void *b); int CompareAlias(const void *a, const void *b);
int CompareRoutes(const void * a, const void * b); int CompareRoutes(const void * a, const void * b);
void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer);
extern VOID KISSTX(struct KISSINFO * KISS, PMESSAGE Buffer); extern VOID KISSTX(struct KISSINFO * KISS, PMESSAGE Buffer);
@ -86,6 +86,7 @@ UCHAR SAVEDAPPLFLAGS = 0;
UCHAR ALIASINVOKED = 0; UCHAR ALIASINVOKED = 0;
extern int MONTOFILEFLAG;
VOID * CMDPTR = 0; VOID * CMDPTR = 0;
@ -155,13 +156,15 @@ char * ALIASPTR = &CMDALIAS[0][0];
extern int RigReconfigFlag; extern int RigReconfigFlag;
extern int DEBUGINP3;
extern int PREFERINP3ROUTES;
struct CMDX COMMANDS[]; struct CMDX COMMANDS[];
int CMDXLEN = sizeof (struct CMDX); int CMDXLEN = sizeof (struct CMDX);
VOID SENDNODESMSG(); VOID SENDNODESMSG(int Portnum);
VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD); VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
VOID STOPCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD); VOID STOPCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
VOID STARTCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD); VOID STARTCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
@ -249,10 +252,81 @@ char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char
return Bufferptr + MsgLen; return Bufferptr + MsgLen;
} }
VOID POLLNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
int Portnum = atoi(CmdTail);
struct PORTCONTROL * PORT = 0;
MESSAGE * Buffer;
UCHAR * ptr1;
if (Portnum)
PORT = GetPortTableEntryFromPortNum(Portnum);
if (Portnum == 0 || PORT == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
if (PORT->PORTQUALITY == 0 || PORT->INP3ONLY)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Quality = 0 or INP3 Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
Buffer = GetBuff();
if (Buffer == 0)
return;
Buffer->PORT = Portnum;
memcpy(Buffer->ORIGIN, NETROMCALL, 7);
memcpy(Buffer->DEST, NODECALL, 7);
Buffer->ORIGIN[6] |= 0x61; // SET CMD END AND RESERVED BITS
Buffer->CTL = UI;
Buffer->PID = 0xCF; // Netrom
ptr1 = &Buffer->L2DATA[0];
*(ptr1++) = 0xfe; // Nodes Poll Flag
memcpy(ptr1, MYALIASTEXT, 6);
ptr1+= 6;
Buffer->LENGTH = (int)(ptr1 - (UCHAR *)Buffer);
if (PORT->TNC && PORT->TNC->Hardware == H_VARA)
SendVARANetromNodes(PORT->TNC, Buffer);
else
PUT_ON_PORT_Q(PORT, Buffer);
strcpy(Bufferptr, OKMSG);
Bufferptr += (int)strlen(OKMSG);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
}
VOID SENDNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD) VOID SENDNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{ {
SENDNODESMSG(); int Portnum = atoi(CmdTail);
struct PORTCONTROL * PORT;
if (Portnum)
{
PORT = GetPortTableEntryFromPortNum(Portnum);
if (PORT == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
}
SENDNODESMSG(Portnum);
strcpy(Bufferptr, OKMSG); strcpy(Bufferptr, OKMSG);
Bufferptr += (int)strlen(OKMSG); Bufferptr += (int)strlen(OKMSG);
@ -1300,6 +1374,17 @@ VOID CMDL00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
else else
Bufferptr = Cmdprintf(Session, Bufferptr, " S=%d P=%d T=%d V=%d Q=%d\r", Bufferptr = Cmdprintf(Session, Bufferptr, " S=%d P=%d T=%d V=%d Q=%d\r",
LINK->L2STATE, LINK->LINKPORT->PORTNUMBER, LINK->LINKTYPE, 2 - LINK->VER1FLAG, Count); LINK->L2STATE, LINK->LINKPORT->PORTNUMBER, LINK->LINKTYPE, 2 - LINK->VER1FLAG, Count);
if (Count > 16 || LINK->LINKWINDOW == 0)
{
// Dump Link State
int secs = time(NULL) - LINK->LASTFRAMESENT;
Bufferptr = Cmdprintf(Session, Bufferptr, " Debug Info: LINK->LINKNS %d LINK->LINKOWS %d SDTSLOT %d LINKWINDOW %d L2FLAGS %d\r", LINK->LINKNS, LINK->LINKOWS, LINK->SDTSLOT, LINK->LINKWINDOW, LINK->L2FLAGS);
Bufferptr = Cmdprintf(Session, Bufferptr, " Debug Info: Slots %x %x %x %x %x %x %x %x\r", LINK->FRAMES[0], LINK->FRAMES[1], LINK->FRAMES[2], LINK->FRAMES[3],
LINK->FRAMES[4], LINK->FRAMES[5], LINK->FRAMES[6], LINK->FRAMES[7]);
}
} }
LINK++; LINK++;
} }
@ -1622,8 +1707,8 @@ char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE *
if (Routes->INP3Node) // INP3 Enabled? if (Routes->INP3Node) // INP3 Enabled?
{ {
double srtt = Routes->SRTT/1000.0; double srtt = Routes->SRTT/100.0;
double nsrtt = Routes->NeighbourSRTT/1000.0; double nsrtt = Routes->NeighbourSRTT/100.0;
Bufferptr = Cmdprintf(Session, Bufferptr, " %4.2fs %4.2fs", srtt, nsrtt); Bufferptr = Cmdprintf(Session, Bufferptr, " %4.2fs %4.2fs", srtt, nsrtt);
} }
@ -2169,6 +2254,32 @@ VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIS
return; return;
} }
BOOL CheckLink(UCHAR * LinkCall, UCHAR * OurCall, int Port)
{
// Check if a link exists betwwn a pair of calls on a port. Return TRUE if found
struct _LINKTABLE * LINK = LINKS;
int n = MAXLINKS;
while (n--)
{
if (LINK->LINKCALL[0] == 0) // Spare
{
LINK++;
continue;
}
if ((LINK->LINKPORT->PORTNUMBER == Port) && CompareCalls(LINK->LINKCALL, LinkCall) && CompareCalls(LINK->OURCALL, OurCall))
return TRUE;
LINK++;
}
// ENTRY NOT FOUND
return FALSE;
}
BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE ** REQLINK) BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE ** REQLINK)
{ {
struct _LINKTABLE * LINK = LINKS; struct _LINKTABLE * LINK = LINKS;
@ -2194,6 +2305,7 @@ BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE **
LINK++; LINK++;
} }
// ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL // ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL
*REQLINK = FIRSTSPARE; *REQLINK = FIRSTSPARE;
@ -2388,6 +2500,9 @@ NoPort:
// Convert to an APPL command, so any alias is actioned // Convert to an APPL command, so any alias is actioned
memcpy(Session->APPL,APPL->APPLCMD, 12);
// SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND // SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND
if (APPL->APPLHASALIAS && APPL->APPLALIASVAL[0] != 0x20) if (APPL->APPLHASALIAS && APPL->APPLALIASVAL[0] != 0x20)
@ -2939,7 +3054,7 @@ char * DoOneNode(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST *
if (Neighbour) if (Neighbour)
{ {
double srtt = Route->SRTT/1000.0; double srtt = Route->SRTT/100.0;
len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall); len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall);
Normcall[len] = 0; Normcall[len] = 0;
@ -2988,7 +3103,7 @@ int DoINP3ViaEntry(struct DEST_LIST * Dest, int n, char * line, int cursor)
if (Dest->INP3ROUTE[n].ROUT_NEIGHBOUR != 0) if (Dest->INP3ROUTE[n].ROUT_NEIGHBOUR != 0)
{ {
srtt = Dest->INP3ROUTE[n].SRTT/1000.0; srtt = Dest->INP3ROUTE[n].SRTT/100.0;
len=ConvFromAX25(Dest->INP3ROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall); len=ConvFromAX25(Dest->INP3ROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall);
Portcall[len]=0; Portcall[len]=0;
@ -4258,6 +4373,7 @@ struct CMDX COMMANDS[] =
"RIGRECONFIG ",8, &RIGRECONFIG, 0, "RIGRECONFIG ",8, &RIGRECONFIG, 0,
"RESTART ",7, &RESTART,0, "RESTART ",7, &RESTART,0,
"RESTARTTNC ",10,&RESTARTTNC,0, "RESTARTTNC ",10,&RESTARTTNC,0,
"POLLNODES ",8, &POLLNODES,0,
"SENDNODES ",8, &SENDNODES,0, "SENDNODES ",8, &SENDNODES,0,
"EXTRESTART ",10, EXTPORTVAL, offsetof(EXTPORTDATA, EXTRESTART), "EXTRESTART ",10, EXTPORTVAL, offsetof(EXTPORTDATA, EXTRESTART),
"TXDELAY ",3, PORTVAL, offsetof(PORTCONTROLX, PORTTXDELAY), "TXDELAY ",3, PORTVAL, offsetof(PORTCONTROLX, PORTTXDELAY),
@ -4275,6 +4391,10 @@ struct CMDX COMMANDS[] =
"MAXUSERS ",4,PORTVAL, offsetof(PORTCONTROLX, USERS), "MAXUSERS ",4,PORTVAL, offsetof(PORTCONTROLX, USERS),
"L3ONLY ",6,PORTVAL, offsetof(PORTCONTROLX, PORTL3FLAG), "L3ONLY ",6,PORTVAL, offsetof(PORTCONTROLX, PORTL3FLAG),
"BBSALIAS ",4,PORTVAL, offsetof(PORTCONTROLX, PORTBBSFLAG), "BBSALIAS ",4,PORTVAL, offsetof(PORTCONTROLX, PORTBBSFLAG),
"INP3ONLY ",8,PORTVAL, offsetof(PORTCONTROLX, INP3ONLY),
"ALLOWINP3 ",9,PORTVAL, offsetof(PORTCONTROLX, ALLOWINP3),
"ENABLEINP3 ",10,PORTVAL, offsetof(PORTCONTROLX, ENABLEINP3),
"MONTOFILE ",9,SWITCHVAL,(size_t)&MONTOFILEFLAG,
"VALIDCALLS ",5,VALNODES,0, "VALIDCALLS ",5,VALNODES,0,
"WL2KSYSOP ",5,WL2KSYSOP,0, "WL2KSYSOP ",5,WL2KSYSOP,0,
"STOPPORT ",4,STOPPORT,0, "STOPPORT ",4,STOPPORT,0,
@ -4286,6 +4406,7 @@ struct CMDX COMMANDS[] =
"KISS ",4,KISSCMD,0, "KISS ",4,KISSCMD,0,
"GETPORTCTEXT",9,GetPortCTEXT, 0, "GETPORTCTEXT",9,GetPortCTEXT, 0,
#ifdef EXCLUDEBITS #ifdef EXCLUDEBITS
"EXCLUDE ",4,ListExcludedCalls,0, "EXCLUDE ",4,ListExcludedCalls,0,
@ -4310,6 +4431,10 @@ struct CMDX COMMANDS[] =
"L4DELAY ",7,SWITCHVAL,(size_t)&L4DELAY, "L4DELAY ",7,SWITCHVAL,(size_t)&L4DELAY,
"L4WINDOW ",6,SWITCHVAL,(size_t)&L4DEFAULTWINDOW, "L4WINDOW ",6,SWITCHVAL,(size_t)&L4DEFAULTWINDOW,
"BTINTERVAL ",5,SWITCHVAL,(size_t)&BTINTERVAL, "BTINTERVAL ",5,SWITCHVAL,(size_t)&BTINTERVAL,
"DEBUGINP3 ",8,SWITCHVAL,(size_t)&DEBUGINP3,
"MAXHOPS ",7,SWITCHVAL,(size_t)&MaxHops,
"PREFERINP3 ",10,SWITCHVAL,(size_t)&PREFERINP3ROUTES,
"MAXRTT ",6,SWITCHVALW,(size_t)&MAXRTT,
"PASSWORD ", 8, PWDCMD, 0, "PASSWORD ", 8, PWDCMD, 0,
"************", 12, APPLCMD, 0, "************", 12, APPLCMD, 0,

View file

@ -79,6 +79,7 @@ extern VOID * ENDBUFFERPOOL;
extern int PoolBuilt; extern int PoolBuilt;
extern int EnableOARCAPI;
// Read/Write length field in a buffer header // Read/Write length field in a buffer header
@ -3313,8 +3314,12 @@ SOCKADDR_IN reportdest = {0};
SOCKET ReportSocket = 0; SOCKET ReportSocket = 0;
SOCKET NodeAPISocket = 0 ;
SOCKADDR_IN Chatreportdest = {0}; SOCKADDR_IN Chatreportdest = {0};
SOCKADDR_IN UDPreportdest = {0};
extern char LOCATOR[]; // Locator for Reporting - may be Maidenhead or LAT:LON extern char LOCATOR[]; // Locator for Reporting - may be Maidenhead or LAT:LON
extern char MAPCOMMENT[]; // Locator for Reporting - may be Maidenhead or LAT:LON extern char MAPCOMMENT[]; // Locator for Reporting - may be Maidenhead or LAT:LON
extern char LOC[7]; // Maidenhead Locator for Reporting extern char LOC[7]; // Maidenhead Locator for Reporting
@ -3670,11 +3675,16 @@ pthread_t ResolveUpdateThreadId = 0;
char NodeMapServer[80] = "update.g8bpq.net"; char NodeMapServer[80] = "update.g8bpq.net";
char ChatMapServer[80] = "chatupdate.g8bpq.net"; char ChatMapServer[80] = "chatupdate.g8bpq.net";
char NodeAPIServer[80] = "node-api.packet.oarc.uk";
int NodeAPIPort = 13579;
VOID ResolveUpdateThread(void * Unused) VOID ResolveUpdateThread(void * Unused)
{ {
struct hostent * HostEnt1; struct hostent * HostEnt1;
struct hostent * HostEnt2; struct hostent * HostEnt2;
struct hostent * HostEnt3;
ResolveUpdateThreadId = GetCurrentThreadId(); ResolveUpdateThreadId = GetCurrentThreadId();
@ -3702,6 +3712,14 @@ VOID ResolveUpdateThread(void * Unused)
if (HostEnt2) if (HostEnt2)
memcpy(&Chatreportdest.sin_addr.s_addr,HostEnt2->h_addr,4); memcpy(&Chatreportdest.sin_addr.s_addr,HostEnt2->h_addr,4);
Debugprintf("Resolving %s", NodeAPIServer);
HostEnt3 = gethostbyname(NodeAPIServer);
if (HostEnt3)
memcpy(&UDPreportdest.sin_addr.s_addr,HostEnt3->h_addr,4);
if (HostEnt1 && HostEnt2) if (HostEnt1 && HostEnt2)
{ {
Sleep(1000 * 60 * 30); Sleep(1000 * 60 * 30);
@ -3742,6 +3760,13 @@ VOID OpenReportingSockets()
ConvToAX25("DUMMY-1", ReportDest); ConvToAX25("DUMMY-1", ReportDest);
} }
UDPreportdest.sin_family = AF_INET;
UDPreportdest.sin_port = htons(NodeAPIPort);
if (EnableOARCAPI)
NodeAPISocket = socket(AF_INET, SOCK_DGRAM, 0);
// Set up Chat Report even if no LOCATOR reportdest.sin_family = AF_INET; // Set up Chat Report even if no LOCATOR reportdest.sin_family = AF_INET;
// Socket must be opened in MailChat Process // Socket must be opened in MailChat Process
@ -5194,14 +5219,14 @@ skipit:
} }
} }
void SendDataToPktMapThread(); void SendDataToPktMapThread(void * Param);
void SendDataToPktMap() void SendDataToPktMap()
{ {
_beginthread(SendDataToPktMapThread,2048000,0); _beginthread(SendDataToPktMapThread,2048000,0);
} }
void SendDataToPktMapThread() void SendDataToPktMapThread(void * Param)
{ {
char Return[256] = ""; char Return[256] = "";
char Request[64]; char Request[64];

View file

@ -43,8 +43,16 @@ void MQTTReportSession(char * Msg);
extern int MQTT; extern int MQTT;
int UDPSeq = 0;
extern SOCKET NodeAPISocket;
extern SOCKADDR_IN UDPreportdest;
extern char Modenames[19][10]; extern char Modenames[19][10];
extern char NODECALLLOPPED[10];
// Runs use specified routine on certain event // Runs use specified routine on certain event
#ifndef WIN32 #ifndef WIN32
@ -117,7 +125,11 @@ DllExport void APIENTRY RunEventProgram(char * Program, char * Param)
void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK) void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK)
{ {
// Incoming SABM // Incoming SABM accepted
char UDPMsg[1024];
int udplen;
LINK->ConnectTime = time(NULL); LINK->ConnectTime = time(NULL);
LINK->bytesTXed = LINK->bytesRXed = 0; LINK->bytesTXed = LINK->bytesRXed = 0;
@ -125,8 +137,19 @@ void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _
strcpy(LINK->callingCall, remotecall); strcpy(LINK->callingCall, remotecall);
strcpy(LINK->receivingCall, ourcall); strcpy(LINK->receivingCall, ourcall);
strcpy(LINK->Direction, "In"); strcpy(LINK->Direction, "In");
if (NodeAPISocket)
{
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall);
Debugprintf(UDPMsg);
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
}
} }
void hookL2SessionDeleted(struct _LINKTABLE * LINK) void hookL2SessionDeleted(struct _LINKTABLE * LINK)
{ {
// calculate session time and av bytes/min in and out // calculate session time and av bytes/min in and out
@ -141,12 +164,14 @@ void hookL2SessionDeleted(struct _LINKTABLE * LINK)
else else
{ {
char Msg[256]; char Msg[256];
char timestamp[16]; char timestamp[64];
time_t sessionTime = time(NULL) - LINK->ConnectTime; time_t sessionTime = time(NULL) - LINK->ConnectTime;
double avBytesSent = LINK->bytesTXed / (sessionTime / 60.0); double avBytesSent = LINK->bytesTXed / (sessionTime / 60.0);
double avBytesRXed = LINK->bytesRXed / (sessionTime / 60.0); double avBytesRXed = LINK->bytesRXed / (sessionTime / 60.0);
time_t Now = time(NULL); time_t Now = time(NULL);
struct tm * TM = localtime(&Now); struct tm * TM = localtime(&Now);
char UDPMsg[1024];
int udplen;
sprintf(timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec); sprintf(timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec);
@ -164,6 +189,21 @@ void hookL2SessionDeleted(struct _LINKTABLE * LINK)
if (MQTT) if (MQTT)
MQTTReportSession(Msg); MQTTReportSession(Msg);
if (NodeAPISocket)
{
if (strcmp(LINK->Direction, "Out") == 0)
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall);
else
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall);
Debugprintf(UDPMsg);
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
}
} }
LINK->ConnectTime = 0; LINK->ConnectTime = 0;
@ -186,6 +226,27 @@ void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _L
strcpy(LINK->Direction, "Out"); strcpy(LINK->Direction, "Out");
} }
void hookL2SessionConnected(struct _LINKTABLE * LINK)
{
// UA received in reponse to SABM
char UDPMsg[1024];
int udplen;
if (NodeAPISocket)
{
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkUpEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\"}",
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall);
Debugprintf(UDPMsg);
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
}
}
void hookL4SessionAttempt(struct STREAMINFO * STREAM, char * remotecall, char * ourcall) void hookL4SessionAttempt(struct STREAMINFO * STREAM, char * remotecall, char * ourcall)
{ {
// Outgoing Connect // Outgoing Connect
@ -210,6 +271,20 @@ void hookL4SessionAccepted(struct STREAMINFO * STREAM, char * remotecall, char *
strcpy(STREAM->Direction, "In"); strcpy(STREAM->Direction, "In");
} }
/*
{
"eventSource": "circuit",
"time": "2025-10-08T14:05:54+00:00",
"id": 23,
"direction": "incoming",
"port": "0",
"remote": "G8PZT@G8PZT:15aa",
"local": "GE8PZT:0017",
"event": "disconnect",
"@type": "event"
}
*/
void hookL4SessionDeleted(struct TNCINFO * TNC, struct STREAMINFO * STREAM) void hookL4SessionDeleted(struct TNCINFO * TNC, struct STREAMINFO * STREAM)
{ {
char Msg[256]; char Msg[256];

View file

@ -426,7 +426,7 @@ VOID ChatExpandAndSendMessage(ChatCIRCUIT * conn, char * Msg, int LOG)
len = RemoveLF(NewMessage, (int)strlen(NewMessage)); len = RemoveLF(NewMessage, (int)strlen(NewMessage));
ChatWriteLogLine(conn, '>', NewMessage, len, LOG); ChatWriteLogLine(conn, '>', NewMessage, len, LOG_CHAT);
ChatQueueMsg(conn, NewMessage, len); ChatQueueMsg(conn, NewMessage, len);
} }

237
L2Code.c
View file

@ -64,7 +64,7 @@ VOID L2SENDRESPONSE(struct _LINKTABLE * LINK, int CMD);
VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD); VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD);
VOID ACKMSG(struct _LINKTABLE * LINK); VOID ACKMSG(struct _LINKTABLE * LINK);
VOID InformPartner(struct _LINKTABLE * LINK, int Reason); VOID InformPartner(struct _LINKTABLE * LINK, int Reason);
UINT RR_OR_RNR(struct _LINKTABLE * LINK); UINT RR_OR_RNR(struct _LINKTABLE * LINK, int CMD);
VOID L2TIMEOUT(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT); VOID L2TIMEOUT(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT);
VOID CLEAROUTLINK(struct _LINKTABLE * LINK); VOID CLEAROUTLINK(struct _LINKTABLE * LINK);
VOID SENDFRMR(struct _LINKTABLE * LINK); VOID SENDFRMR(struct _LINKTABLE * LINK);
@ -99,6 +99,7 @@ VOID L2SENDXID(struct _LINKTABLE * LINK);
VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Debugprintf(const char * format, ...);
VOID Q_IP_MSG(MESSAGE * Buffer); VOID Q_IP_MSG(MESSAGE * Buffer);
VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT); VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT);
VOID PROCESSNODESPOLL(struct PORTCONTROL * PORT);
VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG);
BOOL CompareAliases(UCHAR * c1, UCHAR * c2); BOOL CompareAliases(UCHAR * c1, UCHAR * c2);
VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG);
@ -120,8 +121,10 @@ int CheckKissInterlock(struct PORTCONTROL * MYPORT, int Exclusive);
void hookL2SessionAccepted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK); void hookL2SessionAccepted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(struct _LINKTABLE * LINK); void hookL2SessionDeleted(struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK); void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionConnected(struct _LINKTABLE * LINK);
int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len); int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len);
VOID DeleteINP3Routes(struct ROUTE * Route); VOID DeleteINP3Routes(struct ROUTE * Route);
VOID SendRTTMsg(struct ROUTE * Route);
extern int REALTIMETICKS; extern int REALTIMETICKS;
@ -445,6 +448,8 @@ TRYBBS:
if ((PORT->PERMITTEDAPPLS & APPLMASK) != 0) if ((PORT->PERMITTEDAPPLS & APPLMASK) != 0)
{ {
ALIASMSG = 0; ALIASMSG = 0;
strcpy(LINK->ApplName, APPL->APPLCMD);
if (CompareCalls(Buffer->DEST, APPL->APPLCALL)) if (CompareCalls(Buffer->DEST, APPL->APPLCALL))
goto FORUS; goto FORUS;
@ -479,9 +484,9 @@ NOWTRY_NODES:
if (CompareCalls(Buffer->DEST, NODECALL)) if (CompareCalls(Buffer->DEST, NODECALL))
{ {
if (Buffer->L2DATA[0] == 0xff) // Valid NODES Broadcast if (Buffer->L2DATA[0] == 0xff) // Valid NODES Broadcast
{
PROCESSNODEMESSAGE(Buffer, PORT); PROCESSNODEMESSAGE(Buffer, PORT);
} else if (Buffer->L2DATA[0] == 0xfe) // Paula's NODES Poll (request Nodes broadcast on port)
PROCESSNODESPOLL(PORT);
} }
ReleaseBuffer(Buffer); ReleaseBuffer(Buffer);
@ -808,7 +813,15 @@ VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buff
if (CTLlessPF == XID) if (CTLlessPF == XID)
{ {
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG); // We could possibly get an XID response if packet is badly delayed and we had timed out
if ((MSGFLAG & CMDBIT)) // Command
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
else
{
Debugprintf("Unexpected XID response with no session");
ReleaseBuffer(Buffer); // Ignore if not
}
return; return;
} }
@ -929,6 +942,7 @@ VOID ProcessXIDCommand(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESS
LINK->L2STATE = 1; // XID received LINK->L2STATE = 1; // XID received
LINK->Ver2point2 = TRUE; // Must support 2.2 if sent XID LINK->Ver2point2 = TRUE; // Must support 2.2 if sent XID
LINK->L2TIME = PORT->PORTT1; LINK->L2TIME = PORT->PORTT1;
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
LINK->LINKPORT = PORT; LINK->LINKPORT = PORT;
@ -1076,87 +1090,128 @@ VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
return; return;
} }
if (CTLlessPF == XID)
if (LINK->L2STATE == 1)
{ {
// XID State. Should be XID response if 2.2 ok or DM/FRMR if not // XID command or response on active session.
// if Command and state = 2 then other end missed XID Response. Process command again
if (MSGFLAG & RESP) if ((MSGFLAG & CMDBIT))
{ {
if (CTLlessPF == DM || CTLlessPF == FRMR) if (LINK->L2STATE == 2)
{ {
// Doesn't support XID - Send SABM // I think we can just process as normal.
LINK->L2STATE = 2; ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
LINK->Ver2point2 = FALSE; return;
LINK->L2TIMER = 1; // Use retry to send SABM
} }
else if (CTLlessPF == XID)
if (LINK->L2STATE == 1) // We've just sent XID so is probably XID Collision
{ {
// Process response to make sure ok, Send SABM or DISC // I think we can just process as normal. If we don't send a response the other end may not switch to 2.2
LINK->L2STATE = 2; ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
LINK->Ver2point2 = TRUE;// Must support 2.2 if responded to XID return;
// if Compress enabled set it
ptr = &ADJBUFFER->PID;
if (*ptr++ == 0x82 && *ptr++ == 0x80)
{
int Type;
int Len;
unsigned int value;
int xidlen = *(ptr++) << 8;
xidlen += *ptr++;
// XID is set of Type, Len, Value n-tuples
while (xidlen > 0)
{
Type = *ptr++;
Len = *ptr++;
value = 0;
xidlen -= (Len + 2);
while (Len--)
{
value <<=8;
value += *ptr++;
}
switch(Type)
{
case 17:
// Compression
if (L2Compress)
LINK->AllowCompress = 1;
}
}
}
LINK->L2TIMER = 1; // Use retry to send SABM
} }
// XID Command on active session. Other end may be restarting. Reset session
InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END
LINK->CIRCUITPOINTER = 0;
// I think it is safer to ignore it. The retry will be processed normally as XID command with no session
ReleaseBuffer(Buffer); ReleaseBuffer(Buffer);
return; return;
} }
// Command on existing session. Could be due to other end missing
// the XID response, so if XID just resend response
// XID Response
// if Link State = 1 this is a normal response. Check it then send SABM
if (LINK->L2STATE == 1)
{
LINK->L2STATE = 2;
LINK->Ver2point2 = TRUE;// Must support 2.2 if responded to XID
// if Compress enabled set it
ptr = &ADJBUFFER->PID;
if (*ptr++ == 0x82 && *ptr++ == 0x80)
{
int Type;
int Len;
unsigned int value;
int xidlen = *(ptr++) << 8;
xidlen += *ptr++;
// XID is set of Type, Len, Value n-tuples
while (xidlen > 0)
{
Type = *ptr++;
Len = *ptr++;
value = 0;
xidlen -= (Len + 2);
while (Len--)
{
value <<=8;
value += *ptr++;
}
switch(Type)
{
case 17:
// Compression
if (L2Compress)
LINK->AllowCompress = 1;
}
}
}
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
LINK->L2TIMER = 1; // Use retry to send SABM
ReleaseBuffer(Buffer);
return;
}
// XID response, not in state 1.
// This "shouldn't happen"
Debugprintf("Unexpected XID response, State = %d", LINK->L2STATE);
// Discard
ReleaseBuffer(Buffer);
return;
} }
if (CTLlessPF == XID && (MSGFLAG & CMDBIT))
{
// XID Command on active session. Other end may be restarting. Send Response
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG); // Not XID
return;
// if state = 1 then unexpected response to XID
if (LINK->L2STATE == 1)
{
if (CTLlessPF == DM || CTLlessPF == FRMR)
{
// Doesn't support XID - Send SABM
LINK->L2STATE = 2;
LINK->Ver2point2 = FALSE;
LINK->L2TIMER = 1; // Use retry to send SABM
ReleaseBuffer(Buffer);
return;
}
} }
@ -1288,6 +1343,16 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
Debugprintf("INP3 Incoming connect from %s", fromCall); Debugprintf("INP3 Incoming connect from %s", fromCall);
DeleteINP3Routes(ROUTE); DeleteINP3Routes(ROUTE);
} }
else
{
if (PORT->ENABLEINP3)
{
// We will offer INP3 by sending an RTT probe.
SendRTTMsg(ROUTE);
}
}
} }
if (NO_CTEXT == 1) if (NO_CTEXT == 1)
@ -1388,6 +1453,8 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
return; return;
} }
strcpy(Session->APPL, LINK->ApplName);
// NOW TRY A BBS CONNECT // NOW TRY A BBS CONNECT
// IF APPL CONNECT, SEE IF APPL HAS AN ALIAS // IF APPL CONNECT, SEE IF APPL HAS AN ALIAS
@ -1987,15 +2054,26 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B
{ {
Debugprintf("INP3 Route to %s connected", fromCall); Debugprintf("INP3 Route to %s connected", fromCall);
} }
else
{
if (PORT->ENABLEINP3)
{
// We will offer INP3 by sending an RTT probe.
SendRTTMsg(ROUTE);
}
}
} }
hookL2SessionConnected(LINK);
SendL2ToMonMap(PORT, fromCall, '+', 'O'); SendL2ToMonMap(PORT, fromCall, '+', 'O');
LINK->L2STATE = 5; LINK->L2STATE = 5;
LINK->L2TIMER = 0; // CANCEL TIMER LINK->L2TIMER = 0; // CANCEL TIMER
LINK->L2RETRIES = 0; LINK->L2RETRIES = 0;
LINK->L2SLOTIM, T3; // SET FRAME SENT RECENTLY LINK->L2SLOTIM = T3; // SET FRAME SENT RECENTLY
// IF VERSION 1 MSG, SET FLAG // IF VERSION 1 MSG, SET FLAG
@ -2274,7 +2352,7 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
if (LINK->LAST_F_TIME + 15 > REALTIMETICKS) if (LINK->LAST_F_TIME + 15 > REALTIMETICKS)
return; // DISCARD return; // DISCARD
CTL = RR_OR_RNR(LINK); CTL = RR_OR_RNR(LINK, FALSE); // Sending response
CTL |= LINK->LINKNR << 5; // SHIFT N(R) TO TOP 3 BITS CTL |= LINK->LINKNR << 5; // SHIFT N(R) TO TOP 3 BITS
CTL |= PFBIT; CTL |= PFBIT;
@ -2981,9 +3059,9 @@ VOID SDETX(struct _LINKTABLE * LINK)
// **** Debug code **** look for stuck links // **** Debug code **** look for stuck links
if (LINK->LASTFRAMESENT && (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs if (LINK->LINKWINDOW == 0 || LINK->LASTFRAMESENT == 0 || (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs
{ {
if (COUNT_AT_L2(LINK) > 16) if (COUNT_AT_L2(LINK) > 16 || LINK->LINKWINDOW == 0)
{ {
// Dump Link State // Dump Link State
@ -3316,7 +3394,7 @@ VOID L2TimerProc()
{ {
// Was busy // Was busy
if (RR_OR_RNR(LINK) != RNR) // SEE IF STILL BUSY if (RR_OR_RNR(LINK, 0) != RNR) // SEE IF STILL BUSY
{ {
// Not still busy - tell other end // Not still busy - tell other end
@ -3375,7 +3453,7 @@ VOID L2TimerProc()
{ {
SendSupervisCmd(LINK); SendSupervisCmd(LINK);
LINK++; LINK++;
continue; continue;
} }
} }
@ -3432,7 +3510,7 @@ VOID SendSupervisCmd(struct _LINKTABLE * LINK)
LINK->L2ACKREQ = 0; // CLEAR ACK NEEDED LINK->L2ACKREQ = 0; // CLEAR ACK NEEDED
CTL = RR_OR_RNR(LINK); CTL = RR_OR_RNR(LINK, TRUE);
// MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK' // MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK'
@ -3450,7 +3528,7 @@ void SEND_RR_RESP(struct _LINKTABLE * LINK, UCHAR PF)
{ {
UCHAR CTL; UCHAR CTL;
CTL = RR_OR_RNR(LINK); CTL = RR_OR_RNR(LINK, FALSE);
// MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK' // MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK'
@ -3801,6 +3879,7 @@ VOID L2SENDXID(struct _LINKTABLE * LINK)
if (PORT) if (PORT)
{ {
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
Buffer->PORT = PORT->PORTNUMBER; Buffer->PORT = PORT->PORTNUMBER;
PUT_ON_PORT_Q(PORT, Buffer); PUT_ON_PORT_Q(PORT, Buffer);
} }
@ -3944,7 +4023,7 @@ VOID InformPartner(struct _LINKTABLE * LINK, int Reason)
} }
UINT RR_OR_RNR(struct _LINKTABLE * LINK) UINT RR_OR_RNR(struct _LINKTABLE * LINK, int CMD)
{ {
UCHAR Temp; UCHAR Temp;
TRANSPORTENTRY * Session; TRANSPORTENTRY * Session;
@ -4026,7 +4105,9 @@ stayinREJ2:
// Dont send SREJ if clearing RNR - causes FRMR // Dont send SREJ if clearing RNR - causes FRMR
if (SaveRNRSent) // Latest Spec says shouldn't send SREJ as Command
if (SaveRNRSent || CMD == 1)
return REJ; return REJ;
if (LINK->Ver2point2) // We only allow 2.2 with SREJ Multi if (LINK->Ver2point2) // We only allow 2.2 with SREJ Multi

View file

@ -60,6 +60,10 @@ VOID L3TRYNEXTDEST(struct ROUTE * ROUTE);
VOID SendNETROMRoute(struct PORTCONTROL * PORT, unsigned char * axcall); VOID SendNETROMRoute(struct PORTCONTROL * PORT, unsigned char * axcall);
void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer); void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer);
void SendVARANetromMsg(struct TNCINFO * TNC,L3MESSAGEBUFFER * Buffer); void SendVARANetromMsg(struct TNCINFO * TNC,L3MESSAGEBUFFER * Buffer);
VOID SENDNODESMSG(int Portnum);
extern int NODESINPROGRESS;
extern int NODESToOnePort;
extern BOOL NODESINPROGRESS ;; extern BOOL NODESINPROGRESS ;;
PPORTCONTROL L3CURRENTPORT; PPORTCONTROL L3CURRENTPORT;
@ -241,6 +245,13 @@ char Call1[10];
char Call2[10]; char Call2[10];
char Call3[10]; char Call3[10];
VOID PROCESSNODESPOLL(struct PORTCONTROL * PORT)
{
// Pauls G8BPT's request NODES Broadcast
SENDNODESMSG(PORT->PORTNUMBER);
return;
}
VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT) VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT)
{ {
// PROCESS A NET/ROM 'NODES' MESSAGE // PROCESS A NET/ROM 'NODES' MESSAGE
@ -744,12 +755,26 @@ VOID L3BG();
VOID SENDNEXTNODESFRAGMENT(); VOID SENDNEXTNODESFRAGMENT();
VOID SENDNODESMSG() VOID SENDNODESMSG(int Portnum)
{ {
if (NODESINPROGRESS) if (NODESINPROGRESS)
return; return;
L3CURRENTPORT = PORTTABLE; NODESToOnePort = Portnum;
if (Portnum) // Nodes to one port only
{
L3CURRENTPORT = GetPortTableEntryFromPortNum(Portnum);
if (L3CURRENTPORT == 0)
{
NODESToOnePort = 0;
return;
}
}
else
L3CURRENTPORT = PORTTABLE;
SENDNEXTNODESFRAGMENT(); SENDNEXTNODESFRAGMENT();
} }
@ -785,16 +810,19 @@ VOID SENDNEXTNODESFRAGMENT()
// No NODES to this port, so go to next // No NODES to this port, so go to next
PORT = PORT->PORTPOINTER; PORT = PORT->PORTPOINTER;
if (PORT == NULL)
if (PORT == NULL || NODESToOnePort)
{ {
// Finished // Finished
NODESToOnePort = 0;
NODESINPROGRESS = 0; NODESINPROGRESS = 0;
return; return;
} }
} }
L3CURRENTPORT = PORT; if (NODESToOnePort == 0) // CurrentPort already set if NODESToOnePort
L3CURRENTPORT = PORT;
DEST = CURRENTNODE = DESTS; // START OF LIST DEST = CURRENTNODE = DESTS; // START OF LIST
NODESINPROGRESS = 1; NODESINPROGRESS = 1;
@ -851,13 +879,24 @@ VOID SENDNEXTNODESFRAGMENT()
if (DEST >= ENDDESTLIST) if (DEST >= ENDDESTLIST)
{ {
CURRENTNODE = 0; // Finished on this port CURRENTNODE = 0; // Finished on this port
L3CURRENTPORT = PORT->PORTPOINTER;
if (L3CURRENTPORT == NULL)
{
// Finished
// if sending to only one port then stop
if (NODESToOnePort)
{
NODESToOnePort = 0;
NODESINPROGRESS = 0; NODESINPROGRESS = 0;
} }
else
{
L3CURRENTPORT = PORT->PORTPOINTER;
if (L3CURRENTPORT == NULL)
{
// Finished
NODESINPROGRESS = 0;
}
}
goto Sendit; goto Sendit;
} }
@ -1044,7 +1083,7 @@ VOID L3TimerProc()
L3TIMER = L3INTERVAL; L3TIMER = L3INTERVAL;
UPDATEDESTLIST(); UPDATEDESTLIST();
SENDNODESMSG(); SENDNODESMSG(0);
} }
} }

View file

@ -791,7 +791,7 @@ VOID L4BG()
complen = L2Compressit(Compressed, 8192, toCompress, toCompressLen); complen = L2Compressit(Compressed, 8192, toCompress, toCompressLen);
Debugprintf("%d %d %d%%", toCompressLen, complen, ((toCompressLen - complen) * 100) / toCompressLen); // Debugprintf("%d %d %d%%", toCompressLen, complen, ((toCompressLen - complen) * 100) / toCompressLen);
// Send compressed // Send compressed
@ -826,7 +826,7 @@ VOID L4BG()
Len = ChunkSize; Len = ChunkSize;
complen = L2Compressit(Compressed, 8192, CompressPtr, Len); complen = L2Compressit(Compressed, 8192, CompressPtr, Len);
Debugprintf("Chunked %d %d %d%%", Len, complen, ((Len - complen) * 100) / Len); // Debugprintf("Chunked %d %d %d%%", Len, complen, ((Len - complen) * 100) / Len);
sendChunk(L4, Compressed, complen, savePort); sendChunk(L4, Compressed, complen, savePort);

View file

@ -84,7 +84,7 @@ void RHPPoll();
VOID GetPGConfig(); VOID GetPGConfig();
void SendBBSDataToPktMap(); void SendBBSDataToPktMap();
extern uint64_t timeLoadedMS; extern uint64_t INP3timeLoadedMS;
BOOL IncludesMail = FALSE; BOOL IncludesMail = FALSE;
BOOL IncludesChat = FALSE; BOOL IncludesChat = FALSE;
@ -839,15 +839,14 @@ int main(int argc, char * argv[])
#endif #endif
#endif #endif
// Disable Console Terminal if stdout redirected // Disable Console Terminal if stdout redirected
// printf("STDOUT %d\n",isatty(STDOUT_FILENO)); // printf("STDOUT %d\n",isatty(STDOUT_FILENO));
// printf("STDIN %d\n",isatty(STDIN_FILENO)); // printf("STDIN %d\n",isatty(STDIN_FILENO));
if (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO)) if (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO))
Redirected = 1; Redirected = 1;
timeLoadedMS = GetTickCount(); INP3timeLoadedMS = GetTickCount();
#endif #endif

View file

@ -691,6 +691,14 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
return Output; return Output;
} }
if (ADJBUFFER->L2DATA[0] == 0xfe) // Paula's Nodes Poll
{
memcpy(Alias, ++ptr, 6);
Output += sprintf((char *)Output, " NODES POLL from %s\r", Alias);
return Output;
}
// Display normal NET/ROM transmissions // Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r "); Output += sprintf((char *)Output, " NET/ROM\r ");
@ -985,3 +993,87 @@ char * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output)
ptr[15], ptr[16], ptr[17], ptr[18], Dest, ptr[26], ptr[27], ptr[28], ptr[29]); ptr[15], ptr[16], ptr[17], ptr[18], Dest, ptr[26], ptr[27], ptr[28], ptr[29]);
} }
char Lastpacketlog[256];
int PacketLogDelay = 30000;
extern BPQVECSTRUC * FILEMONVECTOR;
extern UCHAR LogDirectory[260];
void WritePacketLogThread(void * param)
{
char FN[256];
time_t T;
struct tm * tm;
FILE * Handle;
int MsgLen;
MESSAGE * MSG;
MESSAGE * Q;
char buffer[512];
while(1)
{
BOOL SaveMTX = MTX;
BOOL SaveMCOM = MCOM;
BOOL SaveMUI = MUIONLY;
Sleep(PacketLogDelay);
// Get chain of queued packets under semaphore
GetSemaphore(&Semaphore, 101);
Q = FILEMONVECTOR->HOSTTRACEQ;
FILEMONVECTOR->HOSTTRACEQ = 0;
FreeSemaphore(&Semaphore);
if (Q == 0)
continue;
// Open log file and write decoded packets
T = time(NULL);
tm = gmtime(&T);
if (LogDirectory[0] == 0)
{
strcpy(FN, "logs/PacketLog");
}
else
{
strcpy(FN, LogDirectory);
strcat(FN, "/");
strcat(FN, "logs/PacketLog");
}
sprintf(&FN[strlen(FN)], "_%04d%02d%02d.log", tm->tm_year +1900, tm->tm_mon+1, tm->tm_mday);
Handle = fopen(FN, "ab");
if (Handle == NULL)
return;
while (Q)
{
MSG = Q;
Q = MSG->CHAIN; // get first
IntSetTraceOptionsEx(MMASK, 1, 1, 0);
MsgLen = IntDecodeFrame(MSG, buffer, MSG->Timestamp, 0xffffffffffffffff, FALSE, FALSE);
IntSetTraceOptionsEx(MMASK, SaveMTX, SaveMCOM, SaveMUI);
fwrite(buffer , 1, MsgLen, Handle);
GetSemaphore(&Semaphore, 101);
ReleaseBuffer(MSG);
FreeSemaphore(&Semaphore);
}
fclose(Handle);
}
return;
}

View file

@ -110,7 +110,7 @@ VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT);
int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr); int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr);
void ProcessHAMLIBFrame(struct RIGPORTINFO * PORT, int Length); void ProcessHAMLIBFrame(struct RIGPORTINFO * PORT, int Length);
VOID HAMLIBPoll(struct RIGPORTINFO * PORT); VOID HAMLIBPoll(struct RIGPORTINFO * PORT);
void HAMLIBSlaveThread(struct RIGINFO * RIG); void HAMLIBSlaveThread(VOID * Param);
void CheckAndProcessRTLUDP(struct RIGPORTINFO * PORT); void CheckAndProcessRTLUDP(struct RIGPORTINFO * PORT);
VOID RTLUDPPoll(struct RIGPORTINFO * PORT); VOID RTLUDPPoll(struct RIGPORTINFO * PORT);
VOID ConnecttoRTLUDP(struct RIGPORTINFO * PORT); VOID ConnecttoRTLUDP(struct RIGPORTINFO * PORT);
@ -122,8 +122,8 @@ VOID ProcessSDRRadioFrame(struct RIGPORTINFO * PORT, int Length);
VOID SDRRadioPoll(struct RIGPORTINFO * PORT); VOID SDRRadioPoll(struct RIGPORTINFO * PORT);
VOID SetupPortRIGPointers(); VOID SetupPortRIGPointers();
VOID PTTCATThread(struct RIGINFO *RIG); VOID PTTCATThread(void * Param);
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT);
// ----- G7TAJ ---- // ----- G7TAJ ----
VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT); VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT);
@ -7484,8 +7484,9 @@ VOID SetupPortRIGPointers()
#ifdef WIN32 #ifdef WIN32
VOID PTTCATThread(struct RIGINFO *RIG) VOID PTTCATThread(void * Param)
{ {
struct RIGINFO * RIG = (struct RIGINFO *)Param;
DWORD dwLength = 0; DWORD dwLength = 0;
int Length, ret, i; int Length, ret, i;
UCHAR * ptr1; UCHAR * ptr1;
@ -8471,7 +8472,7 @@ int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr)
return 1; return 1;
} }
VOID HAMLIBThread(struct RIGPORTINFO * PORT); VOID HAMLIBThread(void * Param);
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT) VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT)
{ {
@ -8481,10 +8482,11 @@ VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT)
return ; return ;
} }
VOID HAMLIBThread(struct RIGPORTINFO * PORT) VOID HAMLIBThread(void * Param)
{ {
// Opens sockets and looks for data // Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO * )Param;
char Msg[255]; char Msg[255];
int err, i, ret; int err, i, ret;
u_long param=1; u_long param=1;
@ -8606,10 +8608,11 @@ Lost:
void HAMLIBSlaveThread(struct RIGINFO * RIG) void HAMLIBSlaveThread(VOID * Param)
{ {
// Wait for connections and messages from HAMLIB Clients // Wait for connections and messages from HAMLIB Clients
struct RIGINFO * RIG = (struct RIGINFO *)Param;
fd_set readfs; fd_set readfs;
fd_set errorfs; fd_set errorfs;
struct timeval timeout; struct timeval timeout;
@ -8925,7 +8928,7 @@ VOID FLRIGSendCommand(struct RIGPORTINFO * PORT, char * Command, char * Value)
VOID FLRIGThread(struct RIGPORTINFO * PORT); VOID FLRIGThread(VOID * Param);
VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT) VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT)
{ {
@ -8934,10 +8937,11 @@ VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT)
return ; return ;
} }
VOID FLRIGThread(struct RIGPORTINFO * PORT) VOID FLRIGThread(VOID * Param)
{ {
// Opens sockets and looks for data // Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO *)Param;
char Msg[255]; char Msg[255];
int err, i, ret; int err, i, ret;
u_long param=1; u_long param=1;
@ -10177,7 +10181,7 @@ void ProcessSDRANGELFrame(struct RIGPORTINFO * PORT)
VOID SDRANGELThread(struct RIGPORTINFO * PORT); VOID SDRANGELThread(VOID * Param);
VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT) VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT)
{ {
@ -10186,9 +10190,11 @@ VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT)
return ; return ;
} }
VOID SDRANGELThread(struct RIGPORTINFO * PORT) VOID SDRANGELThread(VOID * Param)
{ {
// Opens sockets and looks for data // Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO *)Param;
char Msg[512]; char Msg[512];
int err, i, ret; int err, i, ret;
u_long param=1; u_long param=1;

View file

@ -10,15 +10,15 @@
#endif #endif
#define KVers 6,0,25,1 #define KVers 6,0,25,6
#define KVerstring "6.0.25.1\0" #define KVerstring "6.0.25.6\0"
#ifdef CKernel #ifdef CKernel
#define Vers KVers #define Vers KVers
#define Verstring KVerstring #define Verstring KVerstring
#define Datestring "August 2025" #define Datestring "October 2025"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring #define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0" #define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0" #define VerDesc "BPQ32 Switch\0"

View file

@ -64,15 +64,6 @@ extern int ENDOFDATA;
extern int L3LIVES; extern int L3LIVES;
extern int NUMBEROFNODES; extern int NUMBEROFNODES;
struct CMDX
{
char String[12]; // COMMAND STRING
UCHAR CMDLEN; // SIGNIFICANT LENGTH
// VOID (*CMDPROC)(struct _TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);// COMMAND PROCESSOR
VOID (*CMDPROC)();// COMMAND PROCESSOR
size_t CMDFLAG; // FLAG/VALUE Offset
};
struct APPLCONFIG struct APPLCONFIG
{ {
@ -230,12 +221,13 @@ typedef struct ROUTE
BOOL NoKeepAlive; // Suppress Keepalive Processing BOOL NoKeepAlive; // Suppress Keepalive Processing
int LastConnectAttempt; // To stop us trying too often int LastConnectAttempt; // To stop us trying too often
int Status; // int Status; //
int OldBPQ; // Set if other end is BPQ sending RIF in mS
int LastRTT; // Last Value Reported int LastRTT; // Last Value Reported
int RTT; // Current int RTT; // Current
int SRTT; // Smoothed RTT int SRTT; // Smoothed RTT
int NeighbourSRTT; // Other End SRTT int NeighbourSRTT; // Other End SRTT
// int RTTIncrement; // Average of Ours and Neighbours SRTT in 10 ms int RTTIncrement; // Average of Ours and Neighbours SRTT in 10 ms - smoothed neighbor transport time (SNTT) in spec
int BCTimer; // Time to next L3RTT Broadcast int BCTimer; // Time to next L3RTT Broadcast
int Timeout; // Lost Response Timer int Timeout; // Lost Response Timer
int Retries; // Lost Response Count int Retries; // Lost Response Count
@ -244,6 +236,8 @@ typedef struct ROUTE
int OtherendsRouteQual; // Route quality used by other end. int OtherendsRouteQual; // Route quality used by other end.
int OtherendLocked; // Route quality locked by ROUTES entry. int OtherendLocked; // Route quality locked by ROUTES entry.
int FirstTimeFlag; // Set once quality has been set by direct receive int FirstTimeFlag; // Set once quality has been set by direct receive
int RemoteMAXRTT; // For INP3
int RemoteMAXHOPS;
} *PROUTE; } *PROUTE;
@ -701,7 +695,8 @@ typedef struct PORTCONTROL
BOOL NormalizeQuality; // Normalise Node Qualities BOOL NormalizeQuality; // Normalise Node Qualities
BOOL IgnoreUnlocked; // Ignore Unlocked routes BOOL IgnoreUnlocked; // Ignore Unlocked routes
BOOL INP3ONLY; // Default to INP3 and disallow NODES BOOL INP3ONLY; // Default to INP3 and disallow NODES
BOOL ALLOWINP3; BOOL ALLOWINP3; // Accept INP3 if offered by other end
BOOL ENABLEINP3; // Send INP3 RTT probes to discovered neighbours
void (* UIHook)(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); // Used for KISSARQ void (* UIHook)(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); // Used for KISSARQ
struct PORTCONTROL * HookPort; struct PORTCONTROL * HookPort;
@ -981,6 +976,8 @@ typedef struct _LINKTABLE
int Received; int Received;
int ReceivedAfterExpansion; int ReceivedAfterExpansion;
char ApplName[16];
} LINKTABLE; } LINKTABLE;
@ -1472,6 +1469,16 @@ struct AXIPPORTINFO
}; };
struct CMDX
{
char String[12]; // COMMAND STRING
UCHAR CMDLEN; // SIGNIFICANT LENGTH
VOID (*CMDPROC)(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);// COMMAND PROCESSOR
// VOID (*CMDPROC)();// COMMAND PROCESSOR
size_t CMDFLAG; // FLAG/VALUE Offset
};
#define Disconnect(stream) SessionControl(stream,2,0) #define Disconnect(stream) SessionControl(stream,2,0)
#define Connect(stream) SessionControl(stream,1,0) #define Connect(stream) SessionControl(stream,1,0)

View file

@ -192,8 +192,8 @@ extern UCHAR BPQDirectory[];
extern int OffsetH, OffsetW; extern int OffsetH, OffsetW;
static void ResolveNames(struct AXIPPORTINFO * PORT); static void ResolveNames(VOID * Param);
void OpenSockets(struct AXIPPORTINFO * PORT); void OpenSockets(VOID * Param);
void CloseSockets(struct AXIPPORTINFO * PORT); void CloseSockets(struct AXIPPORTINFO * PORT);
@ -221,7 +221,7 @@ int KissDecode(UCHAR * inbuff, int len);
int Socket_Accept(int SocketId); int Socket_Accept(int SocketId);
int Socket_Connect(int SocketId, int Error); int Socket_Connect(int SocketId, int Error);
int Socket_Data(int sock, int error, int eventcode); int Socket_Data(int sock, int error, int eventcode);
VOID TCPConnectThread(struct arp_table_entry * arp); VOID TCPConnectThread(VOID * Param);
VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Debugprintf(const char * format, ...);
VOID __cdecl Consoleprintf(const char * format, ...); VOID __cdecl Consoleprintf(const char * format, ...);
BOOL OpenListeningSocket(struct AXIPPORTINFO * PORT, struct arp_table_entry * arp); BOOL OpenListeningSocket(struct AXIPPORTINFO * PORT, struct arp_table_entry * arp);
@ -692,7 +692,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
else else
Consoleprintf("Failed to reread config file - leaving config unchanged"); Consoleprintf("Failed to reread config file - leaving config unchanged");
_beginthread(OpenSockets, 0, PORT ); _beginthread(OpenSockets, 0, PORT);
GetAXIPCache(PORT); GetAXIPCache(PORT);
@ -844,8 +844,9 @@ int InitAXIP(int Port)
return (TRUE); return (TRUE);
} }
void OpenSockets(struct AXIPPORTINFO * PORT) void OpenSockets(void * Param)
{ {
struct AXIPPORTINFO * PORT = (struct AXIPPORTINFO *)Param;
char Msg[255]; char Msg[255];
int err; int err;
u_long param=1; u_long param=1;
@ -1528,8 +1529,9 @@ static void CreateResolverWindow(struct AXIPPORTINFO * PORT)
extern HWND hWndPopup; extern HWND hWndPopup;
static void ResolveNames(struct AXIPPORTINFO * PORT) static void ResolveNames(VOID * Param)
{ {
struct AXIPPORTINFO * PORT = (struct AXIPPORTINFO *)Param;
int count = 0; int count = 0;
PORT->ResolveNamesThreadId = GetCurrentThreadId(); // Detect if another started PORT->ResolveNamesThreadId = GetCurrentThreadId(); // Detect if another started
@ -2996,8 +2998,9 @@ int KissDecode(UCHAR * inbuff, int len)
return txptr; return txptr;
} }
VOID TCPConnectThread(struct arp_table_entry * arp) VOID TCPConnectThread(void * Param)
{ {
struct arp_table_entry * arp = (struct arp_table_entry *)Param;
char Msg[255]; char Msg[255];
int err, i; int err, i;
u_long param=1; u_long param=1;

35
cMain.c
View file

@ -54,6 +54,7 @@ void MQTTTimer();
void SaveMH(); void SaveMH();
VOID InformPartner(struct _LINKTABLE * LINK, int Reason); VOID InformPartner(struct _LINKTABLE * LINK, int Reason);
VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD); VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD);
void WritePacketLogThread(void * param);
#include "configstructs.h" #include "configstructs.h"
@ -61,6 +62,7 @@ VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD);
extern struct CONFIGTABLE xxcfg; extern struct CONFIGTABLE xxcfg;
extern BOOL needAIS; extern BOOL needAIS;
extern int needADSB; extern int needADSB;
extern int EnableOARCAPI;
struct PORTCONFIG * PortRec; struct PORTCONFIG * PortRec;
@ -181,6 +183,7 @@ extern VOID * ENDPOOL;
extern void * APPL_Q; // Queue of frames for APRS Appl extern void * APPL_Q; // Queue of frames for APRS Appl
extern BOOL APRSActive; extern BOOL APRSActive;
extern int DEBUGINP3;
#define BPQHOSTSTREAMS 64 #define BPQHOSTSTREAMS 64
@ -194,9 +197,12 @@ BPQVECSTRUC * TELNETMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS];
BPQVECSTRUC * AGWMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 1]; BPQVECSTRUC * AGWMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 1];
BPQVECSTRUC * APRSMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 2]; BPQVECSTRUC * APRSMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 2];
BPQVECSTRUC * IPHOSTVECTORPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 3]; BPQVECSTRUC * IPHOSTVECTORPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 3];
BPQVECSTRUC * FILEMONVECTOR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 4];
int BPQVECLENGTH = sizeof(BPQVECSTRUC); int BPQVECLENGTH = sizeof(BPQVECSTRUC);
int MONTOFILEFLAG = 0;
int NODEORDER = 0; int NODEORDER = 0;
UCHAR LINKEDFLAG = 0; UCHAR LINKEDFLAG = 0;
@ -250,6 +256,8 @@ int CFLAG = 0; // C =HOST Command
VOID * IDMSG_Q = NULL; // ID/BEACONS WAITING TO BE SENT VOID * IDMSG_Q = NULL; // ID/BEACONS WAITING TO BE SENT
int NODESINPROGRESS = 0; int NODESINPROGRESS = 0;
int NODESToOnePort = 0; // Set to port num to send NODES to only one port.
VOID * CURRENTNODE = NULL; // NEXT _NODE TO SEND VOID * CURRENTNODE = NULL; // NEXT _NODE TO SEND
VOID * DESTHEADER = NULL; // HEAD OF SORTED NODES CHAIN VOID * DESTHEADER = NULL; // HEAD OF SORTED NODES CHAIN
@ -862,6 +870,11 @@ BOOL Start()
PREFERINP3ROUTES = cfg->C_PREFERINP3ROUTES; PREFERINP3ROUTES = cfg->C_PREFERINP3ROUTES;
if (cfg->C_DEBUGINP3)
DEBUGINP3 = 0;
EnableOARCAPI = cfg->C_OARCAPI;
if (cfg->C_OnlyVer2point0) if (cfg->C_OnlyVer2point0)
SUPPORT2point2 = 0; SUPPORT2point2 = 0;
@ -992,6 +1005,7 @@ BOOL Start()
PORT->IgnoreUnlocked = PortRec->IGNOREUNLOCKED; PORT->IgnoreUnlocked = PortRec->IGNOREUNLOCKED;
PORT->INP3ONLY = PortRec->INP3ONLY; PORT->INP3ONLY = PortRec->INP3ONLY;
PORT->ALLOWINP3 = PortRec->AllowINP3; PORT->ALLOWINP3 = PortRec->AllowINP3;
PORT->ENABLEINP3 = PortRec->EnableINP3;
PORT->PORTWINDOW = (UCHAR)PortRec->MAXFRAME; PORT->PORTWINDOW = (UCHAR)PortRec->MAXFRAME;
@ -1564,6 +1578,10 @@ BOOL Start()
upnpInit(); upnpInit();
// Start Monitor to file thread
_beginthread(WritePacketLogThread, 0, NULL);
lastSaveSecs = CurrentSecs = lastSlowSecs = time(NULL); lastSaveSecs = CurrentSecs = lastSlowSecs = time(NULL);
return 0; return 0;
@ -2514,9 +2532,9 @@ ENDOFLIST:
{ {
// Stuck link debug check // Stuck link debug check
if (LINK->LASTFRAMESENT && (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs if (LINK->LINKWINDOW == 0 || LINK->LASTFRAMESENT == 0 || (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs
{ {
if (COUNT_AT_L2(LINK) > 16) if (COUNT_AT_L2(LINK) > 16 || LINK->LINKWINDOW == 0)
{ {
// Dump Link State // Dump Link State
@ -2675,6 +2693,19 @@ int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS)
L4++; L4++;
} }
// And to the Monitor to File system.
if (MONTOFILEFLAG) // Trace Enabled?
{
Buffer = GetBuff();
if (Buffer)
{
memcpy(&Buffer->PORT, &Msg->PORT, BUFFLEN - sizeof(void *)); // Dont copy chain word
C_Q_ADD(&FILEMONVECTOR->HOSTTRACEQ, Buffer);
}
}
return TRUE; return TRUE;
} }
; ;

View file

@ -49,7 +49,39 @@ Stuff to make compiling on WINDOWS and LINUX easier
int pthread_equal(pthread_t T1, pthread_t T2); int pthread_equal(pthread_t T1, pthread_t T2);
uintptr_t _beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist); uintptr_t _beginthread(void(__cdecl start_address)(void *), unsigned stack_size, void *arglist);
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf c99_snprintf
#define vsnprintf c99_vsnprintf
__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
int count = -1;
if (size != 0)
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
if (count == -1)
count = _vscprintf(format, ap);
return count;
}
__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = c99_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#endif
#else #else
@ -152,9 +184,7 @@ int stricmp(const unsigned char * pStr1, const unsigned char *pStr2);
char * strupr(char* s); char * strupr(char* s);
char * strlwr(char* s); char * strlwr(char* s);
pthread_t _beginthread(void(*start_address)(), unsigned stack_size, VOID * arglist); pthread_t _beginthread(void(start_address)(void *), unsigned stack_size, VOID * arglist);
#define WSAGetLastError() errno #define WSAGetLastError() errno
#define GetLastError() errno #define GetLastError() errno

View file

@ -309,7 +309,7 @@ static char *keywords[] =
"LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS", "LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS",
"EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS", "EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS",
"L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe", "L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe",
"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0" "L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0", "DEBUGINP3", "ENABLEOARCAPI"
}; /* parameter keywords */ }; /* parameter keywords */
static void * offset[] = static void * offset[] =
@ -332,7 +332,7 @@ static void * offset[] =
&xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs, &xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs,
&xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS, &xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS,
&xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen, &xxcfg.C_L2Compress, &xxcfg.C_L2CompMaxframe, &xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen, &xxcfg.C_L2Compress, &xxcfg.C_L2CompMaxframe,
&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0}; /* offset for corresponding data in config file */ &xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0, &xxcfg.C_DEBUGINP3, &xxcfg.C_OARCAPI}; /* offset for corresponding data in config file */
static int routine[] = static int routine[] =
{ {
@ -354,7 +354,7 @@ static int routine[] =
2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2,
2, 2, 0, 1, 20, 20, 2, 2, 0, 1, 20, 20,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1} ; // Routine to process param 1, 1, 1, 1, 1}; // Routine to process param
int PARAMLIM = sizeof(routine)/sizeof(int); int PARAMLIM = sizeof(routine)/sizeof(int);
//int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int); //int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int);
@ -376,7 +376,7 @@ static char *pkeywords[] =
"BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY", "BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY",
"UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE", "UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE",
"IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE", "IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE",
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort", "ALLOWINP3"}; /* parameter keywords */ "SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort", "ALLOWINP3", "ENABLEINP3"}; /* parameter keywords */
static void * poffset[] = static void * poffset[] =
{ {
@ -390,7 +390,7 @@ static void * poffset[] =
&xxp.BCALL, &xxp.DIGIMASK, &xxp.DefaultNoKeepAlives, &xxp.IOADDR, &xxp.DLLNAME, &xxp.WL2K, &xxp.UIONLY, &xxp.BCALL, &xxp.DIGIMASK, &xxp.DefaultNoKeepAlives, &xxp.IOADDR, &xxp.DLLNAME, &xxp.WL2K, &xxp.UIONLY,
&xxp.IOADDR, &xxp.IPADDR, &xxp.INTLEVEL, &xxp.IOADDR, &xxp.IOADDR, &xxp.ListenPort, &xxp.NoNormalize, &xxp.IOADDR, &xxp.IPADDR, &xxp.INTLEVEL, &xxp.IOADDR, &xxp.IOADDR, &xxp.ListenPort, &xxp.NoNormalize,
&xxp.IGNOREUNLOCKED, &xxp.INP3ONLY, &xxp.TCPPORT, &xxp.RIGPORT, &xxp.PERMITTEDAPPLS, &xxp.Hide, &xxp.IGNOREUNLOCKED, &xxp.INP3ONLY, &xxp.TCPPORT, &xxp.RIGPORT, &xxp.PERMITTEDAPPLS, &xxp.Hide,
&xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort, &xxp.AllowINP3}; /* offset for corresponding data in config file */ &xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort, &xxp.AllowINP3, &xxp.EnableINP3}; /* offset for corresponding data in config file */
static int proutine[] = static int proutine[] =
{ {
@ -404,7 +404,7 @@ static int proutine[] =
0, 1, 2, 18, 15, 16, 2, 0, 1, 2, 18, 15, 16, 2,
1, 17, 1, 1, 1, 1, 2, 1, 17, 1, 1, 1, 1, 2,
2, 2, 1, 1, 19, 2, 2, 2, 1, 1, 19, 2,
1, 20, 1, 21, 22, 1, 1}; /* routine to process parameter */ 1, 20, 1, 21, 22, 1, 1, 1}; /* routine to process parameter */
int PPARAMLIM = sizeof(proutine)/sizeof(int); int PPARAMLIM = sizeof(proutine)/sizeof(int);
@ -601,7 +601,6 @@ BOOL ProcessConfig()
for (i=0;i<24;i++) for (i=0;i<24;i++)
paramok[45+i]=1; /* or APPLCALLS, APPLALIASS APPLQUAL */ paramok[45+i]=1; /* or APPLCALLS, APPLALIASS APPLQUAL */
paramok[69]=1; // BText optional paramok[69]=1; // BText optional
@ -630,7 +629,9 @@ BOOL ProcessConfig()
paramok[90]=1; // L2Compress Maxframe paramok[90]=1; // L2Compress Maxframe
paramok[91]=1; // L2Compress Paclen paramok[91]=1; // L2Compress Paclen
paramok[92]=1; // PREFERINP3ROUTES paramok[92]=1; // PREFERINP3ROUTES
paramok[93]=1; // C_ONLYVer2point0 paramok[93]=1; // ONLYVer2point0
paramok[94]=1; // DEBUGINP3
paramok[95]=1; // EnableOARCAPI
for (i=0; i < PARAMLIM; i++) for (i=0; i < PARAMLIM; i++)
{ {

View file

@ -82,6 +82,7 @@ struct PORTCONFIG
char * M0LTEMapInfo; char * M0LTEMapInfo;
int QtSMPort; int QtSMPort;
int AllowINP3; int AllowINP3;
int EnableINP3;
}; };
struct ROUTECONFIG struct ROUTECONFIG
@ -179,6 +180,8 @@ struct CONFIGTABLE
int C_L2CompPaclen; int C_L2CompPaclen;
int C_PREFERINP3ROUTES; int C_PREFERINP3ROUTES;
int C_OnlyVer2point0; int C_OnlyVer2point0;
int C_DEBUGINP3;
int C_OARCAPI;
//#define ApplOffset 80000 // Applications offset in config buffer //#define ApplOffset 80000 // Applications offset in config buffer

View file

@ -35,6 +35,9 @@ int RFOnly = 0;
int MAXRTT = 9000; // 90 secs int MAXRTT = 9000; // 90 secs
int MaxHops = 4; int MaxHops = 4;
int DEBUGINP3 = 0;
int EnableOARCAPI = 0;
int RTTInterval = 24; // 4 Minutes int RTTInterval = 24; // 4 Minutes

10
kiss.c
View file

@ -1905,7 +1905,7 @@ int i2cPoll(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO)
// KISS Over TCP Routines // KISS Over TCP Routines
VOID ConnecttoTCPThread(NPASYINFO ASY); VOID ConnecttoTCPThread(void * Param);
int ConnecttoTCP(NPASYINFO ASY) int ConnecttoTCP(NPASYINFO ASY)
{ {
@ -1914,8 +1914,9 @@ int ConnecttoTCP(NPASYINFO ASY)
return 0; return 0;
} }
VOID ConnecttoTCPThread(NPASYINFO ASY) VOID ConnecttoTCPThread(void * Param)
{ {
NPASYINFO ASY = (NPASYINFO)Param;
char Msg[255]; char Msg[255];
int err,i; int err,i;
u_long param=1; u_long param=1;
@ -2131,7 +2132,7 @@ int KISSGetTCPMessage(NPASYINFO ASY)
// Interface to QtSM Managmemt Interface // Interface to QtSM Managmemt Interface
VOID QtSMThread(struct PORTCONTROL * PORT); VOID QtSMThread(void * Param);
VOID ConnecttoQtSM(struct PORTCONTROL * PORT) VOID ConnecttoQtSM(struct PORTCONTROL * PORT)
{ {
@ -2141,11 +2142,12 @@ VOID ConnecttoQtSM(struct PORTCONTROL * PORT)
return ; return ;
} }
VOID QtSMThread(struct PORTCONTROL * PORT) VOID QtSMThread(void * Param)
{ {
// This is the Managemt Interface in QtSM. It receives PTT ON/OFF msgs from QtSM and allows changing modem mode and freq. // This is the Managemt Interface in QtSM. It receives PTT ON/OFF msgs from QtSM and allows changing modem mode and freq.
// Also will collect link usage stats // Also will collect link usage stats
struct PORTCONTROL * PORT = (struct PORTCONTROL *)Param;
char Msg[255]; char Msg[255];
int err, i, ret; int err, i, ret;
u_long param = 1; u_long param = 1;

View file

@ -852,14 +852,14 @@ double LatFromLOC = 0;
double LonFromLOC = 0; double LonFromLOC = 0;
#endif #endif
void SendBBSDataToPktMapThread(); void SendBBSDataToPktMapThread(void * Param);
void SendBBSDataToPktMap() void SendBBSDataToPktMap()
{ {
_beginthread(SendBBSDataToPktMapThread, 0, 0); _beginthread(SendBBSDataToPktMapThread, 0, 0);
} }
void SendBBSDataToPktMapThread() void SendBBSDataToPktMapThread(void * Param)
{ {
char Request[64]; char Request[64];
char * Params; char * Params;

204
nodeapi.c
View file

@ -9,6 +9,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "tncinfo.h" #include "tncinfo.h"
#include "asmstrucs.h" #include "asmstrucs.h"
#include "telnetserver.h"
#include "kiss.h" #include "kiss.h"
// Constants // Constants
@ -56,6 +57,7 @@ int sendUserList(char * response, char * token, char * Rest, int Local);
int sendInfo(char * response, char * token, char * Rest, int Local); int sendInfo(char * response, char * token, char * Rest, int Local);
int sendLinks(char * response, char * token, char * Rest, int Local); int sendLinks(char * response, char * token, char * Rest, int Local);
int sendPortMHList(char * response, char * token, char * Rest, int Local); int sendPortMHList(char * response, char * token, char * Rest, int Local);
int sendPortQState(char * response, char * token, char * Rest, int Local);
int sendWhatsPacState(char * response, char * token, char * param, int Local); int sendWhatsPacState(char * response, char * token, char * param, int Local);
int sendWhatsPacConfig(char * response, char * token, char * param, int Local); int sendWhatsPacConfig(char * response, char * token, char * param, int Local);
@ -74,6 +76,7 @@ struct API APIList[] =
"/api/links", 10, sendLinks, 0, "/api/links", 10, sendLinks, 0,
"/api/users", 10, sendUserList, 0, "/api/users", 10, sendUserList, 0,
"/api/mheard", 11, sendPortMHList, 0, "/api/mheard", 11, sendPortMHList, 0,
"/api/tcpqueues", 14, sendPortQState, 0,
"/api/v1/config", 14, sendWhatsPacConfig, AuthSysop, "/api/v1/config", 14, sendWhatsPacConfig, AuthSysop,
"/api/v1/state", 13, sendWhatsPacState, AuthSysop "/api/v1/state", 13, sendWhatsPacState, AuthSysop
}; };
@ -799,37 +802,192 @@ int sendLinks(char * response, char * token, char * param, int Local)
int sendPortMHList(char * response, char * token, char * param, int Local) int sendPortMHList(char * response, char * token, char * param, int Local)
{ {
struct PORTCONTROL * PORTVEC ; struct PORTCONTROL * PORTVEC ;
int n; int n;
int port = 0; int port = 0;
if (param[0] = '?' || param[0] == '/') if (param[0] = '?' || param[0] == '/')
port = atoi(&param[1]); port = atoi(&param[1]);
PORTVEC = GetPortTableEntryFromPortNum(port); PORTVEC = GetPortTableEntryFromPortNum(port);
response[0] = 0; response[0] = 0;
if (PORTVEC == 0) if (PORTVEC == 0)
return send_http_response(response, "401 Invalid API Call"); return send_http_response(response, "401 Invalid API Call");
n = sprintf(response,"{\"mheard\":[\r\n"); n = sprintf(response,"{\"mheard\":[\r\n");
BuildPortMH(&response[n], PORTVEC ); BuildPortMH(&response[n], PORTVEC );
if (response[n] == 0) // No entries if (response[n] == 0) // No entries
{ {
response[strlen(response) - 2] = '\0'; // remove \r\n response[strlen(response) - 2] = '\0'; // remove \r\n
strcat(response, "]}\r\n"); strcat(response, "]}\r\n");
} }
else else
{ {
response[strlen(response)-3 ] = '\0'; // remove ,\r\n response[strlen(response)-3 ] = '\0'; // remove ,\r\n
strcat(response, "\r\n]}\r\n"); strcat(response, "\r\n]}\r\n");
// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response); // printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
} }
return strlen(response);
return strlen(response);
} }
int sendPortQState(char * response, char * token, char * param, int Local)
{
struct TNCINFO * TNC;
struct TCPINFO * TCP;
struct ConnectionInfo * Conn;
struct STREAMINFO * STREAM;
int Stream;
int tcpqueue;
int Queued;
int n;
int port = 0;
char Type[10];
char Appl[20];
int radioport = 0;
if (param[0] = '?' || param[0] == '/')
port = atoi(&param[1]);
TNC = TNCInfo[port];
// At the moment only supports Telnet Ports
if (TNC == 0 || TNC->Hardware != H_TELNET)
return send_http_response(response, "401 Invalid API Call");
response[0] = 0;
TCP = TNC->TCPInfo;
if (TCP == 0)
return send_http_response(response, "401 Invalid API Call");
n = sprintf(response,"{\"QState\":[\r\n");
for (Stream = 0; Stream <= TCP->MaxSessions; Stream++)
{
char Call[10];
STREAM = &TNC->Streams[Stream];
Conn = TNC->Streams[Stream].ConnectionInfo;
// if connected to the node
if (Conn->SocketActive)
{
TRANSPORTENTRY * Sess1 = TNC->PortRecord->ATTACHEDSESSIONS[Stream];
TRANSPORTENTRY * Sess2 = NULL;
if (Sess1)
Sess2 = Sess1->L4CROSSLINK;
else
continue;
radioport = 0;
// Can't use TXCount - it is Semaphored=
Queued = C_Q_COUNT(&TNC->Streams[Stream].PACTORtoBPQ_Q);
Queued += C_Q_COUNT((UINT *)&TNC->PortRecord->PORTCONTROL.PORTRX_Q);
if (Sess2)
Queued += CountFramesQueuedOnSession(Sess2);
if (Sess1)
Queued += CountFramesQueuedOnSession(Sess1);
// CountFramesQueuedOnSession(TRANSPORTENTRY * Session)
tcpqueue = Conn->FromHostBuffPutptr - Conn->FromHostBuffGetptr;
if (Sess2)
Sess1 = Sess2;
Call[ConvFromAX25(Sess1->L4USER, Call)] = 0;
if (Sess1->L4CIRCUITTYPE & BPQHOST)
strcpy(Type, "Host");
else if (Sess1->L4CIRCUITTYPE & SESSION)
{
struct DEST_LIST * DEST = Sess1->L4TARGET.DEST;
strcpy(Type, "NETROM");
if (DEST)
{
int ActiveRoute = DEST->DEST_ROUTE;
if (ActiveRoute)
{
struct ROUTE * ROUTE = DEST->NRROUTE[ActiveRoute - 1].ROUT_NEIGHBOUR;
if (ROUTE)
{
struct _LINKTABLE * LINK = ROUTE->NEIGHBOUR_LINK;
if (LINK && LINK->LINKPORT)
radioport = LINK->LINKPORT->PORTNUMBER;
}
}
}
}
else if (Sess1->L4CIRCUITTYPE & PACTOR)
{
// PACTOR Type - Frames are queued on the Port Entry
struct PORTCONTROL * PORT = Sess1->L4TARGET.PORT;
strcpy(Type, "HFLINK");
if (PORT)
radioport = PORT->PORTNUMBER;
}
else
{
struct _LINKTABLE * LINK = Sess1->L4TARGET.LINK;
strcpy(Type, "L2 Link");
if (LINK && LINK->LINKPORT)
radioport = LINK->LINKPORT->PORTNUMBER;
}
memcpy(Appl, Sess1->APPL, 16);
strlop(Appl, ' ');
n += sprintf(&response[n], "{\"APPL\": \"%s\", \"callSign\": \"%s\", \"type\": \"%s\", \"tcpqueue\": %d, \"packets\": %d, \"port\": %d},\r\n" , Appl, Call, Type, tcpqueue, Queued, radioport);
}
}
if (n < 20) // No entries
{
response[strlen(response) - 2] = '\0'; // remove \r\n
strcat(response, "]}\r\n");
}
else
{
response[strlen(response)-3 ] = '\0'; // remove ,\r\n
strcat(response, "\r\n]}\r\n");
// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
}
return strlen(response);
}
// WhatsPac configuration interface // WhatsPac configuration interface
// WhatsPac also uses Paula's Remote Host Protocol (RHP). This is in a separate module // WhatsPac also uses Paula's Remote Host Protocol (RHP). This is in a separate module