diff --git a/BBSUtilities.c b/BBSUtilities.c
index 2cb6ee5..833d3f9 100644
--- a/BBSUtilities.c
+++ b/BBSUtilities.c
@@ -10823,6 +10823,15 @@ int Disconnected (int Stream)
 				}
 			}
 
+			user = conn->UserPointer;
+
+			if (user && (conn->lastmsg > user->lastmsg))
+			{
+				user->lastmsg = conn->lastmsg;
+				SaveUserDatabase();
+			}
+
+
 			// if sysop was chatting to user clear link
 #ifndef LINBPQ
 			if (conn->BBSFlags & SYSOPCHAT)
diff --git a/BPQChat.vcproj.SKIGACER.johnw.user b/BPQChat.vcproj.SKIGACER.johnw.user
deleted file mode 100644
index b5b0536..0000000
--- a/BPQChat.vcproj.SKIGACER.johnw.user
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-	
-		
-			
-		
-		
-			
-		
-	
-
diff --git a/BPQMail.c b/BPQMail.c
index 91b66ba..bbc9ece 100644
--- a/BPQMail.c
+++ b/BPQMail.c
@@ -1129,6 +1129,8 @@
 //	Add TO and AT to "Message has nowhere to go" message (28)
 //	Add My Sent and My Received filter options to Webmail (30)
 //	Add Send P to multiple BBS's when routing on HR (30)
+//	Fix Traffic stats for T messages received via B2 forwarding  (31)
+//	Fix possible failure to update last listed count when user disconnects without using B command
 
 #include "bpqmail.h"
 #include "winstdint.h"
diff --git a/BPQMail.vcproj.NOTTSDESKTOP.John.user b/BPQMail.vcproj.NOTTSDESKTOP.John.user
deleted file mode 100644
index fa82c00..0000000
--- a/BPQMail.vcproj.NOTTSDESKTOP.John.user
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-	
-		
-			
-		
-		
-			
-		
-	
-
diff --git a/BPQWinAPP.vcproj.NOTTSDESKTOP.John.user b/BPQWinAPP.vcproj.NOTTSDESKTOP.John.user
deleted file mode 100644
index fa82c00..0000000
--- a/BPQWinAPP.vcproj.NOTTSDESKTOP.John.user
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-	
-		
-			
-		
-		
-			
-		
-	
-
diff --git a/Bpq32.c b/Bpq32.c
index d826062..c7b939c 100644
--- a/Bpq32.c
+++ b/Bpq32.c
@@ -1209,6 +1209,8 @@ along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
 //	Improvments to reporting to M0LTE Map (26)
 //	IPGateway fix from github user isavitsky (27)
 //  Fix possible crash in SCSPactor PTCPORT code (29)
+//	Add NodeAPI call sendLinks and remove get from other calls (32)
+//	Improve validation of Web Beacon Config (33)
 
 #define CKernel
 
@@ -6518,6 +6520,7 @@ VOID GetParam(char * input, char * key, char * value)
 	char * ptr1, * ptr2;
 	char c;
 
+
 	if (ptr)
 	{
 		ptr2 = strchr(ptr, '&');
diff --git a/CBPQ32.vcproj.NOTTSDESKTOP.John.user b/CBPQ32.vcproj.NOTTSDESKTOP.John.user
deleted file mode 100644
index 270b67b..0000000
--- a/CBPQ32.vcproj.NOTTSDESKTOP.John.user
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-	
-		
-			
-		
-		
-			
-		
-	
-
diff --git a/CBPQ32.vcproj.SKIGACER.johnw.user b/CBPQ32.vcproj.SKIGACER.johnw.user
deleted file mode 100644
index f8a6101..0000000
--- a/CBPQ32.vcproj.SKIGACER.johnw.user
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-	
-		
-			
-		
-		
-			
-		
-	
-
diff --git a/CommonCode.c b/CommonCode.c
index abcbee1..da9b2d7 100644
--- a/CommonCode.c
+++ b/CommonCode.c
@@ -5003,20 +5003,20 @@ extern int MasterPort[MAXBPQPORTS+1];
 
 void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT)
 {
-  struct tm * TM;
-  static char MHTIME[50];
-  time_t szClock;
-  MHSTRUC * MH = PORT->PORTMHEARD;
-  int count = MHENTRIES;
-  char Normcall[20];
-  int len;
-  char * ptr;
-  char mhstr[400];
+	struct tm * TM;
+	static char MHTIME[50];
+	time_t szClock;
+	MHSTRUC * MH = PORT->PORTMHEARD;
+	int count = MHENTRIES;
+	char Normcall[20];
+	int len;
+	char * ptr;
+	char mhstr[400];
 
-   if (MH == NULL)
-	return;
+	if (MH == NULL)
+		return;
 
-   while (count--)
+	while (count--)
 	{
 		if (MH->MHCALL[0] == 0)
 			break;
@@ -5028,22 +5028,22 @@ void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT)
 
 		if ((*ptr & 1) == 0)
 		{
-  		  // at least one digi - which we are not going to include
-		  MH++;
- 		  continue;
+			// at least one digi - which we are not going to include
+			MH++;
+			continue;
 		}
 
 		Normcall[len++] = 0;
 
 		//format TIME
-		
+
 		szClock = MH->MHTIME;
 		TM = gmtime(&szClock);
 		sprintf(MHTIME, "%d-%d-%d %02d:%02d:%02d",
-		    TM->tm_year+1900, TM->tm_mon + 1, TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec);
+			TM->tm_year+1900, TM->tm_mon + 1, TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec);
 
 		sprintf(mhstr, "{\"callSign\": \"%s\", \"port\": \"%d\", \"packets\": %d, \"lastHeard\": \"%s\" },\r\n" ,
-	  	  Normcall, PORT->PORTNUMBER, MH->MHCOUNT, MHTIME);
+			Normcall, PORT->PORTNUMBER, MH->MHCOUNT, MHTIME);
 
 		strcat( MHJSON, mhstr );
 
diff --git a/HTTPcode.c b/HTTPcode.c
index 049fce3..0e62928 100644
--- a/HTTPcode.c
+++ b/HTTPcode.c
@@ -2462,29 +2462,29 @@ doHeader:
 					return 1;
 				}
 
-				GetParam(input, "Port", &Param[0]);
-				Port = atoi(&Param[1]);
+				GetParam(input, "Port=", &Param[0]);
+				Port = atoi(&Param[0]);
 				PORT = GetPortTableEntryFromPortNum(Port); // Need slot not number
 				if (PORT)
 					Slot = PORT->PortSlot;
 
-				GetParam(input, "Every", &Param[0]);
-				Interval[Slot] = atoi(&Param[1]);
+				GetParam(input, "Every=", &Param[0]);
+				Interval[Slot] = atoi(&Param[0]);
 
-				GetParam(input, "Dest", &Param[0]);
+				GetParam(input, "Dest=", &Param[0]);
 				_strupr(Param);
-				strcpy(UIUIDEST[Slot], &Param[1]);
+				strcpy(UIUIDEST[Slot], &Param[0]);
 
-				GetParam(input, "Path", &Param[0]);
+				GetParam(input, "Path=", &Param[0]);
 				_strupr(Param);
 				if (UIUIDigi[Slot])
 					free(UIUIDigi[Slot]);
-				UIUIDigi[Slot] = _strdup(&Param[1]);
+				UIUIDigi[Slot] = _strdup(&Param[0]);
 
-				GetParam(input, "File", &Param[0]);
+				GetParam(input, "File=", &Param[0]);
 				strcpy(FN[Slot], &Param[1]);
-				GetParam(input, "Text", &Param[0]);
-				strcpy(Message[Slot], &Param[1]);
+				GetParam(input, "Text=", &Param[0]);
+				strcpy(Message[Slot], &Param[0]);
 
 				MinCounter[Slot] = Interval[Slot];
 
diff --git a/MailNode.vcproj.NOTTSDESKTOP.John.user b/MailNode.vcproj.NOTTSDESKTOP.John.user
deleted file mode 100644
index fa82c00..0000000
--- a/MailNode.vcproj.NOTTSDESKTOP.John.user
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-	
-		
-			
-		
-		
-			
-		
-	
-
diff --git a/RTKnown.txt b/RTKnown.txt
new file mode 100644
index 0000000..e69de29
diff --git a/Versions.h b/Versions.h
index 0c9ebab..b83cbbe 100644
--- a/Versions.h
+++ b/Versions.h
@@ -10,8 +10,8 @@
 
 #endif
 
-#define KVers 6,0,24,30
-#define KVerstring "6.0.24.30\0"
+#define KVers 6,0,24,33
+#define KVerstring "6.0.24.33\0"
 
 #ifdef CKernel
 
diff --git a/WebMail.c b/WebMail.c
index f493c06..569796f 100644
--- a/WebMail.c
+++ b/WebMail.c
@@ -3715,7 +3715,6 @@ char * BuildB2Header(WebMailInfo * WebMail, struct MsgInfo * Msg, char ** ToCall
 
 		for (i = 0; i < Calls; i++)
 			NewMsg += sprintf(NewMsg, "To: %s\r\n",	ToCalls[i]);
-
 	}
 	else
 	{
diff --git a/WinRPRHelper.vcproj.NOTTSDESKTOP.John.user b/WinRPRHelper.vcproj.NOTTSDESKTOP.John.user
deleted file mode 100644
index fa82c00..0000000
--- a/WinRPRHelper.vcproj.NOTTSDESKTOP.John.user
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-	
-		
-			
-		
-		
-			
-		
-	
-
diff --git a/WinmorControl.vcproj.NOTTSDESKTOP.John.user b/WinmorControl.vcproj.NOTTSDESKTOP.John.user
deleted file mode 100644
index fa82c00..0000000
--- a/WinmorControl.vcproj.NOTTSDESKTOP.John.user
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-	
-		
-			
-		
-		
-			
-		
-	
-
diff --git a/bpqmail.h b/bpqmail.h
index 9081e19..0071261 100644
--- a/bpqmail.h
+++ b/bpqmail.h
@@ -620,7 +620,7 @@ struct MsgInfo
 	char	title[61];
 	int		nntpnum;			// Number within topic (ie Bull TO Addr) - used for nntp
 
-	UCHAR	B2Flags;
+	UCHAR	B2Flags;			// Not all flags specific to B2
 
 	#define B2Msg 1				// Set if Message File is a formatted B2 message
 	#define Attachments 2		// Set if B2 message has attachments
@@ -629,6 +629,7 @@ struct MsgInfo
 	#define FromRMSExpress 16 
 	#define RadioOnlyMsg 32		// Received using call-T
 	#define RadioOnlyFwd 64		// Received using call-R
+	#define WarnNotForwardedSent 128
 
 	int		xdatecreated;
 	int		xdatechanged;
diff --git a/chatconfig.cfg b/chatconfig.cfg
index 1533ced..49e3f4e 100644
--- a/chatconfig.cfg
+++ b/chatconfig.cfg
@@ -18,5 +18,5 @@ Chat :
   MonitorSize = "828,1644,148,770";
   DebugSize = "0,0,0,0";
   WindowSize = "231,835,254,602";
-  Version = "6,0,23,59";
+  Version = "6,0,24,32";
 };
diff --git a/debian/README.Debian b/debian/README.Debian
new file mode 100644
index 0000000..bf7265b
--- /dev/null
+++ b/debian/README.Debian
@@ -0,0 +1,23 @@
+README for linbpq on Debian
+===========================
+
+Please see https://wiki.oarc.uk/packet:linbpq-apt-installation for this guide
+
+# Set config
+Copy the config, edit it & set permissions.
+The permissions are so linbpq web interface can edit the config. 
+
+sudo mv /usr/share/doc/linbpq/examples/bpq32.cfg /etc/bpq32.cfg
+sudo nano /etc/bpq32.cfg
+sudo chown :linbpq /etc/bpq32.cfg
+sudo chmod 644 /etc/bpq32.cfg
+
+# Start linbpq
+
+sudo systemctl start linbpq
+
+# Access your node
+
+It shall be available by accessing http://localhost:8008 in the browser or telnet localhost 8010
+
+-- Dave Hibberd   Tue, 26 Mar 2024 00:53:42 +0000
diff --git a/debian/bpq32.cfg b/debian/bpq32.cfg
new file mode 100644
index 0000000..56b0c65
--- /dev/null
+++ b/debian/bpq32.cfg
@@ -0,0 +1,49 @@
+SIMPLE
+NODECALL=MB7NAA
+NODEALIAS=AANODE
+LOCATOR=AA00aa
+PASSWORD=xxxxxxxx
+AUTOSAVE=1
+NODESINTERVAL=10
+MINQUAL=10
+CTEXT:
+Thanks for connecting.
+Type ? for help.
+***
+PORT
+  PORTNUM=1
+  ID=VHF
+  TYPE=ASYNC
+  PROTOCOL=KISS
+  KISSOPTIONS=ACKMODE
+  COMPORT=/dev/ttyACM0
+  SPEED=57600
+  FRACK=4000
+  PACLEN=150
+  DIGIFLAG=0
+  QUALITY=192
+  MINQUAL=20
+ENDPORT
+
+
+PORT
+  PORTNUM=9
+  ID=Telnet
+  DRIVER=Telnet
+  CONFIG
+    LOGGING=1
+    CMS=1
+    DisconnectOnClose=1
+    TCPPORT=8010
+    FBBPORT=8011
+    HTTPPORT=8008
+    LOGINPROMPT=user:
+    PASSWORDPROMPT=password:
+    MAXSESSIONS=10
+    CTEXT=Thanks for connecting\n Enter ? for list of commands\n\n
+    USER=username,xxxxxxxx,m0aaa,,SYSOP
+ENDPORT
+
+LINCHAT
+
+APPLICATION 1,CHAT,,MB7NAA-9,AACHAT,255
\ No newline at end of file
diff --git a/debian/changelog b/debian/changelog
index 6b20a72..f338634 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+linbpq (6.0.24.33-1) unstable; urgency=medium
+
+  * Upstream bump 
+  * Moved config file to examples
+  * Updated service to fail on no config
+  * Added helpful README.Debian
+
+ -- Dave Hibberd   Tue, 26 Mar 2024 20:24:08 +0000
+
 linbpq (6.0.24.30-1~bpo12+1) bookworm; urgency=medium
 
   * Rebuild for bookworm.
diff --git a/debian/install b/debian/install
deleted file mode 100644
index 3367546..0000000
--- a/debian/install
+++ /dev/null
@@ -1 +0,0 @@
-debian/templates/bpq32.cfg etc/
diff --git a/debian/linbpq.examples b/debian/linbpq.examples
new file mode 100644
index 0000000..601e4d9
--- /dev/null
+++ b/debian/linbpq.examples
@@ -0,0 +1 @@
+debian/bpq32.cfg
diff --git a/debian/linbpq.service b/debian/linbpq.service
index 598393c..ef57d04 100644
--- a/debian/linbpq.service
+++ b/debian/linbpq.service
@@ -1,5 +1,7 @@
 [Unit]
+Description=Linbpq systemd service file
 After=network.target
+ConditionPathExists=/etc/bpq32.cfg
 
 [Service]
 ExecStart=/usr/sbin/linbpq -c /etc -d /opt/oarc/bpq -l /opt/oarc/bpq
diff --git a/debian/templates/bpq32.cfg b/debian/templates/bpq32.cfg
deleted file mode 100644
index 59f1666..0000000
--- a/debian/templates/bpq32.cfg
+++ /dev/null
@@ -1,425 +0,0 @@
-;
-;
-;	CONFIGURATION FILE FOR G8BPQ SWITCH SOFTWARE
-;
-;	The order of parameters in not important, but they
-;	all must be specified - there are no defaults
-;
-PASSWORD=ABCDEFGHILKLMNOPQRSTUVWXY	  	 ; SYSOP Passord
-
-LOCATOR=IO68VL		; Enable Map Reporting
-MAPCOMMENT=BPQ32 Test Node
Skigersta, Isle of Lewis
-
-;
-;
-;	BBS enables the Application support system. If you have specified any of the APPLnCALLS,
-;	you should set BBS to 1.
-;
-BBS=1		; INCLUDE BBS SUPPORT
-;
-;	NODE
-NODE=1		; INCLUDE SWITCH SUPPORT
-
-
-
-; The NODES and ROUTES tables can be saved, so that they can be reloaded when the software is restarted,
-; rather than having to wait for the tables to be rebuilt. There is a program SAVENODES.exe and a command
-; to the BPQ32 console to to this. By Setting AUTOSAVE=1, the tables will be saved each time the softare closes
-
-AUTOSAVE=1		; Save Nodes File before exiting
-
-;
-;	Station Identification.
-;
-;	If a user connects to the NODE Callsign or Alias, he is linked
-;	to the switch code, and can use normal NetRom/TheNet commands
-;
-;	If he connects to an Application Callsign or Alias he will be connected
-;	directly to the corresponding application. If not available, the connect will
-;	be rejected. See the section on Application Calls towards the bottom of the file for
-;	more information.
-;
-;	Note that for compatibility with the DOS version, and older versions of BPQ32, BBSCALL is an alias for APPL1CALL,
-;	and BBSALIAS is an alias for APPL1ALIAS. If both BBSCALL and APPL1CALL are specified, the BBSCALL will be ignored.	
-;
-
-NODECALL=G8BPQ-2	; NODE CALLSIGN
-NODEALIAS=BPQ
-
-;	'ID' MESSAGE - SENT EVERY IDINTERVAL MINS
-;
-;	WILL BE ADDRESSED FROM THE PORT CALLSIGN (IF DEFINED)
-;	     ELSE FROM THE NODE CALL
-;
-;	The main purpose of this is to satisfy the requrements of those administations that require a regular station 
-;	identification in the same mode as used for communication. 
-
-IDMSG:
-Network node (BPQ)
-***
-;
-
-;	'I' COMMAND TEXT
-;
-;
-INFOMSG:
-G8BPQ Win32 Test Switch, Skigersta, Isle of Lewis.
-***
-
-; BTEXT is the default beacon sent by the Node. Note that application programs may change this, or
-; generate their own beacons.
-
-; An APRS compatible position may be included. 
-
-BTEXT:
-=5828.54N/00612.69W- {BPQ32}
-G8BPQ's Test Node
-***
-
-IDINTERVAL=15		; 'ID' BROADCAST INTERVAL (UK Regs require an AX25 ID every 15 mins)
-BTINTERVAL=15		; BTEXT is sent at this interval
-
-;
-;	CTEXT - Normally will only be sent when someone connects to 
-;	the NODE ALIAS at level 2. If FULL_CTEXT is set to 1, it 
-;	will be sent to all connectees. Note that this could confuse BBS
-;	forwarding connect scripts. 
-;
-CTEXT:
-Welcome to G8BPQ's Test Switch in Skigersta
-Type ? for list of available commands.
-***
-
-FULL_CTEXT=0		; SEND CTEXT TO EVERYBODY
-
-HFCTEXT=BPQ32 Node, Skigersta
-
-;	Network System Parameters. 
-;
-;	These are my values. Many other node sysops use other values. If in doubt, liase with
-;	those running nodes that you link to
-
-OBSINIT=5		; INITIAL OBSOLESCENCE VALUE
-OBSMIN=4		; MINIMUM TO BROADCAST
-NODESINTERVAL=60		; 'NODES' INTERVAL IN MINS
-
-L3TIMETOLIVE=25		; MAX L3 HOPS
-L4RETRIES=4;		; LEVEL 4 RETRY COUNT
-;
-L4TIMEOUT=60;		; LEVEL 4 TIMEOUT
-L4DELAY=10		; LEVEL 4 DELAYED ACK TIMER
-L4WINDOW=4		; DEFAULT LEVEL 4 WINDOW
-;
-MINQUAL=140		; MINIMUM QUALITY TO ADD TO NODES TABLE	
-
-
-
-;	The following MAX params set the limits for various tables. 
-;
-;	Although significantly larger values can be used, a common area is used
-;	for these tables and the buffer pool, so don't increase them more than 
-;	necessary.
-
-MAXLINKS=100		; MAX LEVEL 2 LINKS (UP,DOWN AND INTERNODE)
-MAXNODES=300; 		; MAX NODES IN SYSTEM
-MAXROUTES=30		; MAX ADJACENT NODES
-MAXCIRCUITS=150		; NUMBER OF L4 CIRCUITS
-
-	
-
-BUFFERS=999		; PACKET BUFFERS - 999 MEANS ALLOCATE AS MANY
-				; AS POSSIBLE - NORMALLY ABOUT 600, DEPENDING
-				; ON OTHER TABLE SIZES
-;
-;	TNC DEFAULT PARAMS
-;
-PACLEN=236		; MAX PACKET SIZE
-;
-;	PACLEN is a problem! The ideal size depends on the link(s) over
-;	which a packet will be sent. For a session involving another node,
-;	we have no idea what is at the far end. Ideally each node should have
-;	the capability to combine and then refragment messages to suit each
-;	link segment - maybe when there are more of my nodes about than 'real'
-;	ones, i'll do it. When the node is accessed directly, things are a
-;	bit easier, as we know at least something about the link.
-;	So there are two PACLEN params, one here and
-;	one in the PORTS section. This one is used to set the initial value
-;	for sessions via other nodes, and for sessions initiated from here.
-;	The other is used for incoming direct (Level 2)	sessions. In all cases
-;	the Node PACLEN command can be used to override the defaults.
-;
-;	236 is the largest that can be sent over a NETROM link without fragmetation.
-;	so don't go above this unless you don't have ant NETROM links.
-;
-;	Level 2 Parameters
-;
-; 	Most Level 2 parametes are specified in the PORTS section'
-;
-T3=180	 	   	 	; LINK VALIDATION TIMER (3 MINS)
-IDLETIME=900		; IDLE LINK SHUTDOWN TIMER (15 MINS)	
-;
-;
-HIDENODES=0		; IF SET TO 1, NODES STARTING WITH # WILL
-				; ONLY BE DISPLAYED BY A NODES * COMMAND
-;
-;	THE *** LINKED COMMAND IS INTENDED FOR USE BY GATEWAY SOFTWARE, AND
-;	CONCERN HAS BEEN EXPRESSED THAT IT COULD BE MISUSED. I RECOMMEND THAT
-;	IT IS DISABLED IF NOT NEEDED.
-;
-ENABLE_LINKED=A		; CONTROLS PROCESSING OF *** LINKED COMMAND
-				; Y ALLOWS UNRESTRICTED USE
-				; A ALLOWS USE BY APPLICATION PROGRAM
-				; N (OR ANY OTHER VALUE) DISABLE
-;
-;	AX25 PORT DEFINITIONS
-;
-;	These define the external links - normally to radios, but possibly
-;   to other computers, modems, etc. 
-; 
-
-;	The KISS protocol supports dual port TNC's such as the KAM and KPC4.
-;	You should define two port entries with the same IO addr
-;	and SPEED - set CHANNEL=A for the first and B for the second.
-;
-; 	Note that all timer values are in ms intervals. Most TNC's
-;	use different units for the various timers, so be careful!
-;
-;	All parameters should be set for all ports, but not all
-;	drivers support all features. For instance, the NETROM driver
-;	does not use the TXDELAY, SLOTTIME and PERSIST values. The NETROM
-;	driver only works in FULL DUPLEX mode, and the HDLC only in
-;	HALF DUPLEX.
-;;
-;	CWID works only on DRSI and PC120 cards, and can be suppressed 
-;	by omitting the parameter.
-;
-;	BECAUSE OF OUR ODD LICENCING CONDITIONS YOU MAY WISH TO BAN
-;	CONNECTIONS TO THE BBS CALLSIGN ON SOME PORTS - USERS MAY STILL
-;	CONNECT USING L4, OR CONNECT TO THE NODE ADDR, AND USE BBS
-;	COMMAND. PUT 'BBSFLAG=NOBBS' TO ACTIVATE THIS FUNCTION.
-;	'BBSFLAG=BBSOK', OR NO PARM, MEANS BEHAVE AS NORMAL
-;
-;	You can have an extra callsign and alias for each
-;	port for user access only. The callsigns defined in NODECALL and
-;	BBSCALL are used for all networking activity.
-;
-
-PORT
- ID=LOOPBACK
- TYPE=INTERNAL
- PROTOCOL=KISS
- CHANNEL=A
- QUALITY=0
- MAXFRAME=6
- FULLDUP=0
- FRACK=10000
- RESPTIME=3000
- RETRIES=10
- PACLEN=200
- TXDELAY=500
- SLOTTIME=100
- PERSIST=64
- DIGIFLAG=1
- UNPROTO=FBB
-ENDPORT
-
-PORT
- ID=AXIP Link
- TYPE=EXTERNAL
- DLLNAME=BPQAXIP.DLL
- QUALITY=200
- MAXFRAME=4
- FRACK=5000
- RESPTIME=1000
- RETRIES=10
- PACLEN=236
- MINQUAL=150
- UNPROTO=FBB		; DEFAULT UNPROTO ADDR
- BCALL=GM8BPQ		; Call for Beacons
- 
- CONFIG
- 
- UDP 10093                 # Optional. Enables UDP support, and defines the port
-                           # AX.IP listens on. You can specify more than one
-                           # UDP line if you need to listen on more than one port
-                                 
- MHEARD                    # Optional - opens a window to display a "Heard List" 
-
- BROADCAST NODES
-
- MAP G8BPQ-7 G8BPQ.NO-IP.COM UDP 10093 B
- 
- ; Steve Conrad, VE9SC, provides a service which displays a map of BPQMailChat
- ; nodes dynamically updated:  http://guardian.no-ip.org/bpqmap/ChatNetwork.htm
- ; The following line causes your Chat Node to be included on the map.
-
- MAP DUMMY chatmap.g8bpq.net UDP 10090
-
-ENDPORT
-
-PORT
- ID=BPQEther Link
- TYPE=EXTERNAL
- DLLNAME=BPQETHER.DLL
- QUALITY=200
- IOADDR=2
- CHANNEL=A
- MAXFRAME=7
- FRACK=5000
- RESPTIME=1000
- RETRIES=10
- PACLEN=236
- MINQUAL=255
- UNPROTO=MAIL		; DEFAULT UNPROTO ADDR
- 
- CONFIG
-  
-  TXMODE BPQ                  # BPQ or RLI
-  RXMODE BPQ                  # BPQ or RLI
-  TYPE 08FF                   # Ethernet Type
-  DEST 01-42-50-51-00-00      # Target Ethernet Addr - Multicast as used in DOS BPQCODE
-  SOURCE 02-FF-60-BA-5C-9E    # Source Ethernet Addr
-  ADAPTER \Device\NPF_{959094A1-C20D-4FFD-AF68-D43229E4854B} # Adapter Name
- 
-ENDPORT
-
-;
-; WINMOR Port
-;
-PORT
- ID=WINMOR Port 1
- TYPE=EXTERNAL
- DLLNAME=WINMOR.DLL
- INTERLOCK=4
- CONFIG
- ADDR 127.0.0.1 8506 PTT DTR
- RIGCONTROL COM61 4800 ICOM IC718 5E 5 3.573/u1nA1 7.077/u1 10.133/u1 10.146/u1wA3 14.1105/u1w
- CWID True
- BW 1600
- DRIVELEVEL 100
- BUSYLOCK False
-
-ENDPORT
-
-PORT
- ID=KAM PACTOR COM 100
- TYPE=EXTERNAL
- PROTOCOL=PACTOR
- IOADDR=64
- SPEED=9600
- DLLNAME=KAMPACTOR.DLL
- QUALITY=0
- INTERLOCK=4
- 
- CONFIG                 ; Driver-Specific Configuration
- 
- APPL RMS               ; Autoconnect to BPQ32 RMS Application
- RIGCONTROL COM2 19200 ICOM IC700 70 4 14.103/U1W 14.112/U1 18.1/U1N 10.12/L1
-
-
- OLDMODE                ; Optional - Causes controller to be set to PACTOR mode instead of TOR mode
- XMITLVL 50/35;
-
-ENDPORT
-
-PORT
- ID=SCS PACTOR COM 103
- DRIVER=SCSPACTOR
- COMPORT=103
- SPEED=38400
- PORTCALL=GM8BPQ
- 
- CONFIG                 ; Driver-Specific Configuration
- 
-  APPL RMS               ; Autoconnect to BPQ32 RMS Application
-  RIGCONTROL COM2 19200 ICOM IC700 70 4 14.103/U1W 14.112/U1 18.1/U1N 10.12/L1
-
-
-  PSKA 140               ; PSK TX Output level.
-  FSKA 100               ; TX Level for FSK modes.
- 
-ENDPORT
-
-PORT
- ID=KISS COM53
- TYPE=ASYNC
- PROTOCOL=KISS
- COMPORT=53
- SPEED=9600
- INTLEVEL=4
- CHANNEL=A
- QUALITY=0
- MAXFRAME=6
- FULLDUP=0
- FRACK=10000
- RESPTIME=3000
- RETRIES=10
- PACLEN=200
- TXDELAY=500
- SLOTTIME=100
- PERSIST=64
- DIGIFLAG=1
-;
-;	KISSOPTIONS=ACKMODE
-;	KISSOPTIONS=POLLED,CHECKSUM
-
- UNPROTO=FBB
-ENDPORT
-
-PORT
- ID=VKISS COM2 Link to MIXW
- DRIVER=BPQVKISS
- QUALITY=200
- COMPORT=2
- CHANNEL=A
- MAXFRAME=4
- FRACK=5000
- RESPTIME=1000
- RETRIES=10
- PACLEN=120
- DIGIFLAG=1
- DIGIMASK=65535		; Digi UI Frames to all ports
-
-ENDPORT
-
-
-
-PORT
- ID=AGW Port 1
- DRIVER=BPQtoAGW
- QUALITY=0
- IOADDR=1F41
- CHANNEL=A
- MAXFRAME=4
- FRACK=7000
- RESPTIME=1000
- RETRIES=10
- PACLEN=120
- UNPROTO=MAIL		; DEFAULT UNPROTO ADDR
-;
-ENDPORT
-
-
-ROUTES:
-;
-;	ROUTES TO LOCK IN
-;
-;	specify Callsign, Quality and Port. You can now also specify
-;	MAXFRAME, FRACK, PACLEN (in that order) to override the port
-;	defaults.
-;
-;
-AE5E-14,200,2,0,0,0,2     ; No Keepalives
-;G4RFG,0,1                ; Marginal, So lock out by setting QUALITY = 0
-;G0GDR-1,100,2,1,6000,100 ; not always very good, so MAXFRAME = 1
-***
-;
-;	APPLICATIONS SUPPORTED
-;
-;	NAMES STARTING WITH * ARE NOT INCLUDED IN 'VALID COMMANDS' DISPALY
-;
-
-APPLICATION 1,RMS,,GM8BPQ-10,BPQRMS,0
-APPLICATION 2,CHAT,,G8BPQ-4,BPQCHT,255
-APPLICATION 3,FBB,,GM8BPQ-3,BPQFBB,0
-APPLICATION 4,BBS,,G8BPQ,BPQBBS,255
diff --git a/lzhuf32.c b/lzhuf32.c
index 7289086..3482b30 100644
--- a/lzhuf32.c
+++ b/lzhuf32.c
@@ -933,15 +933,21 @@ void Decode(CIRCUIT * conn, int FromSync)
 		FBBHeader->MsgType = 'P';
 	}
 
-	if (FBBHeader->MsgType == 'P')
-		Index = PMSG;
-	else if (FBBHeader->MsgType == 'B')
-		Index = BMSG;
-	else if (FBBHeader->MsgType == 'T')
-		Index = TMSG;
+	if (!FBBHeader->B2Message)
+	{
+		// With B2 the Type is specified in the body, so can't update stats now
+			
+		if (FBBHeader->MsgType == 'P')
+			Index = PMSG;
+		else if (FBBHeader->MsgType == 'B')
+			Index = BMSG;
+		else if (FBBHeader->MsgType == 'T')
+			Index = TMSG;
+
+		conn->UserPointer->Total.MsgsReceived[Index]++;
+		conn->UserPointer->Total.BytesForwardedIn[Index] += count;
+	}
 
-	conn->UserPointer->Total.MsgsReceived[Index]++;
-	conn->UserPointer->Total.BytesForwardedIn[Index] += count;
 
 	if (FBBHeader->B2Message)
 	{
@@ -1497,6 +1503,7 @@ File: 5566 NEWBOAT.HOMEPORT.JPG
 
 		// Processed all headers
 
+
 		// If multiple recipents, create one copy for each BBS address, and one for all others (via RMS)
 	
 		if (Recipients == 0 || HddrTo == NULL)
@@ -1702,9 +1709,9 @@ File: 5566 NEWBOAT.HOMEPORT.JPG
 
 					ptr += 7;
 
-					// This handles a message arriving with bull/ or nts/ oerrides
+					// This handles a message arriving with bull/ or nts/ overrides
 
-					if (_memicmp(ptr, "Private", 7) == 0 && Msg->type != 'P')
+ 					if (_memicmp(ptr, "Private", 7) == 0 && Msg->type != 'P')
 					{
 						if (Msg->type == 'T')
 							memcpy(ptr, "Traffic", 7);
@@ -1744,6 +1751,18 @@ File: 5566 NEWBOAT.HOMEPORT.JPG
 				if (i > 0 && Msg->type != 'B')			// Must Change the BID
 					Msg->bid[0] = 0;
 
+				// Update Stats
+
+				if (Msg->type == 'P')
+					Index = PMSG;
+				else if (Msg->type == 'B')
+					Index = BMSG;
+				else if (Msg->type == 'T')
+					Index = TMSG;
+
+				conn->UserPointer->Total.MsgsReceived[Index]++;
+				conn->UserPointer->Total.BytesForwardedIn[Index] += MsgLen;
+
 				CreateMessageFromBuffer(conn);
 			}
 			}	// End not from RMS
@@ -1759,33 +1778,7 @@ File: 5566 NEWBOAT.HOMEPORT.JPG
 			SetupNextFBBMessage(conn);
 			return;
 		}
-/*
-		else
-		{
-			// Single Destination -  Need to put to: line back in message
 
-			char * ptr = HddrTo[0];
-			__int32 ToLen;
-			char toCopy[80];
-			
-			
-			ptr = HddrTo[0];
-
-			if (_memicmp(&ptr[4], "nts:", 4) == 0)
-				memmove(ptr + 4, ptr + 8, strlen(ptr + 7));
-
-			ToLen = strlen(ptr);
-
-			memmove(&conn->MailBuffer[B2To + ToLen], &conn->MailBuffer[B2To], count);
-			memcpy(&conn->MailBuffer[B2To], HddrTo[0], ToLen); 
-			conn->TempMsg->length += ToLen;
-			Msg->type = Type[i];
-	
-			CreateMessageFromBuffer(conn);
-			SetupNextFBBMessage(conn);
-			return;
-		}
-*/
 #ifndef LINBPQ
 		}
 			#define EXCEPTMSG "Error Decoding B2 Message"
@@ -1800,8 +1793,6 @@ File: 5566 NEWBOAT.HOMEPORT.JPG
 #endif	
 	} // end if B2Msg
 
-	// Look for 
-
 	CreateMessageFromBuffer(conn);
 	SetupNextFBBMessage(conn);
 }
\ No newline at end of file
diff --git a/nodeapi.c b/nodeapi.c
index 8a5a814..eef71e8 100644
--- a/nodeapi.c
+++ b/nodeapi.c
@@ -40,6 +40,8 @@ int sendPortList(char * response, char * token,int Flags);
 int sendNodeList(char * response, char * token,int Flags);
 int sendUserList(char * response, char * token,int Flags);
 int sendInfo(char * response, char * token, int Flags);
+int sendLinks(char * response, char * token, int Flags);
+int sendPortMHList(char * response, char * token, int Flags);
 
 DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
 
@@ -64,14 +66,18 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req
 	const char * auth_header = "Authorization: Bearer ";
 	char * token_begin = strstr(request, auth_header);
 	char token[TOKEN_SIZE + 1]= "";
-	char * param = strlop(URL, '?');
 	int Flags = 0;
+	char * Tok = strlop(URL, '?');
+	char * param = strlop(Tok, '&');
 
-	if (param && strlen(param) == TOKEN_SIZE)
+	if (param)
+		Flags = atoi(param);
+
+	if (Tok && strlen(Tok) == TOKEN_SIZE)
 	{
 		// assume auth token
 
-		strcpy(token, param);
+		strcpy(token, Tok);
 	}
 
 	remove_expired_tokens();			// Tidy up
@@ -106,17 +112,20 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req
 
 	// Determine the requested API endpoint
 
-	if (_stricmp(URL, "/api/getports") == 0)
+	if (_stricmp(URL, "/api/ports") == 0)
 		return sendPortList(response, token, Flags);
-	else if (_stricmp(URL, "/api/getnodes") == 0)
+	else if (_stricmp(URL, "/api/nodes") == 0)
 		return sendNodeList(response, token, Flags);
-	else if (_stricmp(URL, "/api/getusers") == 0)
+	else if (_stricmp(URL, "/api/users") == 0)
 		return sendUserList(response, token, Flags);
-	else if (_stricmp(URL, "/api/getinfo") == 0)
+	else if (_stricmp(URL, "/api/info") == 0)
 		return sendInfo(response, token, Flags);
+	else if (_stricmp(URL, "/api/links") == 0)
+		return sendLinks(response, token, Flags);
+	else if (strstr(URL, "/api/mheardport") != 0)
+		return sendPortMHList(response, token, Flags);
 
 	return send_http_response(response, "401 Invalid API Call");
-
 }
 
 int request_token(char * response) 
@@ -631,3 +640,87 @@ int sendInfo(char * response, char * token, int Flags)
 
 	return strlen(response);
 }
+
+int sendLinks(char * response, char * token, int Flags)
+{
+	struct _LINKTABLE * Links = LINKS;
+	int MaxLinks = MAXLINKS;
+	int count;
+	char Normcall1[10];
+	char Normcall2[10];
+	char State[12] = "", Type[12] = "Uplink";
+	int axState;
+	int cctType;
+	int ReplyLen = 0;
+	ReplyLen += sprintf(&response[ReplyLen],"{\"links\":[\r\n");
+
+	for (count=0; countLINKCALL[0] != 0)
+		{
+			int len = ConvFromAX25(Links->LINKCALL, Normcall1);
+			Normcall1[len] = 0;
+
+			len = ConvFromAX25(Links->OURCALL, Normcall2);
+			Normcall2[len] = 0;
+
+
+			axState = Links->L2STATE;
+
+			if (axState == 2)
+				strcpy(State, "Connecting");
+			else if (axState == 3)
+				strcpy(State, "FRMR");
+			else if (axState == 4)
+				strcpy(State, "Closing");
+			else if (axState == 5)
+				strcpy(State, "Active");
+			else if (axState == 6)
+				strcpy(State, "REJ Sent");
+
+			cctType = Links->LINKTYPE;
+
+			if (cctType == 1)
+				strcpy(Type, "Uplink");
+			else if (cctType == 2)
+				strcpy(Type, "Downlink");
+			else if (cctType == 3)
+				strcpy(Type, "Node-Node");
+
+
+
+			ReplyLen += sprintf(&response[ReplyLen], "{\"farCall\": \"%s\",\"ourCall\": \"%s\", \"port\": \"%d\", \"state\": \"%s\", \"linkType\": \"%s\", \"ax25Version\": \"%d\"},\r\n",
+				Normcall1, Normcall2, Links->LINKPORT->PORTNUMBER,
+				State, Type, 2 - Links->VER1FLAG );
+			Links+=1;
+		}
+	}
+
+	if (ReplyLen < 13)
+		ReplyLen -= 2;          // no links
+	else
+		ReplyLen -= 3;         // remove trailing comma
+
+	ReplyLen+= sprintf(&response[ReplyLen], "\r\n]}\r\n");
+
+	return ReplyLen;
+}
+
+int sendPortMHList(char * response, char * token, int Flags)
+{
+        struct PORTCONTROL * PORTVEC = GetPortTableEntryFromPortNum(Flags);
+
+		response[0] = 0;
+
+		if (PORTVEC == 0)
+			return send_http_response(response, "401 Invalid API Call");
+
+        BuildPortMH( response, PORTVEC );
+        response[ strlen(response)-3 ] = '\0';          // remove ,\r\n
+//      printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
+        return strlen(response);
+}
+
+
+
+