Description: This is what's needed to make it build
 The whole bastarding codebase in one patch
 .
 qttermtcp (0.0.0.79-1) UNRELEASED; urgency=medium
 .
   * Update the debian branch for import
   * New upstream version 0.0.0.79
Author: Dave Hibberd <hibby@debian.org>

--- qttermtcp-0.0.0.79.orig/AGWCode.cpp
+++ qttermtcp-0.0.0.79/AGWCode.cpp
@@ -1,1625 +1,1625 @@
-// AGW Interface
-
-#include "QtTermTCP.h"
-#include "TabDialog.h"
-#include <time.h>
-#include <QVBoxLayout>
-#include <QLabel>
-
-#ifndef WIN32
-#define strtok_s strtok_r
-#endif
-
-#define UCHAR unsigned char
-#define byte unsigned char
-
-myTcpSocket * AGWSock;
-
-extern QColor monRxText;
-extern QColor monTxText;
-
-extern QColor outputText;
-extern QColor EchoText;
-extern QColor WarningText;
-
-extern QColor newTabText;
-
-extern QTabWidget *tabWidget;
-extern QWidget * mythis;
-
-extern int AGWEnable;
-extern int AGWMonEnable;
-extern int AGWLocalTime;
-extern int AGWMonNodes;
-extern char AGWTermCall[12];
-extern char AGWBeaconDest[12];
-extern char AGWBeaconPath[80];
-extern int AGWBeaconInterval;
-extern char AGWBeaconPorts[80];
-extern char AGWBeaconMsg[260];
-
-extern char AGWHost[128];
-extern int AGWPortNum;
-extern int AGWPaclen;
-
-extern Ui_ListenSession * KISSMonSess;
-
-extern char listenCText[4096];
-extern int ConnectBeep;
-
-extern QList<Ui_ListenSession *> _sessions;
-
-extern QLabel * Status1;
-extern QLabel * Status2;
-extern QLabel * Status3;
-extern QLabel * Status4;
-
-extern QMenu *connectMenu;
-extern QAction *discAction;
-extern QAction *YAPPSend;
-
-extern QAction *actHost[17];
-
-// Session Type Equates
-
-#define Term 1
-#define Mon 2
-#define Listen 4
-
-extern int TermMode;
-
-#define Single 0
-#define MDI 1
-#define Tabbed 2
-
-extern int singlemodeFormat;
-
-typedef struct AGWUser_t
-{
-	QTcpSocket *socket;
-	unsigned char data_in[8192];
-	int data_in_len;
-	unsigned char  AGW_frame_buf[512];
-	int	Monitor;
-	int	Monitor_raw;
-	Ui_ListenSession * MonSess;			// Window for Monitor info
-
-} AGWUser;
-
-
-struct AGWHeader
-{
-	int Port;
-	unsigned char DataKind;
-	unsigned char filler2;
-	unsigned char PID;
-	unsigned char filler3;
-	char callfrom[10];
-	char callto[10];
-	int DataLength;
-	int reserved;
-};
-
-#define AGWHDDRRLEN sizeof(struct AGWHeader)
-
-typedef struct TAGWPort_t
-{
-	byte PID;
-	int port;
-	char corrcall[10];
-	char mycall[10];
-	int Active;
-	QTcpSocket * socket;
-	Ui_ListenSession * Sess;			// Terminal Session
-
-} TAGWPort;
-
-
-int AGWConnected = 0;
-int AGWConnecting = 0;
-
-char * AGWPortList = NULL;
-
-#define max_sessions 8
-
-TAGWPort AGWPort[max_sessions];
-
-#define    LSB 29
-#define    MSB 30
-#define    MON_ON '1'
-#define    MON_OFF '0'
-#define    MODE_OUR 0
-#define    MODE_OTHER 1
-#define    MODE_RETRY 2
-
-// Don't think we will support more than one, but leave in option
-
-AGWUser *AGWUsers = NULL;				// List of currently connected clients
-
-void AGW_add_socket(QTcpSocket * socket);
-void AGW_Process_Input(AGWUser * AGW);
-void Send_AGW_X_Frame(QTcpSocket* socket, char * CallFrom);
-void Send_AGW_G_Frame(QTcpSocket* socket); 
-void Send_AGW_m_Frame(QTcpSocket* socket);
-void Send_AGW_R_Frame(QTcpSocket* socket);
-
-Ui_ListenSession * FindFreeWindow();
-Ui_ListenSession * newWindow(QObject * parent, int Type, const char * Label = nullptr);
-void AGW_frame_header(UCHAR * Msg, char AGWPort, char DataKind, unsigned char PID, const char * CallFrom, const char * CallTo, int Len);
-
-
-void Debugprintf(const char * format, ...)
-{
-	char Mess[10000];
-	va_list arglist;
-
-	va_start(arglist, format);
-	vsprintf(Mess, format, arglist);
-	qDebug() << Mess;
-
-	return;
-}
-
-int ConvToAX25(char * callsign, unsigned char * ax25call)
-{
-	int i;
-
-	memset(ax25call, 0x40, 6);		// in case short
-	ax25call[6] = 0x60;				// default SSID
-
-	for (i = 0; i < 7; i++)
-	{
-		if (callsign[i] == '-')
-		{
-			//
-			//	process ssid and return
-			//
-			i = atoi(&callsign[i + 1]);
-
-			if (i < 16)
-			{
-				ax25call[6] |= i << 1;
-				return (1);
-			}
-			return (0);
-		}
-
-		if (callsign[i] == 0 || callsign[i] == 13 || callsign[i] == ' ' || callsign[i] == ',')
-		{
-			//
-			//	End of call - no ssid
-			//
-			return (1);
-		}
-
-		ax25call[i] = callsign[i] << 1;
-	}
-
-	//
-	//	Too many chars
-	//
-
-	return (0);
-}
-
-
-int ConvFromAX25(unsigned char * incall, char * outcall)
-{
-	int in, out = 0;
-	unsigned char chr;
-
-	memset(outcall, 0x20, 10);
-
-	for (in = 0; in < 6; in++)
-	{
-		chr = incall[in];
-		if (chr == 0x40)
-			break;
-		chr >>= 1;
-		outcall[out++] = chr;
-	}
-
-	chr = incall[6];				// ssid
-
-	if (chr == 0x42)
-	{
-		outcall[out++] = '-';
-		outcall[out++] = 'T';
-		return out;
-	}
-
-	if (chr == 0x44)
-	{
-		outcall[out++] = '-';
-		outcall[out++] = 'R';
-		return out;
-	}
-
-	chr >>= 1;
-	chr &= 15;
-
-	if (chr > 0)
-	{
-		outcall[out++] = '-';
-		if (chr > 9)
-		{
-			chr -= 10;
-			outcall[out++] = '1';
-		}
-		chr += 48;
-		outcall[out++] = chr;
-	}
-	return (out);
-}
-
-void doAGWBeacon()
-{
-	if (AGWBeaconDest[0] && AGWBeaconPorts[0])
-	{
-		// Send as M or V depending on Digis
-
-		UCHAR Msg[512];	
-		char ports[80];
-
-		char * ptr, * context;
-		int DataLen;
-
-		strcpy(ports, AGWBeaconPorts);			// strtok changes it
-
-
-		// Replace newlines with CR
-
-		while ((ptr = strchr(AGWBeaconMsg, 10)))
-			*ptr = 13;
-
-		ptr = strtok_s(ports, " ,", &context);
-
-		if (AGWBeaconPath[0])
-		{
-
-		}
-		else
-		{
-			while (ptr)
-			{
-				DataLen = (int)strlen(AGWBeaconMsg);
-
-				AGW_frame_header(Msg, atoi(ptr) - 1, 'M', 240, AGWTermCall, AGWBeaconDest, DataLen);
-				memcpy(&Msg[AGWHDDRRLEN], AGWBeaconMsg, DataLen);
-				DataLen += AGWHDDRRLEN;
-				AGWSock->write((char *)Msg, DataLen);
-
-				ptr = strtok_s(NULL, " ,",  &context);
-			}
-		}
-	}
-}
-
-TAGWPort * get_free_port()
-{
-	int i = 0;
-
-	while (i < max_sessions)
-	{
-		if (AGWPort[i].Active == 0)
-			return &AGWPort[i];
-
-		i++;
-	}
-	return nullptr;
-}
-
-TAGWPort * findSession(int AGWChan, char * MyCall, char * OtherCall)
-{
-	int i = 0;
-
-	TAGWPort * Sess = nullptr;
-
-	while (i < max_sessions)
-	{
-		Sess = &AGWPort[i];
-
-		if (Sess->Active && Sess->port == AGWChan && strcmp(Sess->corrcall, OtherCall) == 0 && strcmp(Sess->mycall, MyCall) == 0)
-			return Sess;
-
-		i++;
-	}
-	return nullptr;
-}
-
-
-
-void QtTermTCP::AGWdisplayError(QAbstractSocket::SocketError socketError)
-{
-	switch (socketError)
-	{
-	case QAbstractSocket::RemoteHostClosedError:
-		break;
-
-	case QAbstractSocket::HostNotFoundError:
-		QMessageBox::information(this, tr("QtTermTCP"),
-			tr("AGW host was not found. Please check the "
-				"host name and port settings."));
-
-		Status1->setText("AGW Connection Failed");
-
-		break;
-
-	case QAbstractSocket::ConnectionRefusedError:
-
-		Status1->setText("AGW Connection Refused");
-		break;
-
-	default:
-
-		Status1->setText("AGW Connection Failed");
-	}
-
-	AGWConnecting = 0;
-	AGWConnected = 0;
-}
-
-void QtTermTCP::AGWreadyRead()
-{
-	int Read;
-	unsigned char Buffer[4096];
-	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
-
-	// read the data from the socket
-
-	Read = Socket->read((char *)Buffer, 4095);
-
-	int AGWHeaderLen = sizeof(struct AGWHeader);
-
-	AGWUser * AGW = NULL;
-
-	AGW = AGWUsers;
-
-	if (AGW == NULL)
-		return;
-
-	memcpy(&AGW->data_in[AGW->data_in_len], Buffer, Read);
-
-	AGW->data_in_len += Read;
-
-	while (AGW->data_in_len >= AGWHeaderLen)		// Make sure have at least header
-	{
-		struct AGWHeader * Hddr = (struct AGWHeader *)AGW->data_in;
-
-		int AgwLen = Hddr->DataLength + AGWHeaderLen;
-
-		if (AGW->data_in_len >= AgwLen)
-		{
-			// Have frame as well
-
-			AGW_Process_Input(AGW);
-
-			AGW->data_in_len -= AgwLen;
-
-			memmove(AGW->data_in, &AGW->data_in[AgwLen], AGW->data_in_len);
-		}
-		else
-			return;					// Wait for the data
-	}
-
-}
-
-void QtTermTCP::onAGWSocketStateChanged(QAbstractSocket::SocketState socketState)
-{
-	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
-	Ui_ListenSession * Sess = (Ui_ListenSession *)sender->Sess;
-	int i;
-
-	if (socketState == QAbstractSocket::UnconnectedState)
-	{
-		// Close any connections
-
-		Status1->setText("AGW Disconnected");
-		actHost[16]->setVisible(0);
-
-		int i = 0;
-
-		TAGWPort * AGW = nullptr;
-
-		for (i = 0; i < max_sessions; i++)
-		{
-			AGW = &AGWPort[i];
-
-			if (AGW->Active && AGW->socket)
-			{
-				AGW->Active = 0;
-				AGW->socket = nullptr;
-
-				Sess = AGW->Sess;
-
-				if (Sess)
-				{
-					// Send Disconnected
-
-					char Msg[] = "Disconnected\r";
-
-					WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-						Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
-
-					if (TermMode == MDI)
-					{
-						if (Sess->SessionType == Mon)			// Mon Only
-							Sess->setWindowTitle("Monitor Session Disconnected");
-						else
-							Sess->setWindowTitle("Disconnected");
-					}
-					else if (TermMode == Tabbed)
-					{
-						if (Sess->SessionType == Mon)			// Mon Only
-							tabWidget->setTabText(Sess->Tab, "Monitor");
-						else
-						{
-							char Label[32];
-							sprintf(Label, "Sess %d", Sess->Tab + 1);
-							tabWidget->setTabText(Sess->Tab, Label);
-						}
-					}
-					else if (TermMode == Single)
-					{
-						if (Sess->SessionType == Mon)			// Mon Only
-							mythis->setWindowTitle("Monitor Session Disconnected");
-						else
-							mythis->setWindowTitle("Disconnected");
-					}
-
-					setMenus(false);	
-					
-					// if Single Split or Monitor leave session allocated to AGW
-
-					if (TermMode == Single && (Sess->SessionType & Mon))
-					{
-						return;
-					}
-
-					Sess->AGWSession = nullptr;
-					AGW->Sess = nullptr;
-				}
-			}
-		}
-
-		// Free the monitor Window
-
-		if (AGWUsers && AGWUsers->MonSess)
-		{
-			Sess = AGWUsers->MonSess;
-
-			char Msg[] = "Disconnected\r";
-
-			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-				Sess->monWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
-
-			if (TermMode == MDI)
-				Sess->setWindowTitle("Monitor Session Disconnected");
-
-			else if (TermMode == Tabbed)
-				tabWidget->setTabText(Sess->Tab, "Monitor");
-
-			Sess->AGWSession = nullptr;
-			AGWUsers->MonSess = nullptr;
-		}
-
-		if (TermMode == Single && (singlemodeFormat & Mon))
-		{
-			//Re-renable TCP connects
-
-			for (int i = 0; i < MAXHOSTS; i++)
-				actHost[i]->setVisible(1);
-		}
-
-
-		AGWConnected = 0;
-	}
-	else if (socketState == QAbstractSocket::ConnectedState)
-	{
-		AGWConnected = 1;
-		AGWConnecting = 0;
-
-		Status1->setText("AGW Connected");
-
-		AGW_add_socket(sender);
-
-		actHost[16]->setVisible(1);			// Enable AGW Connect Line
-
-		// Send X frame to register Term Call
-
-		if (AGWTermCall[0])
-			Send_AGW_X_Frame(sender, AGWTermCall);
-
-		Send_AGW_G_Frame(sender);					// Request Port List
-
-		// Attach a Monitor Window if available
-
-		Ui_ListenSession * Sess = NULL;
-		Ui_ListenSession * S;
-
-		if (TermMode == MDI)
-		{
-			// See if an old session can be reused
-
-			for (int i = 0; i < _sessions.size(); ++i)
-			{
-				S = _sessions.at(i);
-
-				//	for (Ui_ListenSession * S: _sessions)
-				//	{
-				if ((S->SessionType == Mon) && S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
-				{
-					Sess = S;
-					break;
-				}
-			}
-
-			// Create a window if none found, else reuse old
-
-			if (Sess == NULL)
-			{
-				Sess = newWindow((QObject *)mythis, Mon, "");
-			}
-		}
-		else if (TermMode == Tabbed)
-		{
-			// Tabbed - look for free session
-
-			for (i = 8; i; i--)
-			{
-				S = _sessions.at(i);
-
-				if (S->clientSocket == NULL && S->KISSSession == NULL && S->AGWSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
-				{
-					Sess = S;
-					break;
-				}
-			}
-		}
-		else if (TermMode == Single && (singlemodeFormat & Mon))
-		{
-			S = _sessions.at(0);
-
-			if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
-				Sess = S;
-
-		}
-
-		if (Sess)
-		{
-			AGWUsers->MonSess = Sess;
-//			Sess->AGWSession = sender;			// Flag as in use
-
-			if (TermMode == MDI)
-				Sess->setWindowTitle("AGW Monitor Window");
-			else if (TermMode == Tabbed)
-				tabWidget->setTabText(Sess->Tab, "AGW Mon");
-			else if (TermMode == Single)
-				mythis->setWindowTitle("AGW Monitor Window");
-
-			if (TermMode == Single && (singlemodeFormat & Mon))
-			{
-				// Can't be connected, so leave state alone, but disable TCP connects
-
-				for (int i = 0; i < MAXHOSTS; i++)
-					actHost[i]->setVisible(0);
-
-			}
-			else if (TermMode != Tabbed)				// Not ideal, but AGW mon window is unlikely to be active window
-			{
-				discAction->setEnabled(false);
-				YAPPSend->setEnabled(false);
-				connectMenu->setEnabled(false);
-			}
-
-			Sess->mlocaltime = AGWLocalTime;
-			Sess->MonitorNODES = AGWMonNodes;
-
-			Send_AGW_R_Frame(sender);			// Request Version
-			Send_AGW_m_Frame(sender);			// Request Monitor Frames
-		}
-	}
-}
-
-
-void QtTermTCP::ConnecttoAGW()
-{
-	delete(AGWSock);
-
-	AGWSock = new myTcpSocket();
-
-	connect(AGWSock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(AGWdisplayError(QAbstractSocket::SocketError)));
-	connect(AGWSock, SIGNAL(readyRead()), this, SLOT(AGWreadyRead()));
-	connect(AGWSock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onAGWSocketStateChanged(QAbstractSocket::SocketState)));
-
-	AGWSock->connectToHost(AGWHost, AGWPortNum);
-
-	Status1->setText("AGW Connecting");
-
-	return;
-}
-
-int AGWBeaconTimer = 0;
-
-
-void QtTermTCP::AGWTimer()
-{
-	// Runs every 10 Seconds
-
-	if (AGWConnected == 0 && AGWConnecting == 0)
-	{
-		AGWConnecting = true;
-		ConnecttoAGW();
-	}
-
-	if (AGWBeaconInterval)
-	{
-		AGWBeaconTimer++;
-
-		if (AGWBeaconTimer >= AGWBeaconInterval * 6)
-		{
-			AGWBeaconTimer = 0;
-
-			if (AGWConnected)
-				doAGWBeacon();
-		}
-	}
-}
-
-
-void AGW_del_socket(void * socket)
-{
-	if (AGWUsers->socket == socket)
-	{
-		free(AGWUsers);
-		AGWUsers = nullptr;
-	}
-}
-
-
-
-void AGW_add_socket(QTcpSocket * socket)
-{
-	AGWUser * User = (struct AGWUser_t *)malloc(sizeof(struct AGWUser_t));			// One Client
-	memset(User, 0, sizeof(struct AGWUser_t));
-
-	User->socket = socket;
-
-	AGWUsers = User;
-};
-
-void AGWWindowClosing(Ui_ListenSession *Sess)
-{
-	if (AGWUsers && AGWUsers->MonSess == Sess)
-		AGWUsers->MonSess = NULL;
-}
-
-
-
-void AGW_frame_header(UCHAR * Msg, char AGWPort, char DataKind, unsigned char PID, const char * CallFrom, const char * CallTo, int Len)
-{
-	struct AGWHeader * Hddr = (struct AGWHeader *)Msg;
-	memset(Hddr, 0, sizeof(struct AGWHeader));
-
-	Hddr->Port = AGWPort;
-	Hddr->DataLength = Len;
-	Hddr->DataKind = DataKind;
-	Hddr->PID = PID;
-	strcpy(Hddr->callfrom, CallFrom);
-	strcpy(Hddr->callto, CallTo);
-};
-
-
-/*
-
-// AGW to APP frames
-
-UCHAR * AGW_R_Frame()
-{
-	UCHAR * Msg = AGW_frame_header(0, 'R', 0, "", "", 8);
-
-//	stringAdd(Msg, (UCHAR *)AGWVersion, 8);
-
-	return Msg;
-};
-*/
-
-
-void Send_AGW_X_Frame(QTcpSocket* socket, char * CallFrom)
-{
-	UCHAR Msg[512];
-
-	AGW_frame_header(Msg, 0, 'X', 0, CallFrom, "", 0);
-	socket->write((char *)Msg, AGWHDDRRLEN);
-}
-
-void Send_AGW_G_Frame(QTcpSocket* socket)
-{
-	UCHAR Msg[512];
-
-	AGW_frame_header(Msg, 0, 'G', 0, "", "", 0);
-	socket->write((char *)Msg, AGWHDDRRLEN);
-}
-
-void Send_AGW_m_Frame(QTcpSocket* socket)
-{
-	UCHAR Msg[512];
-
-	// Request Monitoring. Add Extended form if connected to BPQ
-
-	AGW_frame_header(Msg, 0, 'm', 0, "", "", 12);
-
-	Msg[AGWHDDRRLEN] = AGWLocalTime;
-	Msg[AGWHDDRRLEN + 1] = AGWMonNodes;
-	Msg[AGWHDDRRLEN + 2] = AGWMonEnable;
-	Msg[AGWHDDRRLEN + 3] = 0;
-
-	memcpy(&Msg[AGWHDDRRLEN + 4], (void *)&AGWUsers->MonSess->portmask, 8);
-
-	socket->write((char *)Msg, AGWHDDRRLEN + 12);
-}
-
-void Send_AGW_R_Frame(QTcpSocket* socket)
-{
-	UCHAR Msg[512];
-
-	// Request Version
-
-	AGW_frame_header(Msg, 0, 'R', 0, "", "", 0);
-	socket->write((char *)Msg, AGWHDDRRLEN);
-}
-
-
-/*
-
-
-UCHAR * AGW_Y_Frame(int port, char * CallFrom, char *CallTo, int frame_outstanding)
-{
-	UCHAR * Msg;
-
-	Msg = AGW_frame_header(port, 'Y', 0, CallFrom, CallTo, 4);
-
-	stringAdd(Msg, (UCHAR *)&frame_outstanding, 4);
-	return Msg;
-}
-
-
-
-*/
-
-
-void Send_AGW_C_Frame(Ui_ListenSession * Sess, int Port, char * CallFrom, char * CallTo, char * Data, int DataLen)
-{
-	UCHAR Msg[512];
-	char Title[64];
-
-	// We should allocate a AGW session record
-
-	TAGWPort * AX25Sess;
-
-	// FIrst check that we don't already have a session between these calla
-
-	if (Port == -1)
-		return;
-
-	Debugprintf("Send_AGW_C_Frame");
-
-	AX25Sess = findSession(Port, CallTo, CallFrom);
-
-	if (AX25Sess)
-	{
-		// Seems this can be called twice
-		
-		if (Sess->AGWSession == nullptr)
-			QMessageBox::information(mythis, "QtTermTCP", "You already have a conenction to that call");
-		
-		return;
-	}
-
-	AX25Sess = get_free_port();
-
-	if (AX25Sess)
-	{
-		AX25Sess->Active = 1;
-		AX25Sess->port = Port;
-		AX25Sess->Sess = Sess;				// Crosslink AGW and Term Sessions
-		AX25Sess->PID = 240;
-
-		Sess->AGWSession = AX25Sess;
-
-		strcpy(AX25Sess->mycall, CallTo);
-		strcpy(AX25Sess->corrcall, CallFrom);
-
-		AX25Sess->socket = AGWSock;
-
-		if (DataLen)				// Digis so use 'v' frame
-		{
-			AGW_frame_header(Msg, Port, 'v', 240, CallFrom, CallTo, DataLen);
-			memcpy(&Msg[AGWHDDRRLEN], (UCHAR *)Data, DataLen);
-		}
-		else
-		{
-			AGW_frame_header(Msg, Port, 'C', 240, CallFrom, CallTo, DataLen);
-		}
-		
-		DataLen += AGWHDDRRLEN;
-	
-		AGWSock->write((char *)Msg, DataLen);
-
-		sprintf(Title, "Connecting to %s", CallTo);
-
-		if (TermMode == MDI)
-			Sess->setWindowTitle(Title);
-		else if (TermMode == Tabbed)
-			tabWidget->setTabText(Sess->Tab, "Connecting");
-		else if (TermMode == Single)
-			mythis->setWindowTitle(Title);
-
-	}
-}
-
-
-void Send_AGW_Ds_Frame(void * Sess)
-{
-	TAGWPort * AGW = (TAGWPort *)Sess;
-	UCHAR Msg[512];
-
-	AGW_frame_header(Msg, AGW->port, 'd', 240, AGW->corrcall, AGW->mycall, 0);
-	if (AGW->socket)
-		AGW->socket->write((char *)Msg, AGWHDDRRLEN);
-}
-
-
-
-void Send_AGW_D_Frame(TAGWPort * AGW, UCHAR * Data,  int DataLen)
-{
-	UCHAR Msg[512];
-
-	AGW_frame_header(Msg, AGW->port, 'D', AGW->PID, AGW->corrcall, AGW->mycall, DataLen);
-
-	memcpy(&Msg[AGWHDDRRLEN], Data, DataLen);
-
-	DataLen += AGWHDDRRLEN;
-
-	AGW->socket->write((char *)Msg, DataLen);
-}
-
-
-
-/*
-
-UCHAR * AGW_T_Frame(int port, char * CallFrom, char * CallTo, char * Data)
-{
-	UCHAR * Msg;
-	int DataLen;
-
-	DataLen = strlen(Data);
-
-	Msg = AGW_frame_header(port, 'T', 0, CallFrom, CallTo, DataLen);
-
-	stringAdd(Msg, (byte *)Data, DataLen);
-
-	return Msg;
-}
-
-// Raw Monitor 
-UCHAR * AGW_K_Frame(int port, int PID, char * CallFrom, char * CallTo, UCHAR * Data, int DataLen)
-{
-	UCHAR Msg[512];
-
-	DataLen = Data->Length;
-
-	AGW_frame_header(Msg, port, 'K', PID, CallFrom, CallTo, DataLen);
-
-//	stringAdd(Msg, Data->Data, Data->Length);
-
-//	freeString(Data);
-
-	return Msg;
-}
-
-// APP to AGW frames
-
-void on_AGW_P_frame(AGWUser * AGW)
-{
-	
-}
-
-*/
-
-void on_AGW_G_frame(unsigned char * Data)
-{
-	if (AGWPortList)
-		free(AGWPortList);
-	
-	AGWPortList = (char *)strdup((char *)Data);
-};
-
-/*
-
-void on_AGW_Ms_frame(AGWUser * AGW)
-{
-	AGW->Monitor ^= 1;				// Flip State
-}
-
-
-void on_AGW_R_frame(AGWUser * AGW)
-{
-//	AGW_send_to_app(AGW->socket, AGW_R_Frame());
-}
-
-
-
-void on_AGW_Y_frame(void * socket, int snd_ch, char * CallFrom, char * CallTo)
-{
-	int  frames;
-	TAGWPort * AX25Sess;
-
-//	AX25Sess = get_user_port_by_calls(snd_ch, CallFrom, CallTo);
-
-//	if (AX25Sess)
-//	{
-		//frames = AX25port[snd_ch][user_port].in_data_buf.Count;
-//		frames = AX25Sess->in_data_buf.Count + AX25Sess->I_frame_buf.Count;
-//		;
-//		AGW_send_to_app(socket, AGW_Y_Frame(snd_ch, CallFrom, CallTo, frames));
-//	}
-}
-
-// UI Transmit
-
-void on_AGW_M_frame(int port, byte PID, char * CallFrom, char *CallTo, byte *  Msg, int MsgLen)
-{
-	byte path[80];
-	char Calls[80];
-	UCHAR * Data = newString();
-
-	stringAdd(Data, Msg, MsgLen);
-
-	sprintf(Calls, "%s,%s", CallTo, CallFrom);
-
-	get_addr(Calls, 0, 0, path);
-
-	Add(&all_frame_buf[port],
-		make_frame(Data, path, PID, 0, 0, U_FRM, U_UI, FALSE, SET_F, SET_C));
-
-}
-
-*/
-void on_AGW_C_frame(AGWUser * AGW, struct AGWHeader * Frame, byte * Msg)
-{
-	int snd_ch = Frame->Port;
-	char * CallFrom = Frame->callfrom;
-	char * CallTo = Frame->callto;
-	char Title[64];
-	int i = 0;
-
-	TAGWPort * AX25Sess;
-
-	// Connection received - may be incoming or response to our connect
-
-		// See if incoming
-
-	if (strstr((char *)Msg, (const char *)"CONNECTED To"))
-	{
-		// incoming call
-
-		AX25Sess = get_free_port();
-
-		if (AX25Sess)
-		{
-			// Look for/create Terminal Window for connection
-
-			Ui_ListenSession * Sess = NULL;
-			Ui_ListenSession * S;
-
-
-			if (TermMode == MDI)
-			{
-				// See if an old session can be reused
-
-				for (int i = 0; i < _sessions.size(); ++i)
-				{
-					S = _sessions.at(i);
-
-					//	for (Ui_ListenSession * S: _sessions)
-					//	{
-					if ((S->SessionType & Listen) && S->clientSocket == NULL)
-					{
-						Sess = S;
-						break;
-					}
-				}
-
-				// Create a window if none found, else reuse old
-
-				if (Sess == NULL)
-				{
-					Sess = newWindow((QObject *)mythis, Listen, "");
-				}
-			}
-			else if (TermMode == Tabbed)
-			{
-				// Single Tabbed - look for free session
-
-
-				for (i = 0; i < _sessions.size(); ++i)
-				{
-					S = _sessions.at(i);
-
-					if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL)
-					{
-						Sess = S;
-						break;
-					}
-				}
-			}
-			else
-			{
-				// Single - Only one available
-				S = _sessions.at(0);
-
-				if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL)
-					Sess = S;
-			}
-
-			if (Sess == NULL)
-			{
-				// Clear connection by sendinf d fraame
-
-				UCHAR Msg[512];
-
-				int snd_ch = Frame->Port;
-				char * CallFrom = Frame->callfrom;
-				char * CallTo = Frame->callto;
-
-				AGW_frame_header(Msg, Frame->Port, 'd', 240, Frame->callto, Frame->callfrom, 0);
-				if (AGW->socket)
-					AGW->socket->write((char *)Msg, AGWHDDRRLEN);
-
-				return;
-			}
-		
-			if (Sess)
-			{
-				sprintf(Title, "Connected to %s", CallFrom);
-
-				QApplication::alert(mythis, 0);
-
-				if (TermMode == MDI)
-				{
-					Sess->setWindowTitle(Title);
-				}
-				else if (TermMode == Tabbed)
-				{
-					tabWidget->setTabText(i, CallFrom);
-					tabWidget->tabBar()->setTabTextColor(i, newTabText);
-				}
-
-				else if (TermMode == Single)
-					mythis->setWindowTitle(Title);
-
-				AX25Sess->Active = 1;
-				AX25Sess->port = snd_ch;
-				AX25Sess->Sess = Sess;				// Crosslink AGW and Term Sessions
-				AX25Sess->PID = 240;;
-
-				Sess->AGWSession = AX25Sess;
-
-				strcpy(AX25Sess->mycall, CallFrom);
-				strcpy(AX25Sess->corrcall, CallTo);
-
-				AX25Sess->socket = AGW->socket;
-
-				setMenus(true);
-
-				if (ConnectBeep)
-					myBeep(&ConnectWAV);
-
-				// Send CText if defined
-
-				if (listenCText[0])
-					Send_AGW_D_Frame(AX25Sess, (unsigned char *)listenCText, (int)strlen(listenCText));
-
-				// Send Message to Terminal
-
-				char Msg[80];
-
-				sprintf(Msg, "Incoming AGW Connection from %s\r\r", CallFrom);
-
-				WritetoOutputWindow(Sess, (unsigned char *)Msg, (int)strlen(Msg));
-				return;
-			}
-		}
-	}
-
-	// Reply to out connect request - look for our connection
-
-	AX25Sess = findSession(snd_ch, CallFrom, CallTo);
-
-	if (AX25Sess)
-	{
-		Ui_ListenSession * Sess = AX25Sess->Sess;
-
-		sprintf(Title, "Connected to %s", CallFrom);
-
-		if (TermMode == MDI)
-			Sess->setWindowTitle(Title);
-		else if (TermMode == Tabbed)
-			tabWidget->setTabText(Sess->Tab, CallFrom);
-		else if (TermMode == Single)
-			mythis->setWindowTitle(Title);
-
-		setMenus(true);
-
-		int Len = sprintf(Title, "*** Connected to %s\r", CallFrom);
-
-		ProcessReceivedData(Sess, (unsigned char *)Title, Len);
-	}
-
-}
-
-
-
-void on_AGW_D_frame(int snd_ch, char * CallFrom, char * CallTo, byte * Msg, int Len)
-{
-	TAGWPort * AX25Sess;
-
-	AX25Sess = findSession(snd_ch, CallFrom, CallTo);
-
-	if (AX25Sess)
-	{
-		ProcessReceivedData(AX25Sess->Sess, Msg, Len);
-	}
-}
-
-extern "C" void WritetoMonWindow(Ui_ListenSession * Sess, unsigned char * Msg, int len);
-
-void on_AGW_Mon_frame(byte * Msg, int Len, char Type)
-{
-	if (AGWUsers && AGWUsers->MonSess && AGWUsers->MonSess->monWindow)
-	{
-		unsigned char copy[512];
-
-		copy[0] = 0x1b;
-		if	(Type == 'T')
-			copy[1] = 91;
-		else
-			copy[1] = 17;
-
-		memcpy(&copy[2], Msg, Len);
-		WritetoMonWindow(AGWUsers->MonSess, copy, Len + 2);
-	}
-}
-
-
-
-void on_AGW_Ds_frame(int AGWChan, char * CallFrom, char * CallTo, struct AGWHeader * Frame)
-{
-	TAGWPort * AX25Sess;
-	char * Msg = (char *)Frame;
-	Msg = &Msg[36];
-
-	char Reply[128] = "";
-
-	memcpy(Reply, Msg, Frame->DataLength);
-
-	// Disconnect Sessiom
-
-	AX25Sess = findSession(AGWChan, CallFrom, CallTo);
-
-	if (AX25Sess)
-	{
-		Ui_ListenSession * Sess = AX25Sess->Sess;
-
-		WritetoOutputWindowEx(Sess, (unsigned char *)Reply, (int)strlen(Reply),
-			Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
-
-		if (TermMode == MDI)
-		{
-			if (Sess->SessionType == Mon)			// Mon Only
-				Sess->setWindowTitle("Monitor Session Disconnected");
-			else
-				Sess->setWindowTitle("Disconnected");
-		}
-		else if (TermMode == Tabbed)
-		{
-			if (Sess->SessionType == Mon)			// Mon Only
-				tabWidget->setTabText(Sess->Tab, "Monitor");
-			else
-			{
-				char Label[32];
-				sprintf(Label, "Sess %d", Sess->Tab + 1);
-				tabWidget->setTabText(Sess->Tab, Label);
-			}
-		}
-		else if (TermMode == Single)
-		{
-			if (Sess->SessionType == Mon)			// Mon Only
-				mythis->setWindowTitle("Monitor Session Disconnected");
-			else
-				mythis->setWindowTitle("Disconnected");
-		}
-
-		Sess->AGWSession = nullptr;
-		AX25Sess->Sess = nullptr;
-		AX25Sess->Active = 0;
-
-		setMenus(false);
-	}
-	else
-	{
-		// Session not found
-	}
-}
-
-
-void AGW_AX25_data_in(void  * Sess, UCHAR * data, int Len)
-{
-	TAGWPort * AX25Sess = (TAGWPort *)Sess;
-	int len = 250, sendlen;
-	UCHAR pkt[512];
-
-	while (Len)
-	{
-		if (Len > len)
-			sendlen = len;
-		else
-			sendlen = Len;
-
-		memcpy(pkt, data, sendlen);
-
-		Len -= sendlen;
-
-		memmove(data, &data[sendlen], Len);
-
-		Send_AGW_D_Frame(AX25Sess, pkt, sendlen);
-	}
-
-}
-
-
-/*
-
-void AGW_frame_monitor(byte snd_ch, byte * path, UCHAR * data, byte pid, byte nr, byte ns, byte f_type, byte f_id, byte  rpt, byte pf, byte cr, byte RX)
-{
-	char mon_frm[512];
-	char AGW_path[256];
-	UCHAR * AGW_data;
-
-	const char * frm;
-	byte * datap = data->Data;
-	byte _data[512];
-	byte * p_data = _data;
-	int _datalen;
-
-	char  agw_port;
-	char  CallFrom[10], CallTo[10], Digi[80];
-
-	int i;
-	const char * ctrl;
-	int len;
-
-	AGWUser * AGW;
-
-	UNUSED(rpt);
-
-	len = data->Length;
-
-	//	if (pid == 0xCF)
-	//		data = parse_NETROM(data, f_id);
-		// IP parsing
-	//	else if (pid == 0xCC)
-	//		data = parse_IP(data);
-		// ARP parsing
-	//	else if (pid == 0xCD)
-	//		data = parse_ARP(data);
-		//
-
-	if (len > 0)
-	{
-		for (i = 0; i < len; i++)
-		{
-			if (datap[i] > 31 || datap[i] == 13 || datap[i] == 9)
-				*(p_data++) = datap[i];
-		}
-	}
-
-	_datalen = p_data - _data;
-
-	if (_datalen)
-	{
-		byte * ptr = _data;
-		i = 0;
-
-		// remove successive cr or cr on end		while (i < _datalen)
-
-		while (i < _datalen)
-		{
-			if ((_data[i] == 13) && (_data[i + 1] = 13))
-				i++;
-			else
-				*(ptr++) = _data[i++];
-		}
-
-		if (*(ptr - 1) == 13)
-			ptr--;
-
-		*ptr = 0;
-
-		_datalen = ptr - _data;
-	}
-
-	agw_port = snd_ch;
-
-	get_monitor_path(path, CallTo, CallFrom, Digi);
-
-	ctrl = "";
-	frm = "";
-
-	switch (f_id)
-	{
-	case I_I:
-
-		frm = "I";
-		if (cr == SET_C && pf == SET_P)
-			ctrl = " P";
-
-		break;
-
-	case S_RR:
-
-		frm = "RR";
-		if (pf == SET_P)
-			ctrl = " P/F";
-
-		break;
-
-	case S_RNR:
-
-		frm = "RNR";
-		if (pf == SET_P)
-			ctrl = " P/F";
-
-		break;
-
-	case S_REJ:
-
-		frm = "REJ";
-		if (pf == SET_P)
-			ctrl = " P/F";
-
-		break;
-
-	case U_SABM:
-
-		frm = "SABM";
-		if (cr == SET_C && pf == SET_P)
-			ctrl = " P";
-
-		break;
-
-	case U_DISC:
-
-		frm = "DISC";
-		if (cr == SET_C && pf == SET_P)
-			ctrl = " P";
-		break;
-
-	case U_DM:
-
-		frm = "DM";
-		if ((cr == SET_R) && (pf == SET_P))
-			ctrl = " F ";
-		break;
-
-	case U_UA:
-
-		frm = "UA";
-		if ((cr == SET_R) && (pf == SET_P))
-			ctrl = " F ";
-
-		break;
-
-	case U_FRMR:
-
-		frm = "FRMR";
-		if ((cr == SET_R) && (pf == SET_P))
-			ctrl = " F ";
-		break;
-
-	case U_UI:
-
-		frm = "UI";
-		if ((pf == SET_P))
-			ctrl = " P/F";
-	}
-
-	if (Digi[0])
-		sprintf(AGW_path, " %d:Fm %s To %s Via %s <%s", snd_ch + 1, CallFrom, CallTo, Digi, frm);
-	else
-		sprintf(AGW_path, " %d:Fm %s To %s <%s", snd_ch + 1, CallFrom, CallTo, frm);
-
-
-	switch (f_type)
-	{
-	case I_FRM:
-
-		//mon_frm = AGW_path + ctrl + ' R' + inttostr(nr) + ' S' + inttostr(ns) + ' pid=' + dec2hex(pid) + ' Len=' + inttostr(len) + ' >' + time_now + #13 + _data + #13#13;
-		sprintf(mon_frm, "%s%s R%d S%d pid=%X Len=%d >[%s]\r%s\r", AGW_path, ctrl, nr, ns, pid, len, ShortDateTime(), _data);
-
-		break;
-
-	case U_FRM:
-
-		if (f_id == U_UI)
-		{
-			sprintf(mon_frm, "%s pid=%X Len=%d >[%s]\r%s\r", AGW_path, pid, len, ShortDateTime(), _data); // "= AGW_path + ctrl + '>' + time_now + #13;
-		}
-		else if (f_id == U_FRMR)
-		{
-			//			_data = copy(_data + #0#0#0, 1, 3);
-			//			mon_frm = AGW_path + ctrl + '>' + time_now + #13 + inttohex((byte(data[1]) shl 16) or (byte(data[2]) shl 8) or byte(data[3]), 6) + #13#13;
-		}
-		else
-			sprintf(mon_frm, "%s%s>[%s]\r", AGW_path, ctrl, ShortDateTime()); // "= AGW_path + ctrl + '>' + time_now + #13;
-
-		break;
-
-	case S_FRM:
-
-		//		mon_frm = AGW_path + ctrl + ' R' + inttostr(nr) + ' >' + time_now + #13;
-		sprintf(mon_frm, "%s%s R%d>[%s]\r", AGW_path, ctrl, nr, ShortDateTime()); // "= AGW_path + ctrl + '>' + time_now + #13;
-
-		break;
-
-	}
-
-	//	stringAdd(mon_frm, "", 1); //  Add 0 at the end of each frame
-
-		// I think we send to all AGW sockets
-
-	for (i = 0; i < AGWConCount; i++)
-	{
-		AGW = AGWUsers[i];
-
-		if (AGW->Monitor)
-		{
-			if (RX)
-			{
-				
-
-			case f_id of
-			  I_I   : AGW_data = AGW_I_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  S_RR  : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  S_RNR : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  S_REJ : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  U_SABM: AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  U_DISC: AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  U_DM  : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  U_UA  : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  U_FRMR: AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
-			  U_UI  : AGW_data = AGW_U_frame(agw_port,CallFrom,CallTo,mon_frm);
-
-							AGW_send_to_app(AGW->socket, AGW_data);
-
-			  
-			}
-			else
-			{
-				AGW_data = AGW_T_Frame(agw_port, CallFrom, CallTo, mon_frm);
-				AGW_send_to_app(AGW->socket, AGW_data);
-			}
-		}
-	}
-}
-
-*/
-
-
-
-
-void AGW_Process_Input(AGWUser * AGW)
-{
-	struct AGWHeader * Frame = (struct AGWHeader *)AGW->data_in;
-	byte * Data = &AGW->data_in[36];
-
-	switch (Frame->DataKind)
-	{
-	case 'P':
-
-//		on_AGW_P_frame(AGW);
-//		return;
-
-	case 'X':
-
-		// Registration response - no need to process
-
-		return;
-
-	case 'G':
-
-		on_AGW_G_frame(Data);
-		return;
-/*
-
-	case 'x':
-
-		on_AGW_Xs_frame(Frame->callfrom);
-		return;
-
-
-
-	case 'm':
-
-		on_AGW_Ms_frame(AGW);
-		return;
-
-	case 'R':
-
-		on_AGW_R_frame(AGW);
-		return;
-
-
-		//	'g': on_AGW_Gs_frame(AGW,Frame->Port);
-		//	'H': on_AGW_H_frame(AGW,Frame->Port);
-		//	'y': on_AGW_Ys_frame(AGW,Frame->Port);
-
-	case 'Y':
-		on_AGW_Y_frame(AGW->socket, Frame->Port, Frame->callfrom, Frame->callto);
-		break;
-
-	case 'M':
-
-		on_AGW_M_frame(Frame->Port, Frame->PID, Frame->callfrom, Frame->callto, Data, Frame->DataLength);
-		break;
-*/
-
-	case 'C':
-//	case 'v':				// Call with digis
-
-		on_AGW_C_frame(AGW, Frame, Data);
-		return;
-	
-	
-	case 'D':
-
-		on_AGW_D_frame(Frame->Port, Frame->callfrom, Frame->callto, Data, Frame->DataLength);
-		return;
-
-	case 'd':
-
-		on_AGW_Ds_frame(Frame->Port, Frame->callfrom, Frame->callto, Frame);
-		return;
-
-	case 'U':
-	case 'S':
-	case 'I':
-	case 'T':
-
-			// Monitor Data
-
-			if (AGWMonEnable)
-				on_AGW_Mon_frame(Data, Frame->DataLength, Frame->DataKind);
-		
-			return;
-
-/*
-
-		//	'V': on_AGW_V_frame(AGW,Frame->Port,PID,CallFrom,CallTo,Data);
-		//	'c': on_AGW_Cs_frame(sAGWocket,Frame->Port,PID,CallFrom,CallTo);
-
-
-	case 'K':
-
-		on_AGW_K_frame(Frame);
-		return;
-
-	case 'k':
-		on_AGW_Ks_frame(AGW);
-		return;
-		*/
-	default:
-		Debugprintf("AGW %c", Frame->DataKind);
-	}
-}
+// AGW Interface
+
+#include "QtTermTCP.h"
+#include "TabDialog.h"
+#include <time.h>
+#include <QVBoxLayout>
+#include <QLabel>
+
+#ifndef WIN32
+#define strtok_s strtok_r
+#endif
+
+#define UCHAR unsigned char
+#define byte unsigned char
+
+myTcpSocket * AGWSock;
+
+extern QColor monRxText;
+extern QColor monTxText;
+
+extern QColor outputText;
+extern QColor EchoText;
+extern QColor WarningText;
+
+extern QColor newTabText;
+
+extern QTabWidget *tabWidget;
+extern QWidget * mythis;
+
+extern int AGWEnable;
+extern int AGWMonEnable;
+extern int AGWLocalTime;
+extern int AGWMonNodes;
+extern char AGWTermCall[12];
+extern char AGWBeaconDest[12];
+extern char AGWBeaconPath[80];
+extern int AGWBeaconInterval;
+extern char AGWBeaconPorts[80];
+extern char AGWBeaconMsg[260];
+
+extern char AGWHost[128];
+extern int AGWPortNum;
+extern int AGWPaclen;
+
+extern Ui_ListenSession * KISSMonSess;
+
+extern char listenCText[4096];
+extern int ConnectBeep;
+
+extern QList<Ui_ListenSession *> _sessions;
+
+extern QLabel * Status1;
+extern QLabel * Status2;
+extern QLabel * Status3;
+extern QLabel * Status4;
+
+extern QMenu *connectMenu;
+extern QAction *discAction;
+extern QAction *YAPPSend;
+
+extern QAction *actHost[17];
+
+// Session Type Equates
+
+#define Term 1
+#define Mon 2
+#define Listen 4
+
+extern int TermMode;
+
+#define Single 0
+#define MDI 1
+#define Tabbed 2
+
+extern int singlemodeFormat;
+
+typedef struct AGWUser_t
+{
+	QTcpSocket *socket;
+	unsigned char data_in[8192];
+	int data_in_len;
+	unsigned char  AGW_frame_buf[512];
+	int	Monitor;
+	int	Monitor_raw;
+	Ui_ListenSession * MonSess;			// Window for Monitor info
+
+} AGWUser;
+
+
+struct AGWHeader
+{
+	int Port;
+	unsigned char DataKind;
+	unsigned char filler2;
+	unsigned char PID;
+	unsigned char filler3;
+	char callfrom[10];
+	char callto[10];
+	int DataLength;
+	int reserved;
+};
+
+#define AGWHDDRRLEN sizeof(struct AGWHeader)
+
+typedef struct TAGWPort_t
+{
+	byte PID;
+	int port;
+	char corrcall[10];
+	char mycall[10];
+	int Active;
+	QTcpSocket * socket;
+	Ui_ListenSession * Sess;			// Terminal Session
+
+} TAGWPort;
+
+
+int AGWConnected = 0;
+int AGWConnecting = 0;
+
+char * AGWPortList = NULL;
+
+#define max_sessions 8
+
+TAGWPort AGWPort[max_sessions];
+
+#define    LSB 29
+#define    MSB 30
+#define    MON_ON '1'
+#define    MON_OFF '0'
+#define    MODE_OUR 0
+#define    MODE_OTHER 1
+#define    MODE_RETRY 2
+
+// Don't think we will support more than one, but leave in option
+
+AGWUser *AGWUsers = NULL;				// List of currently connected clients
+
+void AGW_add_socket(QTcpSocket * socket);
+void AGW_Process_Input(AGWUser * AGW);
+void Send_AGW_X_Frame(QTcpSocket* socket, char * CallFrom);
+void Send_AGW_G_Frame(QTcpSocket* socket); 
+void Send_AGW_m_Frame(QTcpSocket* socket);
+void Send_AGW_R_Frame(QTcpSocket* socket);
+
+Ui_ListenSession * FindFreeWindow();
+Ui_ListenSession * newWindow(QObject * parent, int Type, const char * Label = nullptr);
+void AGW_frame_header(UCHAR * Msg, char AGWPort, char DataKind, unsigned char PID, const char * CallFrom, const char * CallTo, int Len);
+
+
+void Debugprintf(const char * format, ...)
+{
+	char Mess[10000];
+	va_list arglist;
+
+	va_start(arglist, format);
+	vsprintf(Mess, format, arglist);
+	qDebug() << Mess;
+
+	return;
+}
+
+int ConvToAX25(char * callsign, unsigned char * ax25call)
+{
+	int i;
+
+	memset(ax25call, 0x40, 6);		// in case short
+	ax25call[6] = 0x60;				// default SSID
+
+	for (i = 0; i < 7; i++)
+	{
+		if (callsign[i] == '-')
+		{
+			//
+			//	process ssid and return
+			//
+			i = atoi(&callsign[i + 1]);
+
+			if (i < 16)
+			{
+				ax25call[6] |= i << 1;
+				return (1);
+			}
+			return (0);
+		}
+
+		if (callsign[i] == 0 || callsign[i] == 13 || callsign[i] == ' ' || callsign[i] == ',')
+		{
+			//
+			//	End of call - no ssid
+			//
+			return (1);
+		}
+
+		ax25call[i] = callsign[i] << 1;
+	}
+
+	//
+	//	Too many chars
+	//
+
+	return (0);
+}
+
+
+int ConvFromAX25(unsigned char * incall, char * outcall)
+{
+	int in, out = 0;
+	unsigned char chr;
+
+	memset(outcall, 0x20, 10);
+
+	for (in = 0; in < 6; in++)
+	{
+		chr = incall[in];
+		if (chr == 0x40)
+			break;
+		chr >>= 1;
+		outcall[out++] = chr;
+	}
+
+	chr = incall[6];				// ssid
+
+	if (chr == 0x42)
+	{
+		outcall[out++] = '-';
+		outcall[out++] = 'T';
+		return out;
+	}
+
+	if (chr == 0x44)
+	{
+		outcall[out++] = '-';
+		outcall[out++] = 'R';
+		return out;
+	}
+
+	chr >>= 1;
+	chr &= 15;
+
+	if (chr > 0)
+	{
+		outcall[out++] = '-';
+		if (chr > 9)
+		{
+			chr -= 10;
+			outcall[out++] = '1';
+		}
+		chr += 48;
+		outcall[out++] = chr;
+	}
+	return (out);
+}
+
+void doAGWBeacon()
+{
+	if (AGWBeaconDest[0] && AGWBeaconPorts[0])
+	{
+		// Send as M or V depending on Digis
+
+		UCHAR Msg[512];	
+		char ports[80];
+
+		char * ptr, * context;
+		int DataLen;
+
+		strcpy(ports, AGWBeaconPorts);			// strtok changes it
+
+
+		// Replace newlines with CR
+
+		while ((ptr = strchr(AGWBeaconMsg, 10)))
+			*ptr = 13;
+
+		ptr = strtok_s(ports, " ,", &context);
+
+		if (AGWBeaconPath[0])
+		{
+
+		}
+		else
+		{
+			while (ptr)
+			{
+				DataLen = (int)strlen(AGWBeaconMsg);
+
+				AGW_frame_header(Msg, atoi(ptr) - 1, 'M', 240, AGWTermCall, AGWBeaconDest, DataLen);
+				memcpy(&Msg[AGWHDDRRLEN], AGWBeaconMsg, DataLen);
+				DataLen += AGWHDDRRLEN;
+				AGWSock->write((char *)Msg, DataLen);
+
+				ptr = strtok_s(NULL, " ,",  &context);
+			}
+		}
+	}
+}
+
+TAGWPort * get_free_port()
+{
+	int i = 0;
+
+	while (i < max_sessions)
+	{
+		if (AGWPort[i].Active == 0)
+			return &AGWPort[i];
+
+		i++;
+	}
+	return nullptr;
+}
+
+TAGWPort * findSession(int AGWChan, char * MyCall, char * OtherCall)
+{
+	int i = 0;
+
+	TAGWPort * Sess = nullptr;
+
+	while (i < max_sessions)
+	{
+		Sess = &AGWPort[i];
+
+		if (Sess->Active && Sess->port == AGWChan && strcmp(Sess->corrcall, OtherCall) == 0 && strcmp(Sess->mycall, MyCall) == 0)
+			return Sess;
+
+		i++;
+	}
+	return nullptr;
+}
+
+
+
+void QtTermTCP::AGWdisplayError(QAbstractSocket::SocketError socketError)
+{
+	switch (socketError)
+	{
+	case QAbstractSocket::RemoteHostClosedError:
+		break;
+
+	case QAbstractSocket::HostNotFoundError:
+		QMessageBox::information(this, tr("QtTermTCP"),
+			tr("AGW host was not found. Please check the "
+				"host name and port settings."));
+
+		Status1->setText("AGW Connection Failed");
+
+		break;
+
+	case QAbstractSocket::ConnectionRefusedError:
+
+		Status1->setText("AGW Connection Refused");
+		break;
+
+	default:
+
+		Status1->setText("AGW Connection Failed");
+	}
+
+	AGWConnecting = 0;
+	AGWConnected = 0;
+}
+
+void QtTermTCP::AGWreadyRead()
+{
+	int Read;
+	unsigned char Buffer[4096];
+	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
+
+	// read the data from the socket
+
+	Read = Socket->read((char *)Buffer, 4095);
+
+	int AGWHeaderLen = sizeof(struct AGWHeader);
+
+	AGWUser * AGW = NULL;
+
+	AGW = AGWUsers;
+
+	if (AGW == NULL)
+		return;
+
+	memcpy(&AGW->data_in[AGW->data_in_len], Buffer, Read);
+
+	AGW->data_in_len += Read;
+
+	while (AGW->data_in_len >= AGWHeaderLen)		// Make sure have at least header
+	{
+		struct AGWHeader * Hddr = (struct AGWHeader *)AGW->data_in;
+
+		int AgwLen = Hddr->DataLength + AGWHeaderLen;
+
+		if (AGW->data_in_len >= AgwLen)
+		{
+			// Have frame as well
+
+			AGW_Process_Input(AGW);
+
+			AGW->data_in_len -= AgwLen;
+
+			memmove(AGW->data_in, &AGW->data_in[AgwLen], AGW->data_in_len);
+		}
+		else
+			return;					// Wait for the data
+	}
+
+}
+
+void QtTermTCP::onAGWSocketStateChanged(QAbstractSocket::SocketState socketState)
+{
+	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
+	Ui_ListenSession * Sess = (Ui_ListenSession *)sender->Sess;
+	int i;
+
+	if (socketState == QAbstractSocket::UnconnectedState)
+	{
+		// Close any connections
+
+		Status1->setText("AGW Disconnected");
+		actHost[16]->setVisible(0);
+
+		int i = 0;
+
+		TAGWPort * AGW = nullptr;
+
+		for (i = 0; i < max_sessions; i++)
+		{
+			AGW = &AGWPort[i];
+
+			if (AGW->Active && AGW->socket)
+			{
+				AGW->Active = 0;
+				AGW->socket = nullptr;
+
+				Sess = AGW->Sess;
+
+				if (Sess)
+				{
+					// Send Disconnected
+
+					char Msg[] = "Disconnected\r";
+
+					WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+						Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
+
+					if (TermMode == MDI)
+					{
+						if (Sess->SessionType == Mon)			// Mon Only
+							Sess->setWindowTitle("Monitor Session Disconnected");
+						else
+							Sess->setWindowTitle("Disconnected");
+					}
+					else if (TermMode == Tabbed)
+					{
+						if (Sess->SessionType == Mon)			// Mon Only
+							tabWidget->setTabText(Sess->Tab, "Monitor");
+						else
+						{
+							char Label[32];
+							sprintf(Label, "Sess %d", Sess->Tab + 1);
+							tabWidget->setTabText(Sess->Tab, Label);
+						}
+					}
+					else if (TermMode == Single)
+					{
+						if (Sess->SessionType == Mon)			// Mon Only
+							mythis->setWindowTitle("Monitor Session Disconnected");
+						else
+							mythis->setWindowTitle("Disconnected");
+					}
+
+					setMenus(false);	
+					
+					// if Single Split or Monitor leave session allocated to AGW
+
+					if (TermMode == Single && (Sess->SessionType & Mon))
+					{
+						return;
+					}
+
+					Sess->AGWSession = nullptr;
+					AGW->Sess = nullptr;
+				}
+			}
+		}
+
+		// Free the monitor Window
+
+		if (AGWUsers && AGWUsers->MonSess)
+		{
+			Sess = AGWUsers->MonSess;
+
+			char Msg[] = "Disconnected\r";
+
+			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+				Sess->monWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
+
+			if (TermMode == MDI)
+				Sess->setWindowTitle("Monitor Session Disconnected");
+
+			else if (TermMode == Tabbed)
+				tabWidget->setTabText(Sess->Tab, "Monitor");
+
+			Sess->AGWSession = nullptr;
+			AGWUsers->MonSess = nullptr;
+		}
+
+		if (TermMode == Single && (singlemodeFormat & Mon))
+		{
+			//Re-renable TCP connects
+
+			for (int i = 0; i < MAXHOSTS; i++)
+				actHost[i]->setVisible(1);
+		}
+
+
+		AGWConnected = 0;
+	}
+	else if (socketState == QAbstractSocket::ConnectedState)
+	{
+		AGWConnected = 1;
+		AGWConnecting = 0;
+
+		Status1->setText("AGW Connected");
+
+		AGW_add_socket(sender);
+
+		actHost[16]->setVisible(1);			// Enable AGW Connect Line
+
+		// Send X frame to register Term Call
+
+		if (AGWTermCall[0])
+			Send_AGW_X_Frame(sender, AGWTermCall);
+
+		Send_AGW_G_Frame(sender);					// Request Port List
+
+		// Attach a Monitor Window if available
+
+		Ui_ListenSession * Sess = NULL;
+		Ui_ListenSession * S;
+
+		if (TermMode == MDI)
+		{
+			// See if an old session can be reused
+
+			for (int i = 0; i < _sessions.size(); ++i)
+			{
+				S = _sessions.at(i);
+
+				//	for (Ui_ListenSession * S: _sessions)
+				//	{
+				if ((S->SessionType == Mon) && S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
+				{
+					Sess = S;
+					break;
+				}
+			}
+
+			// Create a window if none found, else reuse old
+
+			if (Sess == NULL)
+			{
+				Sess = newWindow((QObject *)mythis, Mon, "");
+			}
+		}
+		else if (TermMode == Tabbed)
+		{
+			// Tabbed - look for free session
+
+			for (i = 8; i; i--)
+			{
+				S = _sessions.at(i);
+
+				if (S->clientSocket == NULL && S->KISSSession == NULL && S->AGWSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
+				{
+					Sess = S;
+					break;
+				}
+			}
+		}
+		else if (TermMode == Single && (singlemodeFormat & Mon))
+		{
+			S = _sessions.at(0);
+
+			if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
+				Sess = S;
+
+		}
+
+		if (Sess)
+		{
+			AGWUsers->MonSess = Sess;
+//			Sess->AGWSession = sender;			// Flag as in use
+
+			if (TermMode == MDI)
+				Sess->setWindowTitle("AGW Monitor Window");
+			else if (TermMode == Tabbed)
+				tabWidget->setTabText(Sess->Tab, "AGW Mon");
+			else if (TermMode == Single)
+				mythis->setWindowTitle("AGW Monitor Window");
+
+			if (TermMode == Single && (singlemodeFormat & Mon))
+			{
+				// Can't be connected, so leave state alone, but disable TCP connects
+
+				for (int i = 0; i < MAXHOSTS; i++)
+					actHost[i]->setVisible(0);
+
+			}
+			else if (TermMode != Tabbed)				// Not ideal, but AGW mon window is unlikely to be active window
+			{
+				discAction->setEnabled(false);
+				YAPPSend->setEnabled(false);
+				connectMenu->setEnabled(false);
+			}
+
+			Sess->mlocaltime = AGWLocalTime;
+			Sess->MonitorNODES = AGWMonNodes;
+
+			Send_AGW_R_Frame(sender);			// Request Version
+			Send_AGW_m_Frame(sender);			// Request Monitor Frames
+		}
+	}
+}
+
+
+void QtTermTCP::ConnecttoAGW()
+{
+	delete(AGWSock);
+
+	AGWSock = new myTcpSocket();
+
+	connect(AGWSock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(AGWdisplayError(QAbstractSocket::SocketError)));
+	connect(AGWSock, SIGNAL(readyRead()), this, SLOT(AGWreadyRead()));
+	connect(AGWSock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onAGWSocketStateChanged(QAbstractSocket::SocketState)));
+
+	AGWSock->connectToHost(AGWHost, AGWPortNum);
+
+	Status1->setText("AGW Connecting");
+
+	return;
+}
+
+int AGWBeaconTimer = 0;
+
+
+void QtTermTCP::AGWTimer()
+{
+	// Runs every 10 Seconds
+
+	if (AGWConnected == 0 && AGWConnecting == 0)
+	{
+		AGWConnecting = true;
+		ConnecttoAGW();
+	}
+
+	if (AGWBeaconInterval)
+	{
+		AGWBeaconTimer++;
+
+		if (AGWBeaconTimer >= AGWBeaconInterval * 6)
+		{
+			AGWBeaconTimer = 0;
+
+			if (AGWConnected)
+				doAGWBeacon();
+		}
+	}
+}
+
+
+void AGW_del_socket(void * socket)
+{
+	if (AGWUsers->socket == socket)
+	{
+		free(AGWUsers);
+		AGWUsers = nullptr;
+	}
+}
+
+
+
+void AGW_add_socket(QTcpSocket * socket)
+{
+	AGWUser * User = (struct AGWUser_t *)malloc(sizeof(struct AGWUser_t));			// One Client
+	memset(User, 0, sizeof(struct AGWUser_t));
+
+	User->socket = socket;
+
+	AGWUsers = User;
+};
+
+void AGWWindowClosing(Ui_ListenSession *Sess)
+{
+	if (AGWUsers && AGWUsers->MonSess == Sess)
+		AGWUsers->MonSess = NULL;
+}
+
+
+
+void AGW_frame_header(UCHAR * Msg, char AGWPort, char DataKind, unsigned char PID, const char * CallFrom, const char * CallTo, int Len)
+{
+	struct AGWHeader * Hddr = (struct AGWHeader *)Msg;
+	memset(Hddr, 0, sizeof(struct AGWHeader));
+
+	Hddr->Port = AGWPort;
+	Hddr->DataLength = Len;
+	Hddr->DataKind = DataKind;
+	Hddr->PID = PID;
+	strcpy(Hddr->callfrom, CallFrom);
+	strcpy(Hddr->callto, CallTo);
+};
+
+
+/*
+
+// AGW to APP frames
+
+UCHAR * AGW_R_Frame()
+{
+	UCHAR * Msg = AGW_frame_header(0, 'R', 0, "", "", 8);
+
+//	stringAdd(Msg, (UCHAR *)AGWVersion, 8);
+
+	return Msg;
+};
+*/
+
+
+void Send_AGW_X_Frame(QTcpSocket* socket, char * CallFrom)
+{
+	UCHAR Msg[512];
+
+	AGW_frame_header(Msg, 0, 'X', 0, CallFrom, "", 0);
+	socket->write((char *)Msg, AGWHDDRRLEN);
+}
+
+void Send_AGW_G_Frame(QTcpSocket* socket)
+{
+	UCHAR Msg[512];
+
+	AGW_frame_header(Msg, 0, 'G', 0, "", "", 0);
+	socket->write((char *)Msg, AGWHDDRRLEN);
+}
+
+void Send_AGW_m_Frame(QTcpSocket* socket)
+{
+	UCHAR Msg[512];
+
+	// Request Monitoring. Add Extended form if connected to BPQ
+
+	AGW_frame_header(Msg, 0, 'm', 0, "", "", 12);
+
+	Msg[AGWHDDRRLEN] = AGWLocalTime;
+	Msg[AGWHDDRRLEN + 1] = AGWMonNodes;
+	Msg[AGWHDDRRLEN + 2] = AGWMonEnable;
+	Msg[AGWHDDRRLEN + 3] = 0;
+
+	memcpy(&Msg[AGWHDDRRLEN + 4], (void *)&AGWUsers->MonSess->portmask, 8);
+
+	socket->write((char *)Msg, AGWHDDRRLEN + 12);
+}
+
+void Send_AGW_R_Frame(QTcpSocket* socket)
+{
+	UCHAR Msg[512];
+
+	// Request Version
+
+	AGW_frame_header(Msg, 0, 'R', 0, "", "", 0);
+	socket->write((char *)Msg, AGWHDDRRLEN);
+}
+
+
+/*
+
+
+UCHAR * AGW_Y_Frame(int port, char * CallFrom, char *CallTo, int frame_outstanding)
+{
+	UCHAR * Msg;
+
+	Msg = AGW_frame_header(port, 'Y', 0, CallFrom, CallTo, 4);
+
+	stringAdd(Msg, (UCHAR *)&frame_outstanding, 4);
+	return Msg;
+}
+
+
+
+*/
+
+
+void Send_AGW_C_Frame(Ui_ListenSession * Sess, int Port, char * CallFrom, char * CallTo, char * Data, int DataLen)
+{
+	UCHAR Msg[512];
+	char Title[64];
+
+	// We should allocate a AGW session record
+
+	TAGWPort * AX25Sess;
+
+	// FIrst check that we don't already have a session between these calla
+
+	if (Port == -1)
+		return;
+
+	Debugprintf("Send_AGW_C_Frame");
+
+	AX25Sess = findSession(Port, CallTo, CallFrom);
+
+	if (AX25Sess)
+	{
+		// Seems this can be called twice
+		
+		if (Sess->AGWSession == nullptr)
+			QMessageBox::information(mythis, "QtTermTCP", "You already have a conenction to that call");
+		
+		return;
+	}
+
+	AX25Sess = get_free_port();
+
+	if (AX25Sess)
+	{
+		AX25Sess->Active = 1;
+		AX25Sess->port = Port;
+		AX25Sess->Sess = Sess;				// Crosslink AGW and Term Sessions
+		AX25Sess->PID = 240;
+
+		Sess->AGWSession = AX25Sess;
+
+		strcpy(AX25Sess->mycall, CallTo);
+		strcpy(AX25Sess->corrcall, CallFrom);
+
+		AX25Sess->socket = AGWSock;
+
+		if (DataLen)				// Digis so use 'v' frame
+		{
+			AGW_frame_header(Msg, Port, 'v', 240, CallFrom, CallTo, DataLen);
+			memcpy(&Msg[AGWHDDRRLEN], (UCHAR *)Data, DataLen);
+		}
+		else
+		{
+			AGW_frame_header(Msg, Port, 'C', 240, CallFrom, CallTo, DataLen);
+		}
+		
+		DataLen += AGWHDDRRLEN;
+	
+		AGWSock->write((char *)Msg, DataLen);
+
+		sprintf(Title, "Connecting to %s", CallTo);
+
+		if (TermMode == MDI)
+			Sess->setWindowTitle(Title);
+		else if (TermMode == Tabbed)
+			tabWidget->setTabText(Sess->Tab, "Connecting");
+		else if (TermMode == Single)
+			mythis->setWindowTitle(Title);
+
+	}
+}
+
+
+void Send_AGW_Ds_Frame(void * Sess)
+{
+	TAGWPort * AGW = (TAGWPort *)Sess;
+	UCHAR Msg[512];
+
+	AGW_frame_header(Msg, AGW->port, 'd', 240, AGW->corrcall, AGW->mycall, 0);
+	if (AGW->socket)
+		AGW->socket->write((char *)Msg, AGWHDDRRLEN);
+}
+
+
+
+void Send_AGW_D_Frame(TAGWPort * AGW, UCHAR * Data,  int DataLen)
+{
+	UCHAR Msg[512];
+
+	AGW_frame_header(Msg, AGW->port, 'D', AGW->PID, AGW->corrcall, AGW->mycall, DataLen);
+
+	memcpy(&Msg[AGWHDDRRLEN], Data, DataLen);
+
+	DataLen += AGWHDDRRLEN;
+
+	AGW->socket->write((char *)Msg, DataLen);
+}
+
+
+
+/*
+
+UCHAR * AGW_T_Frame(int port, char * CallFrom, char * CallTo, char * Data)
+{
+	UCHAR * Msg;
+	int DataLen;
+
+	DataLen = strlen(Data);
+
+	Msg = AGW_frame_header(port, 'T', 0, CallFrom, CallTo, DataLen);
+
+	stringAdd(Msg, (byte *)Data, DataLen);
+
+	return Msg;
+}
+
+// Raw Monitor 
+UCHAR * AGW_K_Frame(int port, int PID, char * CallFrom, char * CallTo, UCHAR * Data, int DataLen)
+{
+	UCHAR Msg[512];
+
+	DataLen = Data->Length;
+
+	AGW_frame_header(Msg, port, 'K', PID, CallFrom, CallTo, DataLen);
+
+//	stringAdd(Msg, Data->Data, Data->Length);
+
+//	freeString(Data);
+
+	return Msg;
+}
+
+// APP to AGW frames
+
+void on_AGW_P_frame(AGWUser * AGW)
+{
+	
+}
+
+*/
+
+void on_AGW_G_frame(unsigned char * Data)
+{
+	if (AGWPortList)
+		free(AGWPortList);
+	
+	AGWPortList = (char *)strdup((char *)Data);
+};
+
+/*
+
+void on_AGW_Ms_frame(AGWUser * AGW)
+{
+	AGW->Monitor ^= 1;				// Flip State
+}
+
+
+void on_AGW_R_frame(AGWUser * AGW)
+{
+//	AGW_send_to_app(AGW->socket, AGW_R_Frame());
+}
+
+
+
+void on_AGW_Y_frame(void * socket, int snd_ch, char * CallFrom, char * CallTo)
+{
+	int  frames;
+	TAGWPort * AX25Sess;
+
+//	AX25Sess = get_user_port_by_calls(snd_ch, CallFrom, CallTo);
+
+//	if (AX25Sess)
+//	{
+		//frames = AX25port[snd_ch][user_port].in_data_buf.Count;
+//		frames = AX25Sess->in_data_buf.Count + AX25Sess->I_frame_buf.Count;
+//		;
+//		AGW_send_to_app(socket, AGW_Y_Frame(snd_ch, CallFrom, CallTo, frames));
+//	}
+}
+
+// UI Transmit
+
+void on_AGW_M_frame(int port, byte PID, char * CallFrom, char *CallTo, byte *  Msg, int MsgLen)
+{
+	byte path[80];
+	char Calls[80];
+	UCHAR * Data = newString();
+
+	stringAdd(Data, Msg, MsgLen);
+
+	sprintf(Calls, "%s,%s", CallTo, CallFrom);
+
+	get_addr(Calls, 0, 0, path);
+
+	Add(&all_frame_buf[port],
+		make_frame(Data, path, PID, 0, 0, U_FRM, U_UI, FALSE, SET_F, SET_C));
+
+}
+
+*/
+void on_AGW_C_frame(AGWUser * AGW, struct AGWHeader * Frame, byte * Msg)
+{
+	int snd_ch = Frame->Port;
+	char * CallFrom = Frame->callfrom;
+	char * CallTo = Frame->callto;
+	char Title[64];
+	int i = 0;
+
+	TAGWPort * AX25Sess;
+
+	// Connection received - may be incoming or response to our connect
+
+		// See if incoming
+
+	if (strstr((char *)Msg, (const char *)"CONNECTED To"))
+	{
+		// incoming call
+
+		AX25Sess = get_free_port();
+
+		if (AX25Sess)
+		{
+			// Look for/create Terminal Window for connection
+
+			Ui_ListenSession * Sess = NULL;
+			Ui_ListenSession * S;
+
+
+			if (TermMode == MDI)
+			{
+				// See if an old session can be reused
+
+				for (int i = 0; i < _sessions.size(); ++i)
+				{
+					S = _sessions.at(i);
+
+					//	for (Ui_ListenSession * S: _sessions)
+					//	{
+					if ((S->SessionType & Listen) && S->clientSocket == NULL)
+					{
+						Sess = S;
+						break;
+					}
+				}
+
+				// Create a window if none found, else reuse old
+
+				if (Sess == NULL)
+				{
+					Sess = newWindow((QObject *)mythis, Listen, "");
+				}
+			}
+			else if (TermMode == Tabbed)
+			{
+				// Single Tabbed - look for free session
+
+
+				for (i = 0; i < _sessions.size(); ++i)
+				{
+					S = _sessions.at(i);
+
+					if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL)
+					{
+						Sess = S;
+						break;
+					}
+				}
+			}
+			else
+			{
+				// Single - Only one available
+				S = _sessions.at(0);
+
+				if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL)
+					Sess = S;
+			}
+
+			if (Sess == NULL)
+			{
+				// Clear connection by sendinf d fraame
+
+				UCHAR Msg[512];
+
+				int snd_ch = Frame->Port;
+				char * CallFrom = Frame->callfrom;
+				char * CallTo = Frame->callto;
+
+				AGW_frame_header(Msg, Frame->Port, 'd', 240, Frame->callto, Frame->callfrom, 0);
+				if (AGW->socket)
+					AGW->socket->write((char *)Msg, AGWHDDRRLEN);
+
+				return;
+			}
+		
+			if (Sess)
+			{
+				sprintf(Title, "Connected to %s", CallFrom);
+
+				QApplication::alert(mythis, 0);
+
+				if (TermMode == MDI)
+				{
+					Sess->setWindowTitle(Title);
+				}
+				else if (TermMode == Tabbed)
+				{
+					tabWidget->setTabText(i, CallFrom);
+					tabWidget->tabBar()->setTabTextColor(i, newTabText);
+				}
+
+				else if (TermMode == Single)
+					mythis->setWindowTitle(Title);
+
+				AX25Sess->Active = 1;
+				AX25Sess->port = snd_ch;
+				AX25Sess->Sess = Sess;				// Crosslink AGW and Term Sessions
+				AX25Sess->PID = 240;;
+
+				Sess->AGWSession = AX25Sess;
+
+				strcpy(AX25Sess->mycall, CallFrom);
+				strcpy(AX25Sess->corrcall, CallTo);
+
+				AX25Sess->socket = AGW->socket;
+
+				setMenus(true);
+
+				if (ConnectBeep)
+					myBeep(&ConnectWAV);
+
+				// Send CText if defined
+
+				if (listenCText[0])
+					Send_AGW_D_Frame(AX25Sess, (unsigned char *)listenCText, (int)strlen(listenCText));
+
+				// Send Message to Terminal
+
+				char Msg[80];
+
+				sprintf(Msg, "Incoming AGW Connection from %s\r\r", CallFrom);
+
+				WritetoOutputWindow(Sess, (unsigned char *)Msg, (int)strlen(Msg));
+				return;
+			}
+		}
+	}
+
+	// Reply to out connect request - look for our connection
+
+	AX25Sess = findSession(snd_ch, CallFrom, CallTo);
+
+	if (AX25Sess)
+	{
+		Ui_ListenSession * Sess = AX25Sess->Sess;
+
+		sprintf(Title, "Connected to %s", CallFrom);
+
+		if (TermMode == MDI)
+			Sess->setWindowTitle(Title);
+		else if (TermMode == Tabbed)
+			tabWidget->setTabText(Sess->Tab, CallFrom);
+		else if (TermMode == Single)
+			mythis->setWindowTitle(Title);
+
+		setMenus(true);
+
+		int Len = sprintf(Title, "*** Connected to %s\r", CallFrom);
+
+		ProcessReceivedData(Sess, (unsigned char *)Title, Len);
+	}
+
+}
+
+
+
+void on_AGW_D_frame(int snd_ch, char * CallFrom, char * CallTo, byte * Msg, int Len)
+{
+	TAGWPort * AX25Sess;
+
+	AX25Sess = findSession(snd_ch, CallFrom, CallTo);
+
+	if (AX25Sess)
+	{
+		ProcessReceivedData(AX25Sess->Sess, Msg, Len);
+	}
+}
+
+extern "C" void WritetoMonWindow(Ui_ListenSession * Sess, unsigned char * Msg, int len);
+
+void on_AGW_Mon_frame(byte * Msg, int Len, char Type)
+{
+	if (AGWUsers && AGWUsers->MonSess && AGWUsers->MonSess->monWindow)
+	{
+		unsigned char copy[512];
+
+		copy[0] = 0x1b;
+		if	(Type == 'T')
+			copy[1] = 91;
+		else
+			copy[1] = 17;
+
+		memcpy(&copy[2], Msg, Len);
+		WritetoMonWindow(AGWUsers->MonSess, copy, Len + 2);
+	}
+}
+
+
+
+void on_AGW_Ds_frame(int AGWChan, char * CallFrom, char * CallTo, struct AGWHeader * Frame)
+{
+	TAGWPort * AX25Sess;
+	char * Msg = (char *)Frame;
+	Msg = &Msg[36];
+
+	char Reply[128] = "";
+
+	memcpy(Reply, Msg, Frame->DataLength);
+
+	// Disconnect Sessiom
+
+	AX25Sess = findSession(AGWChan, CallFrom, CallTo);
+
+	if (AX25Sess)
+	{
+		Ui_ListenSession * Sess = AX25Sess->Sess;
+
+		WritetoOutputWindowEx(Sess, (unsigned char *)Reply, (int)strlen(Reply),
+			Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
+
+		if (TermMode == MDI)
+		{
+			if (Sess->SessionType == Mon)			// Mon Only
+				Sess->setWindowTitle("Monitor Session Disconnected");
+			else
+				Sess->setWindowTitle("Disconnected");
+		}
+		else if (TermMode == Tabbed)
+		{
+			if (Sess->SessionType == Mon)			// Mon Only
+				tabWidget->setTabText(Sess->Tab, "Monitor");
+			else
+			{
+				char Label[32];
+				sprintf(Label, "Sess %d", Sess->Tab + 1);
+				tabWidget->setTabText(Sess->Tab, Label);
+			}
+		}
+		else if (TermMode == Single)
+		{
+			if (Sess->SessionType == Mon)			// Mon Only
+				mythis->setWindowTitle("Monitor Session Disconnected");
+			else
+				mythis->setWindowTitle("Disconnected");
+		}
+
+		Sess->AGWSession = nullptr;
+		AX25Sess->Sess = nullptr;
+		AX25Sess->Active = 0;
+
+		setMenus(false);
+	}
+	else
+	{
+		// Session not found
+	}
+}
+
+
+void AGW_AX25_data_in(void  * Sess, UCHAR * data, int Len)
+{
+	TAGWPort * AX25Sess = (TAGWPort *)Sess;
+	int len = 250, sendlen;
+	UCHAR pkt[512];
+
+	while (Len)
+	{
+		if (Len > len)
+			sendlen = len;
+		else
+			sendlen = Len;
+
+		memcpy(pkt, data, sendlen);
+
+		Len -= sendlen;
+
+		memmove(data, &data[sendlen], Len);
+
+		Send_AGW_D_Frame(AX25Sess, pkt, sendlen);
+	}
+
+}
+
+
+/*
+
+void AGW_frame_monitor(byte snd_ch, byte * path, UCHAR * data, byte pid, byte nr, byte ns, byte f_type, byte f_id, byte  rpt, byte pf, byte cr, byte RX)
+{
+	char mon_frm[512];
+	char AGW_path[256];
+	UCHAR * AGW_data;
+
+	const char * frm;
+	byte * datap = data->Data;
+	byte _data[512];
+	byte * p_data = _data;
+	int _datalen;
+
+	char  agw_port;
+	char  CallFrom[10], CallTo[10], Digi[80];
+
+	int i;
+	const char * ctrl;
+	int len;
+
+	AGWUser * AGW;
+
+	UNUSED(rpt);
+
+	len = data->Length;
+
+	//	if (pid == 0xCF)
+	//		data = parse_NETROM(data, f_id);
+		// IP parsing
+	//	else if (pid == 0xCC)
+	//		data = parse_IP(data);
+		// ARP parsing
+	//	else if (pid == 0xCD)
+	//		data = parse_ARP(data);
+		//
+
+	if (len > 0)
+	{
+		for (i = 0; i < len; i++)
+		{
+			if (datap[i] > 31 || datap[i] == 13 || datap[i] == 9)
+				*(p_data++) = datap[i];
+		}
+	}
+
+	_datalen = p_data - _data;
+
+	if (_datalen)
+	{
+		byte * ptr = _data;
+		i = 0;
+
+		// remove successive cr or cr on end		while (i < _datalen)
+
+		while (i < _datalen)
+		{
+			if ((_data[i] == 13) && (_data[i + 1] = 13))
+				i++;
+			else
+				*(ptr++) = _data[i++];
+		}
+
+		if (*(ptr - 1) == 13)
+			ptr--;
+
+		*ptr = 0;
+
+		_datalen = ptr - _data;
+	}
+
+	agw_port = snd_ch;
+
+	get_monitor_path(path, CallTo, CallFrom, Digi);
+
+	ctrl = "";
+	frm = "";
+
+	switch (f_id)
+	{
+	case I_I:
+
+		frm = "I";
+		if (cr == SET_C && pf == SET_P)
+			ctrl = " P";
+
+		break;
+
+	case S_RR:
+
+		frm = "RR";
+		if (pf == SET_P)
+			ctrl = " P/F";
+
+		break;
+
+	case S_RNR:
+
+		frm = "RNR";
+		if (pf == SET_P)
+			ctrl = " P/F";
+
+		break;
+
+	case S_REJ:
+
+		frm = "REJ";
+		if (pf == SET_P)
+			ctrl = " P/F";
+
+		break;
+
+	case U_SABM:
+
+		frm = "SABM";
+		if (cr == SET_C && pf == SET_P)
+			ctrl = " P";
+
+		break;
+
+	case U_DISC:
+
+		frm = "DISC";
+		if (cr == SET_C && pf == SET_P)
+			ctrl = " P";
+		break;
+
+	case U_DM:
+
+		frm = "DM";
+		if ((cr == SET_R) && (pf == SET_P))
+			ctrl = " F ";
+		break;
+
+	case U_UA:
+
+		frm = "UA";
+		if ((cr == SET_R) && (pf == SET_P))
+			ctrl = " F ";
+
+		break;
+
+	case U_FRMR:
+
+		frm = "FRMR";
+		if ((cr == SET_R) && (pf == SET_P))
+			ctrl = " F ";
+		break;
+
+	case U_UI:
+
+		frm = "UI";
+		if ((pf == SET_P))
+			ctrl = " P/F";
+	}
+
+	if (Digi[0])
+		sprintf(AGW_path, " %d:Fm %s To %s Via %s <%s", snd_ch + 1, CallFrom, CallTo, Digi, frm);
+	else
+		sprintf(AGW_path, " %d:Fm %s To %s <%s", snd_ch + 1, CallFrom, CallTo, frm);
+
+
+	switch (f_type)
+	{
+	case I_FRM:
+
+		//mon_frm = AGW_path + ctrl + ' R' + inttostr(nr) + ' S' + inttostr(ns) + ' pid=' + dec2hex(pid) + ' Len=' + inttostr(len) + ' >' + time_now + #13 + _data + #13#13;
+		sprintf(mon_frm, "%s%s R%d S%d pid=%X Len=%d >[%s]\r%s\r", AGW_path, ctrl, nr, ns, pid, len, ShortDateTime(), _data);
+
+		break;
+
+	case U_FRM:
+
+		if (f_id == U_UI)
+		{
+			sprintf(mon_frm, "%s pid=%X Len=%d >[%s]\r%s\r", AGW_path, pid, len, ShortDateTime(), _data); // "= AGW_path + ctrl + '>' + time_now + #13;
+		}
+		else if (f_id == U_FRMR)
+		{
+			//			_data = copy(_data + #0#0#0, 1, 3);
+			//			mon_frm = AGW_path + ctrl + '>' + time_now + #13 + inttohex((byte(data[1]) shl 16) or (byte(data[2]) shl 8) or byte(data[3]), 6) + #13#13;
+		}
+		else
+			sprintf(mon_frm, "%s%s>[%s]\r", AGW_path, ctrl, ShortDateTime()); // "= AGW_path + ctrl + '>' + time_now + #13;
+
+		break;
+
+	case S_FRM:
+
+		//		mon_frm = AGW_path + ctrl + ' R' + inttostr(nr) + ' >' + time_now + #13;
+		sprintf(mon_frm, "%s%s R%d>[%s]\r", AGW_path, ctrl, nr, ShortDateTime()); // "= AGW_path + ctrl + '>' + time_now + #13;
+
+		break;
+
+	}
+
+	//	stringAdd(mon_frm, "", 1); //  Add 0 at the end of each frame
+
+		// I think we send to all AGW sockets
+
+	for (i = 0; i < AGWConCount; i++)
+	{
+		AGW = AGWUsers[i];
+
+		if (AGW->Monitor)
+		{
+			if (RX)
+			{
+				
+
+			case f_id of
+			  I_I   : AGW_data = AGW_I_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  S_RR  : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  S_RNR : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  S_REJ : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  U_SABM: AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  U_DISC: AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  U_DM  : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  U_UA  : AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  U_FRMR: AGW_data = AGW_S_frame(agw_port,CallFrom,CallTo,mon_frm);
+			  U_UI  : AGW_data = AGW_U_frame(agw_port,CallFrom,CallTo,mon_frm);
+
+							AGW_send_to_app(AGW->socket, AGW_data);
+
+			  
+			}
+			else
+			{
+				AGW_data = AGW_T_Frame(agw_port, CallFrom, CallTo, mon_frm);
+				AGW_send_to_app(AGW->socket, AGW_data);
+			}
+		}
+	}
+}
+
+*/
+
+
+
+
+void AGW_Process_Input(AGWUser * AGW)
+{
+	struct AGWHeader * Frame = (struct AGWHeader *)AGW->data_in;
+	byte * Data = &AGW->data_in[36];
+
+	switch (Frame->DataKind)
+	{
+	case 'P':
+
+//		on_AGW_P_frame(AGW);
+//		return;
+
+	case 'X':
+
+		// Registration response - no need to process
+
+		return;
+
+	case 'G':
+
+		on_AGW_G_frame(Data);
+		return;
+/*
+
+	case 'x':
+
+		on_AGW_Xs_frame(Frame->callfrom);
+		return;
+
+
+
+	case 'm':
+
+		on_AGW_Ms_frame(AGW);
+		return;
+
+	case 'R':
+
+		on_AGW_R_frame(AGW);
+		return;
+
+
+		//	'g': on_AGW_Gs_frame(AGW,Frame->Port);
+		//	'H': on_AGW_H_frame(AGW,Frame->Port);
+		//	'y': on_AGW_Ys_frame(AGW,Frame->Port);
+
+	case 'Y':
+		on_AGW_Y_frame(AGW->socket, Frame->Port, Frame->callfrom, Frame->callto);
+		break;
+
+	case 'M':
+
+		on_AGW_M_frame(Frame->Port, Frame->PID, Frame->callfrom, Frame->callto, Data, Frame->DataLength);
+		break;
+*/
+
+	case 'C':
+//	case 'v':				// Call with digis
+
+		on_AGW_C_frame(AGW, Frame, Data);
+		return;
+	
+	
+	case 'D':
+
+		on_AGW_D_frame(Frame->Port, Frame->callfrom, Frame->callto, Data, Frame->DataLength);
+		return;
+
+	case 'd':
+
+		on_AGW_Ds_frame(Frame->Port, Frame->callfrom, Frame->callto, Frame);
+		return;
+
+	case 'U':
+	case 'S':
+	case 'I':
+	case 'T':
+
+			// Monitor Data
+
+			if (AGWMonEnable)
+				on_AGW_Mon_frame(Data, Frame->DataLength, Frame->DataKind);
+		
+			return;
+
+/*
+
+		//	'V': on_AGW_V_frame(AGW,Frame->Port,PID,CallFrom,CallTo,Data);
+		//	'c': on_AGW_Cs_frame(sAGWocket,Frame->Port,PID,CallFrom,CallTo);
+
+
+	case 'K':
+
+		on_AGW_K_frame(Frame);
+		return;
+
+	case 'k':
+		on_AGW_Ks_frame(AGW);
+		return;
+		*/
+	default:
+		Debugprintf("AGW %c", Frame->DataKind);
+	}
+}
--- qttermtcp-0.0.0.79.orig/AGWConnect.ui
+++ qttermtcp-0.0.0.79/AGWConnect.ui
@@ -1,148 +1,148 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>AGWConnectDkg</class>
- <widget class="QDialog" name="AGWConnectDkg">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>500</width>
-    <height>400</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Dialog</string>
-  </property>
-  <widget class="QWidget" name="verticalLayoutWidget">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>10</y>
-     <width>480</width>
-     <height>380</height>
-    </rect>
-   </property>
-   <layout class="QVBoxLayout" name="verticalLayout">
-    <item>
-     <layout class="QFormLayout" name="formLayout_2">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label">
-        <property name="text">
-         <string>Call From </string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLineEdit" name="CallFrom"/>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string>Call To </string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QComboBox" name="CallTo">
-        <property name="editable">
-         <bool>true</bool>
-        </property>
-        <property name="insertPolicy">
-         <enum>QComboBox::NoInsert</enum>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QLabel" name="label_3">
-        <property name="text">
-         <string>Digis</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="QLineEdit" name="Digis"/>
-      </item>
-     </layout>
-    </item>
-    <item>
-     <widget class="QLabel" name="label_4">
-      <property name="text">
-       <string>Radio Ports</string>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QListWidget" name="RadioPorts"/>
-    </item>
-    <item>
-     <layout class="QHBoxLayout">
-      <property name="spacing">
-       <number>6</number>
-      </property>
-      <property name="leftMargin">
-       <number>0</number>
-      </property>
-      <property name="topMargin">
-       <number>0</number>
-      </property>
-      <property name="rightMargin">
-       <number>0</number>
-      </property>
-      <property name="bottomMargin">
-       <number>0</number>
-      </property>
-      <item>
-       <widget class="QPushButton" name="okButton">
-        <property name="text">
-         <string>OK</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QPushButton" name="cancelButton">
-        <property name="text">
-         <string>Cancel</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </item>
-   </layout>
-  </widget>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>okButton</sender>
-   <signal>clicked()</signal>
-   <receiver>AGWConnectDkg</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>278</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>96</x>
-     <y>254</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>cancelButton</sender>
-   <signal>clicked()</signal>
-   <receiver>AGWConnectDkg</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>369</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>179</x>
-     <y>282</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AGWConnectDkg</class>
+ <widget class="QDialog" name="AGWConnectDkg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>500</width>
+    <height>400</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QWidget" name="verticalLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>480</width>
+     <height>380</height>
+    </rect>
+   </property>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QFormLayout" name="formLayout_2">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Call From </string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="CallFrom"/>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Call To </string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QComboBox" name="CallTo">
+        <property name="editable">
+         <bool>true</bool>
+        </property>
+        <property name="insertPolicy">
+         <enum>QComboBox::NoInsert</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_3">
+        <property name="text">
+         <string>Digis</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="Digis"/>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <widget class="QLabel" name="label_4">
+      <property name="text">
+       <string>Radio Ports</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QListWidget" name="RadioPorts"/>
+    </item>
+    <item>
+     <layout class="QHBoxLayout">
+      <property name="spacing">
+       <number>6</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QPushButton" name="okButton">
+        <property name="text">
+         <string>OK</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="cancelButton">
+        <property name="text">
+         <string>Cancel</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>AGWConnectDkg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>278</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>96</x>
+     <y>254</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cancelButton</sender>
+   <signal>clicked()</signal>
+   <receiver>AGWConnectDkg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>369</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>179</x>
+     <y>282</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- qttermtcp-0.0.0.79.orig/AGWParams.ui
+++ qttermtcp-0.0.0.79/AGWParams.ui
@@ -1,395 +1,395 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>AGWParams</class>
- <widget class="QDialog" name="AGWParams">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>562</width>
-    <height>491</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Dialog</string>
-  </property>
-  <widget class="QLineEdit" name="TermCall">
-   <property name="geometry">
-    <rect>
-     <x>120</x>
-     <y>50</y>
-     <width>113</width>
-     <height>20</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QGroupBox" name="groupBox">
-   <property name="geometry">
-    <rect>
-     <x>12</x>
-     <y>83</y>
-     <width>537</width>
-     <height>215</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>Beacon Setup</string>
-   </property>
-   <widget class="QLineEdit" name="beaconDest">
-    <property name="geometry">
-     <rect>
-      <x>110</x>
-      <y>24</y>
-      <width>113</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="beaconPath">
-    <property name="geometry">
-     <rect>
-      <x>110</x>
-      <y>54</y>
-      <width>113</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="beaconInterval">
-    <property name="geometry">
-     <rect>
-      <x>108</x>
-      <y>84</y>
-      <width>45</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="beaconPorts">
-    <property name="geometry">
-     <rect>
-      <x>110</x>
-      <y>114</y>
-      <width>43</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_2">
-    <property name="geometry">
-     <rect>
-      <x>14</x>
-      <y>22</y>
-      <width>75</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Destination</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_3">
-    <property name="geometry">
-     <rect>
-      <x>14</x>
-      <y>52</y>
-      <width>75</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Digipeaters</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_4">
-    <property name="geometry">
-     <rect>
-      <x>14</x>
-      <y>82</y>
-      <width>75</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Interval</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_5">
-    <property name="geometry">
-     <rect>
-      <x>14</x>
-      <y>112</y>
-      <width>75</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Ports</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_6">
-    <property name="geometry">
-     <rect>
-      <x>176</x>
-      <y>82</y>
-      <width>75</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Minutes</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_7">
-    <property name="geometry">
-     <rect>
-      <x>176</x>
-      <y>112</y>
-      <width>137</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>(Separate with commas)</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_11">
-    <property name="geometry">
-     <rect>
-      <x>14</x>
-      <y>144</y>
-      <width>75</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Message</string>
-    </property>
-   </widget>
-   <widget class="QPlainTextEdit" name="beaconText">
-    <property name="geometry">
-     <rect>
-      <x>110</x>
-      <y>140</y>
-      <width>425</width>
-      <height>63</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_12">
-    <property name="geometry">
-     <rect>
-      <x>14</x>
-      <y>158</y>
-      <width>95</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>(max 256 chars)</string>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QGroupBox" name="groupBox_2">
-   <property name="geometry">
-    <rect>
-     <x>12</x>
-     <y>300</y>
-     <width>537</width>
-     <height>123</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>TNC Setup</string>
-   </property>
-   <widget class="QLineEdit" name="Host">
-    <property name="geometry">
-     <rect>
-      <x>110</x>
-      <y>24</y>
-      <width>101</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="Port">
-    <property name="geometry">
-     <rect>
-      <x>110</x>
-      <y>54</y>
-      <width>47</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="Paclen">
-    <property name="geometry">
-     <rect>
-      <x>110</x>
-      <y>84</y>
-      <width>47</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_8">
-    <property name="geometry">
-     <rect>
-      <x>16</x>
-      <y>24</y>
-      <width>47</width>
-      <height>13</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Host</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_9">
-    <property name="geometry">
-     <rect>
-      <x>16</x>
-      <y>54</y>
-      <width>47</width>
-      <height>13</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Port</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_10">
-    <property name="geometry">
-     <rect>
-      <x>16</x>
-      <y>84</y>
-      <width>47</width>
-      <height>13</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Paclen</string>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QLabel" name="label">
-   <property name="geometry">
-    <rect>
-     <x>18</x>
-     <y>48</y>
-     <width>111</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Terminal Callsign</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="okButton">
-   <property name="geometry">
-    <rect>
-     <x>180</x>
-     <y>440</y>
-     <width>95</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>OK</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="cancelButton">
-   <property name="geometry">
-    <rect>
-     <x>292</x>
-     <y>440</y>
-     <width>79</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Cancel</string>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="AGWEnable">
-   <property name="geometry">
-    <rect>
-     <x>152</x>
-     <y>16</y>
-     <width>23</width>
-     <height>25</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_13">
-   <property name="geometry">
-    <rect>
-     <x>20</x>
-     <y>18</y>
-     <width>135</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Enable AGW Interface</string>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="AGWMonEnable">
-   <property name="geometry">
-    <rect>
-     <x>255</x>
-     <y>18</y>
-     <width>216</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string>Enable AGW Monitor Window</string>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>cancelButton</sender>
-   <signal>clicked()</signal>
-   <receiver>AGWParams</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>369</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>179</x>
-     <y>282</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>okButton</sender>
-   <signal>clicked()</signal>
-   <receiver>AGWParams</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>278</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>96</x>
-     <y>254</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AGWParams</class>
+ <widget class="QDialog" name="AGWParams">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>562</width>
+    <height>491</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QLineEdit" name="TermCall">
+   <property name="geometry">
+    <rect>
+     <x>120</x>
+     <y>50</y>
+     <width>113</width>
+     <height>20</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QGroupBox" name="groupBox">
+   <property name="geometry">
+    <rect>
+     <x>12</x>
+     <y>83</y>
+     <width>537</width>
+     <height>215</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>Beacon Setup</string>
+   </property>
+   <widget class="QLineEdit" name="beaconDest">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>24</y>
+      <width>113</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="beaconPath">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>54</y>
+      <width>113</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="beaconInterval">
+    <property name="geometry">
+     <rect>
+      <x>108</x>
+      <y>84</y>
+      <width>45</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="beaconPorts">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>114</y>
+      <width>43</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_2">
+    <property name="geometry">
+     <rect>
+      <x>14</x>
+      <y>22</y>
+      <width>75</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Destination</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_3">
+    <property name="geometry">
+     <rect>
+      <x>14</x>
+      <y>52</y>
+      <width>75</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Digipeaters</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_4">
+    <property name="geometry">
+     <rect>
+      <x>14</x>
+      <y>82</y>
+      <width>75</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Interval</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_5">
+    <property name="geometry">
+     <rect>
+      <x>14</x>
+      <y>112</y>
+      <width>75</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Ports</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_6">
+    <property name="geometry">
+     <rect>
+      <x>176</x>
+      <y>82</y>
+      <width>75</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Minutes</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_7">
+    <property name="geometry">
+     <rect>
+      <x>176</x>
+      <y>112</y>
+      <width>137</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>(Separate with commas)</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_11">
+    <property name="geometry">
+     <rect>
+      <x>14</x>
+      <y>144</y>
+      <width>75</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Message</string>
+    </property>
+   </widget>
+   <widget class="QPlainTextEdit" name="beaconText">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>140</y>
+      <width>425</width>
+      <height>63</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_12">
+    <property name="geometry">
+     <rect>
+      <x>14</x>
+      <y>158</y>
+      <width>95</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>(max 256 chars)</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="groupBox_2">
+   <property name="geometry">
+    <rect>
+     <x>12</x>
+     <y>300</y>
+     <width>537</width>
+     <height>123</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>TNC Setup</string>
+   </property>
+   <widget class="QLineEdit" name="Host">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>24</y>
+      <width>101</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="Port">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>54</y>
+      <width>47</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="Paclen">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>84</y>
+      <width>47</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_8">
+    <property name="geometry">
+     <rect>
+      <x>16</x>
+      <y>24</y>
+      <width>47</width>
+      <height>13</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Host</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_9">
+    <property name="geometry">
+     <rect>
+      <x>16</x>
+      <y>54</y>
+      <width>47</width>
+      <height>13</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Port</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_10">
+    <property name="geometry">
+     <rect>
+      <x>16</x>
+      <y>84</y>
+      <width>47</width>
+      <height>13</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Paclen</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>18</x>
+     <y>48</y>
+     <width>111</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Terminal Callsign</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="okButton">
+   <property name="geometry">
+    <rect>
+     <x>180</x>
+     <y>440</y>
+     <width>95</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>OK</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="cancelButton">
+   <property name="geometry">
+    <rect>
+     <x>292</x>
+     <y>440</y>
+     <width>79</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Cancel</string>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="AGWEnable">
+   <property name="geometry">
+    <rect>
+     <x>152</x>
+     <y>16</y>
+     <width>23</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_13">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>18</y>
+     <width>135</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Enable AGW Interface</string>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="AGWMonEnable">
+   <property name="geometry">
+    <rect>
+     <x>255</x>
+     <y>18</y>
+     <width>216</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string>Enable AGW Monitor Window</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>cancelButton</sender>
+   <signal>clicked()</signal>
+   <receiver>AGWParams</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>369</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>179</x>
+     <y>282</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>AGWParams</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>278</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>96</x>
+     <y>254</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- qttermtcp-0.0.0.79.orig/ColourConfig.ui
+++ qttermtcp-0.0.0.79/ColourConfig.ui
@@ -1,440 +1,440 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ColourDialog</class>
- <widget class="QDialog" name="ColourDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>342</width>
-    <height>407</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Colour Selection</string>
-  </property>
-  <widget class="QWidget" name="layoutWidget">
-   <property name="geometry">
-    <rect>
-     <x>66</x>
-     <y>350</y>
-     <width>199</width>
-     <height>33</height>
-    </rect>
-   </property>
-   <layout class="QHBoxLayout">
-    <property name="spacing">
-     <number>6</number>
-    </property>
-    <property name="leftMargin">
-     <number>0</number>
-    </property>
-    <property name="topMargin">
-     <number>0</number>
-    </property>
-    <property name="rightMargin">
-     <number>0</number>
-    </property>
-    <property name="bottomMargin">
-     <number>0</number>
-    </property>
-    <item>
-     <widget class="QPushButton" name="okButton">
-      <property name="text">
-       <string>OK</string>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QPushButton" name="cancelButton">
-      <property name="text">
-       <string>Cancel</string>
-      </property>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QPushButton" name="TermBG">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>15</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="InputBG">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>247</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="InputColour">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>276</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string>Input</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="TermNormal">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>44</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string>Normal</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="Echoed">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>73</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string>Echoed</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="Warning">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>102</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string>Warning</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>16</y>
-     <width>187</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Terminal Background    </string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_2">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>45</y>
-     <width>185</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Normal Text</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_3">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>74</y>
-     <width>191</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Echoed Text</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_4">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>103</y>
-     <width>185</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Warning Text</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_9">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>248</y>
-     <width>189</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Input Background    </string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_10">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>277</y>
-     <width>183</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Input Text</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="MonRX">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>189</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string>RX Text</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="MonitorBG">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>131</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="MonOther">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>218</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string>Other Text</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="MonTX">
-   <property name="geometry">
-    <rect>
-     <x>216</x>
-     <y>160</y>
-     <width>75</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="minimumSize">
-    <size>
-     <width>75</width>
-     <height>0</height>
-    </size>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>75</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string>TX Text</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_5">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>132</y>
-     <width>187</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Monitor Background    </string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_6">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>161</y>
-     <width>183</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>TX Text</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_7">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>190</y>
-     <width>187</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>RX Text</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_8">
-   <property name="geometry">
-    <rect>
-     <x>21</x>
-     <y>219</y>
-     <width>189</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Other Text</string>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections/>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ColourDialog</class>
+ <widget class="QDialog" name="ColourDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>342</width>
+    <height>407</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Colour Selection</string>
+  </property>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>66</x>
+     <y>350</y>
+     <width>199</width>
+     <height>33</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout">
+    <property name="spacing">
+     <number>6</number>
+    </property>
+    <property name="leftMargin">
+     <number>0</number>
+    </property>
+    <property name="topMargin">
+     <number>0</number>
+    </property>
+    <property name="rightMargin">
+     <number>0</number>
+    </property>
+    <property name="bottomMargin">
+     <number>0</number>
+    </property>
+    <item>
+     <widget class="QPushButton" name="okButton">
+      <property name="text">
+       <string>OK</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="cancelButton">
+      <property name="text">
+       <string>Cancel</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QPushButton" name="TermBG">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>15</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="InputBG">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>247</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="InputColour">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>276</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string>Input</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="TermNormal">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>44</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string>Normal</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="Echoed">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>73</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string>Echoed</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="Warning">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>102</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string>Warning</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>16</y>
+     <width>187</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Terminal Background    </string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>45</y>
+     <width>185</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Normal Text</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_3">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>74</y>
+     <width>191</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Echoed Text</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_4">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>103</y>
+     <width>185</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Warning Text</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_9">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>248</y>
+     <width>189</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Input Background    </string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_10">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>277</y>
+     <width>183</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Input Text</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="MonRX">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>189</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string>RX Text</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="MonitorBG">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>131</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="MonOther">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>218</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string>Other Text</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="MonTX">
+   <property name="geometry">
+    <rect>
+     <x>216</x>
+     <y>160</y>
+     <width>75</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>75</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>75</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="text">
+    <string>TX Text</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_5">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>132</y>
+     <width>187</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Monitor Background    </string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_6">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>161</y>
+     <width>183</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>TX Text</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_7">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>190</y>
+     <width>187</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>RX Text</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_8">
+   <property name="geometry">
+    <rect>
+     <x>21</x>
+     <y>219</y>
+     <width>189</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Other Text</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- qttermtcp-0.0.0.79.orig/DialogButtonBottom.ui
+++ qttermtcp-0.0.0.79/DialogButtonBottom.ui
@@ -1,100 +1,100 @@
-<ui version="4.0">
- <author></author>
- <comment></comment>
- <exportmacro></exportmacro>
- <class>Dialog</class>
- <widget class="QDialog" name="Dialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>400</width>
-    <height>300</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Dialog</string>
-  </property>
-  <widget class="QWidget" name="layoutWidget">
-   <property name="geometry">
-    <rect>
-     <x>20</x>
-     <y>250</y>
-     <width>351</width>
-     <height>33</height>
-    </rect>
-   </property>
-   <layout class="QHBoxLayout">
-    <property name="margin">
-     <number>0</number>
-    </property>
-    <property name="spacing">
-     <number>6</number>
-    </property>
-    <item>
-     <spacer>
-      <property name="orientation">
-       <enum>Qt::Horizontal</enum>
-      </property>
-      <property name="sizeHint">
-       <size>
-        <width>131</width>
-        <height>31</height>
-       </size>
-      </property>
-     </spacer>
-    </item>
-    <item>
-     <widget class="QPushButton" name="okButton">
-      <property name="text">
-       <string>OK</string>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QPushButton" name="cancelButton">
-      <property name="text">
-       <string>Cancel</string>
-      </property>
-     </widget>
-    </item>
-   </layout>
-  </widget>
- </widget>
- <pixmapfunction></pixmapfunction>
- <resources/>
- <connections>
-  <connection>
-   <sender>okButton</sender>
-   <signal>clicked()</signal>
-   <receiver>Dialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>278</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>96</x>
-     <y>254</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>cancelButton</sender>
-   <signal>clicked()</signal>
-   <receiver>Dialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>369</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>179</x>
-     <y>282</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
+<ui version="4.0">
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>250</y>
+     <width>351</width>
+     <height>33</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout">
+    <property name="margin">
+     <number>0</number>
+    </property>
+    <property name="spacing">
+     <number>6</number>
+    </property>
+    <item>
+     <spacer>
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <property name="sizeHint">
+       <size>
+        <width>131</width>
+        <height>31</height>
+       </size>
+      </property>
+     </spacer>
+    </item>
+    <item>
+     <widget class="QPushButton" name="okButton">
+      <property name="text">
+       <string>OK</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="cancelButton">
+      <property name="text">
+       <string>Cancel</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>Dialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>278</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>96</x>
+     <y>254</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cancelButton</sender>
+   <signal>clicked()</signal>
+   <receiver>Dialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>369</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>179</x>
+     <y>282</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- qttermtcp-0.0.0.79.orig/KISSConfig.ui
+++ qttermtcp-0.0.0.79/KISSConfig.ui
@@ -1,536 +1,536 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>KISSDialog</class>
- <widget class="QDialog" name="KISSDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>432</width>
-    <height>399</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>KISS Configuration</string>
-  </property>
-  <widget class="QWidget" name="layoutWidget">
-   <property name="geometry">
-    <rect>
-     <x>40</x>
-     <y>360</y>
-     <width>351</width>
-     <height>33</height>
-    </rect>
-   </property>
-   <layout class="QHBoxLayout">
-    <property name="spacing">
-     <number>6</number>
-    </property>
-    <property name="leftMargin">
-     <number>0</number>
-    </property>
-    <property name="topMargin">
-     <number>0</number>
-    </property>
-    <property name="rightMargin">
-     <number>0</number>
-    </property>
-    <property name="bottomMargin">
-     <number>0</number>
-    </property>
-    <item>
-     <widget class="QPushButton" name="okButton">
-      <property name="text">
-       <string>OK</string>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QPushButton" name="cancelButton">
-      <property name="text">
-       <string>Cancel</string>
-      </property>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QGroupBox" name="TNCInfo_3">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>168</y>
-     <width>401</width>
-     <height>57</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>TCP  Setup</string>
-   </property>
-   <widget class="QLineEdit" name="Host">
-    <property name="geometry">
-     <rect>
-      <x>78</x>
-      <y>20</y>
-      <width>111</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="Port">
-    <property name="geometry">
-     <rect>
-      <x>290</x>
-      <y>21</y>
-      <width>47</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_20">
-    <property name="geometry">
-     <rect>
-      <x>16</x>
-      <y>24</y>
-      <width>47</width>
-      <height>13</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Host</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_21">
-    <property name="geometry">
-     <rect>
-      <x>222</x>
-      <y>24</y>
-      <width>47</width>
-      <height>13</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Port</string>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="Port_2">
-    <property name="geometry">
-     <rect>
-      <x>85</x>
-      <y>63</y>
-      <width>47</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_24">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>66</y>
-      <width>47</width>
-      <height>13</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Port</string>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QGroupBox" name="groupBox_5">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>118</y>
-     <width>411</width>
-     <height>51</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>Serial TNC</string>
-   </property>
-   <widget class="QComboBox" name="SerialPort">
-    <property name="geometry">
-     <rect>
-      <x>138</x>
-      <y>20</y>
-      <width>111</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_9">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>23</y>
-      <width>131</width>
-      <height>16</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Select Device</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_23">
-    <property name="geometry">
-     <rect>
-      <x>276</x>
-      <y>20</y>
-      <width>47</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Speed</string>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="Speed">
-    <property name="geometry">
-     <rect>
-      <x>328</x>
-      <y>21</y>
-      <width>51</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>19200</string>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QLabel" name="label_14">
-   <property name="geometry">
-    <rect>
-     <x>12</x>
-     <y>10</y>
-     <width>149</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Enable KISS Interface</string>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="KISSEnable">
-   <property name="geometry">
-    <rect>
-     <x>158</x>
-     <y>9</y>
-     <width>23</width>
-     <height>25</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_22">
-   <property name="geometry">
-    <rect>
-     <x>214</x>
-     <y>11</y>
-     <width>61</width>
-     <height>17</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>MYCALL</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="MYCALL">
-   <property name="geometry">
-    <rect>
-     <x>292</x>
-     <y>10</y>
-     <width>91</width>
-     <height>22</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_25">
-   <property name="geometry">
-    <rect>
-     <x>25</x>
-     <y>240</y>
-     <width>47</width>
-     <height>13</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Paclen</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="Paclen">
-   <property name="geometry">
-    <rect>
-     <x>98</x>
-     <y>240</y>
-     <width>47</width>
-     <height>22</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_26">
-   <property name="geometry">
-    <rect>
-     <x>213</x>
-     <y>240</y>
-     <width>66</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>MaxFrame</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="Maxframe">
-   <property name="geometry">
-    <rect>
-     <x>288</x>
-     <y>240</y>
-     <width>47</width>
-     <height>22</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_27">
-   <property name="geometry">
-    <rect>
-     <x>25</x>
-     <y>270</y>
-     <width>47</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Frack</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="Frack">
-   <property name="geometry">
-    <rect>
-     <x>98</x>
-     <y>270</y>
-     <width>36</width>
-     <height>22</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_28">
-   <property name="geometry">
-    <rect>
-     <x>213</x>
-     <y>273</y>
-     <width>47</width>
-     <height>13</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Retries</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="Retries">
-   <property name="geometry">
-    <rect>
-     <x>288</x>
-     <y>270</y>
-     <width>36</width>
-     <height>22</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_15">
-   <property name="geometry">
-    <rect>
-     <x>12</x>
-     <y>35</y>
-     <width>149</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Allow incoming connects</string>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="KISSListen">
-   <property name="geometry">
-    <rect>
-     <x>158</x>
-     <y>34</y>
-     <width>23</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="KISSChecksum">
-   <property name="geometry">
-    <rect>
-     <x>160</x>
-     <y>60</y>
-     <width>20</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_16">
-   <property name="geometry">
-    <rect>
-     <x>12</x>
-     <y>60</y>
-     <width>141</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Enable checksum</string>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="KISSACKMODE">
-   <property name="geometry">
-    <rect>
-     <x>160</x>
-     <y>84</y>
-     <width>20</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_17">
-   <property name="geometry">
-    <rect>
-     <x>12</x>
-     <y>85</y>
-     <width>141</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Enable ACKMODE</string>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="SetTXDelay">
-   <property name="geometry">
-    <rect>
-     <x>150</x>
-     <y>300</y>
-     <width>111</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string>Set TXDelay</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="TXDELAY">
-   <property name="geometry">
-    <rect>
-     <x>99</x>
-     <y>300</y>
-     <width>36</width>
-     <height>22</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_29">
-   <property name="geometry">
-    <rect>
-     <x>26</x>
-     <y>302</y>
-     <width>71</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>TXDelay</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_18">
-   <property name="geometry">
-    <rect>
-     <x>200</x>
-     <y>80</y>
-     <width>151</width>
-     <height>30</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Open MH Window</string>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="KISSMH">
-   <property name="geometry">
-    <rect>
-     <x>390</x>
-     <y>83</y>
-     <width>20</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>okButton</sender>
-   <signal>clicked()</signal>
-   <receiver>KISSDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>278</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>96</x>
-     <y>254</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>cancelButton</sender>
-   <signal>clicked()</signal>
-   <receiver>KISSDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>369</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>179</x>
-     <y>282</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>KISSDialog</class>
+ <widget class="QDialog" name="KISSDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>432</width>
+    <height>399</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>KISS Configuration</string>
+  </property>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>40</x>
+     <y>360</y>
+     <width>351</width>
+     <height>33</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout">
+    <property name="spacing">
+     <number>6</number>
+    </property>
+    <property name="leftMargin">
+     <number>0</number>
+    </property>
+    <property name="topMargin">
+     <number>0</number>
+    </property>
+    <property name="rightMargin">
+     <number>0</number>
+    </property>
+    <property name="bottomMargin">
+     <number>0</number>
+    </property>
+    <item>
+     <widget class="QPushButton" name="okButton">
+      <property name="text">
+       <string>OK</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="cancelButton">
+      <property name="text">
+       <string>Cancel</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QGroupBox" name="TNCInfo_3">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>168</y>
+     <width>401</width>
+     <height>57</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>TCP  Setup</string>
+   </property>
+   <widget class="QLineEdit" name="Host">
+    <property name="geometry">
+     <rect>
+      <x>78</x>
+      <y>20</y>
+      <width>111</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="Port">
+    <property name="geometry">
+     <rect>
+      <x>290</x>
+      <y>21</y>
+      <width>47</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_20">
+    <property name="geometry">
+     <rect>
+      <x>16</x>
+      <y>24</y>
+      <width>47</width>
+      <height>13</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Host</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_21">
+    <property name="geometry">
+     <rect>
+      <x>222</x>
+      <y>24</y>
+      <width>47</width>
+      <height>13</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Port</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="Port_2">
+    <property name="geometry">
+     <rect>
+      <x>85</x>
+      <y>63</y>
+      <width>47</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_24">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>66</y>
+      <width>47</width>
+      <height>13</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Port</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="groupBox_5">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>118</y>
+     <width>411</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>Serial TNC</string>
+   </property>
+   <widget class="QComboBox" name="SerialPort">
+    <property name="geometry">
+     <rect>
+      <x>138</x>
+      <y>20</y>
+      <width>111</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_9">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>23</y>
+      <width>131</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Select Device</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_23">
+    <property name="geometry">
+     <rect>
+      <x>276</x>
+      <y>20</y>
+      <width>47</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Speed</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="Speed">
+    <property name="geometry">
+     <rect>
+      <x>328</x>
+      <y>21</y>
+      <width>51</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>19200</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QLabel" name="label_14">
+   <property name="geometry">
+    <rect>
+     <x>12</x>
+     <y>10</y>
+     <width>149</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Enable KISS Interface</string>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="KISSEnable">
+   <property name="geometry">
+    <rect>
+     <x>158</x>
+     <y>9</y>
+     <width>23</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_22">
+   <property name="geometry">
+    <rect>
+     <x>214</x>
+     <y>11</y>
+     <width>61</width>
+     <height>17</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>MYCALL</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="MYCALL">
+   <property name="geometry">
+    <rect>
+     <x>292</x>
+     <y>10</y>
+     <width>91</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_25">
+   <property name="geometry">
+    <rect>
+     <x>25</x>
+     <y>240</y>
+     <width>47</width>
+     <height>13</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Paclen</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="Paclen">
+   <property name="geometry">
+    <rect>
+     <x>98</x>
+     <y>240</y>
+     <width>47</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_26">
+   <property name="geometry">
+    <rect>
+     <x>213</x>
+     <y>240</y>
+     <width>66</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>MaxFrame</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="Maxframe">
+   <property name="geometry">
+    <rect>
+     <x>288</x>
+     <y>240</y>
+     <width>47</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_27">
+   <property name="geometry">
+    <rect>
+     <x>25</x>
+     <y>270</y>
+     <width>47</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Frack</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="Frack">
+   <property name="geometry">
+    <rect>
+     <x>98</x>
+     <y>270</y>
+     <width>36</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_28">
+   <property name="geometry">
+    <rect>
+     <x>213</x>
+     <y>273</y>
+     <width>47</width>
+     <height>13</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Retries</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="Retries">
+   <property name="geometry">
+    <rect>
+     <x>288</x>
+     <y>270</y>
+     <width>36</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_15">
+   <property name="geometry">
+    <rect>
+     <x>12</x>
+     <y>35</y>
+     <width>149</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Allow incoming connects</string>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="KISSListen">
+   <property name="geometry">
+    <rect>
+     <x>158</x>
+     <y>34</y>
+     <width>23</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="KISSChecksum">
+   <property name="geometry">
+    <rect>
+     <x>160</x>
+     <y>60</y>
+     <width>20</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_16">
+   <property name="geometry">
+    <rect>
+     <x>12</x>
+     <y>60</y>
+     <width>141</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Enable checksum</string>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="KISSACKMODE">
+   <property name="geometry">
+    <rect>
+     <x>160</x>
+     <y>84</y>
+     <width>20</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_17">
+   <property name="geometry">
+    <rect>
+     <x>12</x>
+     <y>85</y>
+     <width>141</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Enable ACKMODE</string>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="SetTXDelay">
+   <property name="geometry">
+    <rect>
+     <x>150</x>
+     <y>300</y>
+     <width>111</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string>Set TXDelay</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="TXDELAY">
+   <property name="geometry">
+    <rect>
+     <x>99</x>
+     <y>300</y>
+     <width>36</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_29">
+   <property name="geometry">
+    <rect>
+     <x>26</x>
+     <y>302</y>
+     <width>71</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>TXDelay</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_18">
+   <property name="geometry">
+    <rect>
+     <x>200</x>
+     <y>80</y>
+     <width>151</width>
+     <height>30</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Open MH Window</string>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="KISSMH">
+   <property name="geometry">
+    <rect>
+     <x>390</x>
+     <y>83</y>
+     <width>20</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>KISSDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>278</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>96</x>
+     <y>254</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cancelButton</sender>
+   <signal>clicked()</signal>
+   <receiver>KISSDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>369</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>179</x>
+     <y>282</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- qttermtcp-0.0.0.79.orig/ListenPort.ui
+++ qttermtcp-0.0.0.79/ListenPort.ui
@@ -1,140 +1,140 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ListenPort</class>
- <widget class="QDialog" name="ListenPort">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>445</width>
-    <height>654</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Dialog</string>
-  </property>
-  <widget class="QWidget" name="verticalLayoutWidget">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>431</width>
-     <height>301</height>
-    </rect>
-   </property>
-   <layout class="QVBoxLayout" name="verticalLayout">
-    <item>
-     <layout class="QFormLayout" name="formLayout">
-      <item row="2" column="0">
-       <widget class="QLabel" name="label">
-        <property name="minimumSize">
-         <size>
-          <width>100</width>
-          <height>30</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>100</width>
-          <height>30</height>
-         </size>
-        </property>
-        <property name="text">
-         <string>Port</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="QLineEdit" name="portNo">
-        <property name="minimumSize">
-         <size>
-          <width>0</width>
-          <height>30</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>100</width>
-          <height>30</height>
-         </size>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="0">
-       <widget class="QLabel" name="label_2">
-        <property name="minimumSize">
-         <size>
-          <width>0</width>
-          <height>30</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>16777215</width>
-          <height>30</height>
-         </size>
-        </property>
-        <property name="text">
-         <string>CText</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="1">
-       <widget class="QTextEdit" name="CText">
-        <property name="minimumSize">
-         <size>
-          <width>0</width>
-          <height>150</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>401</width>
-          <height>150</height>
-         </size>
-        </property>
-       </widget>
-      </item>
-      <item row="4" column="0">
-       <layout class="QVBoxLayout" name="verticalLayout_2"/>
-      </item>
-      <item row="4" column="1">
-       <widget class="QDialogButtonBox" name="buttonBox">
-        <property name="minimumSize">
-         <size>
-          <width>0</width>
-          <height>50</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>16777215</width>
-          <height>50</height>
-         </size>
-        </property>
-        <property name="layoutDirection">
-         <enum>Qt::RightToLeft</enum>
-        </property>
-        <property name="standardButtons">
-         <set>QDialogButtonBox::Save</set>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QCheckBox" name="Enabled">
-        <property name="layoutDirection">
-         <enum>Qt::LeftToRight</enum>
-        </property>
-        <property name="text">
-         <string>Enable Listen    </string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </item>
-   </layout>
-  </widget>
- </widget>
- <resources/>
- <connections/>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ListenPort</class>
+ <widget class="QDialog" name="ListenPort">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>445</width>
+    <height>654</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QWidget" name="verticalLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>431</width>
+     <height>301</height>
+    </rect>
+   </property>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QFormLayout" name="formLayout">
+      <item row="2" column="0">
+       <widget class="QLabel" name="label">
+        <property name="minimumSize">
+         <size>
+          <width>100</width>
+          <height>30</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>100</width>
+          <height>30</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>Port</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="portNo">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>30</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>100</width>
+          <height>30</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>30</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>30</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>CText</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QTextEdit" name="CText">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>150</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>401</width>
+          <height>150</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0">
+       <layout class="QVBoxLayout" name="verticalLayout_2"/>
+      </item>
+      <item row="4" column="1">
+       <widget class="QDialogButtonBox" name="buttonBox">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>50</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>50</height>
+         </size>
+        </property>
+        <property name="layoutDirection">
+         <enum>Qt::RightToLeft</enum>
+        </property>
+        <property name="standardButtons">
+         <set>QDialogButtonBox::Save</set>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QCheckBox" name="Enabled">
+        <property name="layoutDirection">
+         <enum>Qt::LeftToRight</enum>
+        </property>
+        <property name="text">
+         <string>Enable Listen    </string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- qttermtcp-0.0.0.79.orig/QtTermTCP.cpp
+++ qttermtcp-0.0.0.79/QtTermTCP.cpp
@@ -1,8165 +1,8165 @@
-// Qt Version of BPQTermTCP
-
-// Application icon design by Red PE1RRR
-
-#define VersionString "0.0.0.79"
-
-
-// .12 Save font weight
-// .13 Display incomplete lines (ie without CR)
-// .14 Add YAPP and Listen Mode
-// .15 Reuse windows in Listen Mode 
-// .17 MDI Version 7/1/20
-// .18 Fix input window losing focus when data arrivn other window
-// .19 Fix Scrollback
-// .20 WinXP compatibility changes
-// .21 Save Window Positions
-// .22 Open a window on first start
-// .23 Add Tabbed display option
-// .24 Fix crash when setting Monitor flags in Tabbed mode
-// .25 Add AGW mode
-// .26 Add sending CTRL/C CTRL/D and CTRL/Z)
-// .27 Limit size of windows to 10000 lines 
-//	   Fix YAPP in Tabbed Mode
-// .28 Add AGW Beacon
-// .29 Fix allocating Listem sessions to tabs connected using AGW
-// .30 Fix allocationd AGW Monitor Sessions
-// .31 Fix output being written to the wrong place when window is scrolled back
-// .32 Fix connect with digis
-// .33 Add StripLF option
-// .34 Improvements for Andriod
-//	   Option to change Menu Fonts
-//	   Fix receiving part lines when scrolled back
-// .35 Fix PE if not in Tabbed Mode
-// .36 Improved dialogs mainly for Android
-//	   Try to make sure sessions are closed before exiting
-// .37 Replace VT with LF (for pasting from BPQ32 Terminal Window)
-//	   Dont show AGW status line if AGW interface is disabled
-//	   Don't show Window Menu in Single Mode
-// .38 Protect against connect to normal Telnet Port.
-//	   Send CTEXT and Beep for inward AGW Connects
-//	   Make sending Idle and Connect beeps configurable
-//	   Change displayed Monitor flags when active window changed.
-//	   Fix duplicate text on long lines
-// .39 Add option to Convert non-utf8 charaters
-// .40 Prevent crash if AGW monitor Window closed
-// .41 Allow AGW Config and Connect dialogs to be resized with scrollbars
-//	   Fix disabling connect flag on current session when AGW connects
-// .42 Fix some bugs in AGW session handling
-// .43 Include Ross KD5LPB's fixes for MAC
-// .44 Ctrl/[ sends ESC (0x1b)
-// .45 Add VARA support							Nov 2021
-// .46 Fix dialog size on VARA setup
-// .47 Move VARA Status indicator. 
-//	   Add FLRIG PTT for VARA
-// .48 Check that YAPP Receive Directory has been set
-//	   Save separate configs for VARA, VARAFM and VARASAT
-// .49 Add BBS Monitor							Dec 2021
-// .50 Make Serial port support optional for Android Version
-// .51 Add KISS TNC Support						May 2022
-// .52 Save partially typed lines on cursor up	May 2022
-// .53 Add UI Mode for KISS Sessions			May 2022
-//     Fix saving KISS Paclen (b)
-//	   Fix Keepalive  (c)
-// .54 Add option to change screen colours		June 2022
-// .55 Build without optimisation
-// .56 Add Teletext mode						Nov 2022
-// .57 Fix KISS mode incoming call handling
-// .58 Add method to toggle Normal/Teletext Mode
-//	   Fix KISS multiple session protection
-// .59 Add Teletext double height mode
-// .60 Add option to name sessions				Jan 2023
-// .61 Add VARA Init Script						Feb 2023
-// .62 Fix running AGW in single session mode	Feb 2023
-// .63 Fix handling split monitor frame (no fe in buffer) Apr 2023
-// .64 Add Clear Screen command to context menu Apr 2023
-// .65 Fixes for 63 port version of BPQ			May 2023
-// .66 Colour Tab of incoming calls				June 2023
-// .67 Add config Yapp RX Size dialog			July 2023
-//	   Fix 63 port montoring
-
-// .68	Sept 2023
-
-//	Remember last used host on restart	
-//	Add AutoConnect in Tabbed Mode
-//	Fix auto copy when QtTerm not active window
-
-// .69	October 2023
-
-//	Options related to sound alerts moved to a separte menu in Setup
-//	Allow use of WAV files instead of Beep sound for sound alerts
-//	Enable an alarm to be sounded when one of a list of words or phrases is received.
-
-//	.70 October 2023
-
-//	Include some .wav files in resources
-//	Add Test button to Alert setup dialog
-
-//	.71 October 2023
-
-//	Add option to use local time
-//	Fixes for Mac OS
-
-//	.72 November 2023
-//	Don't display "Enable Monitor" on startup
-
-//	.73 November 2023
-//	Raise RTS on KISS serial port
-
-//	.74 April 2024
-//	Support BPQKISS TNCs with CHECKSUM and/or ACKMODE enabled
-
-//	.75 May 2024
-//	Flush Monitor log file every minute
-
-//	.76	August 2024
-//	Fix using digs in KISS UI mode.
-//	Add option to send TXDELAY to KISS TNC
-
-//	.77
-//	Support multichannel KISS TNCs (Beta 1)
-//	Fix using AGW listen in single terminal mode
-
-//	.78
-//	Fix restoring monitor flags when connecting to current host
-
-
-//	.79
-//	Add KISS MHEARD Window (Feb 2025)
-
-
-#define _CRT_SECURE_NO_WARNINGS
-
-#define UNUSED(x) (void)(x)
-
-#define USESERIAL
-
-#include "QtTermTCP.h"
-#include "TabDialog.h"
-#include <time.h>
-#include <QVBoxLayout>
-#include <QListWidgetItem>
-#include <QToolButton>
-#include <QInputMethod>
-#include "QTreeWidget"
-#include <QToolBar>
-#include <QLabel>
-#include <QActionGroup>
-#include <QtWidgets>
-#include <QColor>
-#include <QClipboard>
-#ifdef USESERIAL
-#include <QtSerialPort/QSerialPort>
-#include <QtSerialPort/QSerialPortInfo>
-#endif
-#ifndef WIN32
-#define strtok_s strtok_r
-#endif
-#include <fcntl.h>
-#include <errno.h>
-#ifndef WIN32
-#include <unistd.h>
-#endif
-
-#include "ax25.h"
-
-#define UNREFERENCED_PARAMETER(P)          (P)
-
-void DecodeTeleText(Ui_ListenSession * Sess, char * text);
-
-char Host[MAXHOSTS + 1][100] = { "" };
-int Port[MAXHOSTS + 1] = { 0 };
-char UserName[MAXHOSTS + 1][80] = { "" };
-char Password[MAXHOSTS + 1][80] = { "" };
-char MonParams[MAXHOSTS + 1][80] = { "" };
-char SessName[MAXHOSTS + 1][80] = { "" };
-int ListenPort = 8015;
-
-// Session Type Equates
-
-#define Term 1
-#define Mon 2
-#define Listen 4
-
-// Presentation - Single Window, MDI or Tabbed
-
-int TermMode = 0;
-
-#define Single 0
-#define MDI 1
-#define Tabbed 2
-
-int singlemodeFormat = Mon + Term;
-
-char monStyleSheet[128] = "background-color: rgb(0,255,255)";
-char termStyleSheet[128] = "background-color: rgb(255,0,255);";
-char inputStyleSheet[128] = "color: rgb(255, 0, 0); background-color: rgb(255,255,0);";
-
-QColor monBackground = qRgb(0, 255, 255);
-QColor monRxText = qRgb(0, 0, 255);
-QColor monTxText = qRgb(255, 0, 0);
-QColor monOtherText = qRgb(0, 0, 0);
-
-QColor termBackground = qRgb(255, 0, 255);
-QColor outputText = qRgb(0, 0, 0);
-QColor EchoText = qRgb(0, 0, 255);
-QColor WarningText = qRgb(255, 0, 0);
-QColor inputBackground = qRgb(255, 255, 0);
-QColor inputText = qRgb(0, 0, 255);
-
-QColor newTabText = qRgb(255, 0, 0);		// Red
-QColor oldTabText = qRgb(0, 0, 0);			// Black
-
-
-// There is something odd about this. It doesn't match BPQTERMTCP though it looks the same
-
-// Chat uses these (+ 10)
-//{ 0, 4, 9, 11, 13, 16, 17, 42, 45, 50, 61, 64, 66, 72, 81, 84, 85, 86, 87, 89 };
-
-// As we have a white background we need dark colours
-
-// 0 is black. 23 is normal output (blue) 81 is red (used by AGW Mon)
-// for monitor in colour, host sends 17 for RX Text, 81 for TX Text but code converts to monRx/TxText qrgb values
-
-QRgb Colours[256] = { 0,
-		qRgb(0,0,0), qRgb(0,0,128), qRgb(0,0,192), qRgb(0,0,255),				// 1 - 4
-		qRgb(0,64,0), qRgb(0,64,128), qRgb(0,64,192), qRgb(0,64,255),			// 5 - 8
-		qRgb(0,128,0), qRgb(0,128,128), qRgb(0,128,192), qRgb(0,128,255),		// 9 - 12
-		qRgb(0,192,0), qRgb(0,192,128), qRgb(0,192,192), qRgb(0,192,255),		// 13 - 16
-		qRgb(0,255,0), qRgb(0,255,128), qRgb(0,255,192), qRgb(0,255,255),		// 17 - 20
-
-		qRgb(64,0,0), qRgb(64,0,128), qRgb(64,0,192), qRgb(0,0,255),				// 21 
-		qRgb(64,64,0), qRgb(64,64,128), qRgb(64,64,192), qRgb(64,64,255),
-		qRgb(64,128,0), qRgb(64,128,128), qRgb(64,128,192), qRgb(64,128,255),
-		qRgb(64,192,0), qRgb(64,192,128), qRgb(64,192,192), qRgb(64,192,255),
-		qRgb(64,255,0), qRgb(64,255,128), qRgb(64,255,192), qRgb(64,255,255),
-
-		qRgb(128,0,0), qRgb(128,0,128), qRgb(128,0,192), qRgb(128,0,255),				// 41
-		qRgb(128,64,0), qRgb(128,64,128), qRgb(128,64,192), qRgb(128,64,255),
-		qRgb(128,128,0), qRgb(128,128,128), qRgb(128,128,192), qRgb(128,128,255),
-		qRgb(128,192,0), qRgb(128,192,128), qRgb(128,192,192), qRgb(128,192,255),
-		qRgb(128,255,0), qRgb(128,255,128), qRgb(128,255,192), qRgb(128,255,255),
-
-		qRgb(192,0,0), qRgb(192,0,128), qRgb(192,0,192), qRgb(192,0,255),				// 61 - 80
-		qRgb(192,64,0), qRgb(192,64,128), qRgb(192,64,192), qRgb(192,64,255),
-		qRgb(192,128,0), qRgb(192,128,128), qRgb(192,128,192), qRgb(192,128,255),
-		qRgb(192,192,0), qRgb(192,192,128), qRgb(192,192,192), qRgb(192,192,255),
-		qRgb(192,255,0), qRgb(192,255,128), qRgb(192,255,192), qRgb(192,255,255),
-
-		qRgb(255,0,0), qRgb(255,0,128), qRgb(255,0,192), qRgb(255,0,255),				// 81 - 100
-		qRgb(255,64,0), qRgb(255,64,128), qRgb(255,64,192), qRgb(255,64,255),
-		qRgb(255,128,0), qRgb(255,128,128), qRgb(255,128,192), qRgb(255,128,255),
-		qRgb(255,192,0), qRgb(255,192,128), qRgb(255,192,192), qRgb(255,192,255),
-		qRgb(255,255,0), qRgb(255,255,128), qRgb(255,255,192), qRgb(255,255,255)
-};
-
-
-
-int SavedHost = 0;				// from config
-
-char * sessionList = NULL;		// Saved sessions
-
-extern int ChatMode;
-extern int Bells;
-extern int StripLF;
-extern int convUTF8;
-
-extern time_t LastWrite;
-extern int AlertInterval;
-extern int AlertBeep;
-extern int AlertFreq;
-extern int AlertDuration;
-extern int ConnectBeep;
-
-bool useBeep;			// use wav files if not set
-
-extern int UseKeywords;
-extern QString KeyWordsFile;
-
-QString ConnectWAV("");
-QString AlertWAV("");
-QString BellWAV("");
-QString IntervalWAV("");
-
-extern int MaxRXSize;
-
-extern int AutoTeletext;
-
-// AGW Host Interface stuff
-
-int AGWEnable = 0;
-int AGWMonEnable = 0;
-int AGWLocalTime = 0;
-int AGWMonNodes = 0;
-char AGWTermCall[12] = "";
-char AGWBeaconDest[12] = "";
-char AGWBeaconPath[80] = "";
-int AGWBeaconInterval = 0;
-char AGWBeaconPorts[80];
-char AGWBeaconMsg[260] = "";
-
-
-char AGWHost[128] = "127.0.0.1";
-int AGWPortNum = 8000;
-int AGWPaclen = 80;
-extern char * AGWPortList;
-extern myTcpSocket * AGWSock;
-
-typedef struct AGWUser_t
-{
-	QTcpSocket *socket;
-	unsigned char data_in[8192];
-	int data_in_len;
-	unsigned char  AGW_frame_buf[512];
-	int	Monitor;
-	int	Monitor_raw;
-	Ui_ListenSession * MonSess;			// Window for Monitor info
-
-} AGWUser;
-
-extern AGWUser *AGWUsers;				// List of currently connected clients
-void Send_AGW_m_Frame(QTcpSocket* socket);
-
-
-QStringList AGWToCalls;
-
-// KISS Interface
-
-int KISSEnable = 0;
-extern "C" int KISSMonEnable;
-extern "C" int KISSLocalTime;
-extern "C" int KISSMonNodes;
-extern "C" int KISSListen;
-extern "C" int KISSChecksum;
-extern "C" int KISSAckMode;
-extern "C" int KISSMH;
-
-extern "C" short txtail[5];
-extern "C" short txdelay[5];
-extern "C" int sendTXDelay[4];
-
-
-
-char SerialPort[80] = "";
-char KISSHost[128] = "127.0.0.1";
-int KISSPortNum = 1000;
-int KISSBAUD = 19200;
-char KISSMYCALL[32];
-char KISSVia[128];				// Digi String
-
-extern "C" UCHAR axMYCALL[7];			// Mycall in ax.25
-
-int KISSMode = 0;			// Connected (0) or UI (1)
-
-myTcpSocket * KISSSock;
-
-extern "C" void * KISSSockCopy[4];
-
-int KISSConnected = 0;
-int KISSConnecting = 0;
-
-Ui_ListenSession * KISSMonSess = nullptr;
-
-QSerialPort * m_serial = nullptr;
-
-// VARA Interface
-
-int VARAEnable = 0;
-char VARAHost[128] = "127.0.0.1";
-char VARAHostHF[128] = "127.0.0.1";
-char VARAHostFM[128] = "127.0.0.1";
-char VARAHostSAT[128] = "127.0.0.1";
-int VARAPortNum = 8000;
-int VARAPortHF = 8000;
-int VARAPortFM = 8000;
-int VARAPortSAT = 8000;
-char VARATermCall[12] = "";
-char VARAPath[256] = "";
-char VARAInit[256] = "";
-char VARAPathHF[256] = "";
-char VARAPathFM[256] = "";
-char VARAPathSAT[256] = "";
-
-int VARA500 = 0;
-int VARA2300 = 1;
-int VARA2750 = 0;
-
-int VARAHF = 1;
-int VARAFM = 0;
-int VARASAT = 0;
-
-myTcpSocket * VARASock;
-myTcpSocket * VARADataSock;
-
-int VARAConnected = 0;
-int VARAConnecting = 0;
-
-
-extern char YAPPPath[256];
-
-void menuChecked(QAction * Act);
-
-// PTT Stuff
-
-#define PTTRTS		1
-#define PTTDTR		2
-#define PTTCAT		4
-#define PTTCM108	8
-#define PTTHAMLIB	16
-#define PTTFLRIG	32
-
-#ifdef USESERIAL
-
-QSerialPort * hPTTDevice = 0;
-#else
-
-
-#endif
-char PTTPort[80] = "";			// Port for Hardware PTT - may be same as control port.
-int PTTBAUD = 19200;
-int PTTMode = PTTRTS;			// PTT Control Flags.
-
-char PTTOnString[128] = "";
-char PTTOffString[128] = "";
-
-int CATHex = 1;
-
-unsigned char PTTOnCmd[64];
-int PTTOnCmdLen = 0;
-
-unsigned char  PTTOffCmd[64];
-int PTTOffCmdLen = 0;
-
-int pttGPIOPin = 17;			// Default
-int pttGPIOPinR = 17;
-bool pttGPIOInvert = false;
-bool useGPIO = false;
-bool gotGPIO = false;
-
-int HamLibPort = 4532;
-char HamLibHost[32] = "192.168.1.14";
-
-int FLRigPort = 12345;
-char FLRigHost[32] = "127.0.0.1";
-
-
-char CM108Addr[80] = "";
-
-int VID = 0;
-int PID = 0;
-
-// CM108 Code
-
-char * CM108Device = NULL;
-
-QProcess *process = NULL;
-
-void GetSettings();
-
-// These widgets defined here as they are accessed from outside the framework
-
-QLabel * Status1;
-QLabel * Status2;
-QLabel * Status3;
-QLabel * Status4;
-
-QAction *actHost[19];
-QAction *actSetup[16];
-
-QAction * TabSingle = NULL;
-QAction * TabBoth = NULL;
-QAction * TabMon = NULL;
-
-QMenu *monitorMenu;
-QMenu * YAPPMenu;
-QMenu *connectMenu;
-QMenu *disconnectMenu;
-
-QAction *EnableMonitor;
-QAction *EnableMonLog;
-QAction *MonLocalTime;
-QAction *MonTX;
-QAction *MonSup;
-QAction *MonNodes;
-QAction *MonUI;
-QAction *MonColour;
-QAction *MonPort[65];
-QAction *actChatMode;
-QAction *actAutoTeletext;
-QAction *actBells;
-QAction *actStripLF;
-QAction *actIntervalBeep;
-QAction *actConnectBeep;
-QAction *actAuto;
-QAction *actnoConv;
-QAction *actCP1251;
-QAction *actCP1252;
-QAction *actCP437;
-
-QAction *actFonts;
-QAction *actmenuFont;
-QAction *actColours;
-QAction *actmyFonts;
-QAction *YAPPSend;
-QAction *YAPPSetRX;
-QAction *YAPPSetSize;
-QAction *singleAct;
-QAction *singleAct2;
-QAction *MDIAct;
-QAction *tabbedAct;
-QAction *discAction;
-QFont * menufont;
-QMenu *windowMenu;
-QMenu *setupMenu;
-QAction *ListenAction;
-
-QTabWidget *tabWidget;
-QMdiArea *mdiArea;
-QWidget * mythis;
-QStatusBar * myStatusBar;
-
-QTcpServer * _server;
-
-QMenuBar *mymenuBar;
-QToolBar *toolBar;
-QToolButton * but1;
-QToolButton * but2;
-QToolButton * but3;
-QToolButton * but4;
-QToolButton * but5;
-
-QList<Ui_ListenSession *> _sessions;
-
-// Session Type Equates
-
-#define Term 1
-#define Mon 2
-#define Listen 4
-
-int TabType[10] = { Term, Term + Mon, Term, Term, Term, Term, Mon, Mon, Mon };
-
-int AutoConnect[10] = {0, 0 ,0, 0, 0, 0, 0, 0, 0, 0};
-
-int currentHost[10] = {0, 0 ,0, 0, 0, 0, 0, 0, 0, 0};
-
-int listenPort = 8015;
-extern "C" int listenEnable;
-char listenCText[4096] = "";
-
-int ConfigHost = 0;
-
-int Split = 50;				// Mon/Term size split
-
-int termX;
-
-bool Cascading = false;		// Set to stop size being saved when cascading
-
-QMdiSubWindow * ActiveSubWindow = NULL;
-Ui_ListenSession * ActiveSession = NULL;
-
-Ui_ListenSession * newWindow(QObject * parent, int Type, const char * Label = nullptr);
-void Send_AGW_C_Frame(Ui_ListenSession * Sess, int Port, char * CallFrom, char * CallTo, char * Data, int DataLen);
-void AGW_AX25_data_in(void * AX25Sess, unsigned char * data, int Len);
-void AGWMonWindowClosing(Ui_ListenSession *Sess);
-void AGWWindowClosing(Ui_ListenSession *Sess);
-extern "C" void KISSDataReceived(void * socket, unsigned char * data, int length);
-void closeSerialPort();
-int newMHWindow(QObject * parent, int Type, const char * Label);
-
-extern void initUTF8();
-int checkUTF8(unsigned char * Msg, int Len, unsigned char * out);
-
-QDialog * deviceUI;
-
-#include <QStandardPaths>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-
-
-
-void EncodeSettingsLine(int n, char * String)
-{
-	sprintf(String, "%s|%d|%s|%s|%s|%s", Host[n], Port[n], UserName[n], Password[n], MonParams[n], SessName[n]);
-	return;
-}
-
-// This is used for placing discAction in the preference menu
-#ifdef __APPLE__
-bool is_mac = true;
-#else
-bool is_mac = false;
-#endif
-
-QString GetConfPath()
-{
-	std::string conf_path = "QtTermTCP.ini";  // Default conf file stored alongside application.
-
-#ifdef __APPLE__
-
-	// Get configuration path for MacOS.
-
-	// This will usually be placed in /Users/USER/Library/Application Support/QtTermTCP
-
-	std::string directory = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).at(0).toStdString();
-
-	conf_path = directory + "/QtTermTCP.ini";
-
-	mkdir(directory.c_str(), 0775);
-
-#endif
-
-	return QString::fromUtf8(conf_path.c_str());
-
-}
-
-
-
-void DecodeSettingsLine(int n, char * String)
-{
-	char * Param = strdup(String);
-	char * Rest;
-	char * Save = Param;			// for Free
-
-	Rest = strlop(Param, '|');
-
-	if (Rest == NULL)
-		return;
-
-	strcpy(Host[n], Param);
-	Param = Rest;
-
-	Rest = strlop(Param, '|');
-	Port[n] = atoi(Param);
-	Param = Rest;
-
-	Rest = strlop(Param, '|');
-	strcpy(UserName[n], Param);
-	Param = Rest;
-
-	Rest = strlop(Param, '|');
-	strcpy(Password[n], Param);
-	Param = Rest;
-
-	Rest = strlop(Param, '|');
-	strcpy(MonParams[n], Param);
-
-	if (Rest)
-		strcpy(SessName[n], Rest);
-
-	free(Save);
-	return;
-}
-
-//#ifdef ANDROID
-//#define inputheight 60
-//#else
-#define inputheight 25
-//#endif
-
-extern "C" void SendtoAX25(void * conn, unsigned char * Msg, int Len);
-
-void DoTermResize(Ui_ListenSession * Sess)
-{
-
-	QRect r = Sess->rect();
-
-	int H, Mid, monHeight, termHeight, Width, Border = 3;
-
-	Width = r.width();
-	H = r.height();
-
-	if (TermMode == Tabbed)
-	{
-		//					H -= 20;
-		Width -= 7;
-	}
-	else if (TermMode == Single)
-	{
-		Width -= 7;
-		//					H += 20;
-	}
-
-	if (Sess->SessionType == Listen || Sess->SessionType == Term)
-	{
-		// Term and Input
-
-		// Calc Positions of window
-
-		termHeight = H - (inputheight + 3 * Border);
-
-		Sess->termWindow->setGeometry(QRect(Border, Border, Width, termHeight));
-
-		if (Sess->TTActive)
-		{
-			Sess->TTLabel->setGeometry(QRect(Border, Border, 600, 475));
-//			Sess->termWindow->setVisible(false);
-			Sess->TTLabel->setVisible(true);
-		}
-		else
-		{
-//			Sess->termWindow->setVisible(true);
-			Sess->TTLabel->setVisible(false);
-		}
-
-		Sess->inputWindow->setGeometry(QRect(Border, H - (inputheight + Border), Width, inputheight));
-	}
-	else if (Sess->SessionType == (Term | Mon))
-	{
-		// All 3
-
-		// Calc Positions of window
-
-		Mid = (H * Split) / 100;
-
-		monHeight = Mid - Border;
-		termX = Mid;
-		termHeight = H - Mid - (inputheight + 3 * Border);
-
-		Sess->monWindow->setGeometry(QRect(Border, Border, Width, monHeight));
-		Sess->termWindow->setGeometry(QRect(Border, Mid + Border, Width, termHeight));
-
-		if (Sess->TTActive)
-		{
-			Sess->TTLabel->setGeometry(QRect(3, Mid + Border, 600, 475));
-//			Sess->termWindow->setVisible(false);
-			Sess->TTLabel->setVisible(true);
-		}
-		else
-		{
-//			Sess->termWindow->setVisible(true);
-			Sess->TTLabel->setVisible(false);
-		}
-
-		Sess->inputWindow->setGeometry(QRect(Border, H - (inputheight + Border), Width, inputheight));
-
-	}
-	else
-	{
-		// Should just be Mon only
-
-		Sess->monWindow->setGeometry(QRect(Border, Border, Width, H - 2 * Border));
-	}
-}
-
-
-extern "C" Ui_ListenSession * MHWindow;
-
-bool QtTermTCP::eventFilter(QObject* obj, QEvent *event)
-{
-	// See if from a Listening Session
-
-	Ui_ListenSession * Sess;
-
-	if (obj == MHWindow)
-	{
-		if (event->type() == QEvent::Resize)
-		{
-			QRect r = MHWindow->rect();
-
-			int H, Width, Border = 3;
-
-			Width = r.width() - 6;
-			H = r.height() - 6;
-
-			MHWindow->monWindow->setGeometry(QRect(Border, Border, Width, H));
-			return true;
-		}
-		if (event->type() == QEvent::Close)
-		{
-			QSettings mysettings(GetConfPath(), QSettings::IniFormat);
-			mysettings.setValue("MHgeometry", MHWindow->saveGeometry());
-			SaveSettings();
-			MHWindow = 0;
-		}
-	}
-
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		//	Sess = _sessions.at(i);	for (Ui_ListenSession * Sess : _sessions)
-		//	{
-		if (Sess == NULL)
-			continue;
-
-		if (Sess == obj)
-		{
-			if (event->type() == QEvent::Close)
-			{
-				// Window closing
-
-				// This only closed mon sessinos
-
-				if (Sess->AGWMonSession)
-					//					AGWMonWindowClosing(Sess);
-					AGWWindowClosing(Sess);
-
-				if (Sess->AGWSession)
-					AGWWindowClosing(Sess);
-
-				if (Sess->clientSocket)
-				{
-					int loops = 100;
-					Sess->clientSocket->disconnectFromHost();
-					while (Sess->clientSocket && loops-- && Sess->clientSocket->state() != QAbstractSocket::UnconnectedState)
-						QThread::msleep(10);
-				}
-				_sessions.removeOne(Sess);
-				return QMainWindow::eventFilter(obj, event);
-			}
-
-			if (event->type() == QEvent::Resize)
-			{
-				DoTermResize(Sess);
-			}
-		}
-
-		if (Sess->inputWindow == obj)
-		{
-			if (event->type() == QEvent::KeyPress)
-			{
-				QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
-
-				int key = keyEvent->key();
-				Qt::KeyboardModifiers modifier = keyEvent->modifiers();
-
-				if (modifier == Qt::ControlModifier)
-				{
-					char Msg[] = "\0\r";
-
-					if (key == Qt::Key_BracketLeft)
-						Msg[0] = 0x1b;
-					if (key == Qt::Key_Z)
-						Msg[0] = 0x1a;
-					else if (key == Qt::Key_C)
-						Msg[0] = 3;
-					else if (key == Qt::Key_D)
-						Msg[0] = 4;
-
-					if (Msg[0])
-					{
-						if (Sess->KISSSession)
-						{
-							// Send to ax.25 code
-
-							SendtoAX25(Sess->KISSSession, (unsigned char *)Msg, (int)strlen(Msg));
-						}
-						else if (Sess->AGWSession)
-						{
-							// Terminal is in AGWPE mode - send as AGW frame
-
-							AGW_AX25_data_in(Sess->AGWSession, (unsigned char *)Msg, (int)strlen(Msg));
-
-						}
-						else if (Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState)
-						{
-							Sess->clientSocket->write(Msg);
-						}
-
-						return true;
-					}
-				}
-
-				if (key == Qt::Key_Up)
-				{
-					// Scroll up
-
-					if (Sess->KbdStack[Sess->StackIndex] == NULL)
-						return true;
-
-					// If anything typed, stack part command
-
-					QByteArray stringData = Sess->inputWindow->text().toUtf8();
-
-					if (stringData.length() && Sess->StackIndex == 0)
-					{
-						if (Sess->KbdStack[49])
-							free(Sess->KbdStack[49]);
-
-						for (int i = 48; i >= 0; i--)
-						{
-							Sess->KbdStack[i + 1] = Sess->KbdStack[i];
-						}
-
-						Sess->KbdStack[0] = qstrdup(stringData.data());
-						Sess->StackIndex++;
-					}
-
-					Sess->inputWindow->setText(Sess->KbdStack[Sess->StackIndex]);
-					Sess->inputWindow->cursorForward(strlen(Sess->KbdStack[Sess->StackIndex]));
-
-					Sess->StackIndex++;
-					if (Sess->StackIndex == 50)
-						Sess->StackIndex = 49;
-
-					return true;
-				}
-				else if (key == Qt::Key_Down)
-				{
-					// Scroll down
-
-					if (Sess->StackIndex == 0)
-					{
-						Sess->inputWindow->setText("");
-						return true;
-					}
-
-					Sess->StackIndex--;
-
-					if (Sess->StackIndex && Sess->KbdStack[Sess->StackIndex - 1])
-					{
-						Sess->inputWindow->setText(Sess->KbdStack[Sess->StackIndex - 1]);
-						Sess->inputWindow->cursorForward(strlen(Sess->KbdStack[Sess->StackIndex - 1]));
-					}
-					else
-						Sess->inputWindow->setText("");
-
-					return true;
-				}
-				else if (key == Qt::Key_Return || key == Qt::Key_Enter)
-				{
-					LreturnPressed(Sess);
-					return true;
-				}
-
-				return false;
-			}
-
-			if (event->type() == QEvent::MouseButtonPress)
-			{
-				QMouseEvent *k = static_cast<QMouseEvent *> (event);
-
-				// Paste on Right Click
-
-				if (k->button() == Qt::RightButton)
-				{
-					// Get clipboard data and process a line at a time
-
-					QClipboard *clipboard = QGuiApplication::clipboard();
-					QString Text = clipboard->text();
-					QByteArray ba = Text.toLocal8Bit();
-					char * Msg = ba.data();
-
-
-					Sess->inputWindow->paste();
-					return true;
-				}
-				return QMainWindow::eventFilter(obj, event);
-			}
-		}
-	}
-	return QMainWindow::eventFilter(obj, event);
-}
-
-QAction * setupMenuLine(QMenu * Menu, char * Label, QObject * parent, int State)
-{
-	QAction * Act = new QAction(Label, parent);
-	if (Menu)
-		Menu->addAction(Act);
-
-	Act->setCheckable(true);
-	if (State)
-		Act->setChecked(true);
-
-	parent->connect(Act, SIGNAL(triggered()), parent, SLOT(menuChecked()));
-
-	Act->setFont(*menufont);
-
-	return Act;
-}
-
-// This now creates all window types - Term, Mon, Combined, Listen
-
-int xCount = 0;
-int sessNo = 0;
-
-Ui_ListenSession * newWindow(QObject * parent, int Type, const char * Label)
-{
-	Ui_ListenSession * Sess = new(Ui_ListenSession);
-
-	// Need to explicity initialise on Qt4
-
-	Sess->termWindow = NULL;
-	Sess->monWindow = NULL;
-	Sess->inputWindow = NULL;
-
-	for (int i = 0; i < 50; i++)
-		Sess->KbdStack[i] = NULL;
-
-	Sess->StackIndex = 0;
-	Sess->InputMode = 0;
-	Sess->SlowTimer = 0;
-	Sess->MonData = 0;
-	Sess->OutputSaveLen = 0;
-	Sess->MonSaveLen = 0;
-	Sess->PortMonString[0] = 0;
-	Sess->portmask = 0;
-	Sess->portmask = 1;
-	Sess->mtxparam = 1;
-	Sess->mlocaltime = 0;
-	Sess->mcomparam = 1;
-	Sess->monUI = 0;
-	Sess->MonitorNODES = 0;
-	Sess->MonitorColour = 1;
-	Sess->CurrentHost = 0;
-
-	Sess->SessionType = Type;
-	Sess->clientSocket = NULL;
-	Sess->AGWSession = NULL;
-	Sess->AGWMonSession = NULL;
-	Sess->KISSSession = NULL;
-	Sess->KISSMode = 0;
-	Sess->TTActive = 0;
-	Sess->TTFlashToggle = 0;
-	Sess->pageBuffer[0] = 0;
-	Sess->Tab = 0;
-
-	Sess->LogMonitor = false;
-	Sess->monSpan = (char *) "<span style=white-space:pre>";
-	Sess->monLogfile = nullptr;
-	Sess->sessNo = sessNo++;
-
-	_sessions.append(Sess);
-
-//	Sess->TT = new Ui_TeleTextDialog();
-
-//	Sess->TT->setupUi(&Sess->TTUI);
-
-//	Sess->TTUI.show();
-//	Sess->TTUI.raise();
-//	Sess->TTUI.activateWindow();
-
-	//	Sess->setObjectName(QString::fromUtf8("Sess"));
-
-	if (TermMode == MDI)
-	{
-		Sess->sw = mdiArea->addSubWindow(Sess);
-		//		Sess->installEventFilter(parent);
-
-		Sess->sw->resize(800, 600);
-	}
-	else if (TermMode == Tabbed)
-	{
-		Sess->Tab = xCount++;
-
-		if (Type == Mon)
-			tabWidget->addTab(Sess, "Monitor");
-		else
-			tabWidget->addTab(Sess, Label);
-	}
-
-	Sess->installEventFilter(parent);
-
-	QSettings settings(GetConfPath(), QSettings::IniFormat);
-
-#ifdef ANDROID
-    QFont font = QFont(settings.value("FontFamily", "Driod Sans Mono").value<QString>(),
-        settings.value("PointSize", 12).toInt(),
-        settings.value("Weight", 50).toInt());
-#else
-	QFont font = QFont(settings.value("FontFamily", "Courier New").value<QString>(),
-		settings.value("PointSize", 10).toInt(),
-		settings.value("Weight", 50).toInt());
-#endif
-
-	if ((Type & Mon))
-	{
-		Sess->monWindow = new QTextEdit(Sess);
-		Sess->monWindow->setReadOnly(1);
-		Sess->monWindow->document()->setMaximumBlockCount(10000);
-		Sess->monWindow->setFont(font);
-		Sess->monWindow->setStyleSheet(monStyleSheet);
-		mythis->connect(Sess->monWindow, SIGNAL(selectionChanged()), parent, SLOT(onTEselectionChanged()));
-	}
-
-	if ((Type & (Listen | Term)))
-	{
-		Sess->termWindow = new QTextEdit(Sess);
-		Sess->termWindow->setReadOnly(1);
-		Sess->termWindow->document()->setMaximumBlockCount(10000);
-		Sess->termWindow->setFont(font);
-		Sess->termWindow->setStyleSheet(termStyleSheet);
-
-		Sess->TTLabel = new QLabel(Sess);
-		Sess->TTLabel->setGeometry(QRect(0,0 ,500, 500));
-		Sess->TTLabel->setVisible(false);
-
-		Sess->TTBitmap = new QImage(40 * 15, 25 * 19, QImage::Format_RGB32);
-		Sess->TTBitmap->fill(Qt::black);
-
-/*
-
-		char Page[4096];
-
-		QFile file("/savepage.txt");
-		file.open(QIODevice::ReadOnly);
-		file.read(Page, 4096);
-		file.close();
-
-		Sess->TTActive = 1;
-		strcpy(Sess->pageBuffer, Page);
-		DecodeTeleText(Sess, Sess->pageBuffer);
-
-*/
-
-		Sess->TTLabel->setPixmap(QPixmap::fromImage(*Sess->TTBitmap));
-
-		Sess->TTLabel->setContextMenuPolicy(Qt::CustomContextMenu);
-		mythis->connect(Sess->TTLabel, SIGNAL(customContextMenuRequested(const QPoint&)),
-			parent, SLOT(showContextMenuL()));
-
-		mythis->connect(Sess->termWindow, SIGNAL(selectionChanged()), parent, SLOT(onTEselectionChanged()));
-
-		Sess->inputWindow = new QLineEdit(Sess);
-		Sess->inputWindow->installEventFilter(parent);
-		Sess->inputWindow->setFont(font);
-		Sess->inputWindow->setStyleSheet(inputStyleSheet);
-		Sess->inputWindow->setContextMenuPolicy(Qt::PreventContextMenu);
-
-		mythis->connect(Sess->inputWindow, SIGNAL(selectionChanged()), parent, SLOT(onLEselectionChanged()));
-	}
-
-	if (Type == Term || Type == Listen)
-	{
-		// Term Only or Listen Only
-
-		Sess->termWindow->setContextMenuPolicy(Qt::CustomContextMenu);
-
-		mythis->connect(Sess->termWindow, SIGNAL(customContextMenuRequested(const QPoint&)),
-			parent, SLOT(showContextMenuT(const QPoint &)));
-
-	}
-
-	if (Type == Mon)
-	{
-		// Monitor Only
-
-		Sess->monWindow->setContextMenuPolicy(Qt::CustomContextMenu);
-
-		mythis->connect(Sess->monWindow, SIGNAL(customContextMenuRequested(const QPoint&)),
-			parent, SLOT(showContextMenuMOnly(const QPoint &)));
-
-	}
-
-	if (Type == (Term | Mon))
-	{
-		// Combined Term and Mon. Add Custom Menu to set Mon/Term Split with Right Click
-
-		Sess->monWindow->setContextMenuPolicy(Qt::CustomContextMenu);
-		Sess->termWindow->setContextMenuPolicy(Qt::CustomContextMenu);
-
-
-		mythis->connect(Sess->monWindow, SIGNAL(customContextMenuRequested(const QPoint&)),
-			parent, SLOT(showContextMenuM(const QPoint &)));
-
-		mythis->connect(Sess->termWindow, SIGNAL(customContextMenuRequested(const QPoint&)),
-			parent, SLOT(showContextMenuMT(const QPoint &)));
-	}
-
-	if (Sess->SessionType == Mon)			// Mon Only
-		Sess->setWindowTitle("Monitor Session Disconnected");
-	else if (Sess->SessionType == Listen)			// Mon Only
-		Sess->setWindowTitle("Listen Window Disconnected");
-	else
-		Sess->setWindowTitle("Disconnected");
-
-	Sess->installEventFilter(mythis);
-
-	Sess->show();
-
-	int pos = (_sessions.size() - 1) * 20;
-
-	if (TermMode == MDI)
-	{
-		Sess->sw->move(pos, pos);
-	}
-
-	QSize Size(800, 602);						// Not actually used, but Event constructor needs it
-
-	QResizeEvent event(Size, Size);
-
-	QApplication::sendEvent(Sess, &event);		// Resize Widgets to fix Window
-
-	return Sess;
-}
-
-QByteArray timeLoaded = QDateTime::currentDateTime().toString("yymmdd_hhmmss").toUtf8();
-
-QtTermTCP::QtTermTCP(QWidget *parent) : QMainWindow(parent)
-{
-	int i;
-	char Title[80];
-
-	// Get configuration path for MacOS.
-	std::string directory = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).at(0).toStdString();
-	std::string conf_path = directory + "/QtTermTCP.ini";
-
-	//mkdir(directory.c_str(), 0775);
-
-	_server = new QTcpServer();
-
-	mythis = this;
-
-	ui.setupUi(this);
-
-	initUTF8();
-
-	mymenuBar = new QMenuBar(this);
-	mymenuBar->setGeometry(QRect(0, 0, 781, 26));
-	setMenuBar(mymenuBar);
-
-	toolBar = new QToolBar(this);
-	toolBar->setObjectName("mainToolbar");
-	addToolBar(Qt::BottomToolBarArea, toolBar);
-
-	QSettings mysettings(GetConfPath(), QSettings::IniFormat);
-
-	restoreGeometry(mysettings.value("geometry").toByteArray());
-	restoreState(mysettings.value("windowState").toByteArray());
-
-	GetSettings();
-
-	GetKeyWordFile();
-
-	// Set background colours
-
-	sprintf(monStyleSheet, "background-color: rgb(%d, %d, %d);",
-		monBackground.red(), monBackground.green(), monBackground.blue());
-
-	sprintf(termStyleSheet, "background-color: rgb(%d, %d, %d);",
-		termBackground.red(), termBackground.green(), termBackground.blue());
-
-	sprintf(inputStyleSheet, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		inputText.red(), inputText.green(), inputText.blue(),
-		inputBackground.red(), inputBackground.green(), inputBackground.blue());
-
-
-#ifdef ANDROID
-	menufont = new QFont(mysettings.value("MFontFamily", "Driod Sans").value<QString>(),
-		mysettings.value("MPointSize", 12).toInt(),
-		mysettings.value("MWeight", 50).toInt());
-#else
-	menufont = new QFont(mysettings.value("MFontFamily", "Aerial").value<QString>(),
-		mysettings.value("MPointSize", 10).toInt(),
-		mysettings.value("MWeight", 50).toInt());
-
-#endif
-	if (TermMode == MDI)
-	{
-		mdiArea = new QMdiArea(ui.centralWidget);
-		mdiArea->setGeometry(QRect(0, 0, 771, 571));
-
-		mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-		mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-
-		connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(xon_mdiArea_changed()));
-
-		setCentralWidget(mdiArea);
-	}
-	else if (TermMode == Tabbed)
-	{
-		Ui_ListenSession * Sess;
-		int index = 0;
-	
-		tabWidget = new QTabWidget(this);
-		QTabBar* tabBar = tabWidget->tabBar();
-
-//		QString style1 = "QTabWidget::tab-bar{left:0;}";  //  for Mac
-//		tabWidget->setStyleSheet(style1);
-
-		QString style = "QTabBar::tab:selected{background-color: #d0d0d0;} QTabBar::tab:!selected{background-color: #f0f0f0;}";
-
-		tabBar->setStyleSheet(style);
-
-		tabWidget->setContextMenuPolicy(Qt::CustomContextMenu);
-
-		connect(tabWidget, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &)));
-
-		ui.verticalLayout->addWidget(tabWidget);
-		tabWidget->setTabPosition(QTabWidget::South);
-
-		Sess = newWindow(this, TabType[0], "Sess 1");
-		Sess->CurrentHost = currentHost[index++];
-		Sess = newWindow(this, TabType[1], "Sess 2");
-		Sess->CurrentHost = currentHost[index++];
-		Sess = newWindow(this, TabType[2], "Sess 3");
-		Sess->CurrentHost = currentHost[index++];
-		Sess = newWindow(this, TabType[3], "Sess 4");
-		Sess->CurrentHost = currentHost[index++];
-		Sess = newWindow(this, TabType[4], "Sess 5");
-		Sess->CurrentHost = currentHost[index++];
-		Sess = newWindow(this, TabType[5], "Sess 6");
-		Sess->CurrentHost = currentHost[index++];
-		Sess = newWindow(this, TabType[6], "Sess 7");
-		Sess->CurrentHost = currentHost[index++];
-		Sess = newWindow(this, TabType[7], "Monitor");
-		Sess->CurrentHost = currentHost[index++];
-		Sess = newWindow(this, TabType[8], "Monitor");
-		Sess->CurrentHost = currentHost[index++];
-
-		ActiveSession = _sessions.at(0);
-
-		connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabSelected(int)));
-
-		tabWidget->setFont(*menufont);
-
-	}
-
-	sprintf(Title, "QtTermTCP Version %s", VersionString);
-
-	this->setWindowTitle(Title);
-
-	//#ifdef ANDROID
-	//	mymymenuBar->setVisible(false);
-	//#endif
-
-	if (TermMode == Single)
-		windowMenu = mymenuBar->addMenu("");
-	else
-		windowMenu = mymenuBar->addMenu(tr("&Window"));
-
-	connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));
-	windowMenu->setFont(*menufont);
-
-	newTermAct = new QAction(tr("New Terminal Window"), this);
-	connect(newTermAct, SIGNAL(triggered()), this, SLOT(doNewTerm()));
-
-	newMonAct = new QAction(tr("New Monitor Window"), this);
-	connect(newMonAct, SIGNAL(triggered()), this, SLOT(doNewMon()));
-
-	newCombinedAct = new QAction(tr("New Combined Term/Mon Window"), this);
-	connect(newCombinedAct, SIGNAL(triggered()), this, SLOT(doNewCombined()));
-
-	if (TermMode == MDI)
-	{
-		closeAct = new QAction(tr("Cl&ose"), this);
-		closeAct->setStatusTip(tr("Close the active window"));
-		connect(closeAct, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow()));
-
-		closeAllAct = new QAction(tr("Close &All"), this);
-		closeAllAct->setStatusTip(tr("Close all the windows"));
-		connect(closeAllAct, SIGNAL(triggered()), mdiArea, SLOT(closeAllSubWindows()));
-
-		tileAct = new QAction(tr("&Tile"), this);
-		tileAct->setStatusTip(tr("Tile the windows"));
-		connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows()));
-
-		cascadeAct = new QAction(tr("&Cascade"), this);
-		cascadeAct->setStatusTip(tr("Cascade the windows"));
-		connect(cascadeAct, SIGNAL(triggered()), this, SLOT(doCascade()));
-
-		nextAct = new QAction(tr("Ne&xt"), this);
-		nextAct->setShortcuts(QKeySequence::NextChild);
-		nextAct->setStatusTip(tr("Move the focus to the next window"));
-		connect(nextAct, SIGNAL(triggered()), mdiArea, SLOT(activateNextSubWindow()));
-
-		previousAct = new QAction(tr("Pre&vious"), this);
-		previousAct->setShortcuts(QKeySequence::PreviousChild);
-		previousAct->setStatusTip(tr("Move the focus to the previous window"));
-		connect(previousAct, SIGNAL(triggered()), mdiArea, SLOT(activatePreviousSubWindow()));
-	}
-
-	quitAction = new QAction(tr("&Quit"), this);
-	connect(quitAction, SIGNAL(triggered()), this, SLOT(doQuit()));
-
-	windowMenuSeparatorAct = new QAction(this);
-	windowMenuSeparatorAct->setSeparator(true);
-
-	updateWindowMenu();
-
-	if (KISSEnable && KISSMH)
-	{
-		newMHWindow(this, 0, "KISS MH");
-		MHWindow->restoreGeometry(mysettings.value("MHgeometry").toByteArray());
-	}
-
-	connectMenu = mymenuBar->addMenu(tr("&Connect"));
-
-	actHost[16] = new QAction("AGW Connect", this);
-	actHost[16]->setFont(*menufont);
-	actHost[16]->setVisible(0);
-	connectMenu->addAction(actHost[16]);
-
-	connect(actHost[16], SIGNAL(triggered()), this, SLOT(Connect()));
-
-	actHost[17] = new QAction("VARA Connect", this);
-	actHost[17]->setFont(*menufont);
-	actHost[17]->setVisible(0);
-	connectMenu->addAction(actHost[17]);
-
-	connect(actHost[17], SIGNAL(triggered()), this, SLOT(Connect()));
-
-	actHost[18] = new QAction("KISS Connect", this);
-	actHost[18]->setFont(*menufont);
-	actHost[18]->setVisible(KISSEnable);
-	actHost[18]->setEnabled(0);
-	connectMenu->addAction(actHost[18]);
-
-	connect(actHost[18], SIGNAL(triggered()), this, SLOT(Connect()));
-	
-	for (i = 0; i < MAXHOSTS; i++)
-	{
-		if (SessName[i][0])
-		{
-			char Lable[256];
-			sprintf(Lable, "%s(%s)", Host[i], SessName[i]);
-			actHost[i] = new QAction(Lable, this);
-		}
-		else
-			actHost[i] = new QAction(Host[i], this);
-
-		actHost[i]->setFont(*menufont);
-		connectMenu->addAction(actHost[i]);
-		connect(actHost[i], SIGNAL(triggered()), this, SLOT(Connect()));
-	}
-
-	discAction = mymenuBar->addAction("&Disconnect");
-
-	// Place discAction in mac app menu, otherwise it doesn't appear
-	if (is_mac == true) {
-		QMenu * app_menu = mymenuBar->addMenu("App Menu");
-		discAction->setMenuRole(QAction::ApplicationSpecificRole);
-		app_menu->addAction(discAction);
-
-	}
-
-	connect(discAction, SIGNAL(triggered()), this, SLOT(Disconnect()));
-	discAction->setEnabled(false);
-
-	toolBar->setFont(*menufont);
-
-#ifndef ANDROID
-	toolBar->setVisible(false);
-#endif
-	but4 = new QToolButton();
-	but4->setPopupMode(QToolButton::InstantPopup);
-	but4->setText("Window");
-	but4->addAction(windowMenu->menuAction());
-	but4->setFont(*menufont);
-	toolBar->addWidget(but4);
-
-	but5 = new QToolButton();
-	but5->setPopupMode(QToolButton::InstantPopup);
-	but5->setText("Connect");
-	but5->addAction(connectMenu->menuAction());
-	but5->setFont(*menufont);
-
-	toolBar->addWidget(but5);
-
-	toolBar->addAction(discAction);
-
-	setupMenu = mymenuBar->addMenu(tr("&Setup"));
-	hostsubMenu = setupMenu->addMenu("Hosts");
-	hostsubMenu->setFont(*menufont);
-
-	for (i = 0; i < MAXHOSTS; i++)
-	{
-		if (Host[i][0])
-		{
-			char Label[256];
-
-			if (SessName[i][0])
-				sprintf(Label, "%s(%s)", Host[i], SessName[i]);
-			else
-				strcpy(Label, Host[i]);
-
-			actSetup[i] = new QAction(Label, this);
-		}
-		else
-			actSetup[i] = new QAction("New Host", this);
-
-		hostsubMenu->addAction(actSetup[i]);
-		connect(actSetup[i], SIGNAL(triggered()), this, SLOT(SetupHosts()));
-
-		actSetup[i]->setFont(*menufont);
-	}
-
-
-	// Setup Presentation Options
-
-	setupMenu->addSeparator()->setText(tr("Presentation"));
-
-	QActionGroup * termGroup = new QActionGroup(this);
-
-	singleAct = setupMenuLine(nullptr, (char *)"Single Window (Term + Mon)", this, (TermMode == Single) && (singlemodeFormat == Term + Mon));
-	singleAct2 = setupMenuLine(nullptr, (char *)"Single Window (Term only)", this, (TermMode == Single) && (singlemodeFormat == Term));
-	MDIAct = setupMenuLine(nullptr, (char *)"MDI", this, TermMode == MDI);
-	tabbedAct = setupMenuLine(nullptr, (char *)"Tabbed", this, TermMode == Tabbed);
-
-	termGroup->addAction(singleAct);
-	termGroup->addAction(singleAct2);
-	termGroup->addAction(MDIAct);
-	termGroup->addAction(tabbedAct);
-
-	setupMenu->addAction(singleAct);
-	setupMenu->addAction(singleAct2);
-	setupMenu->addAction(MDIAct);
-	setupMenu->addAction(tabbedAct);
-	setupMenu->addSeparator();
-	AlertAction = new QAction("Sound Alerts Setup", this);
-
-	setupMenu->addAction(AlertAction);
-	connect(AlertAction, SIGNAL(triggered()), this, SLOT(AlertSlot()));
-	AlertAction->setFont(*menufont);
-	setupMenu->addSeparator();
-
-	actFonts = new QAction("Terminal Font", this);
-	setupMenu->addAction(actFonts);
-	connect(actFonts, SIGNAL(triggered()), this, SLOT(doFonts()));
-	actFonts->setFont(*menufont);
-
-	actmenuFont = new QAction("Menu Font", this);
-	setupMenu->addAction(actmenuFont);
-	connect(actmenuFont, SIGNAL(triggered()), this, SLOT(doMFonts()));
-	actmenuFont->setFont(*menufont);
-
-	actColours = new QAction("Choose Colours", this);
-	setupMenu->addAction(actColours);
-	connect(actColours, SIGNAL(triggered()), this, SLOT(doColours()));
-	actColours->setFont(*menufont);
-
-	setupMenu->addSeparator();
-
-	AGWAction = new QAction("AGW Setup", this);
-	setupMenu->addAction(AGWAction);
-	connect(AGWAction, SIGNAL(triggered()), this, SLOT(AGWSlot()));
-	AGWAction->setFont(*menufont);
-
-	VARAAction = new QAction("VARA Setup", this);
-	setupMenu->addAction(VARAAction);
-	connect(VARAAction, SIGNAL(triggered()), this, SLOT(VARASlot()));
-	VARAAction->setFont(*menufont);
-
-	KISSAction = new QAction("KISS Setup", this);
-	setupMenu->addAction(KISSAction);
-	connect(KISSAction, SIGNAL(triggered()), this, SLOT(KISSSlot()));
-	KISSAction->setFont(*menufont);
-
-	setupMenu->addSeparator();
-
-	actChatMode = setupMenuLine(setupMenu, (char *)"Chat Terminal Mode (Send Keepalives)", this, ChatMode);
-	actAutoTeletext = setupMenuLine(setupMenu, (char *)"Auto switch to Teletext", this, AutoTeletext);
-	actStripLF = setupMenuLine(setupMenu, (char *)"Strip Line Feeds", this, StripLF);
-
-	setupMenu->addSeparator();
-
-	setupMenu->addAction(new QAction("Interpret non-UTF8 input as:", this));
-	setupMenu->setFont(*menufont);
-
-	QActionGroup * cpGroup = new QActionGroup(this);
-
-	actnoConv = setupMenuLine(nullptr, (char *)"   Don't Convert (assume is UTF-8)", this, convUTF8 == -1);
-	actAuto = setupMenuLine(nullptr, (char *)"   Auto", this, convUTF8 == 0);
-	actCP1251 = setupMenuLine(nullptr, (char *)"   CP1251 (Cyrillic)", this, convUTF8 == 1251);
-	actCP1252 = setupMenuLine(nullptr, (char *)"   CP1252 (Western Europe)", this, convUTF8 == 1252);
-	actCP437 = setupMenuLine(nullptr, (char *)"   CP437 (Windows Line Draw)", this, convUTF8 == 437);
-
-	cpGroup->addAction(actnoConv);
-	cpGroup->addAction(actAuto);
-	cpGroup->addAction(actCP1251);
-	cpGroup->addAction(actCP1252);
-	cpGroup->addAction(actCP437);
-
-	setupMenu->addAction(actnoConv);
-	setupMenu->addAction(actAuto);
-	setupMenu->addAction(actCP1251);
-	setupMenu->addAction(actCP1252);
-	setupMenu->addAction(actCP437);
-
-	monitorMenu = mymenuBar->addMenu(tr("&Monitor"));
-
-	EnableMonitor = setupMenuLine(monitorMenu, (char *)"Enable Monitoring", this, 0);
-	EnableMonitor->setVisible(0);
-	EnableMonLog = setupMenuLine(monitorMenu, (char *)"Log to File", this, 0);
-	MonLocalTime = setupMenuLine(monitorMenu, (char *)"Use local time", this, 0);
-	MonTX = setupMenuLine(monitorMenu, (char *)"Monitor TX", this, 1);
-	MonSup = setupMenuLine(monitorMenu, (char *)"Monitor Supervisory", this, 1);
-	MonUI = setupMenuLine(monitorMenu, (char *)"Only Monitor UI Frames", this, 0);
-	MonNodes = setupMenuLine(monitorMenu, (char *)"Monitor NODES Broadcasts", this, 0);
-	MonColour = setupMenuLine(monitorMenu, (char *)"Enable Colour", this, 1);
-
-	for (i = 0; i < MAXPORTS + 1; i++)
-	{
-		MonPort[i] = setupMenuLine(monitorMenu, (char *)"Port", this, 0);
-		MonPort[i]->setVisible(false);
-	}
-
-	but1 = new QToolButton();
-	but1->setPopupMode(QToolButton::InstantPopup);
-	but1->setText("Monitor");
-	but1->addAction(monitorMenu->menuAction());
-	toolBar->addWidget(but1);
-
-	but2 = new QToolButton();
-	but2->setPopupMode(QToolButton::InstantPopup);
-	but2->setText("Setup");
-	but2->addAction(setupMenu->menuAction());
-	toolBar->addWidget(but2);
-
-	ListenAction = mymenuBar->addAction("&Listen");
-	connect(ListenAction, SIGNAL(triggered()), this, SLOT(ListenSlot()));
-
-
-	// Place Listen Action in mac app menu, otherwise it doesn't appear
-	if (is_mac == true)
-	{
-		QMenu * app_menu = mymenuBar->addMenu("App Menu");
-		ListenAction->setMenuRole(QAction::ApplicationSpecificRole);
-		app_menu->addAction(ListenAction);
-	}
-
-	toolBar->addAction(ListenAction);
-
-	YAPPMenu = mymenuBar->addMenu(tr("&YAPP"));
-
-	YAPPSend = new QAction("Send File", this);
-	YAPPSetRX = new QAction("Set Receive Directory", this);
-	YAPPSetSize = new QAction("Set Max Size", this);
-	YAPPSend->setFont(*menufont);
-	YAPPSetRX->setFont(*menufont);
-	YAPPSetSize->setFont(*menufont);
-
-	YAPPMenu->addAction(YAPPSend);
-	YAPPMenu->addAction(YAPPSetRX);
-	YAPPMenu->addAction(YAPPSetSize);
-	YAPPSend->setEnabled(false);
-
-	connect(YAPPSend, SIGNAL(triggered()), this, SLOT(doYAPPSend()));
-	connect(YAPPSetRX, SIGNAL(triggered()), this, SLOT(doYAPPSetRX()));
-	connect(YAPPSetSize, SIGNAL(triggered()), this, SLOT(doYAPPSetSize()));
-
-	but3 = new QToolButton();
-	but3->setPopupMode(QToolButton::InstantPopup);
-	but3->setText("YAPP");
-	but3->addAction(YAPPMenu->menuAction());
-	but3->setFont(*menufont);
-	toolBar->addWidget(but3);
-
-	toolBar->setFont(*menufont);
-
-	// Set up Status Bar
-
-	setStyleSheet("QStatusBar{border-top: 1px outset black;} QStatusBar::item { border: 1px solid black; border-radius: 3px;}");
-	//	setStyleSheet("QStatusBar{border-top: 1px outset black;}");
-
-
-	Status4 = new QLabel("");
-	Status3 = new QLabel("         ");
-	Status2 = new QLabel("    ");
-	Status1 = new QLabel("  Disconnected  ");
-
-	Status1->setMinimumWidth(100);
-	Status2->setMinimumWidth(100);
-	Status3->setMinimumWidth(100);
-	Status4->setMinimumWidth(100);
-
-	myStatusBar = statusBar();
-
-	statusBar()->addPermanentWidget(Status4);
-	statusBar()->addPermanentWidget(Status3);
-	statusBar()->addPermanentWidget(Status2);
-	statusBar()->addPermanentWidget(Status1);
-
-	statusBar()->setVisible(AGWEnable | VARAEnable | KISSEnable);
-	// Restore saved sessions
-
-	if (TermMode == Single)
-	{
-		Ui_ListenSession * Sess = newWindow(this, singlemodeFormat);
-
-		ActiveSession = Sess;
-		Sess->CurrentHost = currentHost[0];
-
-		ui.verticalLayout->addWidget(Sess);
-
-		connectMenu->setEnabled(true);
-		discAction->setEnabled(false);
-		YAPPSend->setEnabled(false);
-	}
-
-	if (TermMode == MDI)
-	{
-		int n = atoi(sessionList);
-		int index = 0;
-
-		char *p, *Context;
-		char delim[] = "|";
-
-		int type = 0, host = 0, topx, leftx, bottomx, rightx;
-
-		p = strtok_s((char *)sessionList, delim, &Context);
-
-		while (n--)
-		{
-			p = strtok_s(NULL, delim, &Context);
-
-			sscanf(p, "%d,%d,%d,%d,%d,%d", &type, &host, &topx, &leftx, &bottomx, &rightx);
-
-			Ui_ListenSession * Sess = newWindow(this, type);
-
-			Sess->CurrentHost = currentHost[index++];;
-
-			QRect r(leftx, topx, rightx - leftx, bottomx - topx);
-
-			Sess->sw->setGeometry(r);
-			Sess->sw->move(leftx, topx);
-
-		}
-	}
-
-	QTimer *timer = new QTimer(this);
-	connect(timer, SIGNAL(timeout()), this, SLOT(MyTimerSlot()));
-	timer->start(10000);
-
-	QTimer *timer2 = new QTimer(this);
-	connect(timer2, SIGNAL(timeout()), this, SLOT(KISSTimerSlot()));
-	timer2->start(100);
-
-	QTimer *timer3 = new QTimer(this);
-	connect(timer3, SIGNAL(timeout()), this, SLOT(SlowTimerSlot()));
-	timer3->start(60000);
-
-	// Run timer now to connect to AGW if configured
-
-	MyTimerSlot();
-
-	if (listenEnable)
-		_server->listen(QHostAddress::Any, listenPort);
-
-	connect(_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
-
-	setFonts();
-
-	if (VARAEnable)
-		OpenPTTPort();
-
-	memset(axMYCALL, 0, 7);
-	ConvToAX25(KISSMYCALL, axMYCALL);
-
-	// Do any autoconnects
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		if (AutoConnect[i] > 0)
-		{
-			Ui_ListenSession * Sess = _sessions.at(i);
-			
-			Sess->clientSocket = new myTcpSocket();
-			Sess->clientSocket->Sess = Sess;
-
-			connect(Sess->clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
-			connect(Sess->clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
-			connect(Sess->clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
-
-			Sess->clientSocket->connectToHost(&Host[Sess->CurrentHost][0], Port[Sess->CurrentHost]);
-		}
-	}
-
-}
-
-void QtTermTCP::showContextMenu(const QPoint &point)
-{
-	if (point.isNull())
-		return;
-
-	QTabBar* tabBar = tabWidget->tabBar();
-	QRect Wrect = tabWidget->rect();
-	QRect Brect = tabBar->rect();
-	QPoint myPoint = point;
-
-	// Get x coordinate of first tab (on Mac tabs are centre aligned)
-
-	QRect rect = tabWidget->tabBar()->geometry();
-	int left = rect.left();
-
-
-	int n = myPoint.y() - (Wrect.height() - Brect.height());
-	myPoint.setY(n); 
-	n = myPoint.x() - left;
-
-	myPoint.setX(n);
-
-	int tabIndex =  tabBar->tabAt(myPoint);
-
-	QMenu menu(this);
-
-	QAction * Act = new QAction("AutoConnect on load", this);
-	Act->setObjectName(QString::number(tabIndex));
-
-	menu.addAction(Act);
-
-	Act->setCheckable(true);
-
-	if (AutoConnect[tabIndex] <= 0)
-		Act->setChecked(false);
-	else
-		Act->setChecked(true);
-
-	connect(Act, SIGNAL(triggered()), this, SLOT(autoConnectChecked()));
-
-	menu.exec(tabWidget->mapToGlobal(point));
-
-}
-
-void QtTermTCP::autoConnectChecked()
-{
-	QAction * Act = static_cast<QAction*>(QObject::sender());
-	QString Tab = Act->objectName();
-	int tabNo = Tab.toInt();
-
-	tabWidget->setCurrentIndex(tabNo);
-	
-	Ui_ListenSession *Sess = (Ui_ListenSession *)tabWidget->currentWidget();
-	int state = Act->isChecked();
-
-	if (state == 0)
-		AutoConnect[tabNo] = 0;
-	else
-	{
-		if (Sess->clientSocket)		// Connected
-			AutoConnect[tabNo] = 1;
-		else
-			AutoConnect[tabNo] = 0;
-	}
-}
-
-
-void QtTermTCP::setFonts()
-{
-	windowMenu->menuAction()->setFont(*menufont);
-	connectMenu->menuAction()->setFont(*menufont);
-	setupMenu->menuAction()->setFont(*menufont);
-	monitorMenu->menuAction()->setFont(*menufont);
-	YAPPMenu->menuAction()->setFont(*menufont);
-
-	if (tabWidget)
-		tabWidget->setFont(*menufont);
-	mymenuBar->setFont(*menufont);
-	toolBar->setFont(*menufont);
-	but1->setFont(*menufont);
-	but2->setFont(*menufont);
-	but3->setFont(*menufont);
-	but4->setFont(*menufont);
-	but5->setFont(*menufont);
-	discAction->setFont(*menufont);
-	ListenAction->setFont(*menufont);
-
-	for (int i = 0; i < MAXHOSTS; i++)
-	{
-		actHost[i]->setFont(*menufont);
-		actSetup[i]->setFont(*menufont);
-	}
-
-	actHost[16]->setFont(*menufont);			// AGW  Host
-}
-
-void QtTermTCP::doQuit()
-{
-	if (_server->isListening())
-		_server->close();
-
-	SaveSettings();
-
-	QCoreApplication::quit();
-}
-
-void FlashifNotActive()
-{
-	if (!mythis->isActiveWindow())
-		QApplication::alert(mythis, 0);
-}
-
-
-// "Copy on select" Code
-
-
-void QtTermTCP::onTEselectionChanged()
-{
-	QTextEdit * x = static_cast<QTextEdit*>(QObject::sender());
-
-	if (isActiveWindow())
-		x->copy();
-}
-
-void QtTermTCP::onLEselectionChanged()
-{
-	QLineEdit * x = static_cast<QLineEdit*>(QObject::sender());
-	if (isActiveWindow())
-		x->copy();
-}
-
-void QtTermTCP::setVDMode()
-{
-	QAction * sender = static_cast<QAction*>(QObject::sender());
-
-	QTextEdit * window = static_cast<QTextEdit*>(sender->parentWidget());
-
-	// Need to find session with this window as owner
-
-	Ui_ListenSession * Sess = NULL;
-
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		if (Sess->termWindow == window)
-		{
-			Sess->TTActive ^= 1;
-			DoTermResize(Sess);
-			break;
-		}
-	}
-}
-
-int splitY;					// Value when menu added
-
-void QtTermTCP::setSplit()
-{
-	QAction * sender = static_cast<QAction*>(QObject::sender());
-
-	QWidget * Parent = sender->parentWidget();
-
-	if (Parent)
-		Parent = Parent->parentWidget();
-
-	int y = Parent->rect().height() - 50;
-
-	// y is height of whole windom. splitX is new split position
-	// So split = 100 * splitx/x
-
-	Split = (splitY * 100) / y;
-
-	if (Split < 10)
-		Split = 10;
-	else if (Split > 90)
-		Split = 90;
-
-	QSize size(800, 602);
-	QResizeEvent event(size, size);
-
-	eventFilter(Parent, &event);
-}
-
-void QtTermTCP::ClearScreen()
-{
-	QAction * sender = static_cast<QAction*>(QObject::sender());
-	QTextEdit * window = static_cast<QTextEdit*>(sender->parentWidget());
-	window->clear();
-}
-
-
-void QtTermTCP::showContextMenuMT(const QPoint &pt)				// Term Window
-{
-	// Monitor and Terminal (Term Half)
-
-	QTextEdit* sender = static_cast<QTextEdit*>(QObject::sender());
-
-	QMenu *menu = sender->createStandardContextMenu();
-
-	QString style = "QMenu {border-radius:15px; background-color: white;margin: 2px; border: 1px solid rgb(58, 80, 116); color:  rgb(58, 80, 116);}QMenu::separator {height: 2px;background: rgb(58, 80, 116);margin-left: 10px;margin-right: 5px;}";
-	menu->setStyleSheet(style);
-
-	QAction * actSplit = new QAction("Set Monitor/Output Split", sender);
-	QAction * actVDMode = new QAction("Toggle Viewdata Mode", sender);
-	QAction * actClear = new QAction("Clear Screen Buffer", sender);
-
-	menu->addAction(actSplit);
-	menu->addAction(actVDMode);
-	menu->addAction(actClear);
-
-	splitY = pt.y() + termX;
-
-	connect(actSplit, SIGNAL(triggered()), this, SLOT(setSplit()));
-	connect(actVDMode, SIGNAL(triggered()), this, SLOT(setVDMode()));
-	connect(actClear, SIGNAL(triggered()), this, SLOT(ClearScreen()));
-
-	menu->exec(sender->mapToGlobal(pt));
-	delete menu;
-}
-
-void QtTermTCP::showContextMenuMOnly(const QPoint &pt)
-{
-	// Monitor only
-
-	QTextEdit* sender = static_cast<QTextEdit*>(QObject::sender());
-
-	QMenu *menu = sender->createStandardContextMenu();
-
-	QString style = "QMenu {border-radius:15px; background-color: white;margin: 2px; border: 1px solid rgb(58, 80, 116); color:  rgb(58, 80, 116);}QMenu::separator {height: 2px;background: rgb(58, 80, 116);margin-left: 10px;margin-right: 5px;}";
-	menu->setStyleSheet(style);
-
-	QAction * actClear = new QAction("Clear Screen Buffer", sender);
-
-	menu->addAction(actClear);
-	connect(actClear, SIGNAL(triggered()), this, SLOT(ClearScreen()));
-
-	menu->exec(sender->mapToGlobal(pt));
-	delete menu;
-}
-
-
-void QtTermTCP::showContextMenuT(const QPoint &pt)				// Term Window
-{
-	// Just Terminal 
-
-	QTextEdit* sender = static_cast<QTextEdit*>(QObject::sender());
-
-	QMenu *menu = sender->createStandardContextMenu();
-
-	QString style = "QMenu {border-radius:15px; background-color: white;margin: 2px; border: 1px solid rgb(58, 80, 116); color:  rgb(58, 80, 116);}";
-	menu->setStyleSheet(style);
-
-
-	QAction * actVDMode = new QAction("Toggle Viewdata Mode", sender);
-	QAction * actClear = new QAction("Clear Screen Buffer", sender);
-
-	menu->addAction(actVDMode);
-	menu->addAction(actClear);
-
-	connect(actVDMode, SIGNAL(triggered()), this, SLOT(setVDMode()));
-	connect(actClear, SIGNAL(triggered()), this, SLOT(ClearScreen()));
-
-	menu->exec(sender->mapToGlobal(pt));
-	delete menu;
-}
-
-
-void QtTermTCP::showContextMenuL()				// Term Window
-{
-	// Teletext Label Right Clicked - cancel TT Mode
-
-	QLabel * sender = static_cast<QLabel*>(QObject::sender());
-
-	// Need to find session with this label as owner
-
-	Ui_ListenSession * Sess = NULL;
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		if (Sess->TTLabel == sender)
-		{
-			Sess->TTActive ^= 1;
-
-			DoTermResize(Sess);
-			break;
-		}
-	}
-}
-
-
-void QtTermTCP::showContextMenuM(const QPoint &pt)				// Mon Window
-{
-	QTextEdit* sender = static_cast<QTextEdit*>(QObject::sender());
-
-	QMenu *menu = sender->createStandardContextMenu();
-	QString style = "QMenu {border-radius:15px; background-color: white;margin: 2px; border: 1px solid rgb(58, 80, 116); color:  rgb(58, 80, 116);}";
-	menu->setStyleSheet(style);
-
-	QAction * actSplit = new QAction("Set Monitor/Output Split", sender);
-	QAction * actClear = new QAction("Clear Screen Buffer", sender);
-
-	menu->addAction(actSplit);
-	menu->addAction(actClear);
-
-	splitY = pt.y();
-
-	connect(actSplit, SIGNAL(triggered()), this, SLOT(setSplit()));
-	connect(actClear, SIGNAL(triggered()), this, SLOT(ClearScreen()));
-
-	menu->exec(sender->mapToGlobal(pt));
-	delete menu;
-}
-
-extern "C" void setMenus(int State)
-{
-	// Sets Connect, Disconnect and YAPP Send  enable flags to match connection state
-
-	if (State)
-	{
-		connectMenu->setEnabled(false);
-		discAction->setEnabled(true);
-		YAPPSend->setEnabled(true);
-	}
-	else
-	{
-		connectMenu->setEnabled(true);
-		discAction->setEnabled(false);
-		YAPPSend->setEnabled(false);
-	}
-}
-
-extern "C" void SetSessLabel(Ui_ListenSession * Sess, char * label)
-{
-	if (TermMode == MDI)
-		Sess->setWindowTitle(label);
-	else if (TermMode == Tabbed)
-		tabWidget->setTabText(Sess->Tab, label);
-	else if (TermMode == Single)
-		mythis->setWindowTitle(label);
-}
-
-
-extern "C" void ClearSessLabel(Ui_ListenSession * Sess)
-{
-	if (TermMode == MDI)
-	{
-		if (Sess->SessionType == Mon)			// Mon Only
-			Sess->setWindowTitle("Monitor Session Disconnected");
-		else if (Sess->SessionType == Listen)			// Mon Only
-			Sess->setWindowTitle("Listen Window Disconnected");
-		else
-			Sess->setWindowTitle("Disconnected");
-	}
-	else if (TermMode == Tabbed)
-	{
-		if (Sess->SessionType == Mon)			// Mon Only
-			tabWidget->setTabText(Sess->Tab, "Monitor");
-		else
-		{
-			char Label[16];
-			sprintf(Label, "Sess %d", Sess->Tab + 1);
-			tabWidget->setTabText(Sess->Tab, Label);
-		}
-	}
-	else if (TermMode == Single)
-	{
-		if (Sess->SessionType == Mon)			// Mon Only
-			mythis->setWindowTitle("Monitor Session Disconnected");
-		else
-			mythis->setWindowTitle("Disconnected");
-	}
-}
-
-void QtTermTCP::tabSelected(int Current)
-{
-	Ui_ListenSession * Sess = NULL;
-
-	if (Current < _sessions.size())
-	{
-		Sess = _sessions.at(Current);
-
-		if (Sess == nullptr)
-			return;
-
-		ActiveSession = Sess;
-
-		tabWidget->tabBar()->setTabTextColor(tabWidget->currentIndex(), oldTabText);
-
-		if (Sess->clientSocket || Sess->AGWSession || Sess->KISSSession || Sess->KISSMode)
-		{
-			connectMenu->setEnabled(false);
-			discAction->setEnabled(true);
-			YAPPSend->setEnabled(true);
-		}
-		else
-		{
-			connectMenu->setEnabled(true);
-			discAction->setEnabled(false);
-			YAPPSend->setEnabled(false);
-		}
-
-		// If a monitor Window, change Monitor config settings
-
-		EnableMonLog->setChecked(Sess->LogMonitor);
-
-		if (AGWUsers && Sess == AGWUsers->MonSess)		// AGW Monitor
-		{
-			for (int i = 0; i < 64; i++)
-				SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
-
-			connectMenu->setEnabled(false);
-			MonTX->setVisible(0);
-			MonSup->setVisible(0);
-			MonUI->setVisible(0);
-			MonColour->setVisible(0);
-
-			EnableMonitor->setVisible(1);
-			EnableMonitor->setChecked(AGWMonEnable);
-			MonLocalTime->setChecked(Sess->mlocaltime);
-			MonNodes->setChecked(Sess->MonitorNODES);
-		}
-		else if (Sess == KISSMonSess)				// KISS Monitor
-		{
-			for (int i = 0; i < 64; i++)
-				SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
-
-			connectMenu->setEnabled(false);
-			MonTX->setVisible(0);
-			MonSup->setVisible(0);
-			MonUI->setVisible(0);
-			MonColour->setVisible(0);
-
-			EnableMonitor->setVisible(1);
-			EnableMonitor->setChecked(KISSMonEnable);
-			MonLocalTime->setChecked(Sess->mlocaltime);
-			MonNodes->setChecked(Sess->MonitorNODES);
-		}
-		else
-		{
-			EnableMonitor->setVisible(0);
-			MonTX->setVisible(1);
-			MonSup->setVisible(1);
-			MonUI->setVisible(1);
-			MonColour->setVisible(1);
-		}
-
-		if (Sess->PortMonString[0])
-		{
-			char * ptr = (char *)malloc(2048);
-			memcpy(ptr, Sess->PortMonString, 2048);
-
-			int NumberofPorts = atoi((char *)&ptr[2]);
-			char *p, *Context;
-			char msg[80];
-			int portnum, m;
-			char delim[] = "|";
-
-			// Remove old Monitor menu
-
-			for (int i = 0; i < 64; i++)
-			{
-				SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
-			}
-
-			p = strtok_s((char *)&ptr[2], delim, &Context);
-
-			while (NumberofPorts--)
-			{
-				p = strtok_s(NULL, delim, &Context);
-				if (p == NULL)
-					break;
-
-				m = portnum = atoi(p);
-
-				sprintf(msg, "Port %s", p);
-
-				if (m == 0)
-					m = 64;
-
-				if (Sess->portmask & ((uint64_t)1 << (m - 1)))
-					SetPortMonLine(portnum, msg, 1, 1);
-				else
-					SetPortMonLine(portnum, msg, 1, 0);
-			}
-			free(ptr);
-
-			MonLocalTime->setChecked(Sess->mlocaltime);
-			MonTX->setChecked(Sess->mtxparam);
-			MonSup->setChecked(Sess->mcomparam);
-			MonUI->setChecked(Sess->monUI);
-			MonNodes->setChecked(Sess->MonitorNODES);
-			MonColour->setChecked(Sess->MonitorColour);
-		}
-		return;
-	}
-}
-
-void QtTermTCP::SetupHosts()
-{
-	QAction * Act = static_cast<QAction*>(QObject::sender());
-	int i;
-
-	for (i = 0; i < MAXHOSTS; i++)
-	{
-		if (Act == actSetup[i])
-			break;
-	}
-
-	if (i > 15)
-		return;
-
-	ConfigHost = i;
-
-	TabDialog tabdialog(0);
-	tabdialog.exec();
-}
-
-
-void QtTermTCP::Connect()
-{
-	QMdiSubWindow * UI;
-	Ui_ListenSession * Sess = nullptr;
-	QAction * Act = static_cast<QAction*>(QObject::sender());
-
-	int i;
-
-	for (i = 0; i < MAXHOSTS; i++)
-	{
-		if (Act == actHost[i])
-			break;
-	}
-
-	SavedHost = i;				// Last used
-
-	if (TermMode == MDI)
-	{
-		UI = mdiArea->activeSubWindow();
-
-		for (i = 0; i < _sessions.size(); ++i)
-		{
-			Sess = _sessions.at(i);
-
-			if (Sess->sw == UI)
-				break;
-		}
-
-		if (i == _sessions.size())
-			return;
-
-		currentHost[i] = SavedHost;
-	}
-
-	else if (TermMode == Tabbed)
-	{
-		Sess = (Ui_ListenSession *)tabWidget->currentWidget();
-	}
-
-	else if (TermMode == Single)
-		Sess = _sessions.at(0);
-
-	if ((Sess == nullptr || Sess->SessionType & Listen))
-		return;
-
-	Sess->CurrentHost = SavedHost;
-
-	currentHost[Sess->Tab] = SavedHost;
-
-	if (Act == actHost[16])
-	{
-		// This runs the AGW Connection dialog
-
-		Sess->CurrentHost = 16;				// Iast used
-		AGWConnect dialog(0);
-		dialog.exec();
-		return;
-	}
-
-
-	if (Act == actHost[17])
-	{
-		// This runs the VARA Connection dialog
-
-		Sess->CurrentHost = 17;				// Iast used
-		VARADataSock->Sess = Sess;
-		VARASock->Sess = Sess;
-
-		VARAConnect dialog(0);
-		dialog.exec();
-		WritetoOutputWindow(Sess, (unsigned char *)"Connecting...\r", 14);
-
-		return;
-	}
-
-	if (Act == actHost[18])
-	{
-		// This runs the KISS Connection dialog
-
-		Sess->CurrentHost = 18;				// Iast used
-
-		KISSConnect dialog(0);
-		dialog.exec();
-		return;
-	}
-
-	// Set Monitor Params for this host
-
-	sscanf(MonParams[Sess->CurrentHost], "%llx %x %x %x %x %x",
-		&Sess->portmask, &Sess->mtxparam, &Sess->mcomparam,
-		&Sess->MonitorNODES, &Sess->MonitorColour, &Sess->monUI);
-
-	Sess->mlocaltime = (Sess->mtxparam >> 7);
-	Sess->mtxparam &= 1;
-
-	MonLocalTime->setChecked(Sess->mlocaltime);
-	MonTX->setChecked(Sess->mtxparam);
-	MonSup->setChecked(Sess->mcomparam);
-	MonUI->setChecked(Sess->monUI);
-	MonNodes->setChecked(Sess->MonitorNODES);
-	MonColour->setChecked(Sess->MonitorColour);
-
-	// Remove old Monitor menu
-
-	for (i = 0; i < 64; i++)
-	{
-		SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
-	}
-
-	delete(Sess->clientSocket);
-
-	Sess->clientSocket = new myTcpSocket();
-	Sess->clientSocket->Sess = Sess;
-
-	connect(Sess->clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
-	connect(Sess->clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
-	connect(Sess->clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
-
-	Sess->clientSocket->connectToHost(&Host[Sess->CurrentHost][0], Port[Sess->CurrentHost]);
-	return;
-}
-
-extern "C" void rst_timer(TAX25Port * AX25Sess);
-extern "C" void set_unlink(TAX25Port * AX25Sess, Byte * path);
-
-void QtTermTCP::Disconnect()
-{
-	QMdiSubWindow * UI;
-	Ui_ListenSession * Sess = nullptr;
-
-	if (TermMode == MDI)
-	{
-		int i;
-
-		UI = mdiArea->activeSubWindow();
-
-		for (i = 0; i < _sessions.size(); ++i)
-		{
-			Sess = _sessions.at(i);
-
-			if (Sess->sw == UI)
-				break;
-		}
-
-		if (i == _sessions.size())
-			return;
-	}
-
-	else if (TermMode == Tabbed)
-	{
-		Sess = (Ui_ListenSession *)tabWidget->currentWidget();
-	}
-
-	else if (TermMode == Single)
-		Sess = _sessions.at(0);
-
-	// if AGW send a d frame else disconnect TCP session
-
-	if (Sess->AGWSession)
-		Send_AGW_Ds_Frame(Sess->AGWSession);
-	else if (VARASock && VARASock->Sess == Sess)
-		VARASock->write("DISCONNECT\r");
-	else if (Sess->KISSSession)
-	{
-		if (Sess->KISSMode == 0)
-		{
-			TAX25Port * Port = (TAX25Port *)Sess->KISSSession;
-
-			rst_timer(Port);
-			set_unlink(Port, Port->Path);
-		}
-		else
-		{
-			// KISS UI Mode
-
-			char Msg[128];
-			int Len = sprintf(Msg, "Disconnected\r");
-
-			Sess->KISSMode = 0;
-			SendtoTerm(Sess, Msg, Len);
-			ClearSessLabel(Sess);
-			setMenus(0);
-			Sess->KISSSession = NULL;
-		}
-	}
-	else
-
-	{
-		if (Sess && Sess->clientSocket)
-			Sess->clientSocket->disconnectFromHost();
-	}
-	return;
-}
-
-
-void QtTermTCP::doYAPPSend()
-{
-	QFileDialog dialog(this);
-	QStringList fileNames;
-	dialog.setFileMode(QFileDialog::AnyFile);
-
-	QMdiSubWindow * UI;
-	Ui_ListenSession * Sess = nullptr;
-	int i;
-
-	if (TermMode == MDI)
-	{
-		UI = mdiArea->activeSubWindow();
-
-		for (i = 0; i < _sessions.size(); ++i)
-		{
-			Sess = _sessions.at(i);
-
-			if (Sess->sw == UI)
-				break;
-		}
-
-		if (i == _sessions.size())
-			return;
-	}
-
-	else if (TermMode == Tabbed)
-	{
-		Sess = (Ui_ListenSession *)tabWidget->currentWidget();
-	}
-
-	else if (TermMode == Single)
-		Sess = _sessions.at(0);
-
-	if (Sess == nullptr)
-		return;
-
-	if ((Sess->SessionType & Mon))
-	{
-		// Turn off monitoring
-
-		setTraceOff(Sess);
-	}
-
-	if (dialog.exec())
-	{
-		char FN[256];
-
-		fileNames = dialog.selectedFiles();
-		if (fileNames[0].length() < 256)
-		{
-			strcpy(FN, fileNames[0].toUtf8());
-			YAPPSendFile(Sess, FN);
-		}
-	}
-}
-
-void QtTermTCP::doYAPPSetRX()
-{
-	QFileDialog dialog(this);
-	QStringList fileNames;
-	dialog.setFileMode(QFileDialog::Directory);
-	dialog.setDirectory(YAPPPath);
-
-	if (dialog.exec())
-	{
-		fileNames = dialog.selectedFiles();
-		if (fileNames[0].length() < 256)
-			strcpy(YAPPPath, fileNames[0].toUtf8());
-
-		SaveSettings();
-	}
-}
-
-Ui_SizeDialog * YappSize;
-
-void QtTermTCP::doYAPPSetSize()
-{
-	// This runs the VARA Configuration dialog
-
-	char valChar[80];
-
-	YappSize = new(Ui_SizeDialog);
-
-	QDialog UI;
-
-	YappSize->setupUi(&UI);
-
-	UI.setFont(*menufont);
-	deviceUI = &UI;
-
-	sprintf(valChar, "%d", MaxRXSize);
-
-	YappSize->maxSize->setText(valChar);
-
-	QObject::connect(YappSize->okButton, SIGNAL(clicked()), this, SLOT(sizeaccept()));
-	QObject::connect(YappSize->cancelButton, SIGNAL(clicked()), this, SLOT(sizereject()));
-
-	UI.exec();
-}
-
-void QtTermTCP::sizeaccept()
-{
-	QVariant Q;
-	Q = YappSize->maxSize->text();
-
-	MaxRXSize = Q.toInt();
-	SaveSettings();
-	delete(YappSize);
-}
-
-
-void QtTermTCP::sizereject()
-{
-	delete(YappSize);
-	deviceUI->reject();
-}
-
-
-void QtTermTCP::menuChecked()
-{
-	QAction * Act = static_cast<QAction*>(QObject::sender());
-
-	int state = Act->isChecked();
-	int newTermMode = TermMode;
-	int newSingleMode = singlemodeFormat;
-
-	if (Act == TabSingle || Act == TabBoth || Act == TabMon)
-	{
-		// Tabbed Window format had changed
-
-		int i = tabWidget->currentIndex();
-
-		if (Act == TabSingle)
-			TabType[i] = Term;
-		else if (Act == TabBoth)
-			TabType[i] = Term + Mon;
-		else
-			TabType[i] = Mon;
-
-		QMessageBox msgBox;
-		msgBox.setText("Tab Types will change next time program is started.");
-		msgBox.exec();
-
-	}
-
-	if (Act == singleAct || Act == singleAct2 || Act == MDIAct || Act == tabbedAct)
-	{
-		// Term Mode had changed
-
-		if (singleAct->isChecked())
-		{
-			newTermMode = Single;
-			newSingleMode = Mon + Term;
-		}
-		else if (singleAct2->isChecked())
-		{
-			newTermMode = Single;
-			newSingleMode = Term;
-		}
-		else if (MDIAct->isChecked())
-			newTermMode = MDI;
-		else if (tabbedAct->isChecked())
-			newTermMode = Tabbed;
-
-		if (newTermMode != TermMode || newSingleMode != singlemodeFormat)
-		{
-			QSettings settings(GetConfPath(), QSettings::IniFormat);
-			settings.setValue("TermMode", newTermMode);
-			settings.setValue("singlemodeFormat", newSingleMode);
-			QMessageBox msgBox;
-			msgBox.setText("Presentation Mode will change next time program is started.");
-			msgBox.exec();
-		}
-
-		return;
-	}
-
-	if (Act == EnableMonitor)
-		ActiveSession->EnableMonitor = state;
-	else if (Act == EnableMonLog)
-		ActiveSession->LogMonitor = state;
-	else if (Act == MonLocalTime)
-		ActiveSession->mlocaltime = state;
-	else if (Act == MonTX)
-		ActiveSession->mtxparam = state;
-	else if (Act == MonSup)
-		ActiveSession->mcomparam = state;
-	else if (Act == MonUI)
-		ActiveSession->monUI = state;
-	else if (Act == MonNodes)
-		ActiveSession->MonitorNODES = state;
-	else if (Act == MonColour)
-		ActiveSession->MonitorColour = state;
-	else if (Act == actChatMode)
-		ChatMode = state;
-	else if (Act == actAutoTeletext)
-		AutoTeletext = state;
-	else if (Act == actBells)
-		Bells = state;
-	else if (Act == actStripLF)
-		StripLF = state;
-	else if (Act == actIntervalBeep)
-		AlertBeep = state;
-	else if (Act == actConnectBeep)
-		ConnectBeep = state;
-	else if (Act == actnoConv)
-		convUTF8 = -1;
-	else if (Act == actAuto)
-		convUTF8 = 0;
-	else if (Act == actCP1251)
-		convUTF8 = 1251;
-	else if (Act == actCP1252)
-		convUTF8 = 1252;
-	else if (Act == actCP437)
-		convUTF8 = 437;
-	else
-	{
-		// look for port entry
-		for (int i = 0; i < MAXPORTS + 1; i++)
-		{
-			if (Act == MonPort[i])
-			{
-				uint64_t mmask;
-
-				if (i == 0)							// BBS Mon - use bit 63 (Port 64)
-					mmask = (uint64_t)1 << 63;
-				else
-					mmask = (uint64_t)1 << (i - 1);
-
-				if (state)
-					ActiveSession->portmask |= mmask;
-				else
-					ActiveSession->portmask &= ~mmask;
-				break;
-			}
-		}
-	}
-
-
-	if (ActiveSession->clientSocket && ActiveSession->SessionType & Mon)
-		SendTraceOptions(ActiveSession);
-
-	else if (AGWUsers && ActiveSession == AGWUsers->MonSess)
-	{
-		AGWMonEnable = ActiveSession->EnableMonitor;
-		AGWLocalTime = ActiveSession->mlocaltime;
-		AGWMonNodes = ActiveSession->MonitorNODES;
-		Send_AGW_m_Frame((QTcpSocket*)ActiveSession->AGWSession);
-	}
-
-	else if (ActiveSession == KISSMonSess)
-	{
-		KISSLocalTime = ActiveSession->mlocaltime; 
-		KISSMonEnable = ActiveSession->EnableMonitor;
-		KISSMonNodes = ActiveSession->MonitorNODES;
-	}
-	return;
-}
-
-
-
-
-void QtTermTCP::LDisconnect(Ui_ListenSession * LUI)
-{
-	if (LUI->clientSocket)
-		LUI->clientSocket->disconnectFromHost();
-}
-
-extern QApplication * a;
-
-void QtTermTCP::LreturnPressed(Ui_ListenSession * Sess)
-{
-	QByteArray stringData = Sess->inputWindow->text().toUtf8();
-
-	// if multiline input (eg from copy/paste) replace LF with CR
-
-	char * ptr;
-	char * Msgptr;
-	char * Msg;
-
-	QScrollBar *scrollbar = Sess->termWindow->verticalScrollBar();
-	bool scrollbarAtBottom = (scrollbar->value() >= (scrollbar->maximum() - 4));
-
-	if (scrollbarAtBottom)
-		Sess->termWindow->moveCursor(QTextCursor::End);					// So we don't get blank lines
-
-	// Stack it
-
-	Sess->StackIndex = 0;
-
-	if (Sess->KbdStack[49])
-		free(Sess->KbdStack[49]);
-
-	for (int i = 48; i >= 0; i--)
-	{
-		Sess->KbdStack[i + 1] = Sess->KbdStack[i];
-	}
-
-	Sess->KbdStack[0] = qstrdup(stringData.data());
-
-	stringData.append('\n');
-
-	Msgptr = stringData.data();
-
-	if (Sess->TTActive)					// Teletext uses 0x5F for #
-		while ((ptr = strchr(Msgptr, 0x23)))	// Replace VT with LF
-			*ptr++ = 0x5f;
-
-
-	while ((ptr = strchr(Msgptr, 11)))	// Replace VT with LF
-		*ptr++ = 10;
-
-	LastWrite = time(NULL);				// Stop initial beep
-	Sess->SlowTimer = 0;
-
-	Sess->pageBuffer[0] = 0;			// Reset Teletext mode screen buffer
-
-	if (Sess->KISSMode == 1)
-	{
-		// UI session. Send as UI Message
-
-		while ((ptr = strchr(Msgptr, '\n')))
-		{
-			*ptr++ = 0;
-
-			Msg = (char *)malloc(strlen(Msgptr) + 10);
-			strcpy(Msg, Msgptr);
-			strcat(Msg, "\r");
-
-
-			Send_UI(Sess->UIPORT, 0xF0, KISSMYCALL, Sess->UIDEST, Sess->UIPATH, (unsigned char *)Msg, (int)strlen(Msg));
-
-			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
-
-			free(Msg);
-
-			Msgptr = ptr;
-		}
-	}
-	else if (Sess->KISSSession)
-	{
-		// Send to ax.25 code
-
-		while ((ptr = strchr(Msgptr, '\n')))
-		{
-			*ptr++ = 0;
-
-			Msg = (char *)malloc(strlen(Msgptr) + 10);
-			strcpy(Msg, Msgptr);
-			strcat(Msg, "\r");
-
-			SendtoAX25(Sess->KISSSession, (unsigned char *)Msg, (int)strlen(Msg));
-
-			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
-
-			free(Msg);
-
-			Msgptr = ptr;
-		}
-	}
-
-	else if (Sess->AGWSession)
-	{
-		// Terminal is in AGWPE mode - send as AGW frame
-
-		while ((ptr = strchr(Msgptr, '\n')))
-		{
-			*ptr++ = 0;
-
-			Msg = (char *)malloc(strlen(Msgptr) + 10);
-			strcpy(Msg, Msgptr);
-			strcat(Msg, "\r");
-
-			AGW_AX25_data_in(Sess->AGWSession, (unsigned char *)Msg, (int)strlen(Msg));
-
-			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
-
-//			Sess->termWindow->insertPlainText(Msg);
-
-			free(Msg);
-
-			Msgptr = ptr;
-		}
-	}
-
-	else if (VARASock && VARASock->Sess == Sess)
-	{
-		while ((ptr = strchr(Msgptr, '\n')))
-		{
-			*ptr++ = 0;
-
-			Msg = (char *)malloc(strlen(Msgptr) + 10);
-			strcpy(Msg, Msgptr);
-			strcat(Msg, "\r");
-
-			VARADataSock->write(Msg);
-
-			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
-
-//			Sess->termWindow->insertPlainText(Msg);
-
-			free(Msg);
-
-			Msgptr = ptr;
-		}
-	}
-
-	else if (Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState)
-	{
-		while ((ptr = strchr(Msgptr, '\n')))
-		{
-			*ptr++ = 0;
-
-			Msg = (char *)malloc(strlen(Msgptr) + 10);
-			strcpy(Msg, Msgptr);
-			strcat(Msg, "\r");
-
-			Sess->clientSocket->write(Msg);
-			Sess->clientSocket->flush();
-//			QThread::msleep(1500);			// Try to force as separate packets
-			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
-
-//			Sess->termWindow->insertPlainText(Msg);
-
-			free(Msg);
-
-			Msgptr = ptr;
-		}
-	}
-	else
-	{
-		// Not Connected 
-
-		if (Sess->SessionType != Listen)
-		{
-			if (Sess->CurrentHost < MAXHOSTS)
-			{
-				// Last connect was TCP
-
-				char Msg[] = "Connecting....\r";
-
-				WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-					Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
-
-				delete(Sess->clientSocket);
-
-				Sess->clientSocket = new myTcpSocket();
-				Sess->clientSocket->Sess = Sess;
-
-				connect(Sess->clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
-				connect(Sess->clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
-				connect(Sess->clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
-
-
-				// Set Monitor Params for this host
-
-				sscanf(MonParams[Sess->CurrentHost], "%llx %x %x %x %x %x",
-					&Sess->portmask, &Sess->mtxparam, &Sess->mcomparam,
-					&Sess->MonitorNODES, &Sess->MonitorColour, &Sess->monUI);
-
-				Sess->mlocaltime = (Sess->mtxparam >> 7);
-				Sess->mtxparam &= 1;
-
-				MonLocalTime->setChecked(Sess->mlocaltime);
-				MonTX->setChecked(Sess->mtxparam);
-				MonSup->setChecked(Sess->mcomparam);
-				MonUI->setChecked(Sess->monUI);
-				MonNodes->setChecked(Sess->MonitorNODES);
-				MonColour->setChecked(Sess->MonitorColour);
-
-				Sess->clientSocket->connectToHost(&Host[Sess->CurrentHost][0], Port[Sess->CurrentHost]);
-			}
-
-			else if (Sess->CurrentHost == 16)		// AGW
-			{
-				// Invoke AGW connect dialog 
-
-				AGWConnect dialog(0);
-				dialog.exec();
-
-				WritetoOutputWindow(Sess, (unsigned char *)"Connecting...\r", 14);
-				return;
-			}
-
-			else if (Sess->CurrentHost == 17)		// VARA
-			{
-				// Invoke VARA connect dialog 
-
-				VARAConnect dialog(0);
-				dialog.exec();
-
-				WritetoOutputWindow(Sess, (unsigned char *)"Connecting...\r", 14);
-				return;
-			}
-
-			else if (Sess->CurrentHost == 18)		// KISS
-			{
-				// Do we send as UI or invoke kiss connect dialog ??
-
-				// Try Connect Dialog for now - may make a menu option
-
-				KISSConnect dialog(0);
-				dialog.exec();
-
-				WritetoOutputWindow(Sess, (unsigned char *)"Connecting...\r", 14);
-				return;
-			}
-		}
-		else
-		{
-			char Msg[] = "Incoming Session - Can't Connect\r";
-
-			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, 81);		// Red
-
-		}
-	}
-
-	if (scrollbarAtBottom)
-		Sess->termWindow->moveCursor(QTextCursor::End);
-
-	Sess->inputWindow->setText("");
-	a->inputMethod()->hide();
-}
-
-
-void QtTermTCP::displayError(QAbstractSocket::SocketError socketError)
-{
-	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
-
-	switch (socketError)
-	{
-	case QAbstractSocket::RemoteHostClosedError:
-		break;
-
-	case QAbstractSocket::HostNotFoundError:
-		QMessageBox::information(this, tr("QtTermTCP"),
-			tr("The host was not found. Please check the "
-				"host name and portsettings->"));
-		break;
-
-	case QAbstractSocket::ConnectionRefusedError:
-		QMessageBox::information(this, tr("QtTermTCP"),
-			tr("The connection was refused by the peer."));
-		break;
-
-	default:
-		QMessageBox::information(this, tr("QtTermTCP"),
-			tr("The following error occurred: %1.")
-			.arg(sender->errorString()));
-	}
-
-	connectMenu->setEnabled(true);
-}
-
-void QtTermTCP::readyRead()
-{
-	int Read;
-	unsigned char Buffer[8192];
-	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
-
-	Ui_ListenSession * Sess = (Ui_ListenSession *)Socket->Sess;
-
-	// read the data from the socket
-
-	Read = Socket->read((char *)Buffer, 2047);
-
-	while (Read > 0)
-	{
-		//		if (InputMode == 'Y')			// Yapp
-		//		{
-		//			QString myString = QString::fromUtf8((char*)Buffer, Read);
-		//			QByteArray ptr = myString.toLocal8Bit();
-		//			memcpy(Buffer, ptr.data(), ptr.length());
-		//			Read = ptr.length();
-		//		}
-
-			
-		Buffer[Read] = 0;
-
-		ProcessReceivedData(Sess, Buffer, Read);
-
-		QString myString = QString::fromUtf8((char*)Buffer);
-		//		qDebug() << myString;
-		Read = Socket->read((char *)Buffer, 2047);
-	}
-}
-
-extern "C" int SocketSend(Ui_ListenSession * Sess, char * Buffer, int len)
-{
-	myTcpSocket *Socket = Sess->clientSocket;
-
-	if (Socket && Socket->state() == QAbstractSocket::ConnectedState)
-		return Socket->write(Buffer, len);
-
-	return 0;
-}
-
-extern "C" int SocketFlush(Ui_ListenSession * Sess)
-{
-	if (Sess->AGWSession || Sess->KISSSession || (VARASock && VARASock->Sess == Sess))
-		return 0;
-
-	myTcpSocket* Socket = Sess->clientSocket;
-
-	if (Socket && Socket->state() == QAbstractSocket::ConnectedState)
-		return Socket->flush();
-
-	return 0;
-}
-
-extern "C" void mySleep(int ms)
-{
-	QThread::msleep(ms);
-}
-
-extern "C" void SetPortMonLine(int i, char * Text, int visible, int enabled)
-{
-	MonPort[i]->setText(Text);
-	MonPort[i]->setVisible(visible);
-	MonPort[i]->setChecked(enabled);
-}
-
-bool scrollbarAtBottom = 0;
-
-extern "C" void WritetoOutputWindowEx(Ui_ListenSession * Sess, unsigned char * Buffer, int len, QTextEdit * termWindow, int * OutputSaveLen, char * OutputSave, QColor Colour);
-
-extern "C" void WritetoOutputWindow(Ui_ListenSession * Sess, unsigned char * Buffer, int len)
-{
-	WritetoOutputWindowEx(Sess, Buffer, len, Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, outputText);
-}
-
-
-extern "C" void WritetoOutputWindowEx(Ui_ListenSession * Sess, unsigned char * Buffer, int len, QTextEdit * termWindow, int * OutputSaveLen, char * OutputSave, QColor Colour)
-{
-	unsigned char Copy[8192];
-	unsigned char * ptr1, *ptr2;
-	unsigned char Line[8192];
-	unsigned char out[8192];
-	int outlen;
-
-	int num;
-
-	if (termWindow == NULL)
-		return;
-
-	time_t NOW = time(NULL);
-
-	// Beep if no output for a while
-
-	if (AlertInterval && (NOW - LastWrite) > AlertInterval)
-	{
-		if (AlertBeep)
-			myBeep(&IntervalWAV);
-
-	}
-
-	// Alert if QtTerm not active window (unless Mon window)
-
-	if((Sess->SessionType & Mon) == 0)
-		FlashifNotActive();
-
-	// if tabbed and not active tab set tab label red
-
-	if (TermMode == Tabbed)
-	{
-		if (Sess->monWindow != termWindow)		// Not if Monitor
-		{
-			if (ActiveSession != Sess)
-			{
-				tabWidget->tabBar()->setTabTextColor(Sess->Tab, newTabText);
-			}
-		}
-	}
-
-	LastWrite = NOW;
-
-	// Mustn't mess with original buffer
-
-	memcpy(Copy, Buffer, len);
-
-	Copy[len] = 0;
-
-	ptr1 = Copy;
-
-	const QTextCursor old_cursor = termWindow->textCursor();
-	const int old_scrollbar_value = termWindow->verticalScrollBar()->value();
-	const bool is_scrolled_down = old_scrollbar_value == termWindow->verticalScrollBar()->maximum();
-
-	if (*OutputSaveLen)
-	{
-		// Have part line - append to it
-		memcpy(&OutputSave[*OutputSaveLen], Copy, len);
-		*OutputSaveLen += len;
-		ptr1 = (unsigned char *)OutputSave;
-		len = *OutputSaveLen;
-		*OutputSaveLen = 0;
-
-		// part line was written to screen so remove it
-
-//		termWindow->setFocus();
-		termWindow->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
-		termWindow->moveCursor(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
-		termWindow->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor);
-		termWindow->textCursor().removeSelectedText();
-		//		termWindow->textCursor().deletePreviousChar();
-	}
-
-	// Move the cursor to the end of the document.
-
-	termWindow->moveCursor(QTextCursor::End);
-
-	// Insert the text at the position of the cursor (which is the end of the document).
-
-lineloop:
-
-	if (len <= 0)
-	{
-		if (old_cursor.hasSelection() || !is_scrolled_down)
-		{
-			// The user has selected text or scrolled away from the bottom: maintain position.
-			termWindow->setTextCursor(old_cursor);
-			termWindow->verticalScrollBar()->setValue(old_scrollbar_value);
-		}
-		else
-		{
-			// The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom.
-			termWindow->moveCursor(QTextCursor::End);
-			termWindow->verticalScrollBar()->setValue(termWindow->verticalScrollBar()->maximum());
-		}
-
-		return;
-	}
-
-
-	//	copy text to control a line at a time	
-
-	ptr2 = (unsigned char *)memchr(ptr1, 13, len);
-
-	if (ptr2 == 0)	// No CR
-	{
-		if (len > 8000)
-			len = 8000;			// Should never get lines this long
-
-		memmove(OutputSave, ptr1, len);
-		*OutputSaveLen = len;
-
-		// Write part line to screen
-
-		memcpy(Line, ptr1, len);
-		Line[len] = 0;
-
-		// I don't think I need to worry if UTF8 as will be rewritten when rest arrives
-
-		if (Line[0] == 0x1b)			// Colour Escape
-		{
-			if (Sess->MonitorColour)
-				termWindow->setTextColor(Colours[Line[1] - 10]);
-
-			termWindow->textCursor().insertText(QString::fromUtf8((char*)&Line[2]));
-		}
-		else
-		{
-			termWindow->setTextColor(Colour);
-			termWindow->textCursor().insertText(QString::fromUtf8((char*)Line));
-		}
-
-		//		*OutputSaveLen = 0;		// Test if we need to delete part line
-
-		//		if (scrollbarAtBottom)
-		//			termWindow->moveCursor(QTextCursor::End);
-
-		if (old_cursor.hasSelection() || !is_scrolled_down)
-		{
-			// The user has selected text or scrolled away from the bottom: maintain position.
-			termWindow->setTextCursor(old_cursor);
-			termWindow->verticalScrollBar()->setValue(old_scrollbar_value);
-		}
-		else
-		{
-			// The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom.
-			termWindow->moveCursor(QTextCursor::End);
-			termWindow->verticalScrollBar()->setValue(termWindow->verticalScrollBar()->maximum());
-		}
-		return;
-	}
-
-	*(ptr2++) = 0;
-
-	if (Bells)
-	{
-		char * ptr;
-
-		do {
-			ptr = (char *)memchr(ptr1, 7, len);
-
-			if (ptr)
-			{
-				*(ptr) = 32;
-				myBeep(&BellWAV);
-			}
-		} while (ptr);
-	}
-
-	num = ptr2 - ptr1 - 1;
-
-	//		if (LogMonitor) WriteMonitorLine(ptr1, ptr2 - ptr1);
-
-	memcpy(Line, ptr1, num);
-	Line[num++] = 13;
-	Line[num] = 0;
-
-	if (Line[0] == 0x1b)			// Colour Escape
-	{
-		if (Sess->MonitorColour)
-			termWindow->setTextColor(Colours[Line[1] - 10]);
-
-		outlen = checkUTF8(&Line[2], num - 2, out);
-		out[outlen] = 0;
-		termWindow->textCursor().insertText(QString::fromUtf8((char*)out));
-		//		termWindow->textCursor().insertText(QString::fromUtf8((char*)&Line[2]));
-	}
-	else
-	{
-		termWindow->setTextColor(Colour);
-
-		outlen = checkUTF8(Line, num, out);
-		out[outlen] = 0;
-		termWindow->textCursor().insertText(QString::fromUtf8((char*)out));
-		//		termWindow->textCursor().insertText(QString::fromUtf8((char*)Line));
-	}
-
-	len -= (ptr2 - ptr1);
-
-	ptr1 = ptr2;
-
-	if ((len > 0) && StripLF)
-	{
-		if (*ptr1 == 0x0a)					// Line Feed
-		{
-			ptr1++;
-			len--;
-		}
-	}
-
-
-
-	goto lineloop;
-
-}
-
-void WriteMonitorLog(Ui_ListenSession * Sess, char * Msg);
-
-extern "C" void WritetoMonWindow(Ui_ListenSession * Sess, unsigned char * Msg, int len)
-{
-	char * ptr1 = (char *)Msg, *ptr2;
-	char Line[512];
-	int num;
-
-	//	QScrollBar *scrollbar = Sess->monWindow->verticalScrollBar();
-	//	bool scrollbarAtBottom = (scrollbar->value() >= (scrollbar->maximum() - 4));
-
-	if (Sess->monWindow == nullptr)
-		return;
-
-	Sess->monWindow->setStyleSheet(monStyleSheet);
-
-	const QTextCursor old_cursor = Sess->monWindow->textCursor();
-	const int old_scrollbar_value = Sess->monWindow->verticalScrollBar()->value();
-	const bool is_scrolled_down = old_scrollbar_value == Sess->monWindow->verticalScrollBar()->maximum();
-
-	// Move the cursor to the end of the document.
-	Sess->monWindow->moveCursor(QTextCursor::End);
-
-	// Insert the text at the position of the cursor (which is the end of the document).
-
-
-	// Write a line at a time so we can action colour chars
-
-//		Buffer[Len] = 0;
-
-//	if (scrollbarAtBottom)
-//		Sess->monWindow->moveCursor(QTextCursor::End);
-
-	if (Sess->MonSaveLen)
-	{
-		// Have part line - append to it
-		memcpy(&Sess->MonSave[Sess->MonSaveLen], Msg, len);
-		Sess->MonSaveLen += len;
-		ptr1 = Sess->MonSave;
-		len = Sess->MonSaveLen;
-		Sess->MonSaveLen = 0;
-	}
-
-lineloop:
-
-	if (len <= 0)
-	{
-		//		if (scrollbarAtBottom)
-		//			Sess->monWindow->moveCursor(QTextCursor::End);
-
-
-		if (old_cursor.hasSelection() || !is_scrolled_down)
-		{
-			// The user has selected text or scrolled away from the bottom: maintain position.
-			Sess->monWindow->setTextCursor(old_cursor);
-			Sess->monWindow->verticalScrollBar()->setValue(old_scrollbar_value);
-		}
-		else
-		{
-			// The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom.
-			Sess->monWindow->moveCursor(QTextCursor::End);
-			Sess->monWindow->verticalScrollBar()->setValue(Sess->monWindow->verticalScrollBar()->maximum());
-		}
-
-		return;
-	}
-
-	//	copy text to control a line at a time	
-
-	ptr2 = (char *)memchr(ptr1, 13, len);
-
-	if (ptr2 == 0)	// No CR
-	{
-		memmove(Sess->MonSave, ptr1, len);
-		Sess->MonSaveLen = len;
-		return;
-	}
-
-	*(ptr2++) = 0;
-
-	
-	if (Sess->LogMonitor)
-		WriteMonitorLog(Sess, ptr1);
-
-	num = ptr2 - ptr1 - 1;
-
-	memcpy(Line, ptr1, num);
-	Line[num++] = 13;
-	Line[num] = 0;
-
-	if (Line[0] == 0x1b)			// Colour Escape
-	{
-		if (Sess->MonitorColour)
-		{
-			if (Line[1] == 17)
-				Sess->monWindow->setTextColor(monRxText);
-			else
-				Sess->monWindow->setTextColor(monTxText);
-		}
-		else
-			Sess->monWindow->setTextColor(monOtherText);
-
-		Sess->monWindow->textCursor().insertText(QString::fromUtf8((char*)&Line[2]));
-	}
-	else
-	{
-		Sess->monWindow->textCursor().insertText(QString::fromUtf8((char*)Line));
-	}
-	len -= (ptr2 - ptr1);
-
-	ptr1 = ptr2;
-
-	goto lineloop;
-
-}
-
-int ProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len);
-void QueueMsg(Ui_ListenSession * Sess, char * Msg, int Len);
-
-// YAPP stuff
-
-#define SOH 1
-#define STX 2
-#define ETX 3
-#define EOT 4
-#define ENQ 5
-#define ACK 6
-#define DLE	0x10
-#define NAK 0x15
-#define CAN 0x18
-
-extern "C" void SendtoTerm(Ui_ListenSession * Sess, char * Msg, int Len)
-{
-	if (Sess == 0)
-		return;
-	
-	Sess->SlowTimer = 0;
-	Msg[Len] = 0;
-
-	if (Sess->InputMode == 'Y')			// Yapp
-	{
-		ProcessYAPPMessage(Sess, (unsigned char *)Msg, Len);
-		return;
-	}
-
-	// Could be a YAPP Header
-
-	if (Len == 2 && Msg[0] == ENQ && Msg[1] == 1)		// YAPP Send_Init
-	{
-		char YAPPRR[2];
-
-		// Turn off monitoring
-
-		Sess->InputMode = 'Y';
-
-		YAPPRR[0] = ACK;
-		YAPPRR[1] = 1;
-		QueueMsg(Sess, YAPPRR, 2);
-
-		return;
-	}
-
-	if (AutoTeletext && (Msg[0] == 0x1e || Msg[0] == 0x0c))
-	{
-		if (Sess->TTActive == 0)
-		{
-			Sess->TTActive = 1;
-			DoTermResize(Sess);
-		}
-	}
-
-	if (Sess->TTActive)
-	{
-		// Feed to Teletext code
-
-		// We need to decode a whole page. There is no obvious delimiter so process till data stops.
-		// Buffer is cleared when next input is sent
-
-		if (strlen(&Sess->pageBuffer[0] + Len) > 4090)
-			Sess->pageBuffer[0] = 0;							// Protect buffer
-
-		strcat(Sess->pageBuffer, (char *)Msg);
-
-		DecodeTeleText(Sess, (char *)Sess->pageBuffer);			// Re-decode same data until we get the end
-		return;
-	}
-
-	WritetoOutputWindow(Sess, (unsigned char *)Msg, Len);
-
-}
-
-QSettings* settings;
-
-// This makes geting settings for more channels easier
-
-char Prefix[16] = "AX25_A";
-
-void GetPortSettings(int Chan);
-
-QVariant getAX25Param(const char * key, QVariant Default)
-{
-	char fullKey[64];
-
-	sprintf(fullKey, "%s/%s", Prefix, key);
-	return settings->value(fullKey, Default);
-}
-
-void getAX25Params(int chan)
-{
-	Prefix[5] = chan + 'A';
-	GetPortSettings(chan);
-}
-
-
-void GetPortSettings(int Chan)
-{
-	txdelay[Chan] = getAX25Param("TXDelay", 250).toInt();
-	sendTXDelay[Chan] = getAX25Param("sendTXDelay", 0).toInt();
-	maxframe[Chan] = getAX25Param("Maxframe", 4).toInt();
-	fracks[Chan] = getAX25Param("Retries", 10).toInt();
-	frack_time[Chan] = getAX25Param("FrackTime", 8).toInt();
-	persist[Chan] = getAX25Param("Persist", 128).toInt();
-	kisspaclen[Chan] = getAX25Param("Paclen", 128).toInt();
-	idletime[Chan] = getAX25Param("IdleTime", 180).toInt();
-	slottime[Chan] = getAX25Param("SlotTime", 100).toInt();
-	resptime[Chan] = getAX25Param("RespTime", 1500).toInt();
-	TXFrmMode[Chan] = getAX25Param("TXFrmMode", 1).toInt();
-	max_frame_collector[Chan] = getAX25Param("FrameCollector", 6).toInt();
-	//exclude_callsigns[Chan]= getAX25Param("ExcludeCallsigns/");
-	//exclude_APRS_frm[Chan]= getAX25Param("ExcludeAPRSFrmType/");
-	KISS_opt[Chan] = getAX25Param("KISSOptimization", false).toInt();;
-	dyn_frack[Chan] = getAX25Param("DynamicFrack", false).toInt();;
-	IPOLL[Chan] = getAX25Param("IPOLL", 80).toInt();
-
-}
-
-
-void GetSettings()
-{
-	QByteArray qb;
-	int i;
-	char Key[16];
-	char Param[256];
-
-	settings = new QSettings(GetConfPath(), QSettings::IniFormat);
-
-	// Get saved session definitions
-
-	sessionList = strdup(settings->value("Sessions", "1|3, 0, 5, 5, 600, 800|").toString().toUtf8());
-
-	for (i = 0; i < MAXHOSTS; i++)
-	{
-		sprintf(Key, "HostParams%d", i);
-
-		qb = settings->value(Key).toByteArray();
-
-		DecodeSettingsLine(i, qb.data());
-	}
-
-	Split = settings->value("Split", 50).toInt();
-	ChatMode = settings->value("ChatMode", 1).toInt();
-	AutoTeletext = settings->value("AutoTeletext", 0).toInt();
-	Bells = settings->value("Bells", 1).toInt();
-	StripLF = settings->value("StripLF", 1).toInt();
-	useBeep = settings->value("useBeep", true).toBool();
-	AlertBeep = settings->value("AlertBeep", 1).toInt();
-	AlertInterval = settings->value("AlertInterval", 300).toInt();
-	ConnectBeep = settings->value("ConnectBeep", 1).toInt();
-	ConnectWAV = settings->value("ConnectWAV", ":/PCBeep").toString().toUtf8();
-	AlertWAV = settings->value("AlertWAV", ":/PCBeep").toString().toUtf8();
-	BellWAV = settings->value("BellWAV", ":/PCBeep").toString().toUtf8();
-	IntervalWAV = settings->value("IntervalWAV", ":/PCBeep").toString().toUtf8();
-
-	UseKeywords = settings->value("UseKeywords", 0).toInt();
-	KeyWordsFile = settings->value("KeyWordsFile", "keywords.sys").toString().toUtf8();
-
-	SavedHost = settings->value("CurrentHost", 0).toInt();
-	strcpy(YAPPPath, settings->value("YAPPPath", "").toString().toUtf8());
-	MaxRXSize = settings->value("MaxRXSize", 100000).toInt();
-
-	listenPort = settings->value("listenPort", 8015).toInt();
-	listenEnable = settings->value("listenEnable", false).toBool();
-	strcpy(listenCText, settings->value("listenCText", "").toString().toUtf8());
-
-	TermMode = settings->value("TermMode", 0).toInt();
-	singlemodeFormat = settings->value("singlemodeFormat", Term + Mon).toInt();
-
-	AGWEnable = settings->value("AGWEnable", 0).toInt();
-	AGWMonEnable = settings->value("AGWMonEnable", 0).toInt();
-	AGWLocalTime = settings->value("AGWLocalTime", 0).toInt();
-	AGWMonNodes = settings->value("AGWMonNodes", 0).toInt();
-	strcpy(AGWTermCall, settings->value("AGWTermCall", "").toString().toUtf8());
-	strcpy(AGWBeaconDest, settings->value("AGWBeaconDest", "").toString().toUtf8());
-	strcpy(AGWBeaconPath, settings->value("AGWBeaconPath", "").toString().toUtf8());
-	AGWBeaconInterval = settings->value("AGWBeaconInterval", 0).toInt();
-	strcpy(AGWBeaconPorts, settings->value("AGWBeaconPorts", "").toString().toUtf8());
-	strcpy(AGWBeaconMsg, settings->value("AGWBeaconText", "").toString().toUtf8());
-	strcpy(AGWHost, settings->value("AGWHost", "127.0.0.1").toString().toUtf8());
-	AGWPortNum = settings->value("AGWPort", 8000).toInt();
-	AGWPaclen = settings->value("AGWPaclen", 80).toInt();
-	AGWToCalls = settings->value("AGWToCalls", "").toStringList();
-	convUTF8 = settings->value("convUTF8", 0).toInt();
-
-	KISSEnable = settings->value("KISSEnable", 0).toInt();
-	KISSMonEnable = settings->value("KISSMonEnable", 1).toInt();
-	KISSLocalTime = settings->value("KISSLocalTime", 0).toInt();
-	KISSMonNodes = settings->value("KISSMonNodes", 0).toInt();
-
-	KISSListen = settings->value("KISSListen", 1).toInt();
-	KISSChecksum = settings->value("KISSChecksum", 0).toInt();
-	KISSAckMode = settings->value("KISSAckMode", 0).toInt();
-	KISSMH = settings->value("KISSMH", 1).toInt();
-	strcpy(KISSMYCALL, settings->value("MYCALL", "").toString().toUtf8());
-	strcpy(KISSHost, settings->value("KISSHost", "127.0.0.1").toString().toUtf8());
-	KISSPortNum = settings->value("KISSPort", 8100).toInt();
-	KISSMode = settings->value("KISSMode", 0).toInt();
-	strcpy(KISSVia, settings->value("KISSVia", "").toString().toUtf8());
-
-	strcpy(SerialPort, settings->value("KISSSerialPort", "None").toString().toUtf8());
-	KISSBAUD = settings->value("KISSBAUD", 19200).toInt();
-	getAX25Params(0);
-
-	VARAEnable = settings->value("VARAEnable", 0).toInt();
-	strcpy(VARAHost, settings->value("VARAHost", "127.0.0.1").toString().toUtf8());
-	strcpy(VARAHostFM, settings->value("VARAHostFM", "127.0.0.1").toString().toUtf8());
-	strcpy(VARAHostHF, settings->value("VARAHostHF", "127.0.0.1").toString().toUtf8());
-	strcpy(VARAHostSAT, settings->value("VARAHostSAT", "127.0.0.1").toString().toUtf8());
-	VARAPortNum = settings->value("VARAPort", 8300).toInt();
-	VARAPortHF = settings->value("VARAPortHF", 8300).toInt();
-	VARAPortFM = settings->value("VARAPortFM", 8300).toInt();
-	VARAPortSAT = settings->value("VARAPortSAT", 8300).toInt();
-	strcpy(VARAPath, settings->value("VARAPath", "C:\\VARA\\VARA.exe").toString().toUtf8());
-	strcpy(VARAPathHF, settings->value("VARAPathHF", "C:\\VARA\\VARA.exe").toString().toUtf8());
-	strcpy(VARAPathFM, settings->value("VARAPathFM", "C:\\VARA\\VARAFM.exe").toString().toUtf8());
-	strcpy(VARAPathSAT, settings->value("VARAPathSAT", "C:\\VARA\\VARASAT.exe").toString().toUtf8());
-	strcpy(VARATermCall, settings->value("VARATermCall", "").toString().toUtf8());
-	VARA500 = settings->value("VARA500", 0).toInt();
-	VARA2300 = settings->value("VARA2300", 1).toInt();
-	VARA2750 = settings->value("VARA2750", 0).toInt();
-	VARAHF = settings->value("VARAHF", 1).toInt();
-	VARAFM = settings->value("VARAFM", 0).toInt();
-	VARASAT = settings->value("VARASAT", 0).toInt();
-	strcpy(VARAInit, settings->value("VARAInit", "").toString().toUtf8());
-
-	strcpy(PTTPort, settings->value("PTT", "None").toString().toUtf8());
-	PTTMode = settings->value("PTTMode", 19200).toInt();
-	PTTBAUD = settings->value("PTTBAUD", 19200).toInt();
-	CATHex = settings->value("CATHex", 1).toInt();
-
-	strcpy(PTTOnString, settings->value("PTTOnString", "").toString().toUtf8());
-	strcpy(PTTOffString, settings->value("PTTOffString", "").toString().toUtf8());
-
-	pttGPIOPin = settings->value("pttGPIOPin", 17).toInt();
-	pttGPIOPinR = settings->value("pttGPIOPinR", 17).toInt();
-
-#ifdef WIN32
-	strcpy(CM108Addr, settings->value("CM108Addr", "0xD8C:0x08").toString().toUtf8());
-#else
-	strcpy(CM108Addr, settings->value("CM108Addr", "/dev/hidraw0").toString().toUtf8());
-#endif
-
-	HamLibPort = settings->value("HamLibPort", 4532).toInt();
-	strcpy(HamLibHost, settings->value("HamLibHost", "127.0.0.1").toString().toUtf8());
-
-	FLRigPort = settings->value("FLRigPort", 12345).toInt();
-	strcpy(FLRigHost, settings->value("FLRigHost", "127.0.0.1").toString().toUtf8());
-
-
-	strcpy(Param, settings->value("TabType", "1 1 1 1 1 1 1 2 2").toString().toUtf8());
-	sscanf(Param, "%d %d %d %d %d %d %d %d %d %d",
-		&TabType[0], &TabType[1], &TabType[2], &TabType[3], &TabType[4],
-		&TabType[5], &TabType[6], &TabType[7], &TabType[8], &TabType[9]);
-
-	strcpy(Param, settings->value("AutoConnect", "0, 0 ,0, 0, 0, 0, 0, 0, 0, 0").toString().toUtf8());
-	sscanf(Param, "%d %d %d %d %d %d %d %d %d %d",
-		&AutoConnect[0], &AutoConnect[1], &AutoConnect[2], &AutoConnect[3], &AutoConnect[4],
-		&AutoConnect[5], &AutoConnect[6], &AutoConnect[7], &AutoConnect[8], &AutoConnect[9]);
-
-	strcpy(Param, settings->value("currentHost", "0, 0 ,0, 0, 0, 0, 0, 0, 0, 0").toString().toUtf8());
-	sscanf(Param, "%d %d %d %d %d %d %d %d %d %d",
-		&currentHost[0], &currentHost[1], &currentHost[2], &currentHost[3], &currentHost[4],
-		&currentHost[5], &currentHost[6], &currentHost[7], &currentHost[8], &currentHost[9]);
-
-
-	monBackground = settings->value("monBackground", QColor(255, 255, 255)).value<QColor>();
-	monRxText = settings->value("monRxText", QColor(0, 0, 255)).value<QColor>();
-	monTxText = settings->value("monTxText", QColor(255, 0, 0)).value<QColor>();
-	monOtherText = settings->value("monOtherText", QColor(0, 0, 0)).value<QColor>();
-
-	termBackground = settings->value("termBackground", QColor(255, 255, 255)).value<QColor>();
-	outputText = settings->value("outputText", QColor(0, 0, 255)).value<QColor>();
-	EchoText = settings->value("EchoText", QColor(0, 0, 0)).value<QColor>();
-	WarningText = settings->value("WarningText", QColor(255, 0, 0)).value<QColor>();
-
-	inputBackground = settings->value("inputBackground", QColor(255, 255, 255)).value<QColor>();
-	inputText = settings->value("inputText", QColor(0, 0, 0)).value<QColor>();
-
-	delete(settings);
-}
-
-void SavePortSettings(int Chan);
-
-void saveAX25Param(const char * key, QVariant Value)
-{
-	char fullKey[64];
-
-	sprintf(fullKey, "%s/%s", Prefix, key);
-
-	settings->setValue(fullKey, Value);
-}
-
-void saveAX25Params(int chan)
-{
-	Prefix[5] = chan + 'A';
-	SavePortSettings(chan);
-}
-
-void SavePortSettings(int Chan)
-{
-	saveAX25Param("TXDelay", txdelay[Chan]);
-	saveAX25Param("sendTXDelay", sendTXDelay[Chan]);
-	saveAX25Param("Maxframe", maxframe[Chan]);
-	saveAX25Param("Paclen", kisspaclen[Chan]);
-	saveAX25Param("FrackTime", frack_time[Chan]);
-	saveAX25Param("IdleTime", idletime[Chan]);
-	saveAX25Param("SlotTime", slottime[Chan]);
-	saveAX25Param("Persist", persist[Chan]);
-	saveAX25Param("RespTime", resptime[Chan]);
-	saveAX25Param("TXFrmMode", TXFrmMode[Chan]);
-	saveAX25Param("FrameCollector", max_frame_collector[Chan]);
-	saveAX25Param("ExcludeCallsigns", exclude_callsigns[Chan]);
-	saveAX25Param("ExcludeAPRSFrmType", exclude_APRS_frm[Chan]);
-	saveAX25Param("KISSOptimization", KISS_opt[Chan]);
-	saveAX25Param("DynamicFrack", dyn_frack[Chan]);
-	saveAX25Param("BitRecovery", recovery[Chan]);
-	saveAX25Param("IPOLL", IPOLL[Chan]);
-	saveAX25Param("MyDigiCall", MyDigiCall[Chan]);
-}
-
-extern "C" void SaveSettings()
-{
-	int i;
-	char Param[512];
-	char Key[16];
-
-	settings = new QSettings(GetConfPath(), QSettings::IniFormat);
-
-	for (i = 0; i < MAXHOSTS; i++)
-	{
-		sprintf(Key, "HostParams%d", i);
-		EncodeSettingsLine(i, Param);
-		settings->setValue(Key, Param);
-	}
-
-	settings->setValue("Split", Split);
-	settings->setValue("ChatMode", ChatMode);
-	settings->setValue("AutoTeletext", AutoTeletext);
-	settings->setValue("Bells", Bells);
-	settings->setValue("StripLF", StripLF);
-	settings->setValue("AlertBeep", AlertBeep);
-	settings->setValue("useBeep", useBeep);
-	settings->setValue("ConnectBeep", ConnectBeep);
-	settings->setValue("BellWAV", BellWAV);
-	settings->setValue("AlertWAV", AlertWAV);
-	settings->setValue("IntervalWAV", IntervalWAV);
-	settings->setValue("ConnectWAV", ConnectWAV);
-
-	settings->setValue("UseKeywords", UseKeywords);
-	settings->setValue("KeyWordsFile", KeyWordsFile);
-
-	settings->setValue("AlertInterval", AlertInterval);
-	settings->setValue("CurrentHost", SavedHost);
-
-	settings->setValue("YAPPPath", YAPPPath);
-	settings->setValue("MaxRXSize", MaxRXSize);
-
-	settings->setValue("listenPort", listenPort);
-	settings->setValue("listenEnable", listenEnable);
-	settings->setValue("listenCText", listenCText);
-	settings->setValue("convUTF8", convUTF8);
-
-	settings->setValue("PTT", PTTPort);
-	settings->setValue("PTTBAUD", PTTBAUD);
-	settings->setValue("PTTMode", PTTMode);
-
-	settings->setValue("CATHex", CATHex);
-
-	settings->setValue("PTTOffString", PTTOffString);
-	settings->setValue("PTTOnString", PTTOnString);
-
-	settings->setValue("pttGPIOPin", pttGPIOPin);
-	settings->setValue("pttGPIOPinR", pttGPIOPinR);
-
-	settings->setValue("CM108Addr", CM108Addr);
-	settings->setValue("HamLibPort", HamLibPort);
-	settings->setValue("HamLibHost", HamLibHost);
-	settings->setValue("FLRigPort", FLRigPort);
-	settings->setValue("FLRigHost", FLRigHost);
-
-
-	// Save Sessions
-
-	char SessionString[1024];
-	int SessStringLen;
-
-	SessStringLen = sprintf(SessionString, "%d|", _sessions.size());
-
-	if (TermMode == MDI)
-	{
-		for (int i = 0; i < _sessions.size(); ++i)
-		{
-			Ui_ListenSession * Sess = _sessions.at(i);
-
-			QRect r = Sess->sw->geometry();
-
-			SessStringLen += sprintf(&SessionString[SessStringLen],
-				"%d, %d, %d, %d, %d, %d|", Sess->SessionType, Sess->CurrentHost, r.top(), r.left(), r.bottom(), r.right());
-		}
-
-		settings->setValue("Sessions", SessionString);
-	}
-
-	settings->setValue("AGWEnable", AGWEnable);
-	settings->setValue("AGWMonEnable", AGWMonEnable);
-	settings->setValue("AGWLocalTime", AGWLocalTime);
-	settings->setValue("AGWMonNodes", AGWMonNodes);
-	settings->setValue("AGWTermCall", AGWTermCall);
-	settings->setValue("AGWBeaconDest", AGWBeaconDest);
-	settings->setValue("AGWBeaconPath", AGWBeaconPath);
-	settings->setValue("AGWBeaconInterval", AGWBeaconInterval);
-	settings->setValue("AGWBeaconPorts", AGWBeaconPorts);
-	settings->setValue("AGWBeaconText", AGWBeaconMsg);
-	settings->setValue("AGWHost", AGWHost);
-	settings->setValue("AGWPort", AGWPortNum);
-	settings->setValue("AGWPaclen", AGWPaclen);
-	settings->setValue("AGWToCalls", AGWToCalls);
-
-	settings->setValue("KISSEnable", KISSEnable);
-	settings->setValue("KISSMonEnable", KISSMonEnable);
-	settings->setValue("KISSLocalTime", KISSLocalTime);
-	settings->setValue("KISSMonNodes", KISSMonNodes);
-
-	settings->setValue("KISSListen", KISSListen);
-	settings->setValue("KISSChecksum", KISSChecksum);
-	settings->setValue("KISSAckMode", KISSAckMode);
-	settings->setValue("KISSMH", KISSMH);
-	settings->setValue("MYCALL", KISSMYCALL);
-	settings->setValue("KISSHost", KISSHost);
-	settings->setValue("KISSMode", KISSMode);
-	settings->setValue("KISSPort", KISSPortNum);
-	settings->setValue("KISSSerialPort", SerialPort);
-	settings->setValue("KISSBAUD", KISSBAUD);
-	settings->setValue("KISSVia", KISSVia);
-
-	saveAX25Params(0);
-
-	settings->setValue("VARAEnable", VARAEnable);
-	settings->setValue("VARATermCall", VARATermCall);
-	settings->setValue("VARAHost", VARAHost);
-	settings->setValue("VARAPort", VARAPortNum);
-	settings->setValue("VARAInit", VARAInit);
-	settings->setValue("VARAPath", VARAPath);
-	settings->setValue("VARAHostHF", VARAHostHF);
-	settings->setValue("VARAPortHF", VARAPortHF);
-	settings->setValue("VARAPathHF", VARAPathHF);
-	settings->setValue("VARAHostFM", VARAHostFM);
-	settings->setValue("VARAPortFM", VARAPortFM);
-	settings->setValue("VARAPathFM", VARAPathFM);
-	settings->setValue("VARAHostSAT", VARAHostSAT);
-	settings->setValue("VARAPortSAT", VARAPortSAT);
-	settings->setValue("VARAPathSAT", VARAPathSAT);
-	settings->setValue("VARA500", VARA500);
-	settings->setValue("VARA2300", VARA2300);
-	settings->setValue("VARA2750", VARA2750);
-	settings->setValue("VARAHF", VARAHF);
-	settings->setValue("VARAFM", VARAFM);
-	settings->setValue("VARASAT", VARASAT);
-
-	sprintf(Param, "%d %d %d %d %d %d %d %d %d %d",
-		TabType[0], TabType[1], TabType[2], TabType[3], TabType[4], TabType[5], TabType[6], TabType[7], TabType[8], TabType[9]);
-
-	settings->setValue("TabType", Param);
-
-	sprintf(Param, "%d %d %d %d %d %d %d %d %d %d",
-		AutoConnect[0], AutoConnect[1], AutoConnect[2], AutoConnect[3], AutoConnect[4], AutoConnect[5], AutoConnect[6], AutoConnect[7], AutoConnect[8], AutoConnect[9]);
-
-	settings->setValue("AutoConnect", Param);
-
-	sprintf(Param, "%d %d %d %d %d %d %d %d %d %d",
-		currentHost[0], currentHost[1], currentHost[2], currentHost[3], currentHost[4], currentHost[5], currentHost[6], currentHost[7], currentHost[8], currentHost[9]);
-
-	settings->setValue("currentHost", Param);
-
-	settings->setValue("monBackground", monBackground);
-	settings->setValue("monRxText", monRxText);
-	settings->setValue("monTxText", monTxText);
-	settings->setValue("monOtherText", monOtherText);
-
-	settings->setValue("termBackground", termBackground);
-	settings->setValue("outputText", outputText);
-	settings->setValue("EchoText", EchoText);
-	settings->setValue("WarningText", WarningText);
-
-	settings->setValue("inputBackground", inputBackground);
-	settings->setValue("inputText", inputText);
-
-	settings->sync();
-	delete(settings);
-}
-
-#include <QCloseEvent>
-
-void QtTermTCP::closeEvent(QCloseEvent *event)
-{
-	QMessageBox::StandardButton resBtn = QMessageBox::question(this, "QtTermTCP",
-		tr("Are you sure?\n"),
-		QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes,
-		QMessageBox::Yes);
-	if (resBtn != QMessageBox::Yes) {
-		event->ignore();
-	}
-	else
-	{
-		event->accept();
-#ifdef USESERIAL
-		if (hPTTDevice)
-			hPTTDevice->close();
-#endif
-		if (process)
-			process->close();
-
-		if (MHWindow)
-			MHWindow->close();
-
-	}
-}
-
-QtTermTCP::~QtTermTCP()
-{
-	Ui_ListenSession * Sess;
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		if (Sess->monLogfile)
-			Sess->monLogfile->close();
-
-		if (Sess->clientSocket)
-		{
-			int loops = 100;
-			Sess->clientSocket->disconnectFromHost();
-			while (Sess->clientSocket && loops-- && Sess->clientSocket->state() != QAbstractSocket::UnconnectedState)
-				QThread::msleep(10);
-		}
-	}
-
-	if (AGWSock && AGWSock->ConnectedState == QAbstractSocket::ConnectedState)
-	{
-		int loops = 100;
-		AGWSock->disconnectFromHost();
-		QThread::msleep(10);
-		while (AGWSock && loops-- && AGWSock->state() != QAbstractSocket::UnconnectedState)
-			QThread::msleep(10);
-	}
-
-	if (_server->isListening())
-		_server->close();
-
-	delete(_server);
-
-	QSettings mysettings(GetConfPath(), QSettings::IniFormat);
-	mysettings.setValue("geometry", saveGeometry());
-	mysettings.setValue("windowState", saveState());
-
-	if (MHWindow)
-	{
-		mysettings.setValue("MHgeometry", MHWindow->saveGeometry());
-		MHWindow->close();
-	}
-	SaveSettings();
-}
-
-extern "C" void timer_event();
-
-void QtTermTCP::KISSTimerSlot()
-{
-	// Runs every 100 mS
-
-	timer_event();
-}
-
-void QtTermTCP::MyTimerSlot()
-{
-	// Runs every 10 seconds
-
-	Ui_ListenSession * Sess;
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		//	for (Ui_ListenSession * Sess : _sessions)
-		//	{
-		if (Sess == NULL)
-			continue;
-
-		if (!ChatMode)
-			continue;
-
-		if (Sess->KISSSession ||
-			(Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState))
-		{
-			Sess->SlowTimer++;
-
-			if (Sess->SlowTimer > 54)				// About 9 mins
-			{
-				unsigned char Msg[2] = "";
-
-				Sess->SlowTimer = 0;
-
-				if (Sess->KISSSession)
-				{
-					TAX25Port * ax25 = (TAX25Port *)Sess->KISSSession;
-
-					if (ax25->status == STAT_LINK)
-						SendtoAX25(Sess->KISSSession, Msg, 1);
-				}
-				else
-					Sess->clientSocket->write("\0", 1);
-			}
-		}
-	}
-
-	if (AGWEnable)
-		AGWTimer();
-
-	if (VARAEnable)
-		VARATimer();
-
-	if (KISSEnable)
-		KISSTimer();
-
-}
-
-void QtTermTCP::SlowTimerSlot()
-{
-	// Runs every 60 S
-
-	Ui_ListenSession * Sess;
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		if (Sess->monLogfile)
-		{
-			Sess->monLogfile->close();
-			Sess->monLogfile = nullptr;
-		}
-	}
-
-}
-
-
-
-extern "C" void myBeep(QString * WAV)
-{
-	if (useBeep)
-	{
-		QApplication::beep();
-		return;
-	}
-
-	// Using .wav files
-
-//	QSoundEffect effect;
-//	effect.setSource(QUrl::fromLocalFile(*WAV));
-//	effect.setLoopCount(1);
-//	effect.setVolume(1.0f);
-//	effect.play();
-
-	QSound::play(*WAV);
-}
-
-void QtTermTCP::ListenSlot()
-{
-	// This runs the Listen Configuration dialog
-
-	ListenDialog  * xx = new ListenDialog();
-	xx->exec();
-}
-
-void QtTermTCP::AGWSlot()
-{
-	// This runs the AGW Configuration dialog
-
-	AGWDialog dialog(0);
-	dialog.exec();
-}
-
-Ui_Dialog * Dev;
-Ui_AlertDialog * Alert;
-
-static Ui_KISSDialog * KISS;
-static Ui_ColourDialog * COLOURS;
-
-
-char NewPTTPort[80];
-
-int newSoundMode = 0;
-int oldSoundMode = 0;
-
-#ifdef USESERIAL
-QList<QSerialPortInfo> Ports = QSerialPortInfo::availablePorts();
-#endif
-
-
-void QtTermTCP::KISSSlot()
-{
-	// This runs the KISS Configuration dialog
-
-	KISS = new(Ui_KISSDialog);
-
-	QDialog UI;
-
-	KISS->setupUi(&UI);
-
-	UI.setFont(*menufont);
-
-	deviceUI = &UI;
-	KISS->KISSEnable->setChecked(KISSEnable);
-	KISS->KISSListen->setChecked(KISSListen);
-	KISS->KISSChecksum->setChecked(KISSChecksum);
-	KISS->KISSACKMODE->setChecked(KISSAckMode);
-	KISS->KISSMH->setChecked(KISSMH);
-	KISS->MYCALL->setText(KISSMYCALL);
-
-	KISS->TXDELAY->setText(QString::number(txdelay[0]));
-	KISS->SetTXDelay->setChecked(sendTXDelay[0]);
-
-	//	connect(KISS->SerialPort, SIGNAL(currentIndexChanged(int)), this, SLOT(PTTPortChanged(int)));
-
-	QStringList items;
-
-#ifdef USESERIAL
-
-	for (const QSerialPortInfo &info : Ports)
-	{
-		items.append(info.portName());
-	}
-
-	items.sort();
-	items.insert(0, "TCP");
-
-#endif
-
-	for (const QString &info : items)
-	{
-		KISS->SerialPort->addItem(info);
-	}
-
-	KISS->SerialPort->setCurrentIndex(KISS->SerialPort->findText(SerialPort, Qt::MatchFixedString));
-	KISS->Speed->setText(QString::number(KISSBAUD));
-	KISS->Host->setText(KISSHost);
-	KISS->Port->setText(QString::number(KISSPortNum));
-
-	KISS->Paclen->setText(QString::number(kisspaclen[0]));
-	KISS->Maxframe->setText(QString::number(maxframe[0]));
-	KISS->Frack->setText(QString::number(frack_time[0]));
-	KISS->Retries->setText(QString::number(fracks[0]));
-
-	QObject::connect(KISS->okButton, SIGNAL(clicked()), this, SLOT(KISSaccept()));
-	QObject::connect(KISS->cancelButton, SIGNAL(clicked()), this, SLOT(KISSreject()));
-
-	UI.exec();
-
-}
-
-
-void QtTermTCP::KISSaccept()
-{
-	QVariant Q;
-	int OldEnable = KISSEnable;
-	char oldSerialPort[64];
-	int OldPort = KISSPortNum;
-	char oldHost[128];
-
-	strcpy(oldSerialPort, SerialPort);
-	strcpy(oldHost, KISSHost);
-
-	KISSEnable = KISS->KISSEnable->isChecked();
-	KISSListen = KISS->KISSListen->isChecked();
-	KISSChecksum = KISS->KISSChecksum->isChecked();
-	KISSAckMode = KISS->KISSACKMODE->isChecked();
-	KISSMH = KISS->KISSMH->isChecked();
-	actHost[18]->setVisible(KISSEnable);			// Show KISS Connect Line
-
-	strcpy(KISSMYCALL, KISS->MYCALL->text().toUtf8().toUpper());
-
-	memset(axMYCALL, 0, 7);
-	ConvToAX25(KISSMYCALL, axMYCALL);
-
-	Q = KISS->Port->text();
-	KISSPortNum = Q.toInt();
-
-	Q = KISS->Speed->text();
-	KISSBAUD = Q.toInt();
-
-	strcpy(KISSHost, KISS->Host->text().toUtf8().toUpper());
-
-	Q = KISS->SerialPort->currentText();
-	strcpy(SerialPort, Q.toString().toUtf8());
-
-	Q = KISS->Paclen->text();
-	kisspaclen[0] = Q.toInt();
-	Q = KISS->Maxframe->text();
-	maxframe[0] = Q.toInt();
-	Q = KISS->Frack->text();
-	frack_time[0] = Q.toInt();
-	Q = KISS->Retries->text();
-	fracks[0] = Q.toInt();
-
-	Q = KISS->TXDELAY->text();
-	txdelay[0] = Q.toInt();
-	sendTXDelay[0] = KISS->SetTXDelay->isChecked();
-
-	myStatusBar->setVisible(AGWEnable | VARAEnable | KISSEnable);
-
-	if (KISSEnable != OldEnable || KISSPortNum != OldPort ||
-		strcmp(oldHost, KISSHost) != 0 ||
-		strcmp(oldSerialPort, SerialPort) != 0)
-	{
-		// (re)start connection
-
-		if (OldEnable)
-		{
-			if (KISSEnable)
-				Status3->setText("KISS Closed");
-			else
-				Status3->setText("KISS Disabled");
-
-			KISSConnected = 0;
-
-			if (KISSSock && KISSSock->ConnectedState == QAbstractSocket::ConnectedState)
-				KISSSock->disconnectFromHost();
-			else if (m_serial)
-				closeSerialPort();
-		}
-	}
-
-	if (KISSEnable == 0 && MHWindow)
-	{
-		MHWindow->close();
-		MHWindow = 0;
-	}
-
-	if (KISSEnable && KISSMH && MHWindow == 0)
-	{
-			newMHWindow(this, 0, "KISS MH");
-			QSettings mysettings(GetConfPath(), QSettings::IniFormat);
-			MHWindow->restoreGeometry(mysettings.value("MHgeometry").toByteArray());
-	}
-
-	if (!KISSMH && MHWindow)
-	{
-		MHWindow->close();
-		MHWindow = 0;
-	}
-
-
-	delete(KISS);
-	SaveSettings();
-	deviceUI->accept();
-
-	//	QSize newSize(this->size());
-	//	QSize oldSize(this->size());
-
-	//	QResizeEvent *myResizeEvent = new QResizeEvent(newSize, oldSize);
-
-	//	QCoreApplication::postEvent(this, myResizeEvent);
-}
-
-void QtTermTCP::KISSreject()
-{
-	delete(KISS);
-	deviceUI->reject();
-}
-
-
-void QtTermTCP::AlertSlot()
-{
-	// This runs the VARA Configuration dialog
-
-	Alert = new(Ui_AlertDialog);
-
-	QDialog UI;
-
-	Alert->setupUi(&UI);
-
-	UI.setFont(*menufont);
-
-	deviceUI = &UI;
-
-	Alert->Bells->setChecked(Bells);
-	Alert->InboundBeep->setChecked(ConnectBeep);
-	Alert->InactivityBeep->setChecked(AlertBeep);
-	Alert->Interval->setText(QString::number(AlertInterval));
-	Alert->KeywordBeep->setChecked(UseKeywords);
-	Alert->keywordFile->setText(KeyWordsFile);
-
-	Alert->useBeep->setChecked(useBeep);
-	Alert->useFiles->setChecked(!useBeep);
-
-	Alert->connectFile->setCurrentText(ConnectWAV);
-	Alert->bellsFile->setCurrentText(BellWAV);
-	Alert->intervalFile->setCurrentText(IntervalWAV);
-	Alert->keywordWAV->setCurrentText(AlertWAV);
-
-	QObject::connect(Alert->chooseInbound, SIGNAL(clicked()), this, SLOT(chooseInboundWAV()));
-	QObject::connect(Alert->chooseBells, SIGNAL(clicked()), this, SLOT(chooseBellsWAV()));
-	QObject::connect(Alert->chooseInterval, SIGNAL(clicked()), this, SLOT(chooseIntervalWAV()));
-	QObject::connect(Alert->chooseKeyAlert, SIGNAL(clicked()), this, SLOT(chooseAlertWAV()));
-
-	QObject::connect(Alert->testBells, SIGNAL(clicked()), this, SLOT(testBellsWAV()));
-	QObject::connect(Alert->TestInbound, SIGNAL(clicked()), this, SLOT(testInboundWAV()));
-	QObject::connect(Alert->testInterval, SIGNAL(clicked()), this, SLOT(testIntervalWAV()));
-	QObject::connect(Alert->TestKeyAlert, SIGNAL(clicked()), this, SLOT(testAlertWAV()));
-
-	QObject::connect(Alert->okButton, SIGNAL(clicked()), this, SLOT(alertAccept()));
-	QObject::connect(Alert->cancelButton, SIGNAL(clicked()), this, SLOT(alertReject()));
-
-	UI.exec();
-}
-
-
-
-
-
-
-void QtTermTCP::chooseInboundWAV()
-{
-	ConnectWAV = QFileDialog::getOpenFileName(this,
-		tr("Select Wav"), "", tr("Sound Files (*.wav)"));
-
-	Alert->connectFile->setCurrentText(ConnectWAV);
-
-}
-
-void QtTermTCP::chooseBellsWAV()
-{
-	BellWAV = QFileDialog::getOpenFileName(this,
-		tr("Select Wav"), "", tr("Sound Files (*.wav)"));
-
-	Alert->bellsFile->setCurrentText(BellWAV);
-}
-
-void QtTermTCP::chooseIntervalWAV()
-{
-	IntervalWAV = QFileDialog::getOpenFileName(this,
-		tr("Select Wav"), "", tr("Sound Files (*.wav)"));
-
-	Alert->intervalFile->setCurrentText(IntervalWAV);
-}
-
-void QtTermTCP::chooseAlertWAV()
-{
-	AlertWAV = QFileDialog::getOpenFileName(this,
-		tr("Select Wav"), "", tr("Sound Files (*.wav)"));
-
-	Alert->keywordWAV->setCurrentText(AlertWAV);
-}
-
-void QtTermTCP::testInboundWAV()
-{
-	QSound::play(Alert->connectFile->currentText());
-}
-
-void QtTermTCP::testBellsWAV()
-{
-	QSound::play(Alert->bellsFile->currentText());
-}
-
-void QtTermTCP::testIntervalWAV()
-{
-	QSound::play(Alert->intervalFile->currentText());
-}
-
-void QtTermTCP::testAlertWAV()
-{
-	QSound::play(Alert->keywordWAV->currentText());
-}
-
-
-
-void QtTermTCP::alertAccept()
-{
-	QVariant Q;
-
-	useBeep = Alert->useBeep->isChecked();
-
-	Bells = Alert->Bells->isChecked();
-	ConnectBeep = Alert->InboundBeep->isChecked();
-	AlertBeep = Alert->InactivityBeep->isChecked();
-	AlertInterval = Alert->Interval->text().toInt();
-
-	UseKeywords = Alert->KeywordBeep->isChecked();
-	KeyWordsFile = Alert->keywordFile->text();
-
-	ConnectWAV = Alert->connectFile->currentText();
-	BellWAV = Alert->bellsFile->currentText();
-	IntervalWAV = Alert->intervalFile->currentText();
-	AlertWAV = Alert->keywordWAV->currentText();
-
-	delete(Alert);
-	SaveSettings();
-	deviceUI->accept();
-}
-
-void QtTermTCP::alertReject()
-{
-	delete(Alert);
-	deviceUI->reject();
-}
-
-
-
-void QtTermTCP::VARASlot()
-{
-	// This runs the VARA Configuration dialog
-
-	char valChar[80];
-
-	Dev = new(Ui_Dialog);
-
-	QDialog UI;
-
-	Dev->setupUi(&UI);
-
-	UI.setFont(*menufont);
-
-	deviceUI = &UI;
-
-	Dev->VARAEnable->setChecked(VARAEnable);
-	Dev->TermCall->setText(VARATermCall);
-
-	SetVARAParams();
-
-	connect(Dev->VARAHF, SIGNAL(toggled(bool)), this, SLOT(VARAHFChanged(bool)));
-	connect(Dev->VARAFM, SIGNAL(toggled(bool)), this, SLOT(VARAFMChanged(bool)));
-	connect(Dev->VARASAT, SIGNAL(toggled(bool)), this, SLOT(VARASATChanged(bool)));
-
-	if (VARA500)
-		Dev->VARA500->setChecked(true);
-	else if (VARA2750)
-		Dev->VARA2750->setChecked(true);
-	else
-		Dev->VARA2300->setChecked(true);
-
-	if (VARAHF)
-		Dev->VARAHF->setChecked(true);
-	else if (VARAFM)
-		Dev->VARAFM->setChecked(true);
-	else if (VARASAT)
-		Dev->VARASAT->setChecked(true);
-
-	if (VARAHF == 0)
-		Dev->HFMode->setVisible(false);
-
-	connect(Dev->CAT, SIGNAL(toggled(bool)), this, SLOT(CATChanged(bool)));
-	connect(Dev->PTTPort, SIGNAL(currentIndexChanged(int)), this, SLOT(PTTPortChanged(int)));
-
-	if (PTTMode == PTTCAT)
-		Dev->CAT->setChecked(true);
-	else
-		Dev->RTSDTR->setChecked(true);
-
-	if (CATHex)
-		Dev->CATHex->setChecked(true);
-	else
-		Dev->CATText->setChecked(true);
-
-	sprintf(valChar, "%d", pttGPIOPin);
-	Dev->GPIOLeft->setText(valChar);
-	sprintf(valChar, "%d", pttGPIOPinR);
-	Dev->GPIORight->setText(valChar);
-
-	Dev->VIDPID->setText(CM108Addr);
-
-
-	QStringList items;
-
-#ifdef USESERIAL
-
-	for (const QSerialPortInfo &info : Ports)
-	{
-		items.append(info.portName());
-	}
-
-	items.sort();
-
-#endif
-
-	Dev->PTTPort->addItem("None");
-	Dev->PTTPort->addItem("CM108");
-
-#ifdef __ARM_ARCH
-
-	//	Dev->PTTPort->addItem("GPIO");
-
-#endif
-
-	Dev->PTTPort->addItem("FLRIG");
-	Dev->PTTPort->addItem("HAMLIB");
-
-	for (const QString &info : items)
-	{
-		Dev->PTTPort->addItem(info);
-	}
-
-	Dev->PTTPort->setCurrentIndex(Dev->PTTPort->findText(PTTPort, Qt::MatchFixedString));
-
-	PTTPortChanged(0);				// Force reevaluation
-
-	QObject::connect(Dev->okButton, SIGNAL(clicked()), this, SLOT(deviceaccept()));
-	QObject::connect(Dev->cancelButton, SIGNAL(clicked()), this, SLOT(devicereject()));
-
-	UI.exec();
-
-}
-
-extern QProcess *process;
-
-void ClosePTTPort();
-
-void QtTermTCP::deviceaccept()
-{
-	QVariant Q;
-
-	int OldEnable = VARAEnable;
-	int OldPort = VARAPortNum;
-	char oldHost[128];
-	char oldPath[256];
-
-	strcpy(oldHost, VARAHost);
-	strcpy(oldPath, VARAPath);
-
-	VARAEnable = Dev->VARAEnable->isChecked();
-
-	strcpy(VARATermCall, Dev->TermCall->text().toUtf8().toUpper());
-
-	Q = Dev->Port->text();
-
-	VARAPortNum = Q.toInt();
-	strcpy(VARAHost, Dev->Host->text().toUtf8().toUpper());
-	strcpy(VARAPath, Dev->Path->text().toUtf8());
-	strcpy(VARAInit, Dev->InitCommands->text().toUtf8());
-
-	VARA500 = Dev->VARA500->isChecked();
-	VARA2300 = Dev->VARA2300->isChecked();
-	VARA2750 = Dev->VARA2750->isChecked();
-
-	VARAHF = Dev->VARAHF->isChecked();
-	VARAFM = Dev->VARAFM->isChecked();
-	VARASAT = Dev->VARASAT->isChecked();
-
-	if (VARAHF)
-	{
-		strcpy(VARAHostHF, VARAHost);
-		strcpy(VARAPathHF, VARAPath);
-		VARAPortHF = VARAPortNum;
-	}
-	else if (VARAFM)
-	{
-		strcpy(VARAHostFM, VARAHost);
-		strcpy(VARAPathFM, VARAPath);
-		VARAPortFM = VARAPortNum;
-	}
-	else if (VARASAT)
-	{
-		strcpy(VARAHostSAT, VARAHost);
-		strcpy(VARAPathSAT, VARAPath);
-		VARAPortSAT = VARAPortNum;
-	}
-
-	Q = Dev->PTTPort->currentText();
-	strcpy(PTTPort, Q.toString().toUtf8());
-
-	if (Dev->CAT->isChecked())
-		PTTMode = PTTCAT;
-	else
-		PTTMode = PTTRTS;
-
-	if (Dev->CATHex->isChecked())
-		CATHex = 1;
-	else
-		CATHex = 0;
-
-	Q = Dev->PTTOn->text();
-	strcpy(PTTOnString, Q.toString().toUtf8());
-	Q = Dev->PTTOff->text();
-	strcpy(PTTOffString, Q.toString().toUtf8());
-
-	Q = Dev->CATSpeed->text();
-	PTTBAUD = Q.toInt();
-
-	Q = Dev->GPIOLeft->text();
-	pttGPIOPin = Q.toInt();
-
-	Q = Dev->GPIORight->text();
-	pttGPIOPinR = Q.toInt();
-
-	Q = Dev->VIDPID->text();
-
-	if (strcmp(PTTPort, "CM108") == 0)
-		strcpy(CM108Addr, Q.toString().toUtf8());
-	else if (strcmp(PTTPort, "HAMLIB") == 0)
-	{
-		HamLibPort = Q.toInt();
-		Q = Dev->PTTOn->text();
-		strcpy(HamLibHost, Q.toString().toUtf8());
-	}
-
-	if (VARAEnable != OldEnable || VARAPortNum != OldPort || strcmp(oldHost, VARAHost) != 0)
-	{
-		// (re)start connection
-
-		if (OldEnable && VARASock && VARASock->ConnectedState == QAbstractSocket::ConnectedState)
-		{
-			VARASock->disconnectFromHost();
-			if (VARADataSock)
-				VARADataSock->disconnectFromHost();
-			Status2->setText("VARA Disconnected");
-		}
-	}
-
-	if (process && process->state() == QProcess::Running)
-		if ((VARAEnable == 0 || strcmp(oldPath, VARAPath) != 0))
-			process->close();
-
-	myStatusBar->setVisible(AGWEnable | VARAEnable | KISSEnable);
-
-	ClosePTTPort();
-	OpenPTTPort();
-
-	delete(Dev);
-	SaveSettings();
-	deviceUI->accept();
-
-	QSize newSize(this->size());
-	QSize oldSize(this->size());
-
-	QResizeEvent *myResizeEvent = new QResizeEvent(newSize, oldSize);
-
-	QCoreApplication::postEvent(this, myResizeEvent);
-}
-
-void QtTermTCP::devicereject()
-{
-	delete(Dev);
-	deviceUI->reject();
-}
-
-// This handles incoming connections
-
-void QtTermTCP::onNewConnection()
-{
-	myTcpSocket *clientSocket = (myTcpSocket *)_server->nextPendingConnection();
-
-	clientSocket->Sess = NULL;
-
-	Ui_ListenSession * S;
-	Ui_ListenSession  * Sess = NULL;
-
-	char Title[512];
-	int i = 0;
-
-	QByteArray Host = clientSocket->peerAddress().toString().toUtf8();
-
-	if (TermMode == MDI)
-	{
-		// See if an old session can be reused
-
-		for (int i = 0; i < _sessions.size(); ++i)
-		{
-			S = _sessions.at(i);
-
-			//	for (Ui_ListenSession * S: _sessions)
-			//	{
-			if ((S->SessionType & Listen) && S->clientSocket == NULL)
-			{
-				Sess = S;
-				break;
-			}
-		}
-
-		// Create a window if none found, else reuse old
-
-		if (Sess == NULL)
-		{
-			Sess = newWindow(this, Listen);
-		}
-
-		QByteArray Host = clientSocket->peerAddress().toString().toUtf8();
-	}
-	else
-	{
-		// Single or Tabbed - look for free session
-
-		for (i = 0; i < _sessions.size(); ++i)
-		{
-			S = _sessions.at(i);
-
-			if (S->clientSocket == NULL && S->AGWSession == NULL && S->AGWMonSession == NULL && S->KISSSession == NULL)
-			{
-				Sess = S;
-				break;
-			}
-		}
-
-		if (Sess == NULL)
-		{
-			// Clear connection
-
-			clientSocket->disconnectFromHost();
-			return;
-		}
-	}
-
-	_sockets.push_back(clientSocket);
-
-	clientSocket->Sess = Sess;
-
-	// See if any data from host - first msg should be callsign
-
-	clientSocket->waitForReadyRead(1000);
-
-	QByteArray datas = clientSocket->readAll();
-
-	datas.chop(2);
-	datas.truncate(10);				// Just in case!
-
-	strlop(datas.data(), 13);
-
-	if (datas.data()[0] == 0)
-		datas.append("UNKNOWN\0");
-
-	datas.append('\0');
-
-	sprintf(Title, "Inward Connect from %s:%d Call %s",
-		Host.data(), clientSocket->peerPort(), datas.data());
-
-	if (TermMode == MDI)
-	{
-		Sess->setWindowTitle(Title);
-	}
-	else if (TermMode == Tabbed)
-	{
-		tabWidget->setTabText(i, datas.data());
-		tabWidget->tabBar()->setTabTextColor(i, newTabText);
-	}
-
-	else if (TermMode == Single)
-		this->setWindowTitle(Title);
-
-	connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
-	connect(clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
-
-	Sess->clientSocket = clientSocket;
-
-	// We need to set Connect and Disconnect if the window is active
-
-	if (TermMode == MDI && Sess->sw == ActiveSubWindow)
-		setMenus(true);
-
-	if (TermMode == Tabbed && Sess->Tab == tabWidget->currentIndex())
-		setMenus(true);
-
-	if (TermMode == Single)
-		setMenus(true);			// Single
-
-	// Send CText if defined
-
-	if (listenCText[0])
-		Sess->clientSocket->write(listenCText);
-
-	// Send Message to Terminal
-
-	char Msg[80];
-
-	sprintf(Msg, "Listen Connect from %s\r\r", datas.data());
-
-	WritetoOutputWindow(Sess, (unsigned char *)Msg, (int)strlen(Msg));
-
-	if (ConnectBeep)
-		myBeep(&ConnectWAV);
-
-	QApplication::alert(mythis, 0);
-}
-
-void QtTermTCP::onSocketStateChanged(QAbstractSocket::SocketState socketState)
-{
-	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
-	Ui_ListenSession * Sess = (Ui_ListenSession *)sender->Sess;
-
-	if (socketState == QAbstractSocket::UnconnectedState)
-	{
-		char Msg[] = "Disconnected\r";
-
-		WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
-			Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
-
-		if (TermMode == MDI)
-		{
-			if (Sess->SessionType == Mon)			// Mon Only
-				Sess->setWindowTitle("Monitor Session Disconnected");
-			else
-				Sess->setWindowTitle("Disconnected");
-		}
-		else if (TermMode == Tabbed)
-		{
-			if (Sess->SessionType == Mon)			// Mon Only
-				tabWidget->setTabText(Sess->Tab, "Monitor");
-			else
-			{
-				char Label[16];
-				sprintf(Label, "Sess %d", Sess->Tab + 1);
-				tabWidget->setTabText(Sess->Tab, Label);
-			}
-		}
-		else if (TermMode == Single)
-		{
-			if (Sess->AGWMonSession)
-				mythis->setWindowTitle("AGW Monitor Window");
-			else
-			{
-				if (Sess->SessionType == Mon)			// Mon Only
-					this->setWindowTitle("Monitor Session Disconnected");
-				else
-					this->setWindowTitle("Disconnected");
-			}
-		}
-
-		if (Sess->TTActive)
-		{
-			Sess->TTActive = 0;
-			DoTermResize(Sess);
-		}
-
-		Sess->PortMonString[0] = 0;
-
-		//		delete(Sess->clientSocket);
-		Sess->clientSocket = NULL;
-
-		discAction->setEnabled(false);
-
-		if ((Sess->SessionType & Listen))
-			_sockets.removeOne(sender);
-		else
-		{
-			connectMenu->setEnabled(true);
-			YAPPSend->setEnabled(false);
-		}
-	}
-	else if (socketState == QAbstractSocket::ConnectedState)
-	{
-		char Signon[256];
-		char Title[128];
-
-		// only seems to be triggered for outward connect
-
-		sprintf(Signon, "%s\r%s\rBPQTERMTCP\r", UserName[Sess->CurrentHost], Password[Sess->CurrentHost]);
-
-		Sess->clientSocket->write(Signon);
-
-		discAction->setEnabled(true);
-		YAPPSend->setEnabled(true);
-		connectMenu->setEnabled(false);
-
-		SendTraceOptions(Sess);
-
-		Sess->InputMode = 0;
-		Sess->SlowTimer = 0;
-		Sess->MonData = 0;
-		Sess->OutputSaveLen = 0;			// Clear any part line
-		Sess->MonSaveLen = 0;			// Clear any part line
-
-		if (Sess->SessionType == Mon)		// Mon Only
-			sprintf(Title, "Monitor Session Connected to %s", Host[Sess->CurrentHost]);
-		else
-		{
-			char Label[256];
-
-			if (SessName[Sess->CurrentHost][0])
-				sprintf(Label, "%s(%s)", Host[Sess->CurrentHost], SessName[Sess->CurrentHost]);
-			else
-				strcpy(Label, Host[Sess->CurrentHost]);
-
-			sprintf(Title, "Connected to %s", Label);
-		}
-
-		if (TermMode == MDI)
-			Sess->setWindowTitle(Title);
-		else if (TermMode == Tabbed)
-		{
-			if (SessName[Sess->CurrentHost][0])
-				tabWidget->setTabText(Sess->Tab, SessName[Sess->CurrentHost]);
-			else
-				tabWidget->setTabText(Sess->Tab, Host[Sess->CurrentHost]);
-		}
-		else if (TermMode == Single)
-			this->setWindowTitle(Title);
-	}
-}
-
-void QtTermTCP::updateWindowMenu()
-{
-	if (TermMode == MDI)
-	{
-		windowMenu->clear();
-		windowMenu->addAction(newTermAct);
-		windowMenu->addAction(newMonAct);
-		windowMenu->addAction(newCombinedAct);
-		windowMenu->addSeparator();
-		windowMenu->addAction(closeAct);
-		windowMenu->addAction(closeAllAct);
-		windowMenu->addSeparator();
-		windowMenu->addAction(tileAct);
-		windowMenu->addAction(cascadeAct);
-		windowMenu->addSeparator();
-		windowMenu->addAction(nextAct);
-		windowMenu->addAction(previousAct);
-		windowMenu->addAction(quitAction);
-		windowMenu->addAction(windowMenuSeparatorAct);
-
-		QList<QMdiSubWindow *> windows = mdiArea->subWindowList();
-		windowMenuSeparatorAct->setVisible(!windows.isEmpty());
-
-		Ui_ListenSession * Sess;
-
-		for (int i = 0; i < _sessions.size(); ++i)
-		{
-			Sess = _sessions.at(i);
-			Sess->actActivate = windowMenu->addAction(Sess->sw->windowTitle());
-			QAction::connect(Sess->actActivate, SIGNAL(triggered()), this, SLOT(actActivate()));
-			Sess->actActivate->setCheckable(true);
-			Sess->actActivate->setChecked(ActiveSubWindow == Sess->sw);
-		}
-	}
-	else if (TermMode == Tabbed)
-	{
-		windowMenu->clear();
-
-		Ui_ListenSession * Sess = (Ui_ListenSession *)tabWidget->currentWidget();
-
-		QActionGroup * termGroup = new QActionGroup(this);
-
-		delete(TabSingle);
-		delete(TabBoth);
-		delete(TabMon);
-
-		TabSingle = setupMenuLine(nullptr, (char *)"Terminal Only", this, (Sess->SessionType == Term));
-		TabBoth = setupMenuLine(nullptr, (char *)"Terminal + Monitor", this, (Sess->SessionType == Term + Mon));
-		TabMon = setupMenuLine(nullptr, (char *)"Monitor Only", this, (Sess->SessionType == Mon));
-
-		termGroup->addAction(TabSingle);
-		termGroup->addAction(TabBoth);
-		termGroup->addAction(TabMon);
-
-		windowMenu->addAction(TabSingle);
-		windowMenu->addAction(TabBoth);
-		windowMenu->addAction(TabMon);
-
-	}
-}
-
-Ui_ListenSession::~Ui_ListenSession()
-{
-	if (this->clientSocket)
-	{
-		int loops = 100;
-		this->clientSocket->disconnectFromHost();
-		while (loops-- && this->clientSocket->state() != QAbstractSocket::UnconnectedState)
-			QThread::msleep(10);
-	}
-}
-
-extern "C" void setTraceOff(Ui_ListenSession * Sess)
-{
-	if ((Sess->SessionType & Mon) == 0)
-		return;					// Not Monitor
-
-	if (Sess->AGWMonSession)
-		return;
-
-	char Buffer[80];
-	int Len = sprintf(Buffer, "\\\\\\\\0 0 0 0 0 0 0 0\r");
-
-	SocketFlush(Sess);
-	SocketSend(Sess, Buffer, Len);
-	SocketFlush(Sess);
-}
-
-
-extern "C" void SendTraceOptions(Ui_ListenSession * Sess)
-{
-	if ((Sess->SessionType & Mon) == 0)
-		return;					// Not Monitor
-
-	if (Sess->AGWMonSession)
-		return;
-
-	char Buffer[80];
-	int Len = sprintf(Buffer, "\\\\\\\\%llx %x %x %x %x %x %x %x\r", Sess->portmask, Sess->mtxparam | (Sess->mlocaltime << 7),
-		Sess->mcomparam, Sess->MonitorNODES, Sess->MonitorColour, Sess->monUI, 0, 1);
-
-	strcpy(&MonParams[Sess->CurrentHost][0], &Buffer[4]);
-	SaveSettings();
-	SocketFlush(Sess);
-	SocketSend(Sess, Buffer, Len);
-	SocketFlush(Sess);
-}
-
-void QtTermTCP::doNewTerm()
-{
-	newWindow(this, Term);
-}
-
-void QtTermTCP::doNewMon()
-{
-	newWindow(this, Mon);
-}
-
-void QtTermTCP::doNewCombined()
-{
-	newWindow(this, Term + Mon);
-}
-
-void QtTermTCP::doCascade()
-{
-	// Qt Cascade Minimizes windows so do it ourselves
-
-	int x = 0, y = 0;
-
-	Ui_ListenSession * Sess;
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		Sess->sw->move(x, y);
-		x += 14;
-		y += 30;
-	}
-}
-
-void QtTermTCP::actActivate()
-{
-	QAction * sender = static_cast<QAction*>(QObject::sender());
-
-	Ui_ListenSession * Sess;
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		if (Sess->actActivate == sender)
-		{
-			mdiArea->setActiveSubWindow(Sess->sw);
-			return;
-		}
-	}
-}
-
-
-void QtTermTCP::xon_mdiArea_changed()
-{
-	// This is triggered when the Active MDI window changes
-	// and is used to enable/disable Connect, Disconnect and YAPP Send
-
-
-	QMdiSubWindow *SW = mdiArea->activeSubWindow();
-
-	// Dont waste time if not changed
-
-	if (ActiveSubWindow == SW)
-		return;
-
-	ActiveSubWindow = SW;
-
-	Ui_ListenSession * Sess;
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		//	for (Ui_ListenSession * Sess : _sessions)
-		//	{
-		if (Sess->sw == SW)
-		{
-			ActiveSession = Sess;
-
-			if (Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState)
-			{
-				discAction->setEnabled(true);
-				YAPPSend->setEnabled(true);
-				connectMenu->setEnabled(false);
-			}
-			else if (Sess->AGWMonSession)
-			{
-				// Connected AGW Monitor Session
-
-				discAction->setEnabled(false);
-				YAPPSend->setEnabled(false);
-				connectMenu->setEnabled(false);
-			}
-			else if (Sess->AGWSession || Sess->KISSSession)
-			{
-				// Connected AGW or KISS Terminal Session
-
-				discAction->setEnabled(true);
-				YAPPSend->setEnabled(true);
-				connectMenu->setEnabled(false);
-			}
-			else
-			{
-				// Not connected
-
-				discAction->setEnabled(false);
-				YAPPSend->setEnabled(false);
-
-				if ((Sess->SessionType & Listen))		// Listen Sessions can't connect
-					connectMenu->setEnabled(false);
-				else
-					connectMenu->setEnabled(true);
-			}
-
-			// If a monitor Window, change Monitor config settings
-
-			EnableMonLog->setChecked(Sess->LogMonitor);
-
-			if (AGWUsers && Sess == AGWUsers->MonSess)		// AGW Monitor
-			{
-				for (int i = 0; i < 64; i++)
-					SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
-
-				connectMenu->setEnabled(false);
-				MonTX->setVisible(0);
-				MonSup->setVisible(0);
-				MonUI->setVisible(0);
-				MonColour->setVisible(0);
-
-				EnableMonitor->setVisible(1);
-				EnableMonitor->setChecked(AGWMonEnable);
-
-				MonLocalTime->setChecked(Sess->mlocaltime);
-				MonNodes->setChecked(Sess->MonitorNODES);
-			}
-			else if (Sess == KISSMonSess)				// KISS Monitor
-			{
-				for (int i = 0; i < 64; i++)
-					SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
-
-				connectMenu->setEnabled(false);
-				MonTX->setVisible(0);
-				MonSup->setVisible(0);
-				MonUI->setVisible(0);
-				MonColour->setVisible(0);
-
-				EnableMonitor->setVisible(1);
-				EnableMonitor->setChecked(KISSMonEnable);
-				MonLocalTime->setChecked(Sess->mlocaltime);
-				MonNodes->setChecked(Sess->MonitorNODES);
-			}
-
-			else
-			{
-				EnableMonitor->setVisible(0);
-				MonTX->setVisible(1);
-				MonSup->setVisible(1);
-				MonUI->setVisible(1);
-				MonColour->setVisible(1);
-			}
-
-			if (Sess->PortMonString[0])
-			{
-				char * ptr = (char *)malloc(2048);
-				memcpy(ptr, Sess->PortMonString, 2048);
-
-				int NumberofPorts = atoi((char *)&ptr[2]);
-				char *p, *Context;
-				char msg[80];
-				int portnum;
-				char delim[] = "|";
-
-				// Remove old Monitor menu
-
-				for (int i = 0; i < 64; i++)
-				{
-					SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
-				}
-
-				p = strtok_s((char *)&ptr[2], delim, &Context);
-
-				while (NumberofPorts--)
-				{
-					p = strtok_s(NULL, delim, &Context);
-					if (p == NULL)
-						break;
-
-					portnum = atoi(p);
-
-					sprintf(msg, "Port %s", p);
-
-					if (portnum == 0)
-						portnum = 64;
-
-					if (Sess->portmask & (1ll << (portnum - 1)))
-						SetPortMonLine(portnum, msg, 1, 1);
-					else
-						SetPortMonLine(portnum, msg, 1, 0);
-				}
-				free(ptr);
-
-				MonLocalTime->setChecked(Sess->mlocaltime);
-				MonTX->setChecked(Sess->mtxparam);
-				MonSup->setChecked(Sess->mcomparam);
-				MonUI->setChecked(Sess->monUI);
-				MonNodes->setChecked(Sess->MonitorNODES);
-				MonColour->setChecked(Sess->MonitorColour);
-
-			}
-
-			return;
-		}
-	}
-}
-
-void QtTermTCP::doFonts()
-{
-	fontDialog  * xx = new fontDialog(0);
-	xx->exec();
-}
-
-void QtTermTCP::doMFonts()
-{
-	fontDialog  * xx = new fontDialog(1);
-	xx->exec();
-}
-
-QColor TempmonBackground = monBackground;
-QColor TemptermBackground = termBackground;
-QColor TempinputBackground = inputBackground;
-
-QColor TempmonRxText = monRxText;
-QColor TempmonTxText = monTxText;
-QColor TempmonOtherText = monOtherText;
-
-QColor TempoutputText = outputText;
-QColor TempEchoText = EchoText;
-QColor TempWarningText = WarningText;
-
-
-QColor TempinputText = inputText;
-
-
-void setDialogColours()
-{
-	char monStyle[128];
-
-	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		TempmonOtherText.red(), TempmonOtherText.green(), TempmonOtherText.blue(),
-		TempmonBackground.red(), TempmonBackground.green(), TempmonBackground.blue());
-
-	COLOURS->MonitorBG->setStyleSheet(monStyle);
-	COLOURS->MonOther->setStyleSheet(monStyle);
-
-	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		TempmonTxText.red(), TempmonTxText.green(), TempmonTxText.blue(),
-		TempmonBackground.red(), TempmonBackground.green(), TempmonBackground.blue());
-	COLOURS->MonTX->setStyleSheet(monStyle);
-
-	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		TempmonRxText.red(), TempmonRxText.green(), TempmonRxText.blue(),
-		TempmonBackground.red(), TempmonBackground.green(), TempmonBackground.blue());
-
-	COLOURS->MonRX->setStyleSheet(monStyle);
-
-	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		TempoutputText.red(), TempoutputText.green(), TempoutputText.blue(),
-		TemptermBackground.red(), TemptermBackground.green(), TemptermBackground.blue());
-
-	COLOURS->TermBG->setStyleSheet(monStyle);
-	COLOURS->TermNormal->setStyleSheet(monStyle);
-
-	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		TempEchoText.red(), TempEchoText.green(), TempEchoText.blue(),
-		TemptermBackground.red(), TemptermBackground.green(), TemptermBackground.blue());
-
-	COLOURS->Echoed->setStyleSheet(monStyle);
-
-	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		TempWarningText.red(), TempWarningText.green(), TempWarningText.blue(),
-		TemptermBackground.red(), TemptermBackground.green(), TemptermBackground.blue());
-
-	COLOURS->Warning->setStyleSheet(monStyle);
-
-	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		TempinputText.red(), TempinputText.green(), TempinputText.blue(),
-		TempinputBackground.red(), TempinputBackground.green(), TempinputBackground.blue());
-
-	COLOURS->InputBG->setStyleSheet(monStyle);
-	COLOURS->InputColour->setStyleSheet(monStyle);
-
-}
-
-void QtTermTCP::doColours()
-{
-	COLOURS = new(Ui_ColourDialog);
-
-	QDialog UI;
-
-	COLOURS->setupUi(&UI);
-
-	UI.setFont(*menufont);
-
-	deviceUI = &UI;
-
-	TempmonBackground = monBackground;
-	TempmonRxText = monRxText;
-	TempmonTxText = monTxText;
-	TempmonOtherText = monOtherText;
-
-	TemptermBackground = termBackground;
-	TempoutputText = outputText;
-	TempEchoText = EchoText;
-	TempWarningText = WarningText;
-
-	TempinputBackground = inputBackground;
-	TempinputText = inputText;
-
-	setDialogColours();
-
-	QObject::connect(COLOURS->MonitorBG, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->TermBG, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->InputBG, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->MonRX, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->MonTX, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->MonOther, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->TermNormal, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->Echoed, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->Warning, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-	QObject::connect(COLOURS->InputColour, SIGNAL(clicked()), this, SLOT(ColourPressed()));
-
-	QObject::connect(COLOURS->okButton, SIGNAL(clicked()), this, SLOT(Colouraccept()));
-	QObject::connect(COLOURS->cancelButton, SIGNAL(clicked()), this, SLOT(Colourreject()));
-
-	UI.exec();
-
-}
-
-void QtTermTCP::ColourPressed()
-{
-	char Name[32];
-
-	strcpy(Name, sender()->objectName().toUtf8());
-
-	if (strcmp(Name, "MonitorBG") == 0)
-		TempmonBackground = setColor(TempmonBackground);
-
-	else if (strcmp(Name, "MonTX") == 0)
-		TempmonTxText = setColor(TempmonTxText);
-
-	else if (strcmp(Name, "MonRX") == 0)
-		TempmonRxText = setColor(TempmonRxText);
-
-	else if (strcmp(Name, "MonOther") == 0)
-		TempmonOtherText = setColor(TempmonOtherText);
-
-	else if (strcmp(Name, "TermBG") == 0)
-		TemptermBackground = setColor(TemptermBackground);
-
-	else if (strcmp(Name, "InputBG") == 0)
-		TempinputBackground = setColor(TempinputBackground);
-
-	else if (strcmp(Name, "InputColour") == 0)
-		TempinputText = setColor(TempinputText);
-
-	else if (strcmp(Name, "TermNormal") == 0)
-		TempoutputText = setColor(TempoutputText);
-
-	else if (strcmp(Name, "Echoed") == 0)
-		TempEchoText = setColor(TempEchoText);
-
-	else if (strcmp(Name, "Warning") == 0)
-		TempWarningText = setColor(TempWarningText);
-
-	setDialogColours();
-}
-
-
-void QtTermTCP::Colouraccept()
-{
-	monBackground = TempmonBackground;
-	monRxText = TempmonRxText;
-	monTxText = TempmonTxText;
-	monOtherText = TempmonOtherText;
-
-	termBackground = TemptermBackground;
-	EchoText = TempEchoText;
-	WarningText = TempWarningText;
-	outputText = TempoutputText;
-
-	inputBackground = TempinputBackground;
-	inputText = TempinputText;
-
-	// Set background colour for new windows
-
-	sprintf(monStyleSheet, "background-color: rgb(%d, %d, %d);",
-		monBackground.red(), monBackground.green(), monBackground.blue());
-
-	sprintf(termStyleSheet, "background-color: rgb(%d, %d, %d);",
-		termBackground.red(), termBackground.green(), termBackground.blue());
-
-	sprintf(inputStyleSheet, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
-		inputText.red(), inputText.green(), inputText.blue(),
-		inputBackground.red(), inputBackground.green(), inputBackground.blue());
-
-	// Update existing windows
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Ui_ListenSession * S = _sessions.at(i);
-
-		if (S->monWindow)
-			S->monWindow->setStyleSheet(monStyleSheet);
-
-		if (S->termWindow)
-			S->termWindow->setStyleSheet(termStyleSheet);
-
-		if (S->inputWindow)
-			S->inputWindow->setStyleSheet(inputStyleSheet);
-
-	}
-
-
-	delete(COLOURS);
-
-	SaveSettings();
-	deviceUI->accept();
-}
-
-void QtTermTCP::Colourreject()
-{
-	delete(COLOURS);
-	deviceUI->reject();
-}
-
-
-void QtTermTCP::ConnecttoVARA()
-{
-
-	delete(VARASock);
-
-	VARASock = new myTcpSocket();
-
-	connect(VARASock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(VARAdisplayError(QAbstractSocket::SocketError)));
-	connect(VARASock, SIGNAL(readyRead()), this, SLOT(VARAreadyRead()));
-	connect(VARASock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onVARASocketStateChanged(QAbstractSocket::SocketState)));
-
-	VARASock->connectToHost(VARAHost, VARAPortNum);
-
-	Status2->setText("VARA Control Connecting");
-
-	return;
-}
-
-
-void QtTermTCP::VARATimer()
-{
-	// Runs every 10 Seconds
-
-	if (VARAConnected == 0 && VARAConnecting == 0)
-	{
-		if (process == nullptr || process->state() == QProcess::NotRunning)
-		{
-			if (VARAPath[0])
-			{
-				process = new QProcess(this);
-				QString file = VARAPath;
-				process->start(file);
-			}
-		}
-		QThread::msleep(1000);
-		VARAConnecting = true;
-		ConnecttoVARA();
-	}
-}
-
-
-void QtTermTCP::VARAdisplayError(QAbstractSocket::SocketError socketError)
-{
-	switch (socketError)
-	{
-	case QAbstractSocket::RemoteHostClosedError:
-		break;
-
-	case QAbstractSocket::HostNotFoundError:
-		QMessageBox::information(this, tr("QtTermTCP"),
-			tr("VARA host was not found. Please check the "
-				"host name and portsettings->"));
-
-		Status2->setText("VARA Connection Failed");
-
-		break;
-
-	case QAbstractSocket::ConnectionRefusedError:
-
-		Status2->setText("VARA Connection Refused");
-		break;
-
-	default:
-
-		Status2->setText("VARA Connection Failed");
-	}
-
-	VARAConnecting = 0;
-	VARAConnected = 0;
-}
-
-void QtTermTCP::VARAreadyRead()
-{
-	int Read;
-	char Buffer[4096];
-	char * ptr;
-	char * Msg;
-	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
-
-	// read the data from the socket
-
-	Read = Socket->read((char *)Buffer, 4095);
-
-	Buffer[Read] = 0;
-
-	Msg = Buffer;
-
-	ptr = strchr(Msg, 0x0d);
-
-	while (ptr)
-	{
-		*ptr++ = 0;
-
-		if (strcmp(Msg, "IAMALIVE") == 0)
-		{
-		}
-		else if (strcmp(Msg, "PTT ON") == 0)
-		{
-			RadioPTT(1);
-		}
-		else if (strcmp(Msg, "PTT OFF") == 0)
-		{
-			RadioPTT(0);
-		}
-		else if (strcmp(Msg, "PENDING") == 0)
-		{
-		}
-		else if (strcmp(Msg, "CANCELPENDING") == 0)
-		{
-		}
-		else if (strcmp(Msg, "OK") == 0)
-		{
-		}
-		else if (memcmp(Msg, "CONNECTED ", 10) == 0)
-		{
-			Ui_ListenSession * Sess = (Ui_ListenSession *)VARASock->Sess;
-			char Title[128] = "";
-			char CallFrom[64] = "";
-			char CallTo[64] = "";
-			char Mode[64] = "";
-			char Message[128];
-			int n;
-
-
-			sscanf(&Msg[10], "%s %s %s", CallFrom, CallTo, Mode);
-
-			if (Sess)
-			{
-				if (Mode[0])
-					sprintf(Title, "Connected to %s %s Mode", CallTo, Mode);
-				else
-					sprintf(Title, "Connected to %s", CallTo);
-
-				n = sprintf(Message, "%s\r\n", Title);
-				WritetoOutputWindow(Sess, (unsigned char *)Message, n);
-
-				if (TermMode == MDI)
-					Sess->setWindowTitle(Title);
-				else if (TermMode == Tabbed)
-					tabWidget->setTabText(Sess->Tab, CallTo);
-				else if (TermMode == Single)
-					mythis->setWindowTitle(Title);
-
-				setMenus(true);
-			}
-			else
-			{
-				// Incoming Call
-
-				Ui_ListenSession * S;
-				int i = 0;
-
-				if (TermMode == MDI)
-				{
-					// See if an old session can be reused
-
-					for (int i = 0; i < _sessions.size(); ++i)
-					{
-						S = _sessions.at(i);
-
-						//	for (Ui_ListenSession * S: _sessions)
-						//	{
-						if ((S->SessionType & Listen) && S->clientSocket == NULL)
-						{
-							Sess = S;
-							break;
-						}
-					}
-
-					// Create a window if none found, else reuse old
-
-					if (Sess == NULL)
-					{
-						Sess = newWindow(this, Listen);
-					}
-				}
-				else
-				{
-					// Single or Tabbed - look for free session
-
-					for (i = 0; i < _sessions.size(); ++i)
-					{
-						S = _sessions.at(i);
-
-						if (S->clientSocket == NULL && S->AGWSession == NULL && S->AGWMonSession == NULL && S->KISSSession == NULL)
-						{
-							Sess = S;
-							break;
-						}
-					}
-				}
-
-				if (Sess == NULL)
-				{
-					// Clear connection
-
-					VARASock->write("DISCONNECT\r");
-				}
-				else
-				{
-					if (Mode[0])
-					{
-						sprintf(Title, "Connected to %s Mode %s", CallFrom, Mode);
-						n = sprintf(Message, "Incoming VARA Connect from %s %s Mode\r\n", CallFrom, Mode);
-					}
-					else
-					{
-						sprintf(Title, "Connected to %s", CallFrom);
-						n = sprintf(Message, "Incoming VARA Connect from %s\r\n", CallFrom);
-					}
-
-					WritetoOutputWindow(Sess, (unsigned char *)Message, n);
-
-					VARASock->Sess = Sess;
-					VARADataSock->Sess = Sess;
-
-					if (TermMode == MDI)
-						Sess->setWindowTitle(Title);
-					else if (TermMode == Tabbed)
-					{
-						tabWidget->setTabText(Sess->Tab, CallFrom);
-						tabWidget->tabBar()->setTabTextColor(Sess->Tab, newTabText);
-					}
-					else if (TermMode == Single)
-						mythis->setWindowTitle(Title);
-
-					setMenus(true);
-
-					if (ConnectBeep)
-						myBeep(&ConnectWAV);
-
-					if (listenCText[0])
-						VARADataSock->write(listenCText);
-
-					QApplication::alert(mythis, 0);
-
-				}
-			}
-		}
-		else if (strcmp(Msg, "DISCONNECTED") == 0)
-		{
-			Ui_ListenSession * Sess = (Ui_ListenSession *)VARASock->Sess;
-
-			if (Sess)
-			{
-				WritetoOutputWindow(Sess, (unsigned char *)"Disconnected\r\n", 14);
-				VARASock->Sess = 0;
-				VARADataSock->Sess = 0;
-
-				if (TermMode == MDI)
-				{
-					if (Sess->SessionType == Mon)			// Mon Only
-						Sess->setWindowTitle("Monitor Session Disconnected");
-					else
-						Sess->setWindowTitle("Disconnected");
-				}
-				else if (TermMode == Tabbed)
-				{
-					if (Sess->SessionType == Mon)			// Mon Only
-						tabWidget->setTabText(Sess->Tab, "Monitor");
-					else
-					{
-						char Label[16];
-						sprintf(Label, "Sess %d", Sess->Tab + 1);
-						tabWidget->setTabText(Sess->Tab, Label);
-					}
-				}
-				else if (TermMode == Single)
-				{
-					if (Sess->AGWMonSession)
-						mythis->setWindowTitle("AGW Monitor Window");
-					else
-					{
-						if (Sess->SessionType == Mon)			// Mon Only
-							this->setWindowTitle("Monitor Session Disconnected");
-						else
-							this->setWindowTitle("Disconnected");
-					}
-				}
-
-				setMenus(false);
-			}
-		}
-
-		Msg = ptr;
-
-		ptr = strchr(Msg, 0x0d);
-	}
-
-
-
-}
-
-void QtTermTCP::onVARASocketStateChanged(QAbstractSocket::SocketState socketState)
-{
-	//	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
-
-	if (socketState == QAbstractSocket::UnconnectedState)
-	{
-		// Close any connections
-
-		Status2->setText("VARA Disconnected");
-		actHost[17]->setVisible(0);
-
-		VARAConnecting = VARAConnected = 0;
-	}
-	else if (socketState == QAbstractSocket::ConnectedState)
-	{
-		// Connect Data Session. Leave Connecting till that completes
-
-		VARADataSock = new myTcpSocket();
-
-		connect(VARADataSock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(VARADatadisplayError(QAbstractSocket::SocketError)));
-		connect(VARADataSock, SIGNAL(readyRead()), this, SLOT(VARADatareadyRead()));
-		connect(VARADataSock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onVARADataSocketStateChanged(QAbstractSocket::SocketState)));
-
-		VARADataSock->connectToHost(VARAHost, VARAPortNum + 1);
-		Status2->setText("VARA Data Connecting");
-	}
-}
-
-
-void QtTermTCP::VARADatadisplayError(QAbstractSocket::SocketError socketError)
-{
-	switch (socketError)
-	{
-	case QAbstractSocket::RemoteHostClosedError:
-		break;
-
-	case QAbstractSocket::HostNotFoundError:
-		QMessageBox::information(this, tr("QtTermTCP"),
-			tr("VARA host was not found. Please check the "
-				"host name and portsettings->"));
-
-		Status2->setText("VARA Connection Failed");
-
-		break;
-
-	case QAbstractSocket::ConnectionRefusedError:
-
-		Status2->setText("VARA Connection Refused");
-		break;
-
-	default:
-
-		Status2->setText("VARA Connection Failed");
-	}
-
-	VARAConnecting = 0;
-	VARAConnected = 0;
-}
-
-void QtTermTCP::VARADatareadyRead()
-{
-	int Read;
-	unsigned char Buffer[4096];
-	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
-
-	Ui_ListenSession * Sess = (Ui_ListenSession *)Socket->Sess;
-
-	// read the data from the socket
-
-	Read = Socket->read((char *)Buffer, 2047);
-
-	while (Read > 0)
-	{
-		//		if (InputMode == 'Y')			// Yapp
-		//		{
-		//			QString myString = QString::fromUtf8((char*)Buffer, Read);
-		//			QByteArray ptr = myString.toLocal8Bit();
-		//			memcpy(Buffer, ptr.data(), ptr.length());
-		//			Read = ptr.length();
-		//		}
-
-		ProcessReceivedData(Sess, Buffer, Read);
-
-		QString myString = QString::fromUtf8((char*)Buffer);
-		//		qDebug() << myString;
-		Read = Socket->read((char *)Buffer, 2047);
-	}
-}
-
-
-void QtTermTCP::onVARADataSocketStateChanged(QAbstractSocket::SocketState socketState)
-{
-	//	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
-
-	if (socketState == QAbstractSocket::UnconnectedState)
-	{
-		// Close any connections
-
-		Status2->setText("VARA Disconnected");
-		actHost[17]->setVisible(0);
-
-		VARAConnecting = VARAConnected = 0;
-	}
-	else if (socketState == QAbstractSocket::ConnectedState)
-	{
-		char VARACommand[256];
-
-		VARAConnected = 1;
-		VARAConnecting = 0;
-
-		Status2->setText("VARA Connected");
-
-		actHost[17]->setVisible(1);			// Enable VARA Connect Line
-
-		sprintf(VARACommand, "MYCALL %s\r", VARATermCall);
-		VARASock->write(VARACommand);
-
-		if (VARA500)
-			VARASock->write("BW500\r");
-		else if (VARA2300)
-			VARASock->write("BW2300\r");
-		else if (VARA2750)
-			VARASock->write("BW2750\r");
-
-		VARASock->write("COMPRESSION FILES\r");
-
-		if (VARAInit[0])
-		{
-			char Copy[512];
-			char * param, *context;
-
-			strcpy(Copy, VARAInit);
-
-			param = strtok_s(Copy, ",", &context);
-
-			while (param && param[0])
-			{
-				sprintf(VARACommand, "%s\r", param);
-				VARASock->write(VARACommand);
-				param = strtok_s(nullptr, ",", &context);
-			}
-		}
-
-		if (listenEnable)
-			VARASock->write("LISTEN ON\r");
-	}
-}
-
-// PTT Stuff
-
-#include "hidapi.h"
-
-// Serial Port Stuff
-
-
-QTcpSocket * HAMLIBsock;
-int HAMLIBConnected = 0;
-int HAMLIBConnecting = 0;
-
-void QtTermTCP::HAMLIBdisplayError(QAbstractSocket::SocketError socketError)
-{
-	switch (socketError)
-	{
-	case QAbstractSocket::RemoteHostClosedError:
-		break;
-
-	case QAbstractSocket::HostNotFoundError:
-		QMessageBox::information(nullptr, tr("QtSM"),
-			"HAMLIB host was not found. Please check the "
-			"host name and portsettings->");
-
-		break;
-
-	case QAbstractSocket::ConnectionRefusedError:
-
-		qDebug() << "HAMLIB Connection Refused";
-		break;
-
-	default:
-
-		qDebug() << "HAMLIB Connection Failed";
-		break;
-
-	}
-
-	HAMLIBConnecting = 0;
-	HAMLIBConnected = 0;
-}
-
-void QtTermTCP::HAMLIBreadyRead()
-{
-	unsigned char Buffer[4096];
-	QTcpSocket* Socket = static_cast<QTcpSocket*>(QObject::sender());
-
-	// read the data from the socket. Don't do anyhing with it at the moment
-
-	Socket->read((char *)Buffer, 4095);
-}
-
-void QtTermTCP::onHAMLIBSocketStateChanged(QAbstractSocket::SocketState socketState)
-{
-	if (socketState == QAbstractSocket::UnconnectedState)
-	{
-		// Close any connections
-
-		HAMLIBConnected = 0;
-		HAMLIBConnecting = 0;
-
-		//	delete (HAMLIBsock);
-		//	HAMLIBsock = 0;
-
-		qDebug() << "HAMLIB Connection Closed";
-
-	}
-	else if (socketState == QAbstractSocket::ConnectedState)
-	{
-		HAMLIBConnected = 1;
-		HAMLIBConnecting = 0;
-		qDebug() << "HAMLIB Connected";
-	}
-}
-
-
-void QtTermTCP::ConnecttoHAMLIB()
-{
-	delete(HAMLIBsock);
-
-	HAMLIBConnected = 0;
-	HAMLIBConnecting = 1;
-
-	HAMLIBsock = new QTcpSocket();
-
-	connect(HAMLIBsock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(HAMLIBdisplayError(QAbstractSocket::SocketError)));
-	connect(HAMLIBsock, SIGNAL(readyRead()), this, SLOT(HAMLIBreadyRead()));
-	connect(HAMLIBsock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onHAMLIBSocketStateChanged(QAbstractSocket::SocketState)));
-
-	HAMLIBsock->connectToHost(HamLibHost, HamLibPort);
-
-	return;
-}
-
-void QtTermTCP::HAMLIBSetPTT(int PTTState)
-{
-	char Msg[16];
-
-	if (HAMLIBsock == nullptr || HAMLIBsock->state() != QAbstractSocket::ConnectedState)
-		ConnecttoHAMLIB();
-
-	if (HAMLIBsock == nullptr || HAMLIBsock->state() != QAbstractSocket::ConnectedState)
-		return;
-
-	sprintf(Msg, "T %d\r\n", PTTState);
-	HAMLIBsock->write(Msg);
-
-	HAMLIBsock->waitForBytesWritten(3000);
-
-	QByteArray datas = HAMLIBsock->readAll();
-
-	qDebug(datas.data());
-}
-
-QTcpSocket * FLRigsock;
-int FLRigConnected = 0;
-int FLRigConnecting = 0;
-
-void QtTermTCP::FLRigdisplayError(QAbstractSocket::SocketError socketError)
-{
-	switch (socketError)
-	{
-	case QAbstractSocket::RemoteHostClosedError:
-		break;
-
-	case QAbstractSocket::HostNotFoundError:
-		QMessageBox::information(nullptr, tr("QtSM"),
-			"FLRig host was not found. Please check the "
-			"host name and portsettings->");
-
-		break;
-
-	case QAbstractSocket::ConnectionRefusedError:
-
-		qDebug() << "FLRig Connection Refused";
-		break;
-
-	default:
-
-		qDebug() << "FLRig Connection Failed";
-		break;
-
-	}
-
-	FLRigConnecting = 0;
-	FLRigConnected = 0;
-}
-
-void QtTermTCP::FLRigreadyRead()
-{
-	unsigned char Buffer[4096];
-	QTcpSocket* Socket = static_cast<QTcpSocket*>(QObject::sender());
-
-	// read the data from the socket. Don't do anyhing with it at the moment
-
-	Socket->read((char *)Buffer, 4095);
-}
-
-void QtTermTCP::onFLRigSocketStateChanged(QAbstractSocket::SocketState socketState)
-{
-	if (socketState == QAbstractSocket::UnconnectedState)
-	{
-		// Close any connections
-
-		FLRigConnected = 0;
-		FLRigConnecting = 0;
-
-		//	delete (FLRigsock);
-		//	FLRigsock = 0;
-
-		qDebug() << "FLRig Connection Closed";
-
-	}
-	else if (socketState == QAbstractSocket::ConnectedState)
-	{
-		FLRigConnected = 1;
-		FLRigConnecting = 0;
-		qDebug() << "FLRig Connected";
-	}
-}
-
-
-void QtTermTCP::ConnecttoFLRig()
-{
-	delete(FLRigsock);
-
-	FLRigConnected = 0;
-	FLRigConnecting = 1;
-
-	FLRigsock = new QTcpSocket();
-
-	connect(FLRigsock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(FLRigdisplayError(QAbstractSocket::SocketError)));
-	connect(FLRigsock, SIGNAL(readyRead()), this, SLOT(FLRigreadyRead()));
-	connect(FLRigsock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onFLRigSocketStateChanged(QAbstractSocket::SocketState)));
-
-	FLRigsock->connectToHost(FLRigHost, FLRigPort);
-
-	return;
-}
-
-static char MsgHddr[] = "POST /RPC2 HTTP/1.1\r\n"
-"User-Agent: XMLRPC++ 0.8\r\n"
-"Host: 127.0.0.1:7362\r\n"
-"Content-Type: text/xml\r\n"
-"Content-length: %d\r\n"
-"\r\n%s";
-
-static char Req[] = "<?xml version=\"1.0\"?>\r\n"
-"<methodCall><methodName>%s</methodName>\r\n"
-"%s"
-"</methodCall>\r\n";
-
-void QtTermTCP::FLRigSetPTT(int PTTState)
-{
-	int Len;
-	char ReqBuf[512];
-	char SendBuff[512];
-	char ValueString[256] = "";
-
-	sprintf(ValueString, "<params><param><value><i4>%d</i4></value></param></params\r\n>", PTTState);
-
-	Len = sprintf(ReqBuf, Req, "rig.set_ptt", ValueString);
-	Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
-
-	if (FLRigsock == nullptr || FLRigsock->state() != QAbstractSocket::ConnectedState)
-		ConnecttoFLRig();
-
-	if (FLRigsock == nullptr || FLRigsock->state() != QAbstractSocket::ConnectedState)
-		return;
-
-	FLRigsock->write(SendBuff);
-
-	FLRigsock->waitForBytesWritten(3000);
-
-	QByteArray datas = FLRigsock->readAll();
-
-	qDebug(datas.data());
-}
-
-
-
-void QtTermTCP::CATChanged(bool State)
-{
-	UNUSED(State);
-	PTTPortChanged(0);
-}
-
-void QtTermTCP::VARAHFChanged(bool State)
-{
-	Dev->HFMode->setVisible(State);
-
-	if (State)
-	{
-		Dev->TNCInfo->setTitle("VARA HF Paramters");
-		Dev->Host->setText(VARAHostHF);
-		Dev->Port->setText(QString::number(VARAPortHF));
-		Dev->Path->setText(VARAPathHF);
-	}
-}
-
-void QtTermTCP::VARAFMChanged(bool State)
-{
-	if (State)
-	{
-		Dev->TNCInfo->setTitle("VARA FM Paramters");
-		Dev->Host->setText(VARAHostFM);
-		Dev->Port->setText(QString::number(VARAPortFM));
-		Dev->Path->setText(VARAPathFM);
-	}
-}
-
-void QtTermTCP::VARASATChanged(bool State)
-{
-	if (State)
-	{
-		Dev->TNCInfo->setTitle("VARA SAT Paramters");
-		Dev->Host->setText(VARAHostSAT);
-		Dev->Port->setText(QString::number(VARAPortSAT));
-		Dev->Path->setText(VARAPathSAT);
-	}
-}
-
-void QtTermTCP::SetVARAParams()
-{
-	Dev->Host->setText(VARAHost);
-	Dev->Port->setText(QString::number(VARAPortNum));
-	Dev->Path->setText(VARAPath);
-	Dev->InitCommands->setText(VARAInit);
-}
-
-void QtTermTCP::PTTPortChanged(int Selected)
-{
-	UNUSED(Selected);
-
-	QVariant Q = Dev->PTTPort->currentText();
-	strcpy(NewPTTPort, Q.toString().toUtf8());
-
-	Dev->RTSDTR->setVisible(false);
-	Dev->CAT->setVisible(false);
-
-	Dev->PTTOnLab->setVisible(false);
-	Dev->PTTOn->setVisible(false);
-	Dev->PTTOff->setVisible(false);
-	Dev->PTTOffLab->setVisible(false);
-	Dev->CATLabel->setVisible(false);
-	Dev->CATSpeed->setVisible(false);
-	Dev->CATHex->setVisible(false);
-	Dev->CATText->setVisible(false);
-
-	Dev->GPIOLab->setVisible(false);
-	Dev->GPIOLeft->setVisible(false);
-	Dev->GPIORight->setVisible(false);
-	Dev->GPIOLab2->setVisible(false);
-
-	Dev->CM108Label->setVisible(false);
-	Dev->VIDPID->setVisible(false);
-
-	if (strcmp(NewPTTPort, "None") == 0)
-	{
-	}
-	else if (strcmp(NewPTTPort, "GPIO") == 0)
-	{
-		Dev->GPIOLab->setVisible(true);
-		Dev->GPIOLeft->setVisible(true);
-	}
-
-	else if (strcmp(NewPTTPort, "CM108") == 0)
-	{
-		Dev->CM108Label->setVisible(true);
-#ifdef WIN32
-		Dev->CM108Label->setText("CM108 VID/PID");
-#else
-		Dev->CM108Label->setText("CM108 Device");
-#endif
-		Dev->VIDPID->setText(CM108Addr);
-		Dev->VIDPID->setVisible(true);
-	}
-	else if (strcmp(NewPTTPort, "HAMLIB") == 0)
-	{
-		Dev->CM108Label->setVisible(true);
-		Dev->CM108Label->setText("rigctrld Port");
-		Dev->VIDPID->setText(QString::number(HamLibPort));
-		Dev->VIDPID->setVisible(true);
-		Dev->PTTOnLab->setText("rigctrld Host");
-		Dev->PTTOnLab->setVisible(true);
-		Dev->PTTOn->setText(HamLibHost);
-		Dev->PTTOn->setVisible(true);
-	}
-	else if (strcmp(NewPTTPort, "FLRIG") == 0)
-	{
-		Dev->CM108Label->setVisible(true);
-		Dev->CM108Label->setText("FLRig Port");
-		Dev->VIDPID->setText(QString::number(FLRigPort));
-		Dev->VIDPID->setVisible(true);
-		Dev->PTTOnLab->setText("FLRig Host");
-		Dev->PTTOnLab->setVisible(true);
-		Dev->PTTOn->setText(FLRigHost);
-		Dev->PTTOn->setVisible(true);
-	}
-
-	else
-	{
-		Dev->RTSDTR->setVisible(true);
-		Dev->CAT->setVisible(true);
-
-		if (Dev->CAT->isChecked())
-		{
-			Dev->CATHex->setVisible(true);
-			Dev->CATText->setVisible(true);
-			Dev->PTTOnLab->setVisible(true);
-			Dev->PTTOnLab->setText("PTT On String");
-			Dev->PTTOn->setText(PTTOnString);
-			Dev->PTTOn->setVisible(true);
-			Dev->PTTOff->setVisible(true);
-			Dev->PTTOffLab->setVisible(true);
-			Dev->PTTOff->setVisible(true);
-			Dev->PTTOff->setText(PTTOffString);
-			Dev->CATLabel->setVisible(true);
-			Dev->CATSpeed->setVisible(true);
-			Dev->CATSpeed->setText(QString::number(PTTBAUD));
-		}
-	}
-}
-
-
-
-void DecodeCM108(char * ptr)
-{
-	// Called if Device Name or PTT = Param is CM108
-
-#ifdef WIN32
-
-	// Next Param is VID and PID - 0xd8c:0x8 or Full device name
-	// On Windows device name is very long and difficult to find, so 
-	//	easier to use VID/PID, but allow device in case more than one needed
-
-	char * next;
-	long VID = 0, PID = 0;
-	char product[256] = "Unknown";
-
-	struct hid_device_info *devs, *cur_dev;
-	const char *path_to_open = NULL;
-	hid_device *handle = NULL;
-
-	if (strlen(ptr) > 16)
-		CM108Device = _strdup(ptr);
-	else
-	{
-		VID = strtol(ptr, &next, 0);
-		if (next)
-			PID = strtol(++next, &next, 0);
-
-		// Look for Device
-
-		devs = hid_enumerate((unsigned short)VID, (unsigned short)PID);
-		cur_dev = devs;
-
-		while (cur_dev)
-		{
-			if (cur_dev->product_string)
-				wcstombs(product, cur_dev->product_string, 255);
-
-			printf("HID Device %s VID %X PID %X", product, cur_dev->vendor_id, cur_dev->product_id);
-			if (cur_dev->vendor_id == VID && cur_dev->product_id == PID)
-			{
-				path_to_open = cur_dev->path;
-				break;
-			}
-			cur_dev = cur_dev->next;
-		}
-
-		if (path_to_open)
-		{
-			handle = hid_open_path(path_to_open);
-
-			if (handle)
-			{
-				hid_close(handle);
-				CM108Device = _strdup(path_to_open);
-			}
-			else
-			{
-				printf("Unable to open CM108 device %x %x", VID, PID);
-			}
-		}
-		else
-			printf("Couldn't find CM108 device %x %x", VID, PID);
-
-		hid_free_enumeration(devs);
-	}
-#else
-
-	// Linux - Next Param HID Device, eg /dev/hidraw0
-
-	CM108Device = strdup(ptr);
-#endif
-}
-
-
-void QtTermTCP::OpenPTTPort()
-{
-	PTTMode &= ~PTTCM108;
-	PTTMode &= ~PTTHAMLIB;
-	PTTMode &= ~PTTFLRIG;
-
-	if (PTTPort[0] && strcmp(PTTPort, "None") != 0)
-	{
-		if (PTTMode == PTTCAT)
-		{
-			// convert config strings from Hex
-
-			if (CATHex == 0)		// Ascii Strings
-			{
-				strcpy((char *)PTTOffCmd, PTTOffString);
-				PTTOffCmdLen = strlen(PTTOffString);
-
-				strcpy((char *)PTTOnCmd, PTTOnString);
-				PTTOnCmdLen = strlen(PTTOnString);
-			}
-			else
-			{
-				char * ptr1 = PTTOffString;
-				unsigned char * ptr2 = PTTOffCmd;
-				char c;
-				int val;
-
-				while ((c = *(ptr1++)))
-				{
-					val = c - 0x30;
-					if (val > 15) val -= 7;
-					val <<= 4;
-					c = *(ptr1++) - 0x30;
-					if (c > 15) c -= 7;
-					val |= c;
-					*(ptr2++) = val;
-				}
-
-				PTTOffCmdLen = ptr2 - PTTOffCmd;
-
-				ptr1 = PTTOnString;
-				ptr2 = PTTOnCmd;
-
-				while ((c = *(ptr1++)))
-				{
-					val = c - 0x30;
-					if (val > 15) val -= 7;
-					val <<= 4;
-					c = *(ptr1++) - 0x30;
-					if (c > 15) c -= 7;
-					val |= c;
-					*(ptr2++) = val;
-				}
-
-				PTTOnCmdLen = ptr2 - PTTOnCmd;
-			}
-		}
-
-		if (strcmp(PTTPort, "GPIO") == 0)
-		{
-			// Initialise GPIO for PTT if available
-
-#ifdef __ARM_ARCH
-
-//			if (gpioInitialise() == 0)
-//			{
-//				printf("GPIO interface for PTT available\n");
-//				gotGPIO = TRUE;
-
-//				SetupGPIOPTT();
-//			}
-//			else
-//				printf("Couldn't initialise GPIO interface for PTT\n");
-//
-#else
-			printf("GPIO interface for PTT not available on this platform\n");
-#endif
-
-		}
-		else if (strcmp(PTTPort, "CM108") == 0)
-		{
-			DecodeCM108(CM108Addr);
-			PTTMode |= PTTCM108;
-		}
-
-		else if (strcmp(PTTPort, "HAMLIB") == 0)
-		{
-			PTTMode |= PTTHAMLIB;
-			HAMLIBSetPTT(0);			// to open port
-			return;
-		}
-
-		else if (strcmp(PTTPort, "FLRIG") == 0)
-		{
-			PTTMode |= PTTFLRIG;
-			FLRigSetPTT(0);			// to open port
-			return;
-		}
-
-		else		//  Serial Port
-		{
-#ifdef USESERIAL
-			hPTTDevice = new QSerialPort(this);
-			hPTTDevice->setPortName(PTTPort);
-			hPTTDevice->setBaudRate(PTTBAUD);
-			hPTTDevice->setDataBits(QSerialPort::Data8);
-			hPTTDevice->setParity(QSerialPort::NoParity);
-			hPTTDevice->setStopBits(QSerialPort::OneStop);
-			hPTTDevice->setFlowControl(QSerialPort::NoFlowControl);
-			if (hPTTDevice->open(QIODevice::ReadWrite))
-			{
-				qDebug() << "PTT Port Opened";
-			}
-			else
-			{
-				QMessageBox msgBox;
-				msgBox.setText("PTT COM Port Open Failed.");
-				msgBox.exec();
-				qDebug() << "PTT Port Open failed";
-				delete(hPTTDevice);
-				hPTTDevice = 0;
-			}
-#endif
-		}
-	}
-}
-
-void ClosePTTPort()
-{
-#ifdef USESERIAL
-	if (hPTTDevice)
-		hPTTDevice->close();
-	hPTTDevice = 0;
-#endif
-}
-
-#ifndef ANDRIOD
-
-void CM108_set_ptt(int PTTState)
-{
-	unsigned char io[5];
-	int n;
-
-	io[0] = 0;
-	io[1] = 0;
-	io[2] = 1 << (3 - 1);
-	io[3] = PTTState << (3 - 1);
-	io[4] = 0;
-
-	if (CM108Device == NULL)
-		return;
-
-#ifdef WIN32
-	hid_device *handle;
-
-	handle = hid_open_path(CM108Device);
-
-	if (!handle) {
-		printf("unable to open device\n");
-		return;
-	}
-
-	n = hid_write(handle, io, 5);
-	if (n < 0)
-	{
-		printf("Unable to write()\n");
-		printf("Error: %ls\n", hid_error(handle));
-	}
-
-	hid_close(handle);
-
-#else
-
-	int fd;
-
-	fd = open(CM108Device, O_WRONLY);
-
-	if (fd == -1)
-	{
-		printf("Could not open %s for write, errno=%d\n", CM108Device, errno);
-		return;
-	}
-
-	io[0] = 0;
-	io[1] = 0;
-	io[2] = 1 << (3 - 1);
-	io[3] = PTTState << (3 - 1);
-	io[4] = 0;
-
-	n = write(fd, io, 5);
-	if (n != 5)
-	{
-		printf("Write to %s failed, n=%d, errno=%d\n", CM108Device, n, errno);
-	}
-
-	close(fd);
-#endif
-	return;
-
-}
-
-#endif
-
-void QtTermTCP::RadioPTT(bool PTTState)
-{
-#ifdef __ARM_ARCH
-	if (useGPIO)
-	{
-		//		gpioWrite(pttGPIOPin, (pttGPIOInvert ? (1 - PTTState) : (PTTState)));
-		//		return;
-	}
-
-#endif
-
-	if ((PTTMode & PTTCM108))
-	{
-		CM108_set_ptt(PTTState);
-		return;
-	}
-
-	if ((PTTMode & PTTHAMLIB))
-	{
-		HAMLIBSetPTT(PTTState);
-		return;
-	}
-
-	if ((PTTMode & PTTFLRIG))
-	{
-		FLRigSetPTT(PTTState);
-		return;
-	}
-
-#ifdef USESERIAL
-
-	if (hPTTDevice == 0)
-		return;
-
-	if ((PTTMode & PTTCAT))
-	{
-		if (PTTState)
-			hPTTDevice->write((char *)PTTOnCmd, PTTOnCmdLen);
-		else
-			hPTTDevice->write((char *)PTTOffCmd, PTTOffCmdLen);
-
-		hPTTDevice->flush();
-		//		hPTTDevice->error();
-		return;
-
-	}
-
-
-	if ((PTTMode & PTTRTS))
-	{
-		int n = hPTTDevice->setRequestToSend(PTTState);
-		n = n;
-	}
-
-#endif
-
-}
-
-
-
-extern "C" void WriteDebugLog(char * Mess)
-{
-	qDebug() << Mess;
-}
-
-void QtTermTCP::ConnecttoKISS()
-{
-	if (strcmp(SerialPort, "TCP") == 0)
-	{
-		delete(KISSSock);
-
-		KISSSock = new myTcpSocket();
-		KISSSockCopy[0] = (void *)KISSSock;
-
-
-		connect(KISSSock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(KISSdisplayError(QAbstractSocket::SocketError)));
-		connect(KISSSock, SIGNAL(readyRead()), this, SLOT(KISSreadyRead()));
-		connect(KISSSock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onKISSSocketStateChanged(QAbstractSocket::SocketState)));
-
-		KISSSock->connectToHost(KISSHost, KISSPortNum);
-
-		Status3->setText("KISS Connecting");
-	}
-	else
-		openSerialPort();
-
-	return;
-}
-
-
-void QtTermTCP::KISSTimer()
-{
-	// Runs every 10 Seconds
-
-	if (KISSConnected == 0 && KISSConnecting == 0)
-	{
-		ConnecttoKISS();
-	}
-	else
-	{
-		// Verify Serial port is still ok
-
- 		if (m_serial && KISSConnected)
-		{
-			m_serial->clearError();
-			boolean rc = m_serial->isDataTerminalReady();
-
-			if (m_serial->error())
-			{
-				Debugprintf("Serial Port Lost - isOpen %d Error %d", m_serial->isOpen(), m_serial->error());
-				closeSerialPort();
-			}
-		}
-	}
-}
-
-
-
-void QtTermTCP::KISSdisplayError(QAbstractSocket::SocketError socketError)
-{
-	switch (socketError)
-	{
-	case QAbstractSocket::RemoteHostClosedError:
-		break;
-
-	case QAbstractSocket::HostNotFoundError:
-		QMessageBox::information(this, tr("QtTermTCP"),
-			tr("KISS host was not found. Please check the "
-				"host name and portsettings->"));
-
-		Status3->setText("KISS Connection Failed");
-
-		break;
-
-	case QAbstractSocket::ConnectionRefusedError:
-
-		Status3->setText("KISS Connection Refused");
-		break;
-
-	default:
-
-		Status3->setText("KISS Connection Failed");
-	}
-
-	KISSConnecting = 0;
-	KISSConnected = 0;
-}
-
-
-extern "C" void KISSSendtoServer(myTcpSocket* Socket, char * Data, int Length)
-{
-	if (m_serial)
-	{
-		if (m_serial->isOpen())
-		{
-			m_serial->clearError();
-
-			int n = m_serial->write(Data, Length);
-
-			n = m_serial->flush();
-
-			if (m_serial->error())
-			{
-				Debugprintf("Serial Flush Error - Requested = %d Actual %d Error %d", Length, n, m_serial->error());
-				closeSerialPort();
-			}
-		}
-	}
-	else if (Socket)
-		Socket->write(Data, Length);
-}
-
-
-
-void QtTermTCP::KISSreadyRead()
-{
-	int Read;
-	unsigned char Buffer[4096];	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
-
-	// read the data from the socket
-
-	Read = Socket->read((char *)Buffer, 4095);
-
-	KISSDataReceived(Socket, Buffer, Read);
-
-}
-
-extern "C" void KISS_del_socket(void * socket);
-extern "C" void KISS_add_stream(void * Socket);
-
-void QtTermTCP::onKISSSocketStateChanged(QAbstractSocket::SocketState socketState)
-{
-	//	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
-
-	QTcpSocket* sender = static_cast<QTcpSocket*>(QObject::sender());
-
-	if (socketState == QAbstractSocket::UnconnectedState)
-	{
-		// Close any connections
-
-		Ui_ListenSession * Sess = NULL;
-
-		Status3->setText("KISS Disconnected");
-		actHost[18]->setEnabled(0);
-
-		KISSConnecting = KISSConnected = 0;
-
-		// Free the monitor Window
-
-		if (KISSMonSess)
-		{
-			Sess = KISSMonSess;
-
-			if (TermMode == MDI)
-				Sess->setWindowTitle("Monitor Session Disconnected");
-
-			else if (TermMode == Tabbed)
-				tabWidget->setTabText(Sess->Tab, "Monitor");
-
-			KISSMonSess = nullptr;
-		}
-
-		KISS_del_socket(sender);
-		KISSSock = NULL;
-	}
-	else if (socketState == QAbstractSocket::ConnectedState)
-	{
-		int i;
-
-		KISSConnected = 1;
-		KISSConnecting = 0;
-
-		Status3->setText("KISS Connected");
-		actHost[18]->setEnabled(1);			// Enable KISS Connect Line
-
-		KISS_add_stream(sender);
-
-		// send TXDelay if enabled
-
-		if (sendTXDelay[0])
-		{
-			unsigned char Msg[5] = { FEND, 1, 25 , FEND };
-
-			Msg[2] = txdelay[0] / 10;
-			KISSSock->write((char *)Msg, 4);
-		}
-
-		// Attach a Monitor Window if available
-
-		Ui_ListenSession * Sess = NULL;
-		Ui_ListenSession * S;
-
-		if (TermMode == MDI)
-		{
-			// See if an old session can be reused
-
-			for (int i = 0; i < _sessions.size(); ++i)
-			{
-				S = _sessions.at(i);
-
-				//	for (Ui_ListenSession * S: _sessions)
-				//	{
-				if ((S->SessionType == Mon) && S->clientSocket == NULL && S->KISSSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess))  && S != KISSMonSess)
-				{
-					Sess = S;
-					break;
-				}
-			}
-
-			// Create a window if none found, else reuse old
-
-			if (Sess == NULL)
-			{
-				Sess = newWindow((QObject *)mythis, Mon, "");
-			}
-		}
-		else if (TermMode == Tabbed)
-		{
-			// Tabbed - look for free session
-
-			for (i = 8; i; i--)
-			{
-				S = _sessions.at(i);
-
-				if (S->clientSocket == NULL && S->KISSSession == NULL  && S->AGWSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
-				{
-					Sess = S;
-					break;
-				}
-			}
-		}
-		else if (TermMode == Single && (singlemodeFormat & Mon))
-		{
-			S = _sessions.at(0);
-
-			if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
-				Sess = S;
-
-		}
-
-		if (Sess)
-		{
-			KISSMonSess = Sess;			// Flag as in use
-
-			if (TermMode == MDI)
-				Sess->setWindowTitle("KISS Monitor Window");
-			else if (TermMode == Tabbed)
-				tabWidget->setTabText(Sess->Tab, "KISS Mon");
-			else if (TermMode == Single)
-				mythis->setWindowTitle("KISS Monitor Window");
-
-			Sess->mlocaltime = KISSLocalTime;
-			Sess->MonitorNODES = KISSMonNodes;
-
-			//			if (TermMode == Single)	
-			//			{
-			//				discAction->setEnabled(false);
-			//				YAPPSend->setEnabled(false);
-			//				connectMenu->setEnabled(false);
-			//			}
-		}
-	}
-}
-
-
-extern "C" char * frame_monitor(string * frame, char * code, bool tx_stat);
-extern "C" char * ShortDateTime();
-
-extern "C" void monitor_frame(int snd_ch, string * frame, char * code, int  tx, int excluded)
-{
-	UNUSED(excluded);
-	UNUSED(snd_ch);
-
-	int Len;
-	char Msg[1024];
-
-	if (tx)
-		sprintf(Msg, "\x1b\x10%s", frame_monitor(frame, code, tx));
-	else
-		sprintf(Msg, "\x1b\x11%s", frame_monitor(frame, code, tx));
-
-	Len = strlen(Msg);
-
-	if (Len < 10)		// Suppressed NODES
-		return;
-
-	if (Msg[Len - 1] != '\r')
-	{
-		Msg[Len++] = '\r';
-		Msg[Len] = 0;
-	}
-
-	if (KISSMonSess)
-		WritetoMonWindow(KISSMonSess, (unsigned char *)Msg, Len);
-
-}
-
-extern "C" Ui_ListenSession * ax25IncomingConnect(TAX25Port * AX25Sess)
-{
-	// Look for/create Terminal Window for connection
-
-	Ui_ListenSession * Sess = NULL;
-	Ui_ListenSession * S;
-	char Title[80];
-	int i = 0;
-
-	if (TermMode == MDI)
-	{
-		// See if an old session can be reused
-
-		for (int i = 0; i < _sessions.size(); ++i)
-		{
-			S = _sessions.at(i);
-
-			if ((S->SessionType & Listen) && S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL)
-			{
-				Sess = S;
-				break;
-			}
-		}
-
-		// Create a window if none found, else reuse old
-
-		if (Sess == NULL)
-		{
-			Sess = newWindow((QObject *)mythis, Listen, "");
-		}
-	}
-	else
-	{
-		// Single or Tabbed - look for free session
-
-
-		for (i = 0; i < _sessions.size(); ++i)
-		{
-			S = _sessions.at(i);
-
-			if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL)
-			{
-				Sess = S;
-				break;
-			}
-		}
-
-		if (Sess == NULL)
-		{
-			// Clear connection
-
-			return NULL;
-		}
-	}
-
-	if (Sess)
-	{
-		sprintf(Title, "Connected to %s", AX25Sess->corrcall);
-
-		if (TermMode == MDI)
-		{
-			Sess->setWindowTitle(Title);
-		}
-		else if (TermMode == Tabbed)
-		{
-			tabWidget->setTabText(i, AX25Sess->corrcall);
-			tabWidget->tabBar()->setTabTextColor(i, newTabText);
-		}
-		else if (TermMode == Single)
-			mythis->setWindowTitle(Title);
-
-		AX25Sess->port = 0;
-		AX25Sess->Sess = Sess;				// Crosslink KISS and Term Sessions
-		AX25Sess->PID = 240;;
-
-		Sess->KISSSession = AX25Sess;
-
-		setMenus(true);
-
-		if (ConnectBeep)
-			myBeep(&ConnectWAV);
-
-		QApplication::alert(mythis, 0);
-
-		// Send CText if defined
-
-		if (listenCText[0])
-			SendtoAX25(Sess->KISSSession, (unsigned char *)listenCText, (int)strlen(listenCText));
-	}
-	return Sess;
-}
-
-
-extern "C" void AX25_disc(TAX25Port * AX25Sess, Byte mode)
-{
-	char Msg[128];
-	int Len = 0;
-	Ui_ListenSession * Sess = (Ui_ListenSession *)AX25Sess->Sess;
-
-	if (AX25Sess->status == STAT_TRY_LINK)
-	{
-		// Connect failed
-
-		Len = sprintf(Msg, "Connection to %s failed\r", AX25Sess->corrcall);
-	}
-	else
-	{
-		switch (mode)
-		{
-		case MODE_OTHER:
-		case MODE_OUR:
-
-			Len = sprintf(Msg, "Disconnected from %s\r", AX25Sess->corrcall);
-			break;
-
-		case MODE_RETRY:
-
-			Len = sprintf(Msg, "Disconnected from %s - Retry count exceeded\r", AX25Sess->corrcall);
-			break;
-
-		};
-	}
-
-	SendtoTerm(Sess, Msg, Len);
-	ClearSessLabel(Sess);
-	Sess->KISSSession = NULL;
-	AX25Sess->Sess = 0;
-
-	setMenus(0);
-};
-
-int QtTermTCP::openSerialPort()
-{
-	if (m_serial && m_serial->isOpen())
-	{
-		m_serial->close();
-	}
-
-	m_serial = nullptr;
-	m_serial = new QSerialPort(this);
-
-	m_serial->setPortName(SerialPort);
-	boolean ok = m_serial->setBaudRate(KISSBAUD);
-
-	if (m_serial->open(QIODevice::ReadWrite))
-	{
-		int i;
-
-		ok = m_serial->setRequestToSend(true);
-
-		connect(m_serial, &QSerialPort::readyRead, this, &QtTermTCP::readSerialData);
-		//		connect(m_serial, &QSerialPort::errorOccurred, this, &QtTermTCP::handleError);
-
-		KISSConnected = 1;
-		KISSConnecting = 0;
-
-		Status3->setText("KISS Connected");
-		actHost[18]->setEnabled(1);			// Enable KISS Connect Line
-
-		KISS_add_stream(m_serial);
-
-		// send TXDelay if enabled
-
-		if (sendTXDelay[0])
-		{
-			unsigned char Msg[5] = { FEND, 1, 25 , FEND };
-
-			Msg[2] = txdelay[0] / 10;
-			m_serial->write((char *)Msg, 4);
-		}
-
-		// Attach a Monitor Window if available
-
-		Ui_ListenSession * Sess = NULL;
-		Ui_ListenSession * S;
-
-		if (TermMode == MDI)
-		{
-			// See if an old session can be reused
-
-			for (int i = 0; i < _sessions.size(); ++i)
-			{
-				S = _sessions.at(i);
-
-				//	for (Ui_ListenSession * S: _sessions)
-				//	
-				if ((S->SessionType == Mon) && S->clientSocket == NULL && S->KISSSession == NULL)
-				{
-					Sess = S;
-					break;
-				}
-			}
-
-			// Create a window if none found, else reuse old
-
-			if (Sess == NULL)
-			{
-				Sess = newWindow((QObject *)mythis, Mon, "");
-			}
-		}
-		else if (TermMode == Tabbed)
-		{
-			// Tabbed - look for free session
-
-			for (i = 8; i; i--)
-			{
-				S = _sessions.at(i);
-
-				if (S->clientSocket == NULL && S->KISSSession == NULL)
-				{
-					Sess = S;
-					break;
-				}
-			}
-		}
-		else if (TermMode == Single && (singlemodeFormat & Mon))
-		{
-			S = _sessions.at(0);
-
-			if (S->clientSocket == NULL && S->KISSSession == NULL)
-				Sess = S;
-
-		}
-
-		if (Sess)
-		{
-			KISSMonSess = Sess;			// Flag as in use
-
-			if (TermMode == MDI)
-				Sess->setWindowTitle("KISS Monitor Window");
-			else if (TermMode == Tabbed)
-				tabWidget->setTabText(Sess->Tab, "KISS Mon");
-			else if (TermMode == Single)
-				mythis->setWindowTitle("KISS Monitor Window");
-
-			//			if (TermMode == Single)	
-			//			{
-			//				discAction->setEnabled(false);
-			//				YAPPSend->setEnabled(false);
-			//				connectMenu->setEnabled(false);
-			//			}
-		}
-
-
-
-		return 1;
-	}
-	else
-	{
-		Status3->setText("KISS Open Failed");
-		KISSConnected = 0;
-		KISSConnecting = 0;
-		return 0;
-	}
-}
-
-
-
-void closeSerialPort()
-{
-	if (m_serial && m_serial->isOpen())
-	{
-		m_serial->close();
-		m_serial = nullptr;
-	}
-
-	m_serial = nullptr;
-
-	KISSConnected = 0;
-	KISSConnecting = 0;
-
-	Status3->setText("KISS Closed");
-	actHost[18]->setEnabled(0);			// Enable KISS Connect Line
-}
-
-void QtTermTCP::readSerialData()
-{
-	int Read;
-	unsigned char Buffer[8192];
-
-	// read the data from the socket
-
-	m_serial->clearError();
-
-	Read = m_serial->read((char *)Buffer, 2047);
-
-	if (m_serial->error())
-	{
-		Debugprintf("Serial Read Error - RC %d Error %d", Read, m_serial->error());
-		closeSerialPort();
-		return;
-	}
-
-
-	while (Read > 0)
-	{
-		KISSDataReceived(m_serial, Buffer, Read);
-		Read = m_serial->read((char *)Buffer, 2047);
-	}
-}
-
-void QtTermTCP::handleError(QSerialPort::SerialPortError serialPortError)
-{
-	Debugprintf("Serial port Error %d", serialPortError);
-	closeSerialPort();
-}
-
-extern "C" void CheckUIFrame(unsigned char * path, string * data)
-{
-	// If we have KISS enabled and dest is UIDEST look for a KISS window in UI Mode
-
-	if (KISSSock == 0)
-		return;
-
-	char Dest[10];
-	char From[10];
-
-	Dest[ConvFromAX25(path, Dest)] = 0;
-	From[ConvFromAX25(&path[7], From)] = 0;
-
-	// ok, Find a Kiss Session with this Dest
-
-	Ui_ListenSession * Sess = NULL;
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		if (Sess->KISSMode == 1 && strcmp(Dest, Sess->UIDEST) == 0)
-		{
-			char Msg[512];
-			int Len;
-
-			data->Data[data->Length] = 0;
-
-			Len = sprintf(Msg, "%s:%s", From, data->Data);
-			SendtoTerm(Sess, Msg, Len);
-			return;
-		}
-	}
-
-}
-
-
-QColor QtTermTCP::setColor(QColor Colour)
-{
-	//    const QColorDialog::ColorDialogOptions options = QFlag(colorDialogOptionsWidget->value());
-
-
-	QColor col = Colour;
-
-	QColorDialog dialog;
-	dialog.setCurrentColor(Colour);
-	dialog.setOption(QColorDialog::DontUseNativeDialog);
-
-	if (dialog.exec() == QColorDialog::Accepted)
-		col = QVariant(dialog.currentColor()).toString();
-
-
-	//	const QColor color = QColorDialog::getColor(Qt::green, this, "Select Color", 0);
-
-	return col;
-}
-
-// Experimental Viewdata/Teletext/Prestel/CEEFAX Mode
-
-// Uses ideas and some code from 
-
-/***************************************************************
- * Name:      wxTEDMain.cpp
- * Purpose:   Teletext editor Application Frame
- * Author:    Peter Kwan (peterk.vt80@gmail.com)
- * Created:   2014-10-30
- * Copyright: Peter Kwan
- * License:
-  *
- * Copyright (C) 2014-2022, Peter Kwan
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that the copyright notice and this
- * permission notice and warranty disclaimer appear in supporting
- * documentation, and that the name of the author not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * The author disclaims all warranties with regard to this
- * software, including all implied warranties of merchantability
- * and fitness.  In no event shall the author be liable for any
- * special, indirect or consequential damages or any damages
- * whatsoever resulting from loss of use, data or profits, whether
- * in an action of contract, negligence or other tortious action,
- * arising out of or in connection with the use or performance of
- * this software.
- *************************************************************************** **/
-
-
-
-int FontWidth = 16;
-int FontHeight = 16;
-
-bool isMosaic(char ch)
-{
-	ch &= 0x7f;
-	return (ch >= 0x20 && ch < 0x40) || ch >= 0x60;
-}
-
-
-void DecodeTeleText(Ui_ListenSession * Sess, char * page)
-{
-
-	// redraw the whole teletext page
-
-	QColor fg = Qt::white;
-	QColor bg = Qt::black;
-	QColor holdColour;
-	QColor holdfg = fg;			// Colour for held graphic
-	int usehold = 0;
-	int sep = 0;
-
-	QPainter p(Sess->TTBitmap);
-
-	QSettings settings(GetConfPath(), QSettings::IniFormat);
-
-  //p.setFont(QFont("Courier", 14, QFont::Bold));
-
-	p.setFont(QFont(settings.value("FontFamily", "Courier New").value<QString>(), 14));
-
-	p.setPen(QPen(fg));
-
-	bool graphicsMode = false;
-	bool separated = false;
-	bool doubleHeight = false;
-	int skipnextrow = 99;
-	bool flashing = false;
-	bool hold = false;
-	char holdChar = 0;
-	char holdMode = 0;
-	Sess->timer.stop();
-
-	bool concealed = false;
-	char c;
-
-	fg = Qt::white;
-	bg = Qt::black;
-
-	char * ptr = page;
-
-	int col = 0;
-	int line = 0;
-
-	// XXXXXXXXTEEFAX %%# %%a %d %%b C %H:%M.%S
-
-	//p.drawText(0, 19, "P199            HAMFAX");
-
-
-	// interpret data, for now, line by line
-
-
-	while ((c = *(ptr++)))
-	{
-		char ch = c;
-
-		if (c == 0x11)			// Curson On ??
-			continue;
-
-		if (c == 0x14)			// Curson Off ??
-			continue;
-
-		if (c == 9)			// Curson On ??
-		{
-			col++;
-			continue;
-		}
-
-		if (c == 0x0a)
-		{
-			line++;
-
-//			if (doubleHeight)
-//				line++;
-
-			if (line > 24)
-				line = 0;
-
-			continue;
-		}
-
-		if (c == 0x1e)			// Cursor Home
-		{
-			line = col = 0;
-			c = 13;					// So we reset page flags below
-		}
-
-		if (c == 12)
-		{
-			// Clear the page
-
-			Sess->TTBitmap->fill(Qt::black);
-			Sess->TTLabel->setPixmap(QPixmap::fromImage(*Sess->TTBitmap));
-
-			line = col = 0;
-			
-			c = 13;					// So we reset page flags below
-		}
-
-		if (c == 13)
-		{
-			col = 0;
-
-			graphicsMode = false;
-			separated = false;
-			doubleHeight = false;
-			flashing = false;
-			hold = false;
-			holdChar = 0;
-			concealed = false;
-
-			fg = Qt::white;
-			bg = Qt::black;
-
-			continue;			// Next line
-		}
-
-		if (c == 0x1b) // Esc
-		{
-			// I think the control char is displayed as it was before being actioned, sa save current state
-
-			holdfg = holdColour;						// Colour if using held - may be changed before displaying
-			usehold = hold;								// May be changed
-			sep = holdMode;
-
-			char echar = *(ptr++);
-
-			if (echar == 0)
-			{
-				// Esc pair spilt - wait for rest
-
-				Sess->TTLabel->setPixmap(QPixmap::fromImage(*Sess->TTBitmap));
-				return;
-			}
-			
-			switch (echar)
-			{
-			case '@':
-				fg = Qt::black;
-				concealed = false;    // Side effect of colour. It cancels a conceal.
-				graphicsMode = false;
-//				hold = false;
-
-				break;
-			case 'A':
-				fg = Qt::red;
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-
-				break;
-			case 'B':
-				fg = Qt::green;
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-				break;
-			case 'C':
-				fg = Qt::yellow;
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-				break;
-			case 'D':
-				fg = Qt::blue;
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-				break;
-			case 'E':
-				fg = Qt::magenta;
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-				break;
-			case 'F':
-				fg = Qt::cyan;
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-				break;
-			case 'G':
-				fg = Qt::white;
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-				break;
-			case 'H':					// Flash
-				flashing = true;
-				Sess->timer.start(1000, Sess);
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-
-				break;
-
-			case 'I':					// Steady
-				flashing = false;
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-
-				break;
-				//		
-			case 'J':			//ttxCodeEndBox:
-			case 'K':			//ttxCodeStartBox:
-
-				concealed = false;
-				graphicsMode = false;
-				hold = false;
-					
-				break;
-			case 'L': // Normal height
-				doubleHeight = false;
-				hold = false;  
-				break;
-
-			case 'M': // Double height
-				doubleHeight = true;
-				skipnextrow = line + 1;   // ETSI: row to ignore
-				hold = false;
-				holdChar = 0;
-				break;
-			case 'P': // Graphics black
-//				concealed = false;
-				graphicsMode = true;
-				holdColour = fg = Qt::black;
-
-				break;
-			case 'Q': // Graphics red
-//				concealed = false;
-				graphicsMode = true;
-				holdColour = fg = Qt::red;
-
-				break;
-			case 'R': // Graphics green
-//				concealed = false;
-				graphicsMode = true;
-				holdColour = fg = Qt::green;
-
-				break;
-			case 'S': // Graphics yellow
-//				concealed = false;
-				graphicsMode = true;
-				holdColour = fg = Qt::yellow;
-
-				break;
-			case 'T': // Graphics blue
-//				concealed = false;
-				graphicsMode = true;
-				holdColour = fg = Qt::blue;
-
-				break;
-			case 'U': // Graphics magenta
-//				concealed = false;
-				graphicsMode = true;
-				holdColour = fg = Qt::magenta;
-
-				break;
-			case 'V': // Graphics cyan
-//				concealed = false;
-				graphicsMode = true;
-				holdColour = fg = Qt::cyan;
-
-				break;
-			case 'W': // Graphics white
-//				concealed = false;
-				graphicsMode = true;
-				holdColour = fg = Qt::white;
-
-				break;
-
-			case 'X': // Conceal display
-				
-				concealed = 1;
-				break;
-
-			case 'Y': // Contiguous graphics
-
-				separated = false;
-				break;
-
-			case 'Z': // Separated gfx
-
-				separated = true;
-				break;
-
-			case 0x5c: // Background black
-				bg = Qt::black;
-				break;
-
-			case 0x5d: // New background
-
-				bg = fg;
-				break;
-
-			case 0x5e: // Hold gfx
-
-				if (hold == 0)
-				{
-					hold = true;
-					holdColour = fg;
-					holdMode = separated;
-				}
-				break;
-
-			case 0x5f: // Non-hold gfx
-				hold = false;
-				break;
-
-			default:
-				echar++;					// For testign
-				break;
-
-			}  //end of esc case processing
-
-			if (usehold)
-			{
-				// We set sep and color for held char earlier 
-			
-				ch = holdChar;			// Repeat held char
-			}
-			else
-				ch = 0x0;				// Default is space
-
-
-			if (line > skipnextrow)
-				skipnextrow = 99;
-
-			if (line == skipnextrow)
-			{
-				line = line;
-			}
-			else
-			{
-				if (concealed == 0 && (flashing == 0 || Sess->TTFlashToggle == 0))
-				{
-					p.fillRect(col * 15, line * 19, 15, 19, bg);
-
-					// if double height also draw background for next row
-
-					if (doubleHeight)
-						p.fillRect(col * 15, line * 19 + 19, 15, 19, bg);
-
-
-					if (sep)
-					{
-						if (ch & 1)
-							p.fillRect(col * 15 + 2, line * 19 + 2, 5, 4, holdfg);
-						if (ch & 2)
-							p.fillRect(col * 15 + 9, line * 19 + 2, 6, 4, holdfg);
-						if (ch & 4)
-							p.fillRect(col * 15 + 2, line * 19 + 8, 5, 4, holdfg);
-						if (ch & 8)
-							p.fillRect(col * 15 + 9, line * 19 + 8, 6, 4, holdfg);
-						if (ch & 16)
-							p.fillRect(col * 15 + 2, line * 19 + 14, 5, 5, holdfg);
-						if (ch & 32)
-							p.fillRect(col * 15 + 9, line * 19 + 14, 6, 5, holdfg);
-
-					}
-					else
-					{
-						if (ch & 1)
-							p.fillRect(col * 15, line * 19, 7, 6, holdfg);
-						if (ch & 2)
-							p.fillRect(col * 15 + 7, line * 19, 8, 6, holdfg);
-						if (ch & 4)
-							p.fillRect(col * 15, line * 19 + 6, 7, 6, holdfg);
-						if (ch & 8)
-							p.fillRect(col * 15 + 7, line * 19 + 6, 8, 6, holdfg);
-						if (ch & 16)
-							p.fillRect(col * 15, line * 19 + 12, 7, 7, holdfg);
-						if (ch & 32)
-							p.fillRect(col * 15 + 7, line * 19 + 12, 8, 7, holdfg);
-					}
-				}
-			}
-			col++;
-		}
-		else
-		{
-			// Not esc - so normal or graphics
-
-			if (ch < 0x20)
-				continue;
-
-			if (line > skipnextrow)
-				skipnextrow = 99;
-
-			if (line == skipnextrow)
-			{
-				line = line;
-			}
-			else
-			{
-				if (concealed == 0 && (flashing == 0 || Sess->TTFlashToggle == 0))
-				{
-					p.fillRect(col * 15, line * 19, 15, 19, bg);
-
-					if (doubleHeight)
-						p.fillRect(col * 15, line * 19 + 19, 15, 19, bg);
-
-					p.setPen(QPen(fg));;
-
-					if (graphicsMode)
-					{
-						if (ch < 0x40)
-							ch -= 0x20;
-						else
-							if (ch >= 0x60)
-								ch -= 0x40;
-							else
-								goto isText;
-
-						holdChar = ch;
-
-						// Now have 00 - 3f 
-
-
-						// C is bit mask bit posns are
-						// 01
-						// 23
-						// 45
-						// Char cell is 15 * 19 which is a bit asymetrical
-
-						// Chars are 20 - 3f and 60 to 7f but I cant see a logic to the mapping
-
-
-						if (separated)
-						{
-							if (ch & 1)
-								p.fillRect(col * 15 + 2, line * 19 + 2, 5, 4, fg);
-							if (ch & 2)
-								p.fillRect(col * 15 + 9, line * 19 + 2, 6, 4, fg);
-							if (ch & 4)
-								p.fillRect(col * 15 + 2, line * 19 + 8, 5, 4, fg);
-							if (ch & 8)
-								p.fillRect(col * 15 + 9, line * 19 + 8, 6, 4, fg);
-							if (ch & 16)
-								p.fillRect(col * 15 + 2, line * 19 + 14, 5, 5, fg);
-							if (ch & 32)
-								p.fillRect(col * 15 + 9, line * 19 + 14, 6, 5, fg);
-
-						}
-						else
-						{
-							if (ch & 1)
-								p.fillRect(col * 15, line * 19, 7, 6, fg);
-							if (ch & 2)
-								p.fillRect(col * 15 + 7, line * 19, 8, 6, fg);
-							if (ch & 4)
-								p.fillRect(col * 15, line * 19 + 6, 7, 6, fg);
-							if (ch & 8)
-								p.fillRect(col * 15 + 7, line * 19 + 6, 8, 6, fg);
-							if (ch & 16)
-								p.fillRect(col * 15, line * 19 + 12, 7, 7, fg);
-							if (ch & 32)
-								p.fillRect(col * 15 + 7, line * 19 + 12, 8, 7, fg);
-						}
-					}
-					else
-					{
-						// Just write char at current col and line
-
-					isText:
-						char s[5];
-						unsigned char su[5] = "";
-
-						// Some chars are in wrong char set
-
-						su[0] = ch;
-
-						if (ch == '_')
-							su[0] = '#';
-
-						else if (ch == 0x7e)					// division
-						{
-							su[0] = 0xC3;
-							su[1] = 0xB7;
-						}
-						else if (ch == 0x5e)			// up arrow
-						{
-							su[0] = 0xF0;
-							su[1] = 0x9F;
-							su[2] = 0xA0;
-							su[3] = 0x95;
-						}
-						else if (ch == 0x7f)			// up arrow
-						{
-							su[0] = 0xE2;
-							su[1] = 0x96;
-							su[2] = 0x88;
-						}
-
-						memcpy(s, su, 5);
-
-//						if (doubleHeight)
-	//							p.drawText(col * 15, line * 19 + 25, s);
-		//					else
-			//					p.drawText(col * 15, line * 19 + 15, s);
-
-						// if double height draw normally then copy pixels each row of pixels to two scanlines (starting at the bottom)
-
-						if (doubleHeight)
-						{
-							int inscanline = line * 19 + 18;
-							int outscanline = line * 19 + 35;
-							unsigned char * inptr = Sess->TTBitmap->scanLine(inscanline);
-							unsigned char * outptr = Sess->TTBitmap->scanLine(outscanline);
-							int linelen = Sess->TTBitmap->bytesPerLine();
-							int charlen = linelen / 40;			// bytes per char position
-
-							p.drawText(col * 15, line * 19 + 16, s);
-
-							inptr += col * charlen;
-							outptr += col * charlen;
-
-							for (int i = 0; i < 18; i++)
-							{
-								memcpy(outptr, inptr, charlen);
-								outptr -= linelen;
-								memcpy(outptr, inptr, charlen);
-
-								inptr -= linelen;
-								outptr -= linelen;
-
-							}
-						}
-						else
-							p.drawText(col * 15, line * 19 + 15, s);
-
-					}
-				}
-			}
-			col++;
-		}
-
-		if (col > 39)
-		{
-			col = 0;
-			line++;
-			if (line > 24)
-				line = 0;
-
-			graphicsMode = false;
-			separated = false;
-			doubleHeight = false;
-			flashing = false;
-			hold = false;
-			holdChar = 0;
-			concealed = false;
-
-			fg = Qt::white;
-			bg = Qt::black;
-		}
-	}
-	Sess->TTLabel->setPixmap(QPixmap::fromImage(*Sess->TTBitmap));
-	return;
-
-	QFile file("D:/savepage.txt");
-	file.open(QIODevice::WriteOnly);
-	file.write(Sess->pageBuffer);
-	file.close();
-}
-
-
-void Ui_ListenSession::timerEvent(QTimerEvent *event)
-{
-	Ui_ListenSession * Sess = NULL;
-
-	// Used for flashing - resfresh window
-
-	for (int i = 0; i < _sessions.size(); ++i)
-	{
-		Sess = _sessions.at(i);
-
-		if (Sess->timer.timerId() == event->timerId())
-		{
-			if (Sess->TTActive)
-			{
-				Sess->TTFlashToggle ^= 1;
-
-				// if in Tabbed mode only refresh active tab
-
-				if (TermMode == Tabbed && Sess != ActiveSession)
-					return;
-
-				DecodeTeleText(Sess, (char *)Sess->pageBuffer);			// Re-decode same data until we get the end
-			}
-			else
-				Sess->timer.stop();
-
-			return;
-		}
-	}
-	QWidget::timerEvent(event);
-}
-
-// Monitor Log FIle routines
-
-char * doXMLTransparency(char * string)
-{
-	// Make sure string doesn't contain forbidden XML chars (<>"'&)
-
-	char * newstring = (char *)malloc(5 * strlen(string) + 1);		// If len is zero still need null terminator
-
-	char * in = string;
-	char * out = newstring;
-	char c;
-
-	c = *(in++);
-
-	while (c)
-	{
-		switch (c)
-		{
-		case '<':
-
-			strcpy(out, "&lt;");
-			out += 4;
-			break;
-
-		case '>':
-
-			strcpy(out, "&gt;");
-			out += 4;
-			break;
-
-		case '"':
-
-			strcpy(out, "&quot;");
-			out += 6;
-			break;
-
-		case '\'':
-
-			strcpy(out, "&apos;");
-			out += 6;
-			break;
-
-		case '&':
-
-			strcpy(out, "&amp;");
-			out += 5;
-			break;
-
-		default:
-
-			*(out++) = c;
-		}
-		c = *(in++);
-	}
-
-	*(out++) = 0;
-	return newstring;
-}
-
-void WriteMonitorLog(Ui_ListenSession * Sess, char * Msg)
-{
-	// Write as HTML to preserve formatting
-
-	char Line[512];
-	char * HTMLText;
-
-	if (Sess->monLogfile == nullptr)
-	{
-		QString FN = "QTTermMonLog" + timeLoaded + "_" + QString::number(Sess->sessNo) + ".html";
-		Sess->monLogfile = new QFile(FN);
-
-		if (Sess->monLogfile)
-			Sess->monLogfile->open(QIODevice::Append);
-		else
-			return;
-	}
-
-	if (Msg[0] == 0x1b)
-	{
-		// Colour Escape
-
-		if (Msg[1] == 17)
-			Sess->monSpan = (char *)"<span style=\"color:blue; white-space:pre;font-family: monospace\">";// , monRxColour.data());
-		else
-			Sess->monSpan = (char *)"<span style=\"color:red; white-space:pre;font-family: monospace\">";// , monTxColour.data());
-
-		HTMLText = doXMLTransparency(&Msg[2]);
-	}
-	else
-	{
-		// Leave colour at last set value
-
-		HTMLText = doXMLTransparency(Msg);
-	}
-
-	sprintf(Line, "%s%s</span><br>\r\n", Sess->monSpan, HTMLText);
-	
-	Sess->monLogfile->write(Line);
-
-	free(HTMLText);
-
-}
-
-// Create MH Window
-
-
-
-int newMHWindow(QObject * parent, int Type, const char * Label)
-{
-	Ui_ListenSession * Sess = new(Ui_ListenSession);
-
-	MHWindow = Sess;
-
-	// Need to explicity initialise on Qt4
-
-	Sess->termWindow = NULL;
-	Sess->monWindow = NULL;
-	Sess->inputWindow = NULL;
-
-	Sess->StackIndex = 0;
-	Sess->InputMode = 0;
-	Sess->SlowTimer = 0;
-	Sess->MonData = 0;
-	Sess->OutputSaveLen = 0;
-	Sess->MonSaveLen = 0;
-	Sess->PortMonString[0] = 0;
-	Sess->portmask = 0;
-	Sess->portmask = 1;
-	Sess->mtxparam = 1;
-	Sess->mlocaltime = 0;
-	Sess->mcomparam = 1;
-	Sess->monUI = 0;
-	Sess->MonitorNODES = 0;
-	Sess->MonitorColour = 1;
-	Sess->CurrentHost = 0;
-
-	Sess->SessionType = Type;
-	Sess->clientSocket = NULL;
-	Sess->AGWSession = NULL;
-	Sess->AGWMonSession = NULL;
-	Sess->KISSSession = NULL;
-	Sess->KISSMode = 0;
-	Sess->TTActive = 0;
-	Sess->TTFlashToggle = 0;
-	Sess->pageBuffer[0] = 0;
-	Sess->Tab = 0;
-
-	Sess->LogMonitor = false;
-	Sess->monSpan = (char *) "<span style=white-space:pre>";
-	Sess->monLogfile = nullptr;
-	Sess->sessNo = sessNo++;
-
-	QSettings settings(GetConfPath(), QSettings::IniFormat);
-
-#ifdef ANDROID
-	QFont font = QFont(settings.value("FontFamily", "Driod Sans Mono").value<QString>(),
-		settings.value("PointSize", 12).toInt(),
-		settings.value("Weight", 50).toInt());
-#else
-	QFont font = QFont(settings.value("FontFamily", "Courier New").value<QString>(),
-		settings.value("PointSize", 10).toInt(),
-		settings.value("Weight", 50).toInt());
-#endif
-
-	Sess->monWindow = new QTextEdit(Sess);
-	Sess->monWindow->setReadOnly(1);
-	Sess->monWindow->document()->setMaximumBlockCount(10000);
-	Sess->monWindow->setFont(font);
-	Sess->monWindow->setStyleSheet(monStyleSheet);
-
-	Sess->setWindowTitle(Label);
-
-	Sess->installEventFilter(mythis);
-
-	Sess->show();
-
-
-
-	Sess->monWindow->setGeometry(QRect(2, 2, 400, 400));
-	Sess->setGeometry(QRect(400, 400, 400, 400));
-
-
-	QSize Size(800, 602);						// Not actually used, but Event constructor needs it
-
-	QResizeEvent event(Size, Size);
-
-	QApplication::sendEvent(Sess, &event);		// Resize Widgets to fix Window
-
-	return true;
-}
-
-extern "C" void WritetoMHWindow(char * Buffer)
-{
-	unsigned char Copy[8192];
-	unsigned char * ptr1, *ptr2;
-	unsigned char Line[8192];
-	unsigned char out[8192];
-	int outlen;
-
-	int num;
-
-	if (MHWindow == NULL || MHWindow->monWindow == NULL)
-		return;
-
-	MHWindow->monWindow->setText(Buffer);
-}
+// Qt Version of BPQTermTCP
+
+// Application icon design by Red PE1RRR
+
+#define VersionString "0.0.0.79"
+
+
+// .12 Save font weight
+// .13 Display incomplete lines (ie without CR)
+// .14 Add YAPP and Listen Mode
+// .15 Reuse windows in Listen Mode 
+// .17 MDI Version 7/1/20
+// .18 Fix input window losing focus when data arrivn other window
+// .19 Fix Scrollback
+// .20 WinXP compatibility changes
+// .21 Save Window Positions
+// .22 Open a window on first start
+// .23 Add Tabbed display option
+// .24 Fix crash when setting Monitor flags in Tabbed mode
+// .25 Add AGW mode
+// .26 Add sending CTRL/C CTRL/D and CTRL/Z)
+// .27 Limit size of windows to 10000 lines 
+//	   Fix YAPP in Tabbed Mode
+// .28 Add AGW Beacon
+// .29 Fix allocating Listem sessions to tabs connected using AGW
+// .30 Fix allocationd AGW Monitor Sessions
+// .31 Fix output being written to the wrong place when window is scrolled back
+// .32 Fix connect with digis
+// .33 Add StripLF option
+// .34 Improvements for Andriod
+//	   Option to change Menu Fonts
+//	   Fix receiving part lines when scrolled back
+// .35 Fix PE if not in Tabbed Mode
+// .36 Improved dialogs mainly for Android
+//	   Try to make sure sessions are closed before exiting
+// .37 Replace VT with LF (for pasting from BPQ32 Terminal Window)
+//	   Dont show AGW status line if AGW interface is disabled
+//	   Don't show Window Menu in Single Mode
+// .38 Protect against connect to normal Telnet Port.
+//	   Send CTEXT and Beep for inward AGW Connects
+//	   Make sending Idle and Connect beeps configurable
+//	   Change displayed Monitor flags when active window changed.
+//	   Fix duplicate text on long lines
+// .39 Add option to Convert non-utf8 charaters
+// .40 Prevent crash if AGW monitor Window closed
+// .41 Allow AGW Config and Connect dialogs to be resized with scrollbars
+//	   Fix disabling connect flag on current session when AGW connects
+// .42 Fix some bugs in AGW session handling
+// .43 Include Ross KD5LPB's fixes for MAC
+// .44 Ctrl/[ sends ESC (0x1b)
+// .45 Add VARA support							Nov 2021
+// .46 Fix dialog size on VARA setup
+// .47 Move VARA Status indicator. 
+//	   Add FLRIG PTT for VARA
+// .48 Check that YAPP Receive Directory has been set
+//	   Save separate configs for VARA, VARAFM and VARASAT
+// .49 Add BBS Monitor							Dec 2021
+// .50 Make Serial port support optional for Android Version
+// .51 Add KISS TNC Support						May 2022
+// .52 Save partially typed lines on cursor up	May 2022
+// .53 Add UI Mode for KISS Sessions			May 2022
+//     Fix saving KISS Paclen (b)
+//	   Fix Keepalive  (c)
+// .54 Add option to change screen colours		June 2022
+// .55 Build without optimisation
+// .56 Add Teletext mode						Nov 2022
+// .57 Fix KISS mode incoming call handling
+// .58 Add method to toggle Normal/Teletext Mode
+//	   Fix KISS multiple session protection
+// .59 Add Teletext double height mode
+// .60 Add option to name sessions				Jan 2023
+// .61 Add VARA Init Script						Feb 2023
+// .62 Fix running AGW in single session mode	Feb 2023
+// .63 Fix handling split monitor frame (no fe in buffer) Apr 2023
+// .64 Add Clear Screen command to context menu Apr 2023
+// .65 Fixes for 63 port version of BPQ			May 2023
+// .66 Colour Tab of incoming calls				June 2023
+// .67 Add config Yapp RX Size dialog			July 2023
+//	   Fix 63 port montoring
+
+// .68	Sept 2023
+
+//	Remember last used host on restart	
+//	Add AutoConnect in Tabbed Mode
+//	Fix auto copy when QtTerm not active window
+
+// .69	October 2023
+
+//	Options related to sound alerts moved to a separte menu in Setup
+//	Allow use of WAV files instead of Beep sound for sound alerts
+//	Enable an alarm to be sounded when one of a list of words or phrases is received.
+
+//	.70 October 2023
+
+//	Include some .wav files in resources
+//	Add Test button to Alert setup dialog
+
+//	.71 October 2023
+
+//	Add option to use local time
+//	Fixes for Mac OS
+
+//	.72 November 2023
+//	Don't display "Enable Monitor" on startup
+
+//	.73 November 2023
+//	Raise RTS on KISS serial port
+
+//	.74 April 2024
+//	Support BPQKISS TNCs with CHECKSUM and/or ACKMODE enabled
+
+//	.75 May 2024
+//	Flush Monitor log file every minute
+
+//	.76	August 2024
+//	Fix using digs in KISS UI mode.
+//	Add option to send TXDELAY to KISS TNC
+
+//	.77
+//	Support multichannel KISS TNCs (Beta 1)
+//	Fix using AGW listen in single terminal mode
+
+//	.78
+//	Fix restoring monitor flags when connecting to current host
+
+
+//	.79
+//	Add KISS MHEARD Window (Feb 2025)
+
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#define UNUSED(x) (void)(x)
+
+#define USESERIAL
+
+#include "QtTermTCP.h"
+#include "TabDialog.h"
+#include <time.h>
+#include <QVBoxLayout>
+#include <QListWidgetItem>
+#include <QToolButton>
+#include <QInputMethod>
+#include "QTreeWidget"
+#include <QToolBar>
+#include <QLabel>
+#include <QActionGroup>
+#include <QtWidgets>
+#include <QColor>
+#include <QClipboard>
+#ifdef USESERIAL
+#include <QtSerialPort/QSerialPort>
+#include <QtSerialPort/QSerialPortInfo>
+#endif
+#ifndef WIN32
+#define strtok_s strtok_r
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+
+#include "ax25.h"
+
+#define UNREFERENCED_PARAMETER(P)          (P)
+
+void DecodeTeleText(Ui_ListenSession * Sess, char * text);
+
+char Host[MAXHOSTS + 1][100] = { "" };
+int Port[MAXHOSTS + 1] = { 0 };
+char UserName[MAXHOSTS + 1][80] = { "" };
+char Password[MAXHOSTS + 1][80] = { "" };
+char MonParams[MAXHOSTS + 1][80] = { "" };
+char SessName[MAXHOSTS + 1][80] = { "" };
+int ListenPort = 8015;
+
+// Session Type Equates
+
+#define Term 1
+#define Mon 2
+#define Listen 4
+
+// Presentation - Single Window, MDI or Tabbed
+
+int TermMode = 0;
+
+#define Single 0
+#define MDI 1
+#define Tabbed 2
+
+int singlemodeFormat = Mon + Term;
+
+char monStyleSheet[128] = "background-color: rgb(0,255,255)";
+char termStyleSheet[128] = "background-color: rgb(255,0,255);";
+char inputStyleSheet[128] = "color: rgb(255, 0, 0); background-color: rgb(255,255,0);";
+
+QColor monBackground = qRgb(0, 255, 255);
+QColor monRxText = qRgb(0, 0, 255);
+QColor monTxText = qRgb(255, 0, 0);
+QColor monOtherText = qRgb(0, 0, 0);
+
+QColor termBackground = qRgb(255, 0, 255);
+QColor outputText = qRgb(0, 0, 0);
+QColor EchoText = qRgb(0, 0, 255);
+QColor WarningText = qRgb(255, 0, 0);
+QColor inputBackground = qRgb(255, 255, 0);
+QColor inputText = qRgb(0, 0, 255);
+
+QColor newTabText = qRgb(255, 0, 0);		// Red
+QColor oldTabText = qRgb(0, 0, 0);			// Black
+
+
+// There is something odd about this. It doesn't match BPQTERMTCP though it looks the same
+
+// Chat uses these (+ 10)
+//{ 0, 4, 9, 11, 13, 16, 17, 42, 45, 50, 61, 64, 66, 72, 81, 84, 85, 86, 87, 89 };
+
+// As we have a white background we need dark colours
+
+// 0 is black. 23 is normal output (blue) 81 is red (used by AGW Mon)
+// for monitor in colour, host sends 17 for RX Text, 81 for TX Text but code converts to monRx/TxText qrgb values
+
+QRgb Colours[256] = { 0,
+		qRgb(0,0,0), qRgb(0,0,128), qRgb(0,0,192), qRgb(0,0,255),				// 1 - 4
+		qRgb(0,64,0), qRgb(0,64,128), qRgb(0,64,192), qRgb(0,64,255),			// 5 - 8
+		qRgb(0,128,0), qRgb(0,128,128), qRgb(0,128,192), qRgb(0,128,255),		// 9 - 12
+		qRgb(0,192,0), qRgb(0,192,128), qRgb(0,192,192), qRgb(0,192,255),		// 13 - 16
+		qRgb(0,255,0), qRgb(0,255,128), qRgb(0,255,192), qRgb(0,255,255),		// 17 - 20
+
+		qRgb(64,0,0), qRgb(64,0,128), qRgb(64,0,192), qRgb(0,0,255),				// 21 
+		qRgb(64,64,0), qRgb(64,64,128), qRgb(64,64,192), qRgb(64,64,255),
+		qRgb(64,128,0), qRgb(64,128,128), qRgb(64,128,192), qRgb(64,128,255),
+		qRgb(64,192,0), qRgb(64,192,128), qRgb(64,192,192), qRgb(64,192,255),
+		qRgb(64,255,0), qRgb(64,255,128), qRgb(64,255,192), qRgb(64,255,255),
+
+		qRgb(128,0,0), qRgb(128,0,128), qRgb(128,0,192), qRgb(128,0,255),				// 41
+		qRgb(128,64,0), qRgb(128,64,128), qRgb(128,64,192), qRgb(128,64,255),
+		qRgb(128,128,0), qRgb(128,128,128), qRgb(128,128,192), qRgb(128,128,255),
+		qRgb(128,192,0), qRgb(128,192,128), qRgb(128,192,192), qRgb(128,192,255),
+		qRgb(128,255,0), qRgb(128,255,128), qRgb(128,255,192), qRgb(128,255,255),
+
+		qRgb(192,0,0), qRgb(192,0,128), qRgb(192,0,192), qRgb(192,0,255),				// 61 - 80
+		qRgb(192,64,0), qRgb(192,64,128), qRgb(192,64,192), qRgb(192,64,255),
+		qRgb(192,128,0), qRgb(192,128,128), qRgb(192,128,192), qRgb(192,128,255),
+		qRgb(192,192,0), qRgb(192,192,128), qRgb(192,192,192), qRgb(192,192,255),
+		qRgb(192,255,0), qRgb(192,255,128), qRgb(192,255,192), qRgb(192,255,255),
+
+		qRgb(255,0,0), qRgb(255,0,128), qRgb(255,0,192), qRgb(255,0,255),				// 81 - 100
+		qRgb(255,64,0), qRgb(255,64,128), qRgb(255,64,192), qRgb(255,64,255),
+		qRgb(255,128,0), qRgb(255,128,128), qRgb(255,128,192), qRgb(255,128,255),
+		qRgb(255,192,0), qRgb(255,192,128), qRgb(255,192,192), qRgb(255,192,255),
+		qRgb(255,255,0), qRgb(255,255,128), qRgb(255,255,192), qRgb(255,255,255)
+};
+
+
+
+int SavedHost = 0;				// from config
+
+char * sessionList = NULL;		// Saved sessions
+
+extern int ChatMode;
+extern int Bells;
+extern int StripLF;
+extern int convUTF8;
+
+extern time_t LastWrite;
+extern int AlertInterval;
+extern int AlertBeep;
+extern int AlertFreq;
+extern int AlertDuration;
+extern int ConnectBeep;
+
+bool useBeep;			// use wav files if not set
+
+extern int UseKeywords;
+extern QString KeyWordsFile;
+
+QString ConnectWAV("");
+QString AlertWAV("");
+QString BellWAV("");
+QString IntervalWAV("");
+
+extern int MaxRXSize;
+
+extern int AutoTeletext;
+
+// AGW Host Interface stuff
+
+int AGWEnable = 0;
+int AGWMonEnable = 0;
+int AGWLocalTime = 0;
+int AGWMonNodes = 0;
+char AGWTermCall[12] = "";
+char AGWBeaconDest[12] = "";
+char AGWBeaconPath[80] = "";
+int AGWBeaconInterval = 0;
+char AGWBeaconPorts[80];
+char AGWBeaconMsg[260] = "";
+
+
+char AGWHost[128] = "127.0.0.1";
+int AGWPortNum = 8000;
+int AGWPaclen = 80;
+extern char * AGWPortList;
+extern myTcpSocket * AGWSock;
+
+typedef struct AGWUser_t
+{
+	QTcpSocket *socket;
+	unsigned char data_in[8192];
+	int data_in_len;
+	unsigned char  AGW_frame_buf[512];
+	int	Monitor;
+	int	Monitor_raw;
+	Ui_ListenSession * MonSess;			// Window for Monitor info
+
+} AGWUser;
+
+extern AGWUser *AGWUsers;				// List of currently connected clients
+void Send_AGW_m_Frame(QTcpSocket* socket);
+
+
+QStringList AGWToCalls;
+
+// KISS Interface
+
+int KISSEnable = 0;
+extern "C" int KISSMonEnable;
+extern "C" int KISSLocalTime;
+extern "C" int KISSMonNodes;
+extern "C" int KISSListen;
+extern "C" int KISSChecksum;
+extern "C" int KISSAckMode;
+extern "C" int KISSMH;
+
+extern "C" short txtail[5];
+extern "C" short txdelay[5];
+extern "C" int sendTXDelay[4];
+
+
+
+char SerialPort[80] = "";
+char KISSHost[128] = "127.0.0.1";
+int KISSPortNum = 1000;
+int KISSBAUD = 19200;
+char KISSMYCALL[32];
+char KISSVia[128];				// Digi String
+
+extern "C" UCHAR axMYCALL[7];			// Mycall in ax.25
+
+int KISSMode = 0;			// Connected (0) or UI (1)
+
+myTcpSocket * KISSSock;
+
+extern "C" void * KISSSockCopy[4];
+
+int KISSConnected = 0;
+int KISSConnecting = 0;
+
+Ui_ListenSession * KISSMonSess = nullptr;
+
+QSerialPort * m_serial = nullptr;
+
+// VARA Interface
+
+int VARAEnable = 0;
+char VARAHost[128] = "127.0.0.1";
+char VARAHostHF[128] = "127.0.0.1";
+char VARAHostFM[128] = "127.0.0.1";
+char VARAHostSAT[128] = "127.0.0.1";
+int VARAPortNum = 8000;
+int VARAPortHF = 8000;
+int VARAPortFM = 8000;
+int VARAPortSAT = 8000;
+char VARATermCall[12] = "";
+char VARAPath[256] = "";
+char VARAInit[256] = "";
+char VARAPathHF[256] = "";
+char VARAPathFM[256] = "";
+char VARAPathSAT[256] = "";
+
+int VARA500 = 0;
+int VARA2300 = 1;
+int VARA2750 = 0;
+
+int VARAHF = 1;
+int VARAFM = 0;
+int VARASAT = 0;
+
+myTcpSocket * VARASock;
+myTcpSocket * VARADataSock;
+
+int VARAConnected = 0;
+int VARAConnecting = 0;
+
+
+extern char YAPPPath[256];
+
+void menuChecked(QAction * Act);
+
+// PTT Stuff
+
+#define PTTRTS		1
+#define PTTDTR		2
+#define PTTCAT		4
+#define PTTCM108	8
+#define PTTHAMLIB	16
+#define PTTFLRIG	32
+
+#ifdef USESERIAL
+
+QSerialPort * hPTTDevice = 0;
+#else
+
+
+#endif
+char PTTPort[80] = "";			// Port for Hardware PTT - may be same as control port.
+int PTTBAUD = 19200;
+int PTTMode = PTTRTS;			// PTT Control Flags.
+
+char PTTOnString[128] = "";
+char PTTOffString[128] = "";
+
+int CATHex = 1;
+
+unsigned char PTTOnCmd[64];
+int PTTOnCmdLen = 0;
+
+unsigned char  PTTOffCmd[64];
+int PTTOffCmdLen = 0;
+
+int pttGPIOPin = 17;			// Default
+int pttGPIOPinR = 17;
+bool pttGPIOInvert = false;
+bool useGPIO = false;
+bool gotGPIO = false;
+
+int HamLibPort = 4532;
+char HamLibHost[32] = "192.168.1.14";
+
+int FLRigPort = 12345;
+char FLRigHost[32] = "127.0.0.1";
+
+
+char CM108Addr[80] = "";
+
+int VID = 0;
+int PID = 0;
+
+// CM108 Code
+
+char * CM108Device = NULL;
+
+QProcess *process = NULL;
+
+void GetSettings();
+
+// These widgets defined here as they are accessed from outside the framework
+
+QLabel * Status1;
+QLabel * Status2;
+QLabel * Status3;
+QLabel * Status4;
+
+QAction *actHost[19];
+QAction *actSetup[16];
+
+QAction * TabSingle = NULL;
+QAction * TabBoth = NULL;
+QAction * TabMon = NULL;
+
+QMenu *monitorMenu;
+QMenu * YAPPMenu;
+QMenu *connectMenu;
+QMenu *disconnectMenu;
+
+QAction *EnableMonitor;
+QAction *EnableMonLog;
+QAction *MonLocalTime;
+QAction *MonTX;
+QAction *MonSup;
+QAction *MonNodes;
+QAction *MonUI;
+QAction *MonColour;
+QAction *MonPort[65];
+QAction *actChatMode;
+QAction *actAutoTeletext;
+QAction *actBells;
+QAction *actStripLF;
+QAction *actIntervalBeep;
+QAction *actConnectBeep;
+QAction *actAuto;
+QAction *actnoConv;
+QAction *actCP1251;
+QAction *actCP1252;
+QAction *actCP437;
+
+QAction *actFonts;
+QAction *actmenuFont;
+QAction *actColours;
+QAction *actmyFonts;
+QAction *YAPPSend;
+QAction *YAPPSetRX;
+QAction *YAPPSetSize;
+QAction *singleAct;
+QAction *singleAct2;
+QAction *MDIAct;
+QAction *tabbedAct;
+QAction *discAction;
+QFont * menufont;
+QMenu *windowMenu;
+QMenu *setupMenu;
+QAction *ListenAction;
+
+QTabWidget *tabWidget;
+QMdiArea *mdiArea;
+QWidget * mythis;
+QStatusBar * myStatusBar;
+
+QTcpServer * _server;
+
+QMenuBar *mymenuBar;
+QToolBar *toolBar;
+QToolButton * but1;
+QToolButton * but2;
+QToolButton * but3;
+QToolButton * but4;
+QToolButton * but5;
+
+QList<Ui_ListenSession *> _sessions;
+
+// Session Type Equates
+
+#define Term 1
+#define Mon 2
+#define Listen 4
+
+int TabType[10] = { Term, Term + Mon, Term, Term, Term, Term, Mon, Mon, Mon };
+
+int AutoConnect[10] = {0, 0 ,0, 0, 0, 0, 0, 0, 0, 0};
+
+int currentHost[10] = {0, 0 ,0, 0, 0, 0, 0, 0, 0, 0};
+
+int listenPort = 8015;
+extern "C" int listenEnable;
+char listenCText[4096] = "";
+
+int ConfigHost = 0;
+
+int Split = 50;				// Mon/Term size split
+
+int termX;
+
+bool Cascading = false;		// Set to stop size being saved when cascading
+
+QMdiSubWindow * ActiveSubWindow = NULL;
+Ui_ListenSession * ActiveSession = NULL;
+
+Ui_ListenSession * newWindow(QObject * parent, int Type, const char * Label = nullptr);
+void Send_AGW_C_Frame(Ui_ListenSession * Sess, int Port, char * CallFrom, char * CallTo, char * Data, int DataLen);
+void AGW_AX25_data_in(void * AX25Sess, unsigned char * data, int Len);
+void AGWMonWindowClosing(Ui_ListenSession *Sess);
+void AGWWindowClosing(Ui_ListenSession *Sess);
+extern "C" void KISSDataReceived(void * socket, unsigned char * data, int length);
+void closeSerialPort();
+int newMHWindow(QObject * parent, int Type, const char * Label);
+
+extern void initUTF8();
+int checkUTF8(unsigned char * Msg, int Len, unsigned char * out);
+
+QDialog * deviceUI;
+
+#include <QStandardPaths>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+
+
+void EncodeSettingsLine(int n, char * String)
+{
+	sprintf(String, "%s|%d|%s|%s|%s|%s", Host[n], Port[n], UserName[n], Password[n], MonParams[n], SessName[n]);
+	return;
+}
+
+// This is used for placing discAction in the preference menu
+#ifdef __APPLE__
+bool is_mac = true;
+#else
+bool is_mac = false;
+#endif
+
+QString GetConfPath()
+{
+	std::string conf_path = "QtTermTCP.ini";  // Default conf file stored alongside application.
+
+#ifdef __APPLE__
+
+	// Get configuration path for MacOS.
+
+	// This will usually be placed in /Users/USER/Library/Application Support/QtTermTCP
+
+	std::string directory = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).at(0).toStdString();
+
+	conf_path = directory + "/QtTermTCP.ini";
+
+	mkdir(directory.c_str(), 0775);
+
+#endif
+
+	return QString::fromUtf8(conf_path.c_str());
+
+}
+
+
+
+void DecodeSettingsLine(int n, char * String)
+{
+	char * Param = strdup(String);
+	char * Rest;
+	char * Save = Param;			// for Free
+
+	Rest = strlop(Param, '|');
+
+	if (Rest == NULL)
+		return;
+
+	strcpy(Host[n], Param);
+	Param = Rest;
+
+	Rest = strlop(Param, '|');
+	Port[n] = atoi(Param);
+	Param = Rest;
+
+	Rest = strlop(Param, '|');
+	strcpy(UserName[n], Param);
+	Param = Rest;
+
+	Rest = strlop(Param, '|');
+	strcpy(Password[n], Param);
+	Param = Rest;
+
+	Rest = strlop(Param, '|');
+	strcpy(MonParams[n], Param);
+
+	if (Rest)
+		strcpy(SessName[n], Rest);
+
+	free(Save);
+	return;
+}
+
+//#ifdef ANDROID
+//#define inputheight 60
+//#else
+#define inputheight 25
+//#endif
+
+extern "C" void SendtoAX25(void * conn, unsigned char * Msg, int Len);
+
+void DoTermResize(Ui_ListenSession * Sess)
+{
+
+	QRect r = Sess->rect();
+
+	int H, Mid, monHeight, termHeight, Width, Border = 3;
+
+	Width = r.width();
+	H = r.height();
+
+	if (TermMode == Tabbed)
+	{
+		//					H -= 20;
+		Width -= 7;
+	}
+	else if (TermMode == Single)
+	{
+		Width -= 7;
+		//					H += 20;
+	}
+
+	if (Sess->SessionType == Listen || Sess->SessionType == Term)
+	{
+		// Term and Input
+
+		// Calc Positions of window
+
+		termHeight = H - (inputheight + 3 * Border);
+
+		Sess->termWindow->setGeometry(QRect(Border, Border, Width, termHeight));
+
+		if (Sess->TTActive)
+		{
+			Sess->TTLabel->setGeometry(QRect(Border, Border, 600, 475));
+//			Sess->termWindow->setVisible(false);
+			Sess->TTLabel->setVisible(true);
+		}
+		else
+		{
+//			Sess->termWindow->setVisible(true);
+			Sess->TTLabel->setVisible(false);
+		}
+
+		Sess->inputWindow->setGeometry(QRect(Border, H - (inputheight + Border), Width, inputheight));
+	}
+	else if (Sess->SessionType == (Term | Mon))
+	{
+		// All 3
+
+		// Calc Positions of window
+
+		Mid = (H * Split) / 100;
+
+		monHeight = Mid - Border;
+		termX = Mid;
+		termHeight = H - Mid - (inputheight + 3 * Border);
+
+		Sess->monWindow->setGeometry(QRect(Border, Border, Width, monHeight));
+		Sess->termWindow->setGeometry(QRect(Border, Mid + Border, Width, termHeight));
+
+		if (Sess->TTActive)
+		{
+			Sess->TTLabel->setGeometry(QRect(3, Mid + Border, 600, 475));
+//			Sess->termWindow->setVisible(false);
+			Sess->TTLabel->setVisible(true);
+		}
+		else
+		{
+//			Sess->termWindow->setVisible(true);
+			Sess->TTLabel->setVisible(false);
+		}
+
+		Sess->inputWindow->setGeometry(QRect(Border, H - (inputheight + Border), Width, inputheight));
+
+	}
+	else
+	{
+		// Should just be Mon only
+
+		Sess->monWindow->setGeometry(QRect(Border, Border, Width, H - 2 * Border));
+	}
+}
+
+
+extern "C" Ui_ListenSession * MHWindow;
+
+bool QtTermTCP::eventFilter(QObject* obj, QEvent *event)
+{
+	// See if from a Listening Session
+
+	Ui_ListenSession * Sess;
+
+	if (obj == MHWindow)
+	{
+		if (event->type() == QEvent::Resize)
+		{
+			QRect r = MHWindow->rect();
+
+			int H, Width, Border = 3;
+
+			Width = r.width() - 6;
+			H = r.height() - 6;
+
+			MHWindow->monWindow->setGeometry(QRect(Border, Border, Width, H));
+			return true;
+		}
+		if (event->type() == QEvent::Close)
+		{
+			QSettings mysettings(GetConfPath(), QSettings::IniFormat);
+			mysettings.setValue("MHgeometry", MHWindow->saveGeometry());
+			SaveSettings();
+			MHWindow = 0;
+		}
+	}
+
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		//	Sess = _sessions.at(i);	for (Ui_ListenSession * Sess : _sessions)
+		//	{
+		if (Sess == NULL)
+			continue;
+
+		if (Sess == obj)
+		{
+			if (event->type() == QEvent::Close)
+			{
+				// Window closing
+
+				// This only closed mon sessinos
+
+				if (Sess->AGWMonSession)
+					//					AGWMonWindowClosing(Sess);
+					AGWWindowClosing(Sess);
+
+				if (Sess->AGWSession)
+					AGWWindowClosing(Sess);
+
+				if (Sess->clientSocket)
+				{
+					int loops = 100;
+					Sess->clientSocket->disconnectFromHost();
+					while (Sess->clientSocket && loops-- && Sess->clientSocket->state() != QAbstractSocket::UnconnectedState)
+						QThread::msleep(10);
+				}
+				_sessions.removeOne(Sess);
+				return QMainWindow::eventFilter(obj, event);
+			}
+
+			if (event->type() == QEvent::Resize)
+			{
+				DoTermResize(Sess);
+			}
+		}
+
+		if (Sess->inputWindow == obj)
+		{
+			if (event->type() == QEvent::KeyPress)
+			{
+				QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
+
+				int key = keyEvent->key();
+				Qt::KeyboardModifiers modifier = keyEvent->modifiers();
+
+				if (modifier == Qt::ControlModifier)
+				{
+					char Msg[] = "\0\r";
+
+					if (key == Qt::Key_BracketLeft)
+						Msg[0] = 0x1b;
+					if (key == Qt::Key_Z)
+						Msg[0] = 0x1a;
+					else if (key == Qt::Key_C)
+						Msg[0] = 3;
+					else if (key == Qt::Key_D)
+						Msg[0] = 4;
+
+					if (Msg[0])
+					{
+						if (Sess->KISSSession)
+						{
+							// Send to ax.25 code
+
+							SendtoAX25(Sess->KISSSession, (unsigned char *)Msg, (int)strlen(Msg));
+						}
+						else if (Sess->AGWSession)
+						{
+							// Terminal is in AGWPE mode - send as AGW frame
+
+							AGW_AX25_data_in(Sess->AGWSession, (unsigned char *)Msg, (int)strlen(Msg));
+
+						}
+						else if (Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState)
+						{
+							Sess->clientSocket->write(Msg);
+						}
+
+						return true;
+					}
+				}
+
+				if (key == Qt::Key_Up)
+				{
+					// Scroll up
+
+					if (Sess->KbdStack[Sess->StackIndex] == NULL)
+						return true;
+
+					// If anything typed, stack part command
+
+					QByteArray stringData = Sess->inputWindow->text().toUtf8();
+
+					if (stringData.length() && Sess->StackIndex == 0)
+					{
+						if (Sess->KbdStack[49])
+							free(Sess->KbdStack[49]);
+
+						for (int i = 48; i >= 0; i--)
+						{
+							Sess->KbdStack[i + 1] = Sess->KbdStack[i];
+						}
+
+						Sess->KbdStack[0] = qstrdup(stringData.data());
+						Sess->StackIndex++;
+					}
+
+					Sess->inputWindow->setText(Sess->KbdStack[Sess->StackIndex]);
+					Sess->inputWindow->cursorForward(strlen(Sess->KbdStack[Sess->StackIndex]));
+
+					Sess->StackIndex++;
+					if (Sess->StackIndex == 50)
+						Sess->StackIndex = 49;
+
+					return true;
+				}
+				else if (key == Qt::Key_Down)
+				{
+					// Scroll down
+
+					if (Sess->StackIndex == 0)
+					{
+						Sess->inputWindow->setText("");
+						return true;
+					}
+
+					Sess->StackIndex--;
+
+					if (Sess->StackIndex && Sess->KbdStack[Sess->StackIndex - 1])
+					{
+						Sess->inputWindow->setText(Sess->KbdStack[Sess->StackIndex - 1]);
+						Sess->inputWindow->cursorForward(strlen(Sess->KbdStack[Sess->StackIndex - 1]));
+					}
+					else
+						Sess->inputWindow->setText("");
+
+					return true;
+				}
+				else if (key == Qt::Key_Return || key == Qt::Key_Enter)
+				{
+					LreturnPressed(Sess);
+					return true;
+				}
+
+				return false;
+			}
+
+			if (event->type() == QEvent::MouseButtonPress)
+			{
+				QMouseEvent *k = static_cast<QMouseEvent *> (event);
+
+				// Paste on Right Click
+
+				if (k->button() == Qt::RightButton)
+				{
+					// Get clipboard data and process a line at a time
+
+					QClipboard *clipboard = QGuiApplication::clipboard();
+					QString Text = clipboard->text();
+					QByteArray ba = Text.toLocal8Bit();
+					char * Msg = ba.data();
+
+
+					Sess->inputWindow->paste();
+					return true;
+				}
+				return QMainWindow::eventFilter(obj, event);
+			}
+		}
+	}
+	return QMainWindow::eventFilter(obj, event);
+}
+
+QAction * setupMenuLine(QMenu * Menu, char * Label, QObject * parent, int State)
+{
+	QAction * Act = new QAction(Label, parent);
+	if (Menu)
+		Menu->addAction(Act);
+
+	Act->setCheckable(true);
+	if (State)
+		Act->setChecked(true);
+
+	parent->connect(Act, SIGNAL(triggered()), parent, SLOT(menuChecked()));
+
+	Act->setFont(*menufont);
+
+	return Act;
+}
+
+// This now creates all window types - Term, Mon, Combined, Listen
+
+int xCount = 0;
+int sessNo = 0;
+
+Ui_ListenSession * newWindow(QObject * parent, int Type, const char * Label)
+{
+	Ui_ListenSession * Sess = new(Ui_ListenSession);
+
+	// Need to explicity initialise on Qt4
+
+	Sess->termWindow = NULL;
+	Sess->monWindow = NULL;
+	Sess->inputWindow = NULL;
+
+	for (int i = 0; i < 50; i++)
+		Sess->KbdStack[i] = NULL;
+
+	Sess->StackIndex = 0;
+	Sess->InputMode = 0;
+	Sess->SlowTimer = 0;
+	Sess->MonData = 0;
+	Sess->OutputSaveLen = 0;
+	Sess->MonSaveLen = 0;
+	Sess->PortMonString[0] = 0;
+	Sess->portmask = 0;
+	Sess->portmask = 1;
+	Sess->mtxparam = 1;
+	Sess->mlocaltime = 0;
+	Sess->mcomparam = 1;
+	Sess->monUI = 0;
+	Sess->MonitorNODES = 0;
+	Sess->MonitorColour = 1;
+	Sess->CurrentHost = 0;
+
+	Sess->SessionType = Type;
+	Sess->clientSocket = NULL;
+	Sess->AGWSession = NULL;
+	Sess->AGWMonSession = NULL;
+	Sess->KISSSession = NULL;
+	Sess->KISSMode = 0;
+	Sess->TTActive = 0;
+	Sess->TTFlashToggle = 0;
+	Sess->pageBuffer[0] = 0;
+	Sess->Tab = 0;
+
+	Sess->LogMonitor = false;
+	Sess->monSpan = (char *) "<span style=white-space:pre>";
+	Sess->monLogfile = nullptr;
+	Sess->sessNo = sessNo++;
+
+	_sessions.append(Sess);
+
+//	Sess->TT = new Ui_TeleTextDialog();
+
+//	Sess->TT->setupUi(&Sess->TTUI);
+
+//	Sess->TTUI.show();
+//	Sess->TTUI.raise();
+//	Sess->TTUI.activateWindow();
+
+	//	Sess->setObjectName(QString::fromUtf8("Sess"));
+
+	if (TermMode == MDI)
+	{
+		Sess->sw = mdiArea->addSubWindow(Sess);
+		//		Sess->installEventFilter(parent);
+
+		Sess->sw->resize(800, 600);
+	}
+	else if (TermMode == Tabbed)
+	{
+		Sess->Tab = xCount++;
+
+		if (Type == Mon)
+			tabWidget->addTab(Sess, "Monitor");
+		else
+			tabWidget->addTab(Sess, Label);
+	}
+
+	Sess->installEventFilter(parent);
+
+	QSettings settings(GetConfPath(), QSettings::IniFormat);
+
+#ifdef ANDROID
+    QFont font = QFont(settings.value("FontFamily", "Driod Sans Mono").value<QString>(),
+        settings.value("PointSize", 12).toInt(),
+        settings.value("Weight", 50).toInt());
+#else
+	QFont font = QFont(settings.value("FontFamily", "Courier New").value<QString>(),
+		settings.value("PointSize", 10).toInt(),
+		settings.value("Weight", 50).toInt());
+#endif
+
+	if ((Type & Mon))
+	{
+		Sess->monWindow = new QTextEdit(Sess);
+		Sess->monWindow->setReadOnly(1);
+		Sess->monWindow->document()->setMaximumBlockCount(10000);
+		Sess->monWindow->setFont(font);
+		Sess->monWindow->setStyleSheet(monStyleSheet);
+		mythis->connect(Sess->monWindow, SIGNAL(selectionChanged()), parent, SLOT(onTEselectionChanged()));
+	}
+
+	if ((Type & (Listen | Term)))
+	{
+		Sess->termWindow = new QTextEdit(Sess);
+		Sess->termWindow->setReadOnly(1);
+		Sess->termWindow->document()->setMaximumBlockCount(10000);
+		Sess->termWindow->setFont(font);
+		Sess->termWindow->setStyleSheet(termStyleSheet);
+
+		Sess->TTLabel = new QLabel(Sess);
+		Sess->TTLabel->setGeometry(QRect(0,0 ,500, 500));
+		Sess->TTLabel->setVisible(false);
+
+		Sess->TTBitmap = new QImage(40 * 15, 25 * 19, QImage::Format_RGB32);
+		Sess->TTBitmap->fill(Qt::black);
+
+/*
+
+		char Page[4096];
+
+		QFile file("/savepage.txt");
+		file.open(QIODevice::ReadOnly);
+		file.read(Page, 4096);
+		file.close();
+
+		Sess->TTActive = 1;
+		strcpy(Sess->pageBuffer, Page);
+		DecodeTeleText(Sess, Sess->pageBuffer);
+
+*/
+
+		Sess->TTLabel->setPixmap(QPixmap::fromImage(*Sess->TTBitmap));
+
+		Sess->TTLabel->setContextMenuPolicy(Qt::CustomContextMenu);
+		mythis->connect(Sess->TTLabel, SIGNAL(customContextMenuRequested(const QPoint&)),
+			parent, SLOT(showContextMenuL()));
+
+		mythis->connect(Sess->termWindow, SIGNAL(selectionChanged()), parent, SLOT(onTEselectionChanged()));
+
+		Sess->inputWindow = new QLineEdit(Sess);
+		Sess->inputWindow->installEventFilter(parent);
+		Sess->inputWindow->setFont(font);
+		Sess->inputWindow->setStyleSheet(inputStyleSheet);
+		Sess->inputWindow->setContextMenuPolicy(Qt::PreventContextMenu);
+
+		mythis->connect(Sess->inputWindow, SIGNAL(selectionChanged()), parent, SLOT(onLEselectionChanged()));
+	}
+
+	if (Type == Term || Type == Listen)
+	{
+		// Term Only or Listen Only
+
+		Sess->termWindow->setContextMenuPolicy(Qt::CustomContextMenu);
+
+		mythis->connect(Sess->termWindow, SIGNAL(customContextMenuRequested(const QPoint&)),
+			parent, SLOT(showContextMenuT(const QPoint &)));
+
+	}
+
+	if (Type == Mon)
+	{
+		// Monitor Only
+
+		Sess->monWindow->setContextMenuPolicy(Qt::CustomContextMenu);
+
+		mythis->connect(Sess->monWindow, SIGNAL(customContextMenuRequested(const QPoint&)),
+			parent, SLOT(showContextMenuMOnly(const QPoint &)));
+
+	}
+
+	if (Type == (Term | Mon))
+	{
+		// Combined Term and Mon. Add Custom Menu to set Mon/Term Split with Right Click
+
+		Sess->monWindow->setContextMenuPolicy(Qt::CustomContextMenu);
+		Sess->termWindow->setContextMenuPolicy(Qt::CustomContextMenu);
+
+
+		mythis->connect(Sess->monWindow, SIGNAL(customContextMenuRequested(const QPoint&)),
+			parent, SLOT(showContextMenuM(const QPoint &)));
+
+		mythis->connect(Sess->termWindow, SIGNAL(customContextMenuRequested(const QPoint&)),
+			parent, SLOT(showContextMenuMT(const QPoint &)));
+	}
+
+	if (Sess->SessionType == Mon)			// Mon Only
+		Sess->setWindowTitle("Monitor Session Disconnected");
+	else if (Sess->SessionType == Listen)			// Mon Only
+		Sess->setWindowTitle("Listen Window Disconnected");
+	else
+		Sess->setWindowTitle("Disconnected");
+
+	Sess->installEventFilter(mythis);
+
+	Sess->show();
+
+	int pos = (_sessions.size() - 1) * 20;
+
+	if (TermMode == MDI)
+	{
+		Sess->sw->move(pos, pos);
+	}
+
+	QSize Size(800, 602);						// Not actually used, but Event constructor needs it
+
+	QResizeEvent event(Size, Size);
+
+	QApplication::sendEvent(Sess, &event);		// Resize Widgets to fix Window
+
+	return Sess;
+}
+
+QByteArray timeLoaded = QDateTime::currentDateTime().toString("yymmdd_hhmmss").toUtf8();
+
+QtTermTCP::QtTermTCP(QWidget *parent) : QMainWindow(parent)
+{
+	int i;
+	char Title[80];
+
+	// Get configuration path for MacOS.
+	std::string directory = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).at(0).toStdString();
+	std::string conf_path = directory + "/QtTermTCP.ini";
+
+	//mkdir(directory.c_str(), 0775);
+
+	_server = new QTcpServer();
+
+	mythis = this;
+
+	ui.setupUi(this);
+
+	initUTF8();
+
+	mymenuBar = new QMenuBar(this);
+	mymenuBar->setGeometry(QRect(0, 0, 781, 26));
+	setMenuBar(mymenuBar);
+
+	toolBar = new QToolBar(this);
+	toolBar->setObjectName("mainToolbar");
+	addToolBar(Qt::BottomToolBarArea, toolBar);
+
+	QSettings mysettings(GetConfPath(), QSettings::IniFormat);
+
+	restoreGeometry(mysettings.value("geometry").toByteArray());
+	restoreState(mysettings.value("windowState").toByteArray());
+
+	GetSettings();
+
+	GetKeyWordFile();
+
+	// Set background colours
+
+	sprintf(monStyleSheet, "background-color: rgb(%d, %d, %d);",
+		monBackground.red(), monBackground.green(), monBackground.blue());
+
+	sprintf(termStyleSheet, "background-color: rgb(%d, %d, %d);",
+		termBackground.red(), termBackground.green(), termBackground.blue());
+
+	sprintf(inputStyleSheet, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		inputText.red(), inputText.green(), inputText.blue(),
+		inputBackground.red(), inputBackground.green(), inputBackground.blue());
+
+
+#ifdef ANDROID
+	menufont = new QFont(mysettings.value("MFontFamily", "Driod Sans").value<QString>(),
+		mysettings.value("MPointSize", 12).toInt(),
+		mysettings.value("MWeight", 50).toInt());
+#else
+	menufont = new QFont(mysettings.value("MFontFamily", "Aerial").value<QString>(),
+		mysettings.value("MPointSize", 10).toInt(),
+		mysettings.value("MWeight", 50).toInt());
+
+#endif
+	if (TermMode == MDI)
+	{
+		mdiArea = new QMdiArea(ui.centralWidget);
+		mdiArea->setGeometry(QRect(0, 0, 771, 571));
+
+		mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+		mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+		connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(xon_mdiArea_changed()));
+
+		setCentralWidget(mdiArea);
+	}
+	else if (TermMode == Tabbed)
+	{
+		Ui_ListenSession * Sess;
+		int index = 0;
+	
+		tabWidget = new QTabWidget(this);
+		QTabBar* tabBar = tabWidget->tabBar();
+
+//		QString style1 = "QTabWidget::tab-bar{left:0;}";  //  for Mac
+//		tabWidget->setStyleSheet(style1);
+
+		QString style = "QTabBar::tab:selected{background-color: #d0d0d0;} QTabBar::tab:!selected{background-color: #f0f0f0;}";
+
+		tabBar->setStyleSheet(style);
+
+		tabWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+
+		connect(tabWidget, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &)));
+
+		ui.verticalLayout->addWidget(tabWidget);
+		tabWidget->setTabPosition(QTabWidget::South);
+
+		Sess = newWindow(this, TabType[0], "Sess 1");
+		Sess->CurrentHost = currentHost[index++];
+		Sess = newWindow(this, TabType[1], "Sess 2");
+		Sess->CurrentHost = currentHost[index++];
+		Sess = newWindow(this, TabType[2], "Sess 3");
+		Sess->CurrentHost = currentHost[index++];
+		Sess = newWindow(this, TabType[3], "Sess 4");
+		Sess->CurrentHost = currentHost[index++];
+		Sess = newWindow(this, TabType[4], "Sess 5");
+		Sess->CurrentHost = currentHost[index++];
+		Sess = newWindow(this, TabType[5], "Sess 6");
+		Sess->CurrentHost = currentHost[index++];
+		Sess = newWindow(this, TabType[6], "Sess 7");
+		Sess->CurrentHost = currentHost[index++];
+		Sess = newWindow(this, TabType[7], "Monitor");
+		Sess->CurrentHost = currentHost[index++];
+		Sess = newWindow(this, TabType[8], "Monitor");
+		Sess->CurrentHost = currentHost[index++];
+
+		ActiveSession = _sessions.at(0);
+
+		connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabSelected(int)));
+
+		tabWidget->setFont(*menufont);
+
+	}
+
+	sprintf(Title, "QtTermTCP Version %s", VersionString);
+
+	this->setWindowTitle(Title);
+
+	//#ifdef ANDROID
+	//	mymymenuBar->setVisible(false);
+	//#endif
+
+	if (TermMode == Single)
+		windowMenu = mymenuBar->addMenu("");
+	else
+		windowMenu = mymenuBar->addMenu(tr("&Window"));
+
+	connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));
+	windowMenu->setFont(*menufont);
+
+	newTermAct = new QAction(tr("New Terminal Window"), this);
+	connect(newTermAct, SIGNAL(triggered()), this, SLOT(doNewTerm()));
+
+	newMonAct = new QAction(tr("New Monitor Window"), this);
+	connect(newMonAct, SIGNAL(triggered()), this, SLOT(doNewMon()));
+
+	newCombinedAct = new QAction(tr("New Combined Term/Mon Window"), this);
+	connect(newCombinedAct, SIGNAL(triggered()), this, SLOT(doNewCombined()));
+
+	if (TermMode == MDI)
+	{
+		closeAct = new QAction(tr("Cl&ose"), this);
+		closeAct->setStatusTip(tr("Close the active window"));
+		connect(closeAct, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow()));
+
+		closeAllAct = new QAction(tr("Close &All"), this);
+		closeAllAct->setStatusTip(tr("Close all the windows"));
+		connect(closeAllAct, SIGNAL(triggered()), mdiArea, SLOT(closeAllSubWindows()));
+
+		tileAct = new QAction(tr("&Tile"), this);
+		tileAct->setStatusTip(tr("Tile the windows"));
+		connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows()));
+
+		cascadeAct = new QAction(tr("&Cascade"), this);
+		cascadeAct->setStatusTip(tr("Cascade the windows"));
+		connect(cascadeAct, SIGNAL(triggered()), this, SLOT(doCascade()));
+
+		nextAct = new QAction(tr("Ne&xt"), this);
+		nextAct->setShortcuts(QKeySequence::NextChild);
+		nextAct->setStatusTip(tr("Move the focus to the next window"));
+		connect(nextAct, SIGNAL(triggered()), mdiArea, SLOT(activateNextSubWindow()));
+
+		previousAct = new QAction(tr("Pre&vious"), this);
+		previousAct->setShortcuts(QKeySequence::PreviousChild);
+		previousAct->setStatusTip(tr("Move the focus to the previous window"));
+		connect(previousAct, SIGNAL(triggered()), mdiArea, SLOT(activatePreviousSubWindow()));
+	}
+
+	quitAction = new QAction(tr("&Quit"), this);
+	connect(quitAction, SIGNAL(triggered()), this, SLOT(doQuit()));
+
+	windowMenuSeparatorAct = new QAction(this);
+	windowMenuSeparatorAct->setSeparator(true);
+
+	updateWindowMenu();
+
+	if (KISSEnable && KISSMH)
+	{
+		newMHWindow(this, 0, "KISS MH");
+		MHWindow->restoreGeometry(mysettings.value("MHgeometry").toByteArray());
+	}
+
+	connectMenu = mymenuBar->addMenu(tr("&Connect"));
+
+	actHost[16] = new QAction("AGW Connect", this);
+	actHost[16]->setFont(*menufont);
+	actHost[16]->setVisible(0);
+	connectMenu->addAction(actHost[16]);
+
+	connect(actHost[16], SIGNAL(triggered()), this, SLOT(Connect()));
+
+	actHost[17] = new QAction("VARA Connect", this);
+	actHost[17]->setFont(*menufont);
+	actHost[17]->setVisible(0);
+	connectMenu->addAction(actHost[17]);
+
+	connect(actHost[17], SIGNAL(triggered()), this, SLOT(Connect()));
+
+	actHost[18] = new QAction("KISS Connect", this);
+	actHost[18]->setFont(*menufont);
+	actHost[18]->setVisible(KISSEnable);
+	actHost[18]->setEnabled(0);
+	connectMenu->addAction(actHost[18]);
+
+	connect(actHost[18], SIGNAL(triggered()), this, SLOT(Connect()));
+	
+	for (i = 0; i < MAXHOSTS; i++)
+	{
+		if (SessName[i][0])
+		{
+			char Lable[256];
+			sprintf(Lable, "%s(%s)", Host[i], SessName[i]);
+			actHost[i] = new QAction(Lable, this);
+		}
+		else
+			actHost[i] = new QAction(Host[i], this);
+
+		actHost[i]->setFont(*menufont);
+		connectMenu->addAction(actHost[i]);
+		connect(actHost[i], SIGNAL(triggered()), this, SLOT(Connect()));
+	}
+
+	discAction = mymenuBar->addAction("&Disconnect");
+
+	// Place discAction in mac app menu, otherwise it doesn't appear
+	if (is_mac == true) {
+		QMenu * app_menu = mymenuBar->addMenu("App Menu");
+		discAction->setMenuRole(QAction::ApplicationSpecificRole);
+		app_menu->addAction(discAction);
+
+	}
+
+	connect(discAction, SIGNAL(triggered()), this, SLOT(Disconnect()));
+	discAction->setEnabled(false);
+
+	toolBar->setFont(*menufont);
+
+#ifndef ANDROID
+	toolBar->setVisible(false);
+#endif
+	but4 = new QToolButton();
+	but4->setPopupMode(QToolButton::InstantPopup);
+	but4->setText("Window");
+	but4->addAction(windowMenu->menuAction());
+	but4->setFont(*menufont);
+	toolBar->addWidget(but4);
+
+	but5 = new QToolButton();
+	but5->setPopupMode(QToolButton::InstantPopup);
+	but5->setText("Connect");
+	but5->addAction(connectMenu->menuAction());
+	but5->setFont(*menufont);
+
+	toolBar->addWidget(but5);
+
+	toolBar->addAction(discAction);
+
+	setupMenu = mymenuBar->addMenu(tr("&Setup"));
+	hostsubMenu = setupMenu->addMenu("Hosts");
+	hostsubMenu->setFont(*menufont);
+
+	for (i = 0; i < MAXHOSTS; i++)
+	{
+		if (Host[i][0])
+		{
+			char Label[256];
+
+			if (SessName[i][0])
+				sprintf(Label, "%s(%s)", Host[i], SessName[i]);
+			else
+				strcpy(Label, Host[i]);
+
+			actSetup[i] = new QAction(Label, this);
+		}
+		else
+			actSetup[i] = new QAction("New Host", this);
+
+		hostsubMenu->addAction(actSetup[i]);
+		connect(actSetup[i], SIGNAL(triggered()), this, SLOT(SetupHosts()));
+
+		actSetup[i]->setFont(*menufont);
+	}
+
+
+	// Setup Presentation Options
+
+	setupMenu->addSeparator()->setText(tr("Presentation"));
+
+	QActionGroup * termGroup = new QActionGroup(this);
+
+	singleAct = setupMenuLine(nullptr, (char *)"Single Window (Term + Mon)", this, (TermMode == Single) && (singlemodeFormat == Term + Mon));
+	singleAct2 = setupMenuLine(nullptr, (char *)"Single Window (Term only)", this, (TermMode == Single) && (singlemodeFormat == Term));
+	MDIAct = setupMenuLine(nullptr, (char *)"MDI", this, TermMode == MDI);
+	tabbedAct = setupMenuLine(nullptr, (char *)"Tabbed", this, TermMode == Tabbed);
+
+	termGroup->addAction(singleAct);
+	termGroup->addAction(singleAct2);
+	termGroup->addAction(MDIAct);
+	termGroup->addAction(tabbedAct);
+
+	setupMenu->addAction(singleAct);
+	setupMenu->addAction(singleAct2);
+	setupMenu->addAction(MDIAct);
+	setupMenu->addAction(tabbedAct);
+	setupMenu->addSeparator();
+	AlertAction = new QAction("Sound Alerts Setup", this);
+
+	setupMenu->addAction(AlertAction);
+	connect(AlertAction, SIGNAL(triggered()), this, SLOT(AlertSlot()));
+	AlertAction->setFont(*menufont);
+	setupMenu->addSeparator();
+
+	actFonts = new QAction("Terminal Font", this);
+	setupMenu->addAction(actFonts);
+	connect(actFonts, SIGNAL(triggered()), this, SLOT(doFonts()));
+	actFonts->setFont(*menufont);
+
+	actmenuFont = new QAction("Menu Font", this);
+	setupMenu->addAction(actmenuFont);
+	connect(actmenuFont, SIGNAL(triggered()), this, SLOT(doMFonts()));
+	actmenuFont->setFont(*menufont);
+
+	actColours = new QAction("Choose Colours", this);
+	setupMenu->addAction(actColours);
+	connect(actColours, SIGNAL(triggered()), this, SLOT(doColours()));
+	actColours->setFont(*menufont);
+
+	setupMenu->addSeparator();
+
+	AGWAction = new QAction("AGW Setup", this);
+	setupMenu->addAction(AGWAction);
+	connect(AGWAction, SIGNAL(triggered()), this, SLOT(AGWSlot()));
+	AGWAction->setFont(*menufont);
+
+	VARAAction = new QAction("VARA Setup", this);
+	setupMenu->addAction(VARAAction);
+	connect(VARAAction, SIGNAL(triggered()), this, SLOT(VARASlot()));
+	VARAAction->setFont(*menufont);
+
+	KISSAction = new QAction("KISS Setup", this);
+	setupMenu->addAction(KISSAction);
+	connect(KISSAction, SIGNAL(triggered()), this, SLOT(KISSSlot()));
+	KISSAction->setFont(*menufont);
+
+	setupMenu->addSeparator();
+
+	actChatMode = setupMenuLine(setupMenu, (char *)"Chat Terminal Mode (Send Keepalives)", this, ChatMode);
+	actAutoTeletext = setupMenuLine(setupMenu, (char *)"Auto switch to Teletext", this, AutoTeletext);
+	actStripLF = setupMenuLine(setupMenu, (char *)"Strip Line Feeds", this, StripLF);
+
+	setupMenu->addSeparator();
+
+	setupMenu->addAction(new QAction("Interpret non-UTF8 input as:", this));
+	setupMenu->setFont(*menufont);
+
+	QActionGroup * cpGroup = new QActionGroup(this);
+
+	actnoConv = setupMenuLine(nullptr, (char *)"   Don't Convert (assume is UTF-8)", this, convUTF8 == -1);
+	actAuto = setupMenuLine(nullptr, (char *)"   Auto", this, convUTF8 == 0);
+	actCP1251 = setupMenuLine(nullptr, (char *)"   CP1251 (Cyrillic)", this, convUTF8 == 1251);
+	actCP1252 = setupMenuLine(nullptr, (char *)"   CP1252 (Western Europe)", this, convUTF8 == 1252);
+	actCP437 = setupMenuLine(nullptr, (char *)"   CP437 (Windows Line Draw)", this, convUTF8 == 437);
+
+	cpGroup->addAction(actnoConv);
+	cpGroup->addAction(actAuto);
+	cpGroup->addAction(actCP1251);
+	cpGroup->addAction(actCP1252);
+	cpGroup->addAction(actCP437);
+
+	setupMenu->addAction(actnoConv);
+	setupMenu->addAction(actAuto);
+	setupMenu->addAction(actCP1251);
+	setupMenu->addAction(actCP1252);
+	setupMenu->addAction(actCP437);
+
+	monitorMenu = mymenuBar->addMenu(tr("&Monitor"));
+
+	EnableMonitor = setupMenuLine(monitorMenu, (char *)"Enable Monitoring", this, 0);
+	EnableMonitor->setVisible(0);
+	EnableMonLog = setupMenuLine(monitorMenu, (char *)"Log to File", this, 0);
+	MonLocalTime = setupMenuLine(monitorMenu, (char *)"Use local time", this, 0);
+	MonTX = setupMenuLine(monitorMenu, (char *)"Monitor TX", this, 1);
+	MonSup = setupMenuLine(monitorMenu, (char *)"Monitor Supervisory", this, 1);
+	MonUI = setupMenuLine(monitorMenu, (char *)"Only Monitor UI Frames", this, 0);
+	MonNodes = setupMenuLine(monitorMenu, (char *)"Monitor NODES Broadcasts", this, 0);
+	MonColour = setupMenuLine(monitorMenu, (char *)"Enable Colour", this, 1);
+
+	for (i = 0; i < MAXPORTS + 1; i++)
+	{
+		MonPort[i] = setupMenuLine(monitorMenu, (char *)"Port", this, 0);
+		MonPort[i]->setVisible(false);
+	}
+
+	but1 = new QToolButton();
+	but1->setPopupMode(QToolButton::InstantPopup);
+	but1->setText("Monitor");
+	but1->addAction(monitorMenu->menuAction());
+	toolBar->addWidget(but1);
+
+	but2 = new QToolButton();
+	but2->setPopupMode(QToolButton::InstantPopup);
+	but2->setText("Setup");
+	but2->addAction(setupMenu->menuAction());
+	toolBar->addWidget(but2);
+
+	ListenAction = mymenuBar->addAction("&Listen");
+	connect(ListenAction, SIGNAL(triggered()), this, SLOT(ListenSlot()));
+
+
+	// Place Listen Action in mac app menu, otherwise it doesn't appear
+	if (is_mac == true)
+	{
+		QMenu * app_menu = mymenuBar->addMenu("App Menu");
+		ListenAction->setMenuRole(QAction::ApplicationSpecificRole);
+		app_menu->addAction(ListenAction);
+	}
+
+	toolBar->addAction(ListenAction);
+
+	YAPPMenu = mymenuBar->addMenu(tr("&YAPP"));
+
+	YAPPSend = new QAction("Send File", this);
+	YAPPSetRX = new QAction("Set Receive Directory", this);
+	YAPPSetSize = new QAction("Set Max Size", this);
+	YAPPSend->setFont(*menufont);
+	YAPPSetRX->setFont(*menufont);
+	YAPPSetSize->setFont(*menufont);
+
+	YAPPMenu->addAction(YAPPSend);
+	YAPPMenu->addAction(YAPPSetRX);
+	YAPPMenu->addAction(YAPPSetSize);
+	YAPPSend->setEnabled(false);
+
+	connect(YAPPSend, SIGNAL(triggered()), this, SLOT(doYAPPSend()));
+	connect(YAPPSetRX, SIGNAL(triggered()), this, SLOT(doYAPPSetRX()));
+	connect(YAPPSetSize, SIGNAL(triggered()), this, SLOT(doYAPPSetSize()));
+
+	but3 = new QToolButton();
+	but3->setPopupMode(QToolButton::InstantPopup);
+	but3->setText("YAPP");
+	but3->addAction(YAPPMenu->menuAction());
+	but3->setFont(*menufont);
+	toolBar->addWidget(but3);
+
+	toolBar->setFont(*menufont);
+
+	// Set up Status Bar
+
+	setStyleSheet("QStatusBar{border-top: 1px outset black;} QStatusBar::item { border: 1px solid black; border-radius: 3px;}");
+	//	setStyleSheet("QStatusBar{border-top: 1px outset black;}");
+
+
+	Status4 = new QLabel("");
+	Status3 = new QLabel("         ");
+	Status2 = new QLabel("    ");
+	Status1 = new QLabel("  Disconnected  ");
+
+	Status1->setMinimumWidth(100);
+	Status2->setMinimumWidth(100);
+	Status3->setMinimumWidth(100);
+	Status4->setMinimumWidth(100);
+
+	myStatusBar = statusBar();
+
+	statusBar()->addPermanentWidget(Status4);
+	statusBar()->addPermanentWidget(Status3);
+	statusBar()->addPermanentWidget(Status2);
+	statusBar()->addPermanentWidget(Status1);
+
+	statusBar()->setVisible(AGWEnable | VARAEnable | KISSEnable);
+	// Restore saved sessions
+
+	if (TermMode == Single)
+	{
+		Ui_ListenSession * Sess = newWindow(this, singlemodeFormat);
+
+		ActiveSession = Sess;
+		Sess->CurrentHost = currentHost[0];
+
+		ui.verticalLayout->addWidget(Sess);
+
+		connectMenu->setEnabled(true);
+		discAction->setEnabled(false);
+		YAPPSend->setEnabled(false);
+	}
+
+	if (TermMode == MDI)
+	{
+		int n = atoi(sessionList);
+		int index = 0;
+
+		char *p, *Context;
+		char delim[] = "|";
+
+		int type = 0, host = 0, topx, leftx, bottomx, rightx;
+
+		p = strtok_s((char *)sessionList, delim, &Context);
+
+		while (n--)
+		{
+			p = strtok_s(NULL, delim, &Context);
+
+			sscanf(p, "%d,%d,%d,%d,%d,%d", &type, &host, &topx, &leftx, &bottomx, &rightx);
+
+			Ui_ListenSession * Sess = newWindow(this, type);
+
+			Sess->CurrentHost = currentHost[index++];;
+
+			QRect r(leftx, topx, rightx - leftx, bottomx - topx);
+
+			Sess->sw->setGeometry(r);
+			Sess->sw->move(leftx, topx);
+
+		}
+	}
+
+	QTimer *timer = new QTimer(this);
+	connect(timer, SIGNAL(timeout()), this, SLOT(MyTimerSlot()));
+	timer->start(10000);
+
+	QTimer *timer2 = new QTimer(this);
+	connect(timer2, SIGNAL(timeout()), this, SLOT(KISSTimerSlot()));
+	timer2->start(100);
+
+	QTimer *timer3 = new QTimer(this);
+	connect(timer3, SIGNAL(timeout()), this, SLOT(SlowTimerSlot()));
+	timer3->start(60000);
+
+	// Run timer now to connect to AGW if configured
+
+	MyTimerSlot();
+
+	if (listenEnable)
+		_server->listen(QHostAddress::Any, listenPort);
+
+	connect(_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
+
+	setFonts();
+
+	if (VARAEnable)
+		OpenPTTPort();
+
+	memset(axMYCALL, 0, 7);
+	ConvToAX25(KISSMYCALL, axMYCALL);
+
+	// Do any autoconnects
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		if (AutoConnect[i] > 0)
+		{
+			Ui_ListenSession * Sess = _sessions.at(i);
+			
+			Sess->clientSocket = new myTcpSocket();
+			Sess->clientSocket->Sess = Sess;
+
+			connect(Sess->clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
+			connect(Sess->clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
+			connect(Sess->clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
+
+			Sess->clientSocket->connectToHost(&Host[Sess->CurrentHost][0], Port[Sess->CurrentHost]);
+		}
+	}
+
+}
+
+void QtTermTCP::showContextMenu(const QPoint &point)
+{
+	if (point.isNull())
+		return;
+
+	QTabBar* tabBar = tabWidget->tabBar();
+	QRect Wrect = tabWidget->rect();
+	QRect Brect = tabBar->rect();
+	QPoint myPoint = point;
+
+	// Get x coordinate of first tab (on Mac tabs are centre aligned)
+
+	QRect rect = tabWidget->tabBar()->geometry();
+	int left = rect.left();
+
+
+	int n = myPoint.y() - (Wrect.height() - Brect.height());
+	myPoint.setY(n); 
+	n = myPoint.x() - left;
+
+	myPoint.setX(n);
+
+	int tabIndex =  tabBar->tabAt(myPoint);
+
+	QMenu menu(this);
+
+	QAction * Act = new QAction("AutoConnect on load", this);
+	Act->setObjectName(QString::number(tabIndex));
+
+	menu.addAction(Act);
+
+	Act->setCheckable(true);
+
+	if (AutoConnect[tabIndex] <= 0)
+		Act->setChecked(false);
+	else
+		Act->setChecked(true);
+
+	connect(Act, SIGNAL(triggered()), this, SLOT(autoConnectChecked()));
+
+	menu.exec(tabWidget->mapToGlobal(point));
+
+}
+
+void QtTermTCP::autoConnectChecked()
+{
+	QAction * Act = static_cast<QAction*>(QObject::sender());
+	QString Tab = Act->objectName();
+	int tabNo = Tab.toInt();
+
+	tabWidget->setCurrentIndex(tabNo);
+	
+	Ui_ListenSession *Sess = (Ui_ListenSession *)tabWidget->currentWidget();
+	int state = Act->isChecked();
+
+	if (state == 0)
+		AutoConnect[tabNo] = 0;
+	else
+	{
+		if (Sess->clientSocket)		// Connected
+			AutoConnect[tabNo] = 1;
+		else
+			AutoConnect[tabNo] = 0;
+	}
+}
+
+
+void QtTermTCP::setFonts()
+{
+	windowMenu->menuAction()->setFont(*menufont);
+	connectMenu->menuAction()->setFont(*menufont);
+	setupMenu->menuAction()->setFont(*menufont);
+	monitorMenu->menuAction()->setFont(*menufont);
+	YAPPMenu->menuAction()->setFont(*menufont);
+
+	if (tabWidget)
+		tabWidget->setFont(*menufont);
+	mymenuBar->setFont(*menufont);
+	toolBar->setFont(*menufont);
+	but1->setFont(*menufont);
+	but2->setFont(*menufont);
+	but3->setFont(*menufont);
+	but4->setFont(*menufont);
+	but5->setFont(*menufont);
+	discAction->setFont(*menufont);
+	ListenAction->setFont(*menufont);
+
+	for (int i = 0; i < MAXHOSTS; i++)
+	{
+		actHost[i]->setFont(*menufont);
+		actSetup[i]->setFont(*menufont);
+	}
+
+	actHost[16]->setFont(*menufont);			// AGW  Host
+}
+
+void QtTermTCP::doQuit()
+{
+	if (_server->isListening())
+		_server->close();
+
+	SaveSettings();
+
+	QCoreApplication::quit();
+}
+
+void FlashifNotActive()
+{
+	if (!mythis->isActiveWindow())
+		QApplication::alert(mythis, 0);
+}
+
+
+// "Copy on select" Code
+
+
+void QtTermTCP::onTEselectionChanged()
+{
+	QTextEdit * x = static_cast<QTextEdit*>(QObject::sender());
+
+	if (isActiveWindow())
+		x->copy();
+}
+
+void QtTermTCP::onLEselectionChanged()
+{
+	QLineEdit * x = static_cast<QLineEdit*>(QObject::sender());
+	if (isActiveWindow())
+		x->copy();
+}
+
+void QtTermTCP::setVDMode()
+{
+	QAction * sender = static_cast<QAction*>(QObject::sender());
+
+	QTextEdit * window = static_cast<QTextEdit*>(sender->parentWidget());
+
+	// Need to find session with this window as owner
+
+	Ui_ListenSession * Sess = NULL;
+
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		if (Sess->termWindow == window)
+		{
+			Sess->TTActive ^= 1;
+			DoTermResize(Sess);
+			break;
+		}
+	}
+}
+
+int splitY;					// Value when menu added
+
+void QtTermTCP::setSplit()
+{
+	QAction * sender = static_cast<QAction*>(QObject::sender());
+
+	QWidget * Parent = sender->parentWidget();
+
+	if (Parent)
+		Parent = Parent->parentWidget();
+
+	int y = Parent->rect().height() - 50;
+
+	// y is height of whole windom. splitX is new split position
+	// So split = 100 * splitx/x
+
+	Split = (splitY * 100) / y;
+
+	if (Split < 10)
+		Split = 10;
+	else if (Split > 90)
+		Split = 90;
+
+	QSize size(800, 602);
+	QResizeEvent event(size, size);
+
+	eventFilter(Parent, &event);
+}
+
+void QtTermTCP::ClearScreen()
+{
+	QAction * sender = static_cast<QAction*>(QObject::sender());
+	QTextEdit * window = static_cast<QTextEdit*>(sender->parentWidget());
+	window->clear();
+}
+
+
+void QtTermTCP::showContextMenuMT(const QPoint &pt)				// Term Window
+{
+	// Monitor and Terminal (Term Half)
+
+	QTextEdit* sender = static_cast<QTextEdit*>(QObject::sender());
+
+	QMenu *menu = sender->createStandardContextMenu();
+
+	QString style = "QMenu {border-radius:15px; background-color: white;margin: 2px; border: 1px solid rgb(58, 80, 116); color:  rgb(58, 80, 116);}QMenu::separator {height: 2px;background: rgb(58, 80, 116);margin-left: 10px;margin-right: 5px;}";
+	menu->setStyleSheet(style);
+
+	QAction * actSplit = new QAction("Set Monitor/Output Split", sender);
+	QAction * actVDMode = new QAction("Toggle Viewdata Mode", sender);
+	QAction * actClear = new QAction("Clear Screen Buffer", sender);
+
+	menu->addAction(actSplit);
+	menu->addAction(actVDMode);
+	menu->addAction(actClear);
+
+	splitY = pt.y() + termX;
+
+	connect(actSplit, SIGNAL(triggered()), this, SLOT(setSplit()));
+	connect(actVDMode, SIGNAL(triggered()), this, SLOT(setVDMode()));
+	connect(actClear, SIGNAL(triggered()), this, SLOT(ClearScreen()));
+
+	menu->exec(sender->mapToGlobal(pt));
+	delete menu;
+}
+
+void QtTermTCP::showContextMenuMOnly(const QPoint &pt)
+{
+	// Monitor only
+
+	QTextEdit* sender = static_cast<QTextEdit*>(QObject::sender());
+
+	QMenu *menu = sender->createStandardContextMenu();
+
+	QString style = "QMenu {border-radius:15px; background-color: white;margin: 2px; border: 1px solid rgb(58, 80, 116); color:  rgb(58, 80, 116);}QMenu::separator {height: 2px;background: rgb(58, 80, 116);margin-left: 10px;margin-right: 5px;}";
+	menu->setStyleSheet(style);
+
+	QAction * actClear = new QAction("Clear Screen Buffer", sender);
+
+	menu->addAction(actClear);
+	connect(actClear, SIGNAL(triggered()), this, SLOT(ClearScreen()));
+
+	menu->exec(sender->mapToGlobal(pt));
+	delete menu;
+}
+
+
+void QtTermTCP::showContextMenuT(const QPoint &pt)				// Term Window
+{
+	// Just Terminal 
+
+	QTextEdit* sender = static_cast<QTextEdit*>(QObject::sender());
+
+	QMenu *menu = sender->createStandardContextMenu();
+
+	QString style = "QMenu {border-radius:15px; background-color: white;margin: 2px; border: 1px solid rgb(58, 80, 116); color:  rgb(58, 80, 116);}";
+	menu->setStyleSheet(style);
+
+
+	QAction * actVDMode = new QAction("Toggle Viewdata Mode", sender);
+	QAction * actClear = new QAction("Clear Screen Buffer", sender);
+
+	menu->addAction(actVDMode);
+	menu->addAction(actClear);
+
+	connect(actVDMode, SIGNAL(triggered()), this, SLOT(setVDMode()));
+	connect(actClear, SIGNAL(triggered()), this, SLOT(ClearScreen()));
+
+	menu->exec(sender->mapToGlobal(pt));
+	delete menu;
+}
+
+
+void QtTermTCP::showContextMenuL()				// Term Window
+{
+	// Teletext Label Right Clicked - cancel TT Mode
+
+	QLabel * sender = static_cast<QLabel*>(QObject::sender());
+
+	// Need to find session with this label as owner
+
+	Ui_ListenSession * Sess = NULL;
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		if (Sess->TTLabel == sender)
+		{
+			Sess->TTActive ^= 1;
+
+			DoTermResize(Sess);
+			break;
+		}
+	}
+}
+
+
+void QtTermTCP::showContextMenuM(const QPoint &pt)				// Mon Window
+{
+	QTextEdit* sender = static_cast<QTextEdit*>(QObject::sender());
+
+	QMenu *menu = sender->createStandardContextMenu();
+	QString style = "QMenu {border-radius:15px; background-color: white;margin: 2px; border: 1px solid rgb(58, 80, 116); color:  rgb(58, 80, 116);}";
+	menu->setStyleSheet(style);
+
+	QAction * actSplit = new QAction("Set Monitor/Output Split", sender);
+	QAction * actClear = new QAction("Clear Screen Buffer", sender);
+
+	menu->addAction(actSplit);
+	menu->addAction(actClear);
+
+	splitY = pt.y();
+
+	connect(actSplit, SIGNAL(triggered()), this, SLOT(setSplit()));
+	connect(actClear, SIGNAL(triggered()), this, SLOT(ClearScreen()));
+
+	menu->exec(sender->mapToGlobal(pt));
+	delete menu;
+}
+
+extern "C" void setMenus(int State)
+{
+	// Sets Connect, Disconnect and YAPP Send  enable flags to match connection state
+
+	if (State)
+	{
+		connectMenu->setEnabled(false);
+		discAction->setEnabled(true);
+		YAPPSend->setEnabled(true);
+	}
+	else
+	{
+		connectMenu->setEnabled(true);
+		discAction->setEnabled(false);
+		YAPPSend->setEnabled(false);
+	}
+}
+
+extern "C" void SetSessLabel(Ui_ListenSession * Sess, char * label)
+{
+	if (TermMode == MDI)
+		Sess->setWindowTitle(label);
+	else if (TermMode == Tabbed)
+		tabWidget->setTabText(Sess->Tab, label);
+	else if (TermMode == Single)
+		mythis->setWindowTitle(label);
+}
+
+
+extern "C" void ClearSessLabel(Ui_ListenSession * Sess)
+{
+	if (TermMode == MDI)
+	{
+		if (Sess->SessionType == Mon)			// Mon Only
+			Sess->setWindowTitle("Monitor Session Disconnected");
+		else if (Sess->SessionType == Listen)			// Mon Only
+			Sess->setWindowTitle("Listen Window Disconnected");
+		else
+			Sess->setWindowTitle("Disconnected");
+	}
+	else if (TermMode == Tabbed)
+	{
+		if (Sess->SessionType == Mon)			// Mon Only
+			tabWidget->setTabText(Sess->Tab, "Monitor");
+		else
+		{
+			char Label[16];
+			sprintf(Label, "Sess %d", Sess->Tab + 1);
+			tabWidget->setTabText(Sess->Tab, Label);
+		}
+	}
+	else if (TermMode == Single)
+	{
+		if (Sess->SessionType == Mon)			// Mon Only
+			mythis->setWindowTitle("Monitor Session Disconnected");
+		else
+			mythis->setWindowTitle("Disconnected");
+	}
+}
+
+void QtTermTCP::tabSelected(int Current)
+{
+	Ui_ListenSession * Sess = NULL;
+
+	if (Current < _sessions.size())
+	{
+		Sess = _sessions.at(Current);
+
+		if (Sess == nullptr)
+			return;
+
+		ActiveSession = Sess;
+
+		tabWidget->tabBar()->setTabTextColor(tabWidget->currentIndex(), oldTabText);
+
+		if (Sess->clientSocket || Sess->AGWSession || Sess->KISSSession || Sess->KISSMode)
+		{
+			connectMenu->setEnabled(false);
+			discAction->setEnabled(true);
+			YAPPSend->setEnabled(true);
+		}
+		else
+		{
+			connectMenu->setEnabled(true);
+			discAction->setEnabled(false);
+			YAPPSend->setEnabled(false);
+		}
+
+		// If a monitor Window, change Monitor config settings
+
+		EnableMonLog->setChecked(Sess->LogMonitor);
+
+		if (AGWUsers && Sess == AGWUsers->MonSess)		// AGW Monitor
+		{
+			for (int i = 0; i < 64; i++)
+				SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
+
+			connectMenu->setEnabled(false);
+			MonTX->setVisible(0);
+			MonSup->setVisible(0);
+			MonUI->setVisible(0);
+			MonColour->setVisible(0);
+
+			EnableMonitor->setVisible(1);
+			EnableMonitor->setChecked(AGWMonEnable);
+			MonLocalTime->setChecked(Sess->mlocaltime);
+			MonNodes->setChecked(Sess->MonitorNODES);
+		}
+		else if (Sess == KISSMonSess)				// KISS Monitor
+		{
+			for (int i = 0; i < 64; i++)
+				SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
+
+			connectMenu->setEnabled(false);
+			MonTX->setVisible(0);
+			MonSup->setVisible(0);
+			MonUI->setVisible(0);
+			MonColour->setVisible(0);
+
+			EnableMonitor->setVisible(1);
+			EnableMonitor->setChecked(KISSMonEnable);
+			MonLocalTime->setChecked(Sess->mlocaltime);
+			MonNodes->setChecked(Sess->MonitorNODES);
+		}
+		else
+		{
+			EnableMonitor->setVisible(0);
+			MonTX->setVisible(1);
+			MonSup->setVisible(1);
+			MonUI->setVisible(1);
+			MonColour->setVisible(1);
+		}
+
+		if (Sess->PortMonString[0])
+		{
+			char * ptr = (char *)malloc(2048);
+			memcpy(ptr, Sess->PortMonString, 2048);
+
+			int NumberofPorts = atoi((char *)&ptr[2]);
+			char *p, *Context;
+			char msg[80];
+			int portnum, m;
+			char delim[] = "|";
+
+			// Remove old Monitor menu
+
+			for (int i = 0; i < 64; i++)
+			{
+				SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
+			}
+
+			p = strtok_s((char *)&ptr[2], delim, &Context);
+
+			while (NumberofPorts--)
+			{
+				p = strtok_s(NULL, delim, &Context);
+				if (p == NULL)
+					break;
+
+				m = portnum = atoi(p);
+
+				sprintf(msg, "Port %s", p);
+
+				if (m == 0)
+					m = 64;
+
+				if (Sess->portmask & ((uint64_t)1 << (m - 1)))
+					SetPortMonLine(portnum, msg, 1, 1);
+				else
+					SetPortMonLine(portnum, msg, 1, 0);
+			}
+			free(ptr);
+
+			MonLocalTime->setChecked(Sess->mlocaltime);
+			MonTX->setChecked(Sess->mtxparam);
+			MonSup->setChecked(Sess->mcomparam);
+			MonUI->setChecked(Sess->monUI);
+			MonNodes->setChecked(Sess->MonitorNODES);
+			MonColour->setChecked(Sess->MonitorColour);
+		}
+		return;
+	}
+}
+
+void QtTermTCP::SetupHosts()
+{
+	QAction * Act = static_cast<QAction*>(QObject::sender());
+	int i;
+
+	for (i = 0; i < MAXHOSTS; i++)
+	{
+		if (Act == actSetup[i])
+			break;
+	}
+
+	if (i > 15)
+		return;
+
+	ConfigHost = i;
+
+	TabDialog tabdialog(0);
+	tabdialog.exec();
+}
+
+
+void QtTermTCP::Connect()
+{
+	QMdiSubWindow * UI;
+	Ui_ListenSession * Sess = nullptr;
+	QAction * Act = static_cast<QAction*>(QObject::sender());
+
+	int i;
+
+	for (i = 0; i < MAXHOSTS; i++)
+	{
+		if (Act == actHost[i])
+			break;
+	}
+
+	SavedHost = i;				// Last used
+
+	if (TermMode == MDI)
+	{
+		UI = mdiArea->activeSubWindow();
+
+		for (i = 0; i < _sessions.size(); ++i)
+		{
+			Sess = _sessions.at(i);
+
+			if (Sess->sw == UI)
+				break;
+		}
+
+		if (i == _sessions.size())
+			return;
+
+		currentHost[i] = SavedHost;
+	}
+
+	else if (TermMode == Tabbed)
+	{
+		Sess = (Ui_ListenSession *)tabWidget->currentWidget();
+	}
+
+	else if (TermMode == Single)
+		Sess = _sessions.at(0);
+
+	if ((Sess == nullptr || Sess->SessionType & Listen))
+		return;
+
+	Sess->CurrentHost = SavedHost;
+
+	currentHost[Sess->Tab] = SavedHost;
+
+	if (Act == actHost[16])
+	{
+		// This runs the AGW Connection dialog
+
+		Sess->CurrentHost = 16;				// Iast used
+		AGWConnect dialog(0);
+		dialog.exec();
+		return;
+	}
+
+
+	if (Act == actHost[17])
+	{
+		// This runs the VARA Connection dialog
+
+		Sess->CurrentHost = 17;				// Iast used
+		VARADataSock->Sess = Sess;
+		VARASock->Sess = Sess;
+
+		VARAConnect dialog(0);
+		dialog.exec();
+		WritetoOutputWindow(Sess, (unsigned char *)"Connecting...\r", 14);
+
+		return;
+	}
+
+	if (Act == actHost[18])
+	{
+		// This runs the KISS Connection dialog
+
+		Sess->CurrentHost = 18;				// Iast used
+
+		KISSConnect dialog(0);
+		dialog.exec();
+		return;
+	}
+
+	// Set Monitor Params for this host
+
+	sscanf(MonParams[Sess->CurrentHost], "%llx %x %x %x %x %x",
+		&Sess->portmask, &Sess->mtxparam, &Sess->mcomparam,
+		&Sess->MonitorNODES, &Sess->MonitorColour, &Sess->monUI);
+
+	Sess->mlocaltime = (Sess->mtxparam >> 7);
+	Sess->mtxparam &= 1;
+
+	MonLocalTime->setChecked(Sess->mlocaltime);
+	MonTX->setChecked(Sess->mtxparam);
+	MonSup->setChecked(Sess->mcomparam);
+	MonUI->setChecked(Sess->monUI);
+	MonNodes->setChecked(Sess->MonitorNODES);
+	MonColour->setChecked(Sess->MonitorColour);
+
+	// Remove old Monitor menu
+
+	for (i = 0; i < 64; i++)
+	{
+		SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
+	}
+
+	delete(Sess->clientSocket);
+
+	Sess->clientSocket = new myTcpSocket();
+	Sess->clientSocket->Sess = Sess;
+
+	connect(Sess->clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
+	connect(Sess->clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
+	connect(Sess->clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
+
+	Sess->clientSocket->connectToHost(&Host[Sess->CurrentHost][0], Port[Sess->CurrentHost]);
+	return;
+}
+
+extern "C" void rst_timer(TAX25Port * AX25Sess);
+extern "C" void set_unlink(TAX25Port * AX25Sess, Byte * path);
+
+void QtTermTCP::Disconnect()
+{
+	QMdiSubWindow * UI;
+	Ui_ListenSession * Sess = nullptr;
+
+	if (TermMode == MDI)
+	{
+		int i;
+
+		UI = mdiArea->activeSubWindow();
+
+		for (i = 0; i < _sessions.size(); ++i)
+		{
+			Sess = _sessions.at(i);
+
+			if (Sess->sw == UI)
+				break;
+		}
+
+		if (i == _sessions.size())
+			return;
+	}
+
+	else if (TermMode == Tabbed)
+	{
+		Sess = (Ui_ListenSession *)tabWidget->currentWidget();
+	}
+
+	else if (TermMode == Single)
+		Sess = _sessions.at(0);
+
+	// if AGW send a d frame else disconnect TCP session
+
+	if (Sess->AGWSession)
+		Send_AGW_Ds_Frame(Sess->AGWSession);
+	else if (VARASock && VARASock->Sess == Sess)
+		VARASock->write("DISCONNECT\r");
+	else if (Sess->KISSSession)
+	{
+		if (Sess->KISSMode == 0)
+		{
+			TAX25Port * Port = (TAX25Port *)Sess->KISSSession;
+
+			rst_timer(Port);
+			set_unlink(Port, Port->Path);
+		}
+		else
+		{
+			// KISS UI Mode
+
+			char Msg[128];
+			int Len = sprintf(Msg, "Disconnected\r");
+
+			Sess->KISSMode = 0;
+			SendtoTerm(Sess, Msg, Len);
+			ClearSessLabel(Sess);
+			setMenus(0);
+			Sess->KISSSession = NULL;
+		}
+	}
+	else
+
+	{
+		if (Sess && Sess->clientSocket)
+			Sess->clientSocket->disconnectFromHost();
+	}
+	return;
+}
+
+
+void QtTermTCP::doYAPPSend()
+{
+	QFileDialog dialog(this);
+	QStringList fileNames;
+	dialog.setFileMode(QFileDialog::AnyFile);
+
+	QMdiSubWindow * UI;
+	Ui_ListenSession * Sess = nullptr;
+	int i;
+
+	if (TermMode == MDI)
+	{
+		UI = mdiArea->activeSubWindow();
+
+		for (i = 0; i < _sessions.size(); ++i)
+		{
+			Sess = _sessions.at(i);
+
+			if (Sess->sw == UI)
+				break;
+		}
+
+		if (i == _sessions.size())
+			return;
+	}
+
+	else if (TermMode == Tabbed)
+	{
+		Sess = (Ui_ListenSession *)tabWidget->currentWidget();
+	}
+
+	else if (TermMode == Single)
+		Sess = _sessions.at(0);
+
+	if (Sess == nullptr)
+		return;
+
+	if ((Sess->SessionType & Mon))
+	{
+		// Turn off monitoring
+
+		setTraceOff(Sess);
+	}
+
+	if (dialog.exec())
+	{
+		char FN[256];
+
+		fileNames = dialog.selectedFiles();
+		if (fileNames[0].length() < 256)
+		{
+			strcpy(FN, fileNames[0].toUtf8());
+			YAPPSendFile(Sess, FN);
+		}
+	}
+}
+
+void QtTermTCP::doYAPPSetRX()
+{
+	QFileDialog dialog(this);
+	QStringList fileNames;
+	dialog.setFileMode(QFileDialog::Directory);
+	dialog.setDirectory(YAPPPath);
+
+	if (dialog.exec())
+	{
+		fileNames = dialog.selectedFiles();
+		if (fileNames[0].length() < 256)
+			strcpy(YAPPPath, fileNames[0].toUtf8());
+
+		SaveSettings();
+	}
+}
+
+Ui_SizeDialog * YappSize;
+
+void QtTermTCP::doYAPPSetSize()
+{
+	// This runs the VARA Configuration dialog
+
+	char valChar[80];
+
+	YappSize = new(Ui_SizeDialog);
+
+	QDialog UI;
+
+	YappSize->setupUi(&UI);
+
+	UI.setFont(*menufont);
+	deviceUI = &UI;
+
+	sprintf(valChar, "%d", MaxRXSize);
+
+	YappSize->maxSize->setText(valChar);
+
+	QObject::connect(YappSize->okButton, SIGNAL(clicked()), this, SLOT(sizeaccept()));
+	QObject::connect(YappSize->cancelButton, SIGNAL(clicked()), this, SLOT(sizereject()));
+
+	UI.exec();
+}
+
+void QtTermTCP::sizeaccept()
+{
+	QVariant Q;
+	Q = YappSize->maxSize->text();
+
+	MaxRXSize = Q.toInt();
+	SaveSettings();
+	delete(YappSize);
+}
+
+
+void QtTermTCP::sizereject()
+{
+	delete(YappSize);
+	deviceUI->reject();
+}
+
+
+void QtTermTCP::menuChecked()
+{
+	QAction * Act = static_cast<QAction*>(QObject::sender());
+
+	int state = Act->isChecked();
+	int newTermMode = TermMode;
+	int newSingleMode = singlemodeFormat;
+
+	if (Act == TabSingle || Act == TabBoth || Act == TabMon)
+	{
+		// Tabbed Window format had changed
+
+		int i = tabWidget->currentIndex();
+
+		if (Act == TabSingle)
+			TabType[i] = Term;
+		else if (Act == TabBoth)
+			TabType[i] = Term + Mon;
+		else
+			TabType[i] = Mon;
+
+		QMessageBox msgBox;
+		msgBox.setText("Tab Types will change next time program is started.");
+		msgBox.exec();
+
+	}
+
+	if (Act == singleAct || Act == singleAct2 || Act == MDIAct || Act == tabbedAct)
+	{
+		// Term Mode had changed
+
+		if (singleAct->isChecked())
+		{
+			newTermMode = Single;
+			newSingleMode = Mon + Term;
+		}
+		else if (singleAct2->isChecked())
+		{
+			newTermMode = Single;
+			newSingleMode = Term;
+		}
+		else if (MDIAct->isChecked())
+			newTermMode = MDI;
+		else if (tabbedAct->isChecked())
+			newTermMode = Tabbed;
+
+		if (newTermMode != TermMode || newSingleMode != singlemodeFormat)
+		{
+			QSettings settings(GetConfPath(), QSettings::IniFormat);
+			settings.setValue("TermMode", newTermMode);
+			settings.setValue("singlemodeFormat", newSingleMode);
+			QMessageBox msgBox;
+			msgBox.setText("Presentation Mode will change next time program is started.");
+			msgBox.exec();
+		}
+
+		return;
+	}
+
+	if (Act == EnableMonitor)
+		ActiveSession->EnableMonitor = state;
+	else if (Act == EnableMonLog)
+		ActiveSession->LogMonitor = state;
+	else if (Act == MonLocalTime)
+		ActiveSession->mlocaltime = state;
+	else if (Act == MonTX)
+		ActiveSession->mtxparam = state;
+	else if (Act == MonSup)
+		ActiveSession->mcomparam = state;
+	else if (Act == MonUI)
+		ActiveSession->monUI = state;
+	else if (Act == MonNodes)
+		ActiveSession->MonitorNODES = state;
+	else if (Act == MonColour)
+		ActiveSession->MonitorColour = state;
+	else if (Act == actChatMode)
+		ChatMode = state;
+	else if (Act == actAutoTeletext)
+		AutoTeletext = state;
+	else if (Act == actBells)
+		Bells = state;
+	else if (Act == actStripLF)
+		StripLF = state;
+	else if (Act == actIntervalBeep)
+		AlertBeep = state;
+	else if (Act == actConnectBeep)
+		ConnectBeep = state;
+	else if (Act == actnoConv)
+		convUTF8 = -1;
+	else if (Act == actAuto)
+		convUTF8 = 0;
+	else if (Act == actCP1251)
+		convUTF8 = 1251;
+	else if (Act == actCP1252)
+		convUTF8 = 1252;
+	else if (Act == actCP437)
+		convUTF8 = 437;
+	else
+	{
+		// look for port entry
+		for (int i = 0; i < MAXPORTS + 1; i++)
+		{
+			if (Act == MonPort[i])
+			{
+				uint64_t mmask;
+
+				if (i == 0)							// BBS Mon - use bit 63 (Port 64)
+					mmask = (uint64_t)1 << 63;
+				else
+					mmask = (uint64_t)1 << (i - 1);
+
+				if (state)
+					ActiveSession->portmask |= mmask;
+				else
+					ActiveSession->portmask &= ~mmask;
+				break;
+			}
+		}
+	}
+
+
+	if (ActiveSession->clientSocket && ActiveSession->SessionType & Mon)
+		SendTraceOptions(ActiveSession);
+
+	else if (AGWUsers && ActiveSession == AGWUsers->MonSess)
+	{
+		AGWMonEnable = ActiveSession->EnableMonitor;
+		AGWLocalTime = ActiveSession->mlocaltime;
+		AGWMonNodes = ActiveSession->MonitorNODES;
+		Send_AGW_m_Frame((QTcpSocket*)ActiveSession->AGWSession);
+	}
+
+	else if (ActiveSession == KISSMonSess)
+	{
+		KISSLocalTime = ActiveSession->mlocaltime; 
+		KISSMonEnable = ActiveSession->EnableMonitor;
+		KISSMonNodes = ActiveSession->MonitorNODES;
+	}
+	return;
+}
+
+
+
+
+void QtTermTCP::LDisconnect(Ui_ListenSession * LUI)
+{
+	if (LUI->clientSocket)
+		LUI->clientSocket->disconnectFromHost();
+}
+
+extern QApplication * a;
+
+void QtTermTCP::LreturnPressed(Ui_ListenSession * Sess)
+{
+	QByteArray stringData = Sess->inputWindow->text().toUtf8();
+
+	// if multiline input (eg from copy/paste) replace LF with CR
+
+	char * ptr;
+	char * Msgptr;
+	char * Msg;
+
+	QScrollBar *scrollbar = Sess->termWindow->verticalScrollBar();
+	bool scrollbarAtBottom = (scrollbar->value() >= (scrollbar->maximum() - 4));
+
+	if (scrollbarAtBottom)
+		Sess->termWindow->moveCursor(QTextCursor::End);					// So we don't get blank lines
+
+	// Stack it
+
+	Sess->StackIndex = 0;
+
+	if (Sess->KbdStack[49])
+		free(Sess->KbdStack[49]);
+
+	for (int i = 48; i >= 0; i--)
+	{
+		Sess->KbdStack[i + 1] = Sess->KbdStack[i];
+	}
+
+	Sess->KbdStack[0] = qstrdup(stringData.data());
+
+	stringData.append('\n');
+
+	Msgptr = stringData.data();
+
+	if (Sess->TTActive)					// Teletext uses 0x5F for #
+		while ((ptr = strchr(Msgptr, 0x23)))	// Replace VT with LF
+			*ptr++ = 0x5f;
+
+
+	while ((ptr = strchr(Msgptr, 11)))	// Replace VT with LF
+		*ptr++ = 10;
+
+	LastWrite = time(NULL);				// Stop initial beep
+	Sess->SlowTimer = 0;
+
+	Sess->pageBuffer[0] = 0;			// Reset Teletext mode screen buffer
+
+	if (Sess->KISSMode == 1)
+	{
+		// UI session. Send as UI Message
+
+		while ((ptr = strchr(Msgptr, '\n')))
+		{
+			*ptr++ = 0;
+
+			Msg = (char *)malloc(strlen(Msgptr) + 10);
+			strcpy(Msg, Msgptr);
+			strcat(Msg, "\r");
+
+
+			Send_UI(Sess->UIPORT, 0xF0, KISSMYCALL, Sess->UIDEST, Sess->UIPATH, (unsigned char *)Msg, (int)strlen(Msg));
+
+			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
+
+			free(Msg);
+
+			Msgptr = ptr;
+		}
+	}
+	else if (Sess->KISSSession)
+	{
+		// Send to ax.25 code
+
+		while ((ptr = strchr(Msgptr, '\n')))
+		{
+			*ptr++ = 0;
+
+			Msg = (char *)malloc(strlen(Msgptr) + 10);
+			strcpy(Msg, Msgptr);
+			strcat(Msg, "\r");
+
+			SendtoAX25(Sess->KISSSession, (unsigned char *)Msg, (int)strlen(Msg));
+
+			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
+
+			free(Msg);
+
+			Msgptr = ptr;
+		}
+	}
+
+	else if (Sess->AGWSession)
+	{
+		// Terminal is in AGWPE mode - send as AGW frame
+
+		while ((ptr = strchr(Msgptr, '\n')))
+		{
+			*ptr++ = 0;
+
+			Msg = (char *)malloc(strlen(Msgptr) + 10);
+			strcpy(Msg, Msgptr);
+			strcat(Msg, "\r");
+
+			AGW_AX25_data_in(Sess->AGWSession, (unsigned char *)Msg, (int)strlen(Msg));
+
+			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
+
+//			Sess->termWindow->insertPlainText(Msg);
+
+			free(Msg);
+
+			Msgptr = ptr;
+		}
+	}
+
+	else if (VARASock && VARASock->Sess == Sess)
+	{
+		while ((ptr = strchr(Msgptr, '\n')))
+		{
+			*ptr++ = 0;
+
+			Msg = (char *)malloc(strlen(Msgptr) + 10);
+			strcpy(Msg, Msgptr);
+			strcat(Msg, "\r");
+
+			VARADataSock->write(Msg);
+
+			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
+
+//			Sess->termWindow->insertPlainText(Msg);
+
+			free(Msg);
+
+			Msgptr = ptr;
+		}
+	}
+
+	else if (Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState)
+	{
+		while ((ptr = strchr(Msgptr, '\n')))
+		{
+			*ptr++ = 0;
+
+			Msg = (char *)malloc(strlen(Msgptr) + 10);
+			strcpy(Msg, Msgptr);
+			strcat(Msg, "\r");
+
+			Sess->clientSocket->write(Msg);
+			Sess->clientSocket->flush();
+//			QThread::msleep(1500);			// Try to force as separate packets
+			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, EchoText);		// Black
+
+//			Sess->termWindow->insertPlainText(Msg);
+
+			free(Msg);
+
+			Msgptr = ptr;
+		}
+	}
+	else
+	{
+		// Not Connected 
+
+		if (Sess->SessionType != Listen)
+		{
+			if (Sess->CurrentHost < MAXHOSTS)
+			{
+				// Last connect was TCP
+
+				char Msg[] = "Connecting....\r";
+
+				WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+					Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
+
+				delete(Sess->clientSocket);
+
+				Sess->clientSocket = new myTcpSocket();
+				Sess->clientSocket->Sess = Sess;
+
+				connect(Sess->clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
+				connect(Sess->clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
+				connect(Sess->clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
+
+
+				// Set Monitor Params for this host
+
+				sscanf(MonParams[Sess->CurrentHost], "%llx %x %x %x %x %x",
+					&Sess->portmask, &Sess->mtxparam, &Sess->mcomparam,
+					&Sess->MonitorNODES, &Sess->MonitorColour, &Sess->monUI);
+
+				Sess->mlocaltime = (Sess->mtxparam >> 7);
+				Sess->mtxparam &= 1;
+
+				MonLocalTime->setChecked(Sess->mlocaltime);
+				MonTX->setChecked(Sess->mtxparam);
+				MonSup->setChecked(Sess->mcomparam);
+				MonUI->setChecked(Sess->monUI);
+				MonNodes->setChecked(Sess->MonitorNODES);
+				MonColour->setChecked(Sess->MonitorColour);
+
+				Sess->clientSocket->connectToHost(&Host[Sess->CurrentHost][0], Port[Sess->CurrentHost]);
+			}
+
+			else if (Sess->CurrentHost == 16)		// AGW
+			{
+				// Invoke AGW connect dialog 
+
+				AGWConnect dialog(0);
+				dialog.exec();
+
+				WritetoOutputWindow(Sess, (unsigned char *)"Connecting...\r", 14);
+				return;
+			}
+
+			else if (Sess->CurrentHost == 17)		// VARA
+			{
+				// Invoke VARA connect dialog 
+
+				VARAConnect dialog(0);
+				dialog.exec();
+
+				WritetoOutputWindow(Sess, (unsigned char *)"Connecting...\r", 14);
+				return;
+			}
+
+			else if (Sess->CurrentHost == 18)		// KISS
+			{
+				// Do we send as UI or invoke kiss connect dialog ??
+
+				// Try Connect Dialog for now - may make a menu option
+
+				KISSConnect dialog(0);
+				dialog.exec();
+
+				WritetoOutputWindow(Sess, (unsigned char *)"Connecting...\r", 14);
+				return;
+			}
+		}
+		else
+		{
+			char Msg[] = "Incoming Session - Can't Connect\r";
+
+			WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+				Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, 81);		// Red
+
+		}
+	}
+
+	if (scrollbarAtBottom)
+		Sess->termWindow->moveCursor(QTextCursor::End);
+
+	Sess->inputWindow->setText("");
+	a->inputMethod()->hide();
+}
+
+
+void QtTermTCP::displayError(QAbstractSocket::SocketError socketError)
+{
+	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
+
+	switch (socketError)
+	{
+	case QAbstractSocket::RemoteHostClosedError:
+		break;
+
+	case QAbstractSocket::HostNotFoundError:
+		QMessageBox::information(this, tr("QtTermTCP"),
+			tr("The host was not found. Please check the "
+				"host name and portsettings->"));
+		break;
+
+	case QAbstractSocket::ConnectionRefusedError:
+		QMessageBox::information(this, tr("QtTermTCP"),
+			tr("The connection was refused by the peer."));
+		break;
+
+	default:
+		QMessageBox::information(this, tr("QtTermTCP"),
+			tr("The following error occurred: %1.")
+			.arg(sender->errorString()));
+	}
+
+	connectMenu->setEnabled(true);
+}
+
+void QtTermTCP::readyRead()
+{
+	int Read;
+	unsigned char Buffer[8192];
+	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
+
+	Ui_ListenSession * Sess = (Ui_ListenSession *)Socket->Sess;
+
+	// read the data from the socket
+
+	Read = Socket->read((char *)Buffer, 2047);
+
+	while (Read > 0)
+	{
+		//		if (InputMode == 'Y')			// Yapp
+		//		{
+		//			QString myString = QString::fromUtf8((char*)Buffer, Read);
+		//			QByteArray ptr = myString.toLocal8Bit();
+		//			memcpy(Buffer, ptr.data(), ptr.length());
+		//			Read = ptr.length();
+		//		}
+
+			
+		Buffer[Read] = 0;
+
+		ProcessReceivedData(Sess, Buffer, Read);
+
+		QString myString = QString::fromUtf8((char*)Buffer);
+		//		qDebug() << myString;
+		Read = Socket->read((char *)Buffer, 2047);
+	}
+}
+
+extern "C" int SocketSend(Ui_ListenSession * Sess, char * Buffer, int len)
+{
+	myTcpSocket *Socket = Sess->clientSocket;
+
+	if (Socket && Socket->state() == QAbstractSocket::ConnectedState)
+		return Socket->write(Buffer, len);
+
+	return 0;
+}
+
+extern "C" int SocketFlush(Ui_ListenSession * Sess)
+{
+	if (Sess->AGWSession || Sess->KISSSession || (VARASock && VARASock->Sess == Sess))
+		return 0;
+
+	myTcpSocket* Socket = Sess->clientSocket;
+
+	if (Socket && Socket->state() == QAbstractSocket::ConnectedState)
+		return Socket->flush();
+
+	return 0;
+}
+
+extern "C" void mySleep(int ms)
+{
+	QThread::msleep(ms);
+}
+
+extern "C" void SetPortMonLine(int i, char * Text, int visible, int enabled)
+{
+	MonPort[i]->setText(Text);
+	MonPort[i]->setVisible(visible);
+	MonPort[i]->setChecked(enabled);
+}
+
+bool scrollbarAtBottom = 0;
+
+extern "C" void WritetoOutputWindowEx(Ui_ListenSession * Sess, unsigned char * Buffer, int len, QTextEdit * termWindow, int * OutputSaveLen, char * OutputSave, QColor Colour);
+
+extern "C" void WritetoOutputWindow(Ui_ListenSession * Sess, unsigned char * Buffer, int len)
+{
+	WritetoOutputWindowEx(Sess, Buffer, len, Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, outputText);
+}
+
+
+extern "C" void WritetoOutputWindowEx(Ui_ListenSession * Sess, unsigned char * Buffer, int len, QTextEdit * termWindow, int * OutputSaveLen, char * OutputSave, QColor Colour)
+{
+	unsigned char Copy[8192];
+	unsigned char * ptr1, *ptr2;
+	unsigned char Line[8192];
+	unsigned char out[8192];
+	int outlen;
+
+	int num;
+
+	if (termWindow == NULL)
+		return;
+
+	time_t NOW = time(NULL);
+
+	// Beep if no output for a while
+
+	if (AlertInterval && (NOW - LastWrite) > AlertInterval)
+	{
+		if (AlertBeep)
+			myBeep(&IntervalWAV);
+
+	}
+
+	// Alert if QtTerm not active window (unless Mon window)
+
+	if((Sess->SessionType & Mon) == 0)
+		FlashifNotActive();
+
+	// if tabbed and not active tab set tab label red
+
+	if (TermMode == Tabbed)
+	{
+		if (Sess->monWindow != termWindow)		// Not if Monitor
+		{
+			if (ActiveSession != Sess)
+			{
+				tabWidget->tabBar()->setTabTextColor(Sess->Tab, newTabText);
+			}
+		}
+	}
+
+	LastWrite = NOW;
+
+	// Mustn't mess with original buffer
+
+	memcpy(Copy, Buffer, len);
+
+	Copy[len] = 0;
+
+	ptr1 = Copy;
+
+	const QTextCursor old_cursor = termWindow->textCursor();
+	const int old_scrollbar_value = termWindow->verticalScrollBar()->value();
+	const bool is_scrolled_down = old_scrollbar_value == termWindow->verticalScrollBar()->maximum();
+
+	if (*OutputSaveLen)
+	{
+		// Have part line - append to it
+		memcpy(&OutputSave[*OutputSaveLen], Copy, len);
+		*OutputSaveLen += len;
+		ptr1 = (unsigned char *)OutputSave;
+		len = *OutputSaveLen;
+		*OutputSaveLen = 0;
+
+		// part line was written to screen so remove it
+
+//		termWindow->setFocus();
+		termWindow->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
+		termWindow->moveCursor(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
+		termWindow->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor);
+		termWindow->textCursor().removeSelectedText();
+		//		termWindow->textCursor().deletePreviousChar();
+	}
+
+	// Move the cursor to the end of the document.
+
+	termWindow->moveCursor(QTextCursor::End);
+
+	// Insert the text at the position of the cursor (which is the end of the document).
+
+lineloop:
+
+	if (len <= 0)
+	{
+		if (old_cursor.hasSelection() || !is_scrolled_down)
+		{
+			// The user has selected text or scrolled away from the bottom: maintain position.
+			termWindow->setTextCursor(old_cursor);
+			termWindow->verticalScrollBar()->setValue(old_scrollbar_value);
+		}
+		else
+		{
+			// The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom.
+			termWindow->moveCursor(QTextCursor::End);
+			termWindow->verticalScrollBar()->setValue(termWindow->verticalScrollBar()->maximum());
+		}
+
+		return;
+	}
+
+
+	//	copy text to control a line at a time	
+
+	ptr2 = (unsigned char *)memchr(ptr1, 13, len);
+
+	if (ptr2 == 0)	// No CR
+	{
+		if (len > 8000)
+			len = 8000;			// Should never get lines this long
+
+		memmove(OutputSave, ptr1, len);
+		*OutputSaveLen = len;
+
+		// Write part line to screen
+
+		memcpy(Line, ptr1, len);
+		Line[len] = 0;
+
+		// I don't think I need to worry if UTF8 as will be rewritten when rest arrives
+
+		if (Line[0] == 0x1b)			// Colour Escape
+		{
+			if (Sess->MonitorColour)
+				termWindow->setTextColor(Colours[Line[1] - 10]);
+
+			termWindow->textCursor().insertText(QString::fromUtf8((char*)&Line[2]));
+		}
+		else
+		{
+			termWindow->setTextColor(Colour);
+			termWindow->textCursor().insertText(QString::fromUtf8((char*)Line));
+		}
+
+		//		*OutputSaveLen = 0;		// Test if we need to delete part line
+
+		//		if (scrollbarAtBottom)
+		//			termWindow->moveCursor(QTextCursor::End);
+
+		if (old_cursor.hasSelection() || !is_scrolled_down)
+		{
+			// The user has selected text or scrolled away from the bottom: maintain position.
+			termWindow->setTextCursor(old_cursor);
+			termWindow->verticalScrollBar()->setValue(old_scrollbar_value);
+		}
+		else
+		{
+			// The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom.
+			termWindow->moveCursor(QTextCursor::End);
+			termWindow->verticalScrollBar()->setValue(termWindow->verticalScrollBar()->maximum());
+		}
+		return;
+	}
+
+	*(ptr2++) = 0;
+
+	if (Bells)
+	{
+		char * ptr;
+
+		do {
+			ptr = (char *)memchr(ptr1, 7, len);
+
+			if (ptr)
+			{
+				*(ptr) = 32;
+				myBeep(&BellWAV);
+			}
+		} while (ptr);
+	}
+
+	num = ptr2 - ptr1 - 1;
+
+	//		if (LogMonitor) WriteMonitorLine(ptr1, ptr2 - ptr1);
+
+	memcpy(Line, ptr1, num);
+	Line[num++] = 13;
+	Line[num] = 0;
+
+	if (Line[0] == 0x1b)			// Colour Escape
+	{
+		if (Sess->MonitorColour)
+			termWindow->setTextColor(Colours[Line[1] - 10]);
+
+		outlen = checkUTF8(&Line[2], num - 2, out);
+		out[outlen] = 0;
+		termWindow->textCursor().insertText(QString::fromUtf8((char*)out));
+		//		termWindow->textCursor().insertText(QString::fromUtf8((char*)&Line[2]));
+	}
+	else
+	{
+		termWindow->setTextColor(Colour);
+
+		outlen = checkUTF8(Line, num, out);
+		out[outlen] = 0;
+		termWindow->textCursor().insertText(QString::fromUtf8((char*)out));
+		//		termWindow->textCursor().insertText(QString::fromUtf8((char*)Line));
+	}
+
+	len -= (ptr2 - ptr1);
+
+	ptr1 = ptr2;
+
+	if ((len > 0) && StripLF)
+	{
+		if (*ptr1 == 0x0a)					// Line Feed
+		{
+			ptr1++;
+			len--;
+		}
+	}
+
+
+
+	goto lineloop;
+
+}
+
+void WriteMonitorLog(Ui_ListenSession * Sess, char * Msg);
+
+extern "C" void WritetoMonWindow(Ui_ListenSession * Sess, unsigned char * Msg, int len)
+{
+	char * ptr1 = (char *)Msg, *ptr2;
+	char Line[512];
+	int num;
+
+	//	QScrollBar *scrollbar = Sess->monWindow->verticalScrollBar();
+	//	bool scrollbarAtBottom = (scrollbar->value() >= (scrollbar->maximum() - 4));
+
+	if (Sess->monWindow == nullptr)
+		return;
+
+	Sess->monWindow->setStyleSheet(monStyleSheet);
+
+	const QTextCursor old_cursor = Sess->monWindow->textCursor();
+	const int old_scrollbar_value = Sess->monWindow->verticalScrollBar()->value();
+	const bool is_scrolled_down = old_scrollbar_value == Sess->monWindow->verticalScrollBar()->maximum();
+
+	// Move the cursor to the end of the document.
+	Sess->monWindow->moveCursor(QTextCursor::End);
+
+	// Insert the text at the position of the cursor (which is the end of the document).
+
+
+	// Write a line at a time so we can action colour chars
+
+//		Buffer[Len] = 0;
+
+//	if (scrollbarAtBottom)
+//		Sess->monWindow->moveCursor(QTextCursor::End);
+
+	if (Sess->MonSaveLen)
+	{
+		// Have part line - append to it
+		memcpy(&Sess->MonSave[Sess->MonSaveLen], Msg, len);
+		Sess->MonSaveLen += len;
+		ptr1 = Sess->MonSave;
+		len = Sess->MonSaveLen;
+		Sess->MonSaveLen = 0;
+	}
+
+lineloop:
+
+	if (len <= 0)
+	{
+		//		if (scrollbarAtBottom)
+		//			Sess->monWindow->moveCursor(QTextCursor::End);
+
+
+		if (old_cursor.hasSelection() || !is_scrolled_down)
+		{
+			// The user has selected text or scrolled away from the bottom: maintain position.
+			Sess->monWindow->setTextCursor(old_cursor);
+			Sess->monWindow->verticalScrollBar()->setValue(old_scrollbar_value);
+		}
+		else
+		{
+			// The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom.
+			Sess->monWindow->moveCursor(QTextCursor::End);
+			Sess->monWindow->verticalScrollBar()->setValue(Sess->monWindow->verticalScrollBar()->maximum());
+		}
+
+		return;
+	}
+
+	//	copy text to control a line at a time	
+
+	ptr2 = (char *)memchr(ptr1, 13, len);
+
+	if (ptr2 == 0)	// No CR
+	{
+		memmove(Sess->MonSave, ptr1, len);
+		Sess->MonSaveLen = len;
+		return;
+	}
+
+	*(ptr2++) = 0;
+
+	
+	if (Sess->LogMonitor)
+		WriteMonitorLog(Sess, ptr1);
+
+	num = ptr2 - ptr1 - 1;
+
+	memcpy(Line, ptr1, num);
+	Line[num++] = 13;
+	Line[num] = 0;
+
+	if (Line[0] == 0x1b)			// Colour Escape
+	{
+		if (Sess->MonitorColour)
+		{
+			if (Line[1] == 17)
+				Sess->monWindow->setTextColor(monRxText);
+			else
+				Sess->monWindow->setTextColor(monTxText);
+		}
+		else
+			Sess->monWindow->setTextColor(monOtherText);
+
+		Sess->monWindow->textCursor().insertText(QString::fromUtf8((char*)&Line[2]));
+	}
+	else
+	{
+		Sess->monWindow->textCursor().insertText(QString::fromUtf8((char*)Line));
+	}
+	len -= (ptr2 - ptr1);
+
+	ptr1 = ptr2;
+
+	goto lineloop;
+
+}
+
+int ProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len);
+void QueueMsg(Ui_ListenSession * Sess, char * Msg, int Len);
+
+// YAPP stuff
+
+#define SOH 1
+#define STX 2
+#define ETX 3
+#define EOT 4
+#define ENQ 5
+#define ACK 6
+#define DLE	0x10
+#define NAK 0x15
+#define CAN 0x18
+
+extern "C" void SendtoTerm(Ui_ListenSession * Sess, char * Msg, int Len)
+{
+	if (Sess == 0)
+		return;
+	
+	Sess->SlowTimer = 0;
+	Msg[Len] = 0;
+
+	if (Sess->InputMode == 'Y')			// Yapp
+	{
+		ProcessYAPPMessage(Sess, (unsigned char *)Msg, Len);
+		return;
+	}
+
+	// Could be a YAPP Header
+
+	if (Len == 2 && Msg[0] == ENQ && Msg[1] == 1)		// YAPP Send_Init
+	{
+		char YAPPRR[2];
+
+		// Turn off monitoring
+
+		Sess->InputMode = 'Y';
+
+		YAPPRR[0] = ACK;
+		YAPPRR[1] = 1;
+		QueueMsg(Sess, YAPPRR, 2);
+
+		return;
+	}
+
+	if (AutoTeletext && (Msg[0] == 0x1e || Msg[0] == 0x0c))
+	{
+		if (Sess->TTActive == 0)
+		{
+			Sess->TTActive = 1;
+			DoTermResize(Sess);
+		}
+	}
+
+	if (Sess->TTActive)
+	{
+		// Feed to Teletext code
+
+		// We need to decode a whole page. There is no obvious delimiter so process till data stops.
+		// Buffer is cleared when next input is sent
+
+		if (strlen(&Sess->pageBuffer[0] + Len) > 4090)
+			Sess->pageBuffer[0] = 0;							// Protect buffer
+
+		strcat(Sess->pageBuffer, (char *)Msg);
+
+		DecodeTeleText(Sess, (char *)Sess->pageBuffer);			// Re-decode same data until we get the end
+		return;
+	}
+
+	WritetoOutputWindow(Sess, (unsigned char *)Msg, Len);
+
+}
+
+QSettings* settings;
+
+// This makes geting settings for more channels easier
+
+char Prefix[16] = "AX25_A";
+
+void GetPortSettings(int Chan);
+
+QVariant getAX25Param(const char * key, QVariant Default)
+{
+	char fullKey[64];
+
+	sprintf(fullKey, "%s/%s", Prefix, key);
+	return settings->value(fullKey, Default);
+}
+
+void getAX25Params(int chan)
+{
+	Prefix[5] = chan + 'A';
+	GetPortSettings(chan);
+}
+
+
+void GetPortSettings(int Chan)
+{
+	txdelay[Chan] = getAX25Param("TXDelay", 250).toInt();
+	sendTXDelay[Chan] = getAX25Param("sendTXDelay", 0).toInt();
+	maxframe[Chan] = getAX25Param("Maxframe", 4).toInt();
+	fracks[Chan] = getAX25Param("Retries", 10).toInt();
+	frack_time[Chan] = getAX25Param("FrackTime", 8).toInt();
+	persist[Chan] = getAX25Param("Persist", 128).toInt();
+	kisspaclen[Chan] = getAX25Param("Paclen", 128).toInt();
+	idletime[Chan] = getAX25Param("IdleTime", 180).toInt();
+	slottime[Chan] = getAX25Param("SlotTime", 100).toInt();
+	resptime[Chan] = getAX25Param("RespTime", 1500).toInt();
+	TXFrmMode[Chan] = getAX25Param("TXFrmMode", 1).toInt();
+	max_frame_collector[Chan] = getAX25Param("FrameCollector", 6).toInt();
+	//exclude_callsigns[Chan]= getAX25Param("ExcludeCallsigns/");
+	//exclude_APRS_frm[Chan]= getAX25Param("ExcludeAPRSFrmType/");
+	KISS_opt[Chan] = getAX25Param("KISSOptimization", false).toInt();;
+	dyn_frack[Chan] = getAX25Param("DynamicFrack", false).toInt();;
+	IPOLL[Chan] = getAX25Param("IPOLL", 80).toInt();
+
+}
+
+
+void GetSettings()
+{
+	QByteArray qb;
+	int i;
+	char Key[16];
+	char Param[256];
+
+	settings = new QSettings(GetConfPath(), QSettings::IniFormat);
+
+	// Get saved session definitions
+
+	sessionList = strdup(settings->value("Sessions", "1|3, 0, 5, 5, 600, 800|").toString().toUtf8());
+
+	for (i = 0; i < MAXHOSTS; i++)
+	{
+		sprintf(Key, "HostParams%d", i);
+
+		qb = settings->value(Key).toByteArray();
+
+		DecodeSettingsLine(i, qb.data());
+	}
+
+	Split = settings->value("Split", 50).toInt();
+	ChatMode = settings->value("ChatMode", 1).toInt();
+	AutoTeletext = settings->value("AutoTeletext", 0).toInt();
+	Bells = settings->value("Bells", 1).toInt();
+	StripLF = settings->value("StripLF", 1).toInt();
+	useBeep = settings->value("useBeep", true).toBool();
+	AlertBeep = settings->value("AlertBeep", 1).toInt();
+	AlertInterval = settings->value("AlertInterval", 300).toInt();
+	ConnectBeep = settings->value("ConnectBeep", 1).toInt();
+	ConnectWAV = settings->value("ConnectWAV", ":/PCBeep").toString().toUtf8();
+	AlertWAV = settings->value("AlertWAV", ":/PCBeep").toString().toUtf8();
+	BellWAV = settings->value("BellWAV", ":/PCBeep").toString().toUtf8();
+	IntervalWAV = settings->value("IntervalWAV", ":/PCBeep").toString().toUtf8();
+
+	UseKeywords = settings->value("UseKeywords", 0).toInt();
+	KeyWordsFile = settings->value("KeyWordsFile", "keywords.sys").toString().toUtf8();
+
+	SavedHost = settings->value("CurrentHost", 0).toInt();
+	strcpy(YAPPPath, settings->value("YAPPPath", "").toString().toUtf8());
+	MaxRXSize = settings->value("MaxRXSize", 100000).toInt();
+
+	listenPort = settings->value("listenPort", 8015).toInt();
+	listenEnable = settings->value("listenEnable", false).toBool();
+	strcpy(listenCText, settings->value("listenCText", "").toString().toUtf8());
+
+	TermMode = settings->value("TermMode", 0).toInt();
+	singlemodeFormat = settings->value("singlemodeFormat", Term + Mon).toInt();
+
+	AGWEnable = settings->value("AGWEnable", 0).toInt();
+	AGWMonEnable = settings->value("AGWMonEnable", 0).toInt();
+	AGWLocalTime = settings->value("AGWLocalTime", 0).toInt();
+	AGWMonNodes = settings->value("AGWMonNodes", 0).toInt();
+	strcpy(AGWTermCall, settings->value("AGWTermCall", "").toString().toUtf8());
+	strcpy(AGWBeaconDest, settings->value("AGWBeaconDest", "").toString().toUtf8());
+	strcpy(AGWBeaconPath, settings->value("AGWBeaconPath", "").toString().toUtf8());
+	AGWBeaconInterval = settings->value("AGWBeaconInterval", 0).toInt();
+	strcpy(AGWBeaconPorts, settings->value("AGWBeaconPorts", "").toString().toUtf8());
+	strcpy(AGWBeaconMsg, settings->value("AGWBeaconText", "").toString().toUtf8());
+	strcpy(AGWHost, settings->value("AGWHost", "127.0.0.1").toString().toUtf8());
+	AGWPortNum = settings->value("AGWPort", 8000).toInt();
+	AGWPaclen = settings->value("AGWPaclen", 80).toInt();
+	AGWToCalls = settings->value("AGWToCalls", "").toStringList();
+	convUTF8 = settings->value("convUTF8", 0).toInt();
+
+	KISSEnable = settings->value("KISSEnable", 0).toInt();
+	KISSMonEnable = settings->value("KISSMonEnable", 1).toInt();
+	KISSLocalTime = settings->value("KISSLocalTime", 0).toInt();
+	KISSMonNodes = settings->value("KISSMonNodes", 0).toInt();
+
+	KISSListen = settings->value("KISSListen", 1).toInt();
+	KISSChecksum = settings->value("KISSChecksum", 0).toInt();
+	KISSAckMode = settings->value("KISSAckMode", 0).toInt();
+	KISSMH = settings->value("KISSMH", 1).toInt();
+	strcpy(KISSMYCALL, settings->value("MYCALL", "").toString().toUtf8());
+	strcpy(KISSHost, settings->value("KISSHost", "127.0.0.1").toString().toUtf8());
+	KISSPortNum = settings->value("KISSPort", 8100).toInt();
+	KISSMode = settings->value("KISSMode", 0).toInt();
+	strcpy(KISSVia, settings->value("KISSVia", "").toString().toUtf8());
+
+	strcpy(SerialPort, settings->value("KISSSerialPort", "None").toString().toUtf8());
+	KISSBAUD = settings->value("KISSBAUD", 19200).toInt();
+	getAX25Params(0);
+
+	VARAEnable = settings->value("VARAEnable", 0).toInt();
+	strcpy(VARAHost, settings->value("VARAHost", "127.0.0.1").toString().toUtf8());
+	strcpy(VARAHostFM, settings->value("VARAHostFM", "127.0.0.1").toString().toUtf8());
+	strcpy(VARAHostHF, settings->value("VARAHostHF", "127.0.0.1").toString().toUtf8());
+	strcpy(VARAHostSAT, settings->value("VARAHostSAT", "127.0.0.1").toString().toUtf8());
+	VARAPortNum = settings->value("VARAPort", 8300).toInt();
+	VARAPortHF = settings->value("VARAPortHF", 8300).toInt();
+	VARAPortFM = settings->value("VARAPortFM", 8300).toInt();
+	VARAPortSAT = settings->value("VARAPortSAT", 8300).toInt();
+	strcpy(VARAPath, settings->value("VARAPath", "C:\\VARA\\VARA.exe").toString().toUtf8());
+	strcpy(VARAPathHF, settings->value("VARAPathHF", "C:\\VARA\\VARA.exe").toString().toUtf8());
+	strcpy(VARAPathFM, settings->value("VARAPathFM", "C:\\VARA\\VARAFM.exe").toString().toUtf8());
+	strcpy(VARAPathSAT, settings->value("VARAPathSAT", "C:\\VARA\\VARASAT.exe").toString().toUtf8());
+	strcpy(VARATermCall, settings->value("VARATermCall", "").toString().toUtf8());
+	VARA500 = settings->value("VARA500", 0).toInt();
+	VARA2300 = settings->value("VARA2300", 1).toInt();
+	VARA2750 = settings->value("VARA2750", 0).toInt();
+	VARAHF = settings->value("VARAHF", 1).toInt();
+	VARAFM = settings->value("VARAFM", 0).toInt();
+	VARASAT = settings->value("VARASAT", 0).toInt();
+	strcpy(VARAInit, settings->value("VARAInit", "").toString().toUtf8());
+
+	strcpy(PTTPort, settings->value("PTT", "None").toString().toUtf8());
+	PTTMode = settings->value("PTTMode", 19200).toInt();
+	PTTBAUD = settings->value("PTTBAUD", 19200).toInt();
+	CATHex = settings->value("CATHex", 1).toInt();
+
+	strcpy(PTTOnString, settings->value("PTTOnString", "").toString().toUtf8());
+	strcpy(PTTOffString, settings->value("PTTOffString", "").toString().toUtf8());
+
+	pttGPIOPin = settings->value("pttGPIOPin", 17).toInt();
+	pttGPIOPinR = settings->value("pttGPIOPinR", 17).toInt();
+
+#ifdef WIN32
+	strcpy(CM108Addr, settings->value("CM108Addr", "0xD8C:0x08").toString().toUtf8());
+#else
+	strcpy(CM108Addr, settings->value("CM108Addr", "/dev/hidraw0").toString().toUtf8());
+#endif
+
+	HamLibPort = settings->value("HamLibPort", 4532).toInt();
+	strcpy(HamLibHost, settings->value("HamLibHost", "127.0.0.1").toString().toUtf8());
+
+	FLRigPort = settings->value("FLRigPort", 12345).toInt();
+	strcpy(FLRigHost, settings->value("FLRigHost", "127.0.0.1").toString().toUtf8());
+
+
+	strcpy(Param, settings->value("TabType", "1 1 1 1 1 1 1 2 2").toString().toUtf8());
+	sscanf(Param, "%d %d %d %d %d %d %d %d %d %d",
+		&TabType[0], &TabType[1], &TabType[2], &TabType[3], &TabType[4],
+		&TabType[5], &TabType[6], &TabType[7], &TabType[8], &TabType[9]);
+
+	strcpy(Param, settings->value("AutoConnect", "0, 0 ,0, 0, 0, 0, 0, 0, 0, 0").toString().toUtf8());
+	sscanf(Param, "%d %d %d %d %d %d %d %d %d %d",
+		&AutoConnect[0], &AutoConnect[1], &AutoConnect[2], &AutoConnect[3], &AutoConnect[4],
+		&AutoConnect[5], &AutoConnect[6], &AutoConnect[7], &AutoConnect[8], &AutoConnect[9]);
+
+	strcpy(Param, settings->value("currentHost", "0, 0 ,0, 0, 0, 0, 0, 0, 0, 0").toString().toUtf8());
+	sscanf(Param, "%d %d %d %d %d %d %d %d %d %d",
+		&currentHost[0], &currentHost[1], &currentHost[2], &currentHost[3], &currentHost[4],
+		&currentHost[5], &currentHost[6], &currentHost[7], &currentHost[8], &currentHost[9]);
+
+
+	monBackground = settings->value("monBackground", QColor(255, 255, 255)).value<QColor>();
+	monRxText = settings->value("monRxText", QColor(0, 0, 255)).value<QColor>();
+	monTxText = settings->value("monTxText", QColor(255, 0, 0)).value<QColor>();
+	monOtherText = settings->value("monOtherText", QColor(0, 0, 0)).value<QColor>();
+
+	termBackground = settings->value("termBackground", QColor(255, 255, 255)).value<QColor>();
+	outputText = settings->value("outputText", QColor(0, 0, 255)).value<QColor>();
+	EchoText = settings->value("EchoText", QColor(0, 0, 0)).value<QColor>();
+	WarningText = settings->value("WarningText", QColor(255, 0, 0)).value<QColor>();
+
+	inputBackground = settings->value("inputBackground", QColor(255, 255, 255)).value<QColor>();
+	inputText = settings->value("inputText", QColor(0, 0, 0)).value<QColor>();
+
+	delete(settings);
+}
+
+void SavePortSettings(int Chan);
+
+void saveAX25Param(const char * key, QVariant Value)
+{
+	char fullKey[64];
+
+	sprintf(fullKey, "%s/%s", Prefix, key);
+
+	settings->setValue(fullKey, Value);
+}
+
+void saveAX25Params(int chan)
+{
+	Prefix[5] = chan + 'A';
+	SavePortSettings(chan);
+}
+
+void SavePortSettings(int Chan)
+{
+	saveAX25Param("TXDelay", txdelay[Chan]);
+	saveAX25Param("sendTXDelay", sendTXDelay[Chan]);
+	saveAX25Param("Maxframe", maxframe[Chan]);
+	saveAX25Param("Paclen", kisspaclen[Chan]);
+	saveAX25Param("FrackTime", frack_time[Chan]);
+	saveAX25Param("IdleTime", idletime[Chan]);
+	saveAX25Param("SlotTime", slottime[Chan]);
+	saveAX25Param("Persist", persist[Chan]);
+	saveAX25Param("RespTime", resptime[Chan]);
+	saveAX25Param("TXFrmMode", TXFrmMode[Chan]);
+	saveAX25Param("FrameCollector", max_frame_collector[Chan]);
+	saveAX25Param("ExcludeCallsigns", exclude_callsigns[Chan]);
+	saveAX25Param("ExcludeAPRSFrmType", exclude_APRS_frm[Chan]);
+	saveAX25Param("KISSOptimization", KISS_opt[Chan]);
+	saveAX25Param("DynamicFrack", dyn_frack[Chan]);
+	saveAX25Param("BitRecovery", recovery[Chan]);
+	saveAX25Param("IPOLL", IPOLL[Chan]);
+	saveAX25Param("MyDigiCall", MyDigiCall[Chan]);
+}
+
+extern "C" void SaveSettings()
+{
+	int i;
+	char Param[512];
+	char Key[16];
+
+	settings = new QSettings(GetConfPath(), QSettings::IniFormat);
+
+	for (i = 0; i < MAXHOSTS; i++)
+	{
+		sprintf(Key, "HostParams%d", i);
+		EncodeSettingsLine(i, Param);
+		settings->setValue(Key, Param);
+	}
+
+	settings->setValue("Split", Split);
+	settings->setValue("ChatMode", ChatMode);
+	settings->setValue("AutoTeletext", AutoTeletext);
+	settings->setValue("Bells", Bells);
+	settings->setValue("StripLF", StripLF);
+	settings->setValue("AlertBeep", AlertBeep);
+	settings->setValue("useBeep", useBeep);
+	settings->setValue("ConnectBeep", ConnectBeep);
+	settings->setValue("BellWAV", BellWAV);
+	settings->setValue("AlertWAV", AlertWAV);
+	settings->setValue("IntervalWAV", IntervalWAV);
+	settings->setValue("ConnectWAV", ConnectWAV);
+
+	settings->setValue("UseKeywords", UseKeywords);
+	settings->setValue("KeyWordsFile", KeyWordsFile);
+
+	settings->setValue("AlertInterval", AlertInterval);
+	settings->setValue("CurrentHost", SavedHost);
+
+	settings->setValue("YAPPPath", YAPPPath);
+	settings->setValue("MaxRXSize", MaxRXSize);
+
+	settings->setValue("listenPort", listenPort);
+	settings->setValue("listenEnable", listenEnable);
+	settings->setValue("listenCText", listenCText);
+	settings->setValue("convUTF8", convUTF8);
+
+	settings->setValue("PTT", PTTPort);
+	settings->setValue("PTTBAUD", PTTBAUD);
+	settings->setValue("PTTMode", PTTMode);
+
+	settings->setValue("CATHex", CATHex);
+
+	settings->setValue("PTTOffString", PTTOffString);
+	settings->setValue("PTTOnString", PTTOnString);
+
+	settings->setValue("pttGPIOPin", pttGPIOPin);
+	settings->setValue("pttGPIOPinR", pttGPIOPinR);
+
+	settings->setValue("CM108Addr", CM108Addr);
+	settings->setValue("HamLibPort", HamLibPort);
+	settings->setValue("HamLibHost", HamLibHost);
+	settings->setValue("FLRigPort", FLRigPort);
+	settings->setValue("FLRigHost", FLRigHost);
+
+
+	// Save Sessions
+
+	char SessionString[1024];
+	int SessStringLen;
+
+	SessStringLen = sprintf(SessionString, "%d|", _sessions.size());
+
+	if (TermMode == MDI)
+	{
+		for (int i = 0; i < _sessions.size(); ++i)
+		{
+			Ui_ListenSession * Sess = _sessions.at(i);
+
+			QRect r = Sess->sw->geometry();
+
+			SessStringLen += sprintf(&SessionString[SessStringLen],
+				"%d, %d, %d, %d, %d, %d|", Sess->SessionType, Sess->CurrentHost, r.top(), r.left(), r.bottom(), r.right());
+		}
+
+		settings->setValue("Sessions", SessionString);
+	}
+
+	settings->setValue("AGWEnable", AGWEnable);
+	settings->setValue("AGWMonEnable", AGWMonEnable);
+	settings->setValue("AGWLocalTime", AGWLocalTime);
+	settings->setValue("AGWMonNodes", AGWMonNodes);
+	settings->setValue("AGWTermCall", AGWTermCall);
+	settings->setValue("AGWBeaconDest", AGWBeaconDest);
+	settings->setValue("AGWBeaconPath", AGWBeaconPath);
+	settings->setValue("AGWBeaconInterval", AGWBeaconInterval);
+	settings->setValue("AGWBeaconPorts", AGWBeaconPorts);
+	settings->setValue("AGWBeaconText", AGWBeaconMsg);
+	settings->setValue("AGWHost", AGWHost);
+	settings->setValue("AGWPort", AGWPortNum);
+	settings->setValue("AGWPaclen", AGWPaclen);
+	settings->setValue("AGWToCalls", AGWToCalls);
+
+	settings->setValue("KISSEnable", KISSEnable);
+	settings->setValue("KISSMonEnable", KISSMonEnable);
+	settings->setValue("KISSLocalTime", KISSLocalTime);
+	settings->setValue("KISSMonNodes", KISSMonNodes);
+
+	settings->setValue("KISSListen", KISSListen);
+	settings->setValue("KISSChecksum", KISSChecksum);
+	settings->setValue("KISSAckMode", KISSAckMode);
+	settings->setValue("KISSMH", KISSMH);
+	settings->setValue("MYCALL", KISSMYCALL);
+	settings->setValue("KISSHost", KISSHost);
+	settings->setValue("KISSMode", KISSMode);
+	settings->setValue("KISSPort", KISSPortNum);
+	settings->setValue("KISSSerialPort", SerialPort);
+	settings->setValue("KISSBAUD", KISSBAUD);
+	settings->setValue("KISSVia", KISSVia);
+
+	saveAX25Params(0);
+
+	settings->setValue("VARAEnable", VARAEnable);
+	settings->setValue("VARATermCall", VARATermCall);
+	settings->setValue("VARAHost", VARAHost);
+	settings->setValue("VARAPort", VARAPortNum);
+	settings->setValue("VARAInit", VARAInit);
+	settings->setValue("VARAPath", VARAPath);
+	settings->setValue("VARAHostHF", VARAHostHF);
+	settings->setValue("VARAPortHF", VARAPortHF);
+	settings->setValue("VARAPathHF", VARAPathHF);
+	settings->setValue("VARAHostFM", VARAHostFM);
+	settings->setValue("VARAPortFM", VARAPortFM);
+	settings->setValue("VARAPathFM", VARAPathFM);
+	settings->setValue("VARAHostSAT", VARAHostSAT);
+	settings->setValue("VARAPortSAT", VARAPortSAT);
+	settings->setValue("VARAPathSAT", VARAPathSAT);
+	settings->setValue("VARA500", VARA500);
+	settings->setValue("VARA2300", VARA2300);
+	settings->setValue("VARA2750", VARA2750);
+	settings->setValue("VARAHF", VARAHF);
+	settings->setValue("VARAFM", VARAFM);
+	settings->setValue("VARASAT", VARASAT);
+
+	sprintf(Param, "%d %d %d %d %d %d %d %d %d %d",
+		TabType[0], TabType[1], TabType[2], TabType[3], TabType[4], TabType[5], TabType[6], TabType[7], TabType[8], TabType[9]);
+
+	settings->setValue("TabType", Param);
+
+	sprintf(Param, "%d %d %d %d %d %d %d %d %d %d",
+		AutoConnect[0], AutoConnect[1], AutoConnect[2], AutoConnect[3], AutoConnect[4], AutoConnect[5], AutoConnect[6], AutoConnect[7], AutoConnect[8], AutoConnect[9]);
+
+	settings->setValue("AutoConnect", Param);
+
+	sprintf(Param, "%d %d %d %d %d %d %d %d %d %d",
+		currentHost[0], currentHost[1], currentHost[2], currentHost[3], currentHost[4], currentHost[5], currentHost[6], currentHost[7], currentHost[8], currentHost[9]);
+
+	settings->setValue("currentHost", Param);
+
+	settings->setValue("monBackground", monBackground);
+	settings->setValue("monRxText", monRxText);
+	settings->setValue("monTxText", monTxText);
+	settings->setValue("monOtherText", monOtherText);
+
+	settings->setValue("termBackground", termBackground);
+	settings->setValue("outputText", outputText);
+	settings->setValue("EchoText", EchoText);
+	settings->setValue("WarningText", WarningText);
+
+	settings->setValue("inputBackground", inputBackground);
+	settings->setValue("inputText", inputText);
+
+	settings->sync();
+	delete(settings);
+}
+
+#include <QCloseEvent>
+
+void QtTermTCP::closeEvent(QCloseEvent *event)
+{
+	QMessageBox::StandardButton resBtn = QMessageBox::question(this, "QtTermTCP",
+		tr("Are you sure?\n"),
+		QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes,
+		QMessageBox::Yes);
+	if (resBtn != QMessageBox::Yes) {
+		event->ignore();
+	}
+	else
+	{
+		event->accept();
+#ifdef USESERIAL
+		if (hPTTDevice)
+			hPTTDevice->close();
+#endif
+		if (process)
+			process->close();
+
+		if (MHWindow)
+			MHWindow->close();
+
+	}
+}
+
+QtTermTCP::~QtTermTCP()
+{
+	Ui_ListenSession * Sess;
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		if (Sess->monLogfile)
+			Sess->monLogfile->close();
+
+		if (Sess->clientSocket)
+		{
+			int loops = 100;
+			Sess->clientSocket->disconnectFromHost();
+			while (Sess->clientSocket && loops-- && Sess->clientSocket->state() != QAbstractSocket::UnconnectedState)
+				QThread::msleep(10);
+		}
+	}
+
+	if (AGWSock && AGWSock->ConnectedState == QAbstractSocket::ConnectedState)
+	{
+		int loops = 100;
+		AGWSock->disconnectFromHost();
+		QThread::msleep(10);
+		while (AGWSock && loops-- && AGWSock->state() != QAbstractSocket::UnconnectedState)
+			QThread::msleep(10);
+	}
+
+	if (_server->isListening())
+		_server->close();
+
+	delete(_server);
+
+	QSettings mysettings(GetConfPath(), QSettings::IniFormat);
+	mysettings.setValue("geometry", saveGeometry());
+	mysettings.setValue("windowState", saveState());
+
+	if (MHWindow)
+	{
+		mysettings.setValue("MHgeometry", MHWindow->saveGeometry());
+		MHWindow->close();
+	}
+	SaveSettings();
+}
+
+extern "C" void timer_event();
+
+void QtTermTCP::KISSTimerSlot()
+{
+	// Runs every 100 mS
+
+	timer_event();
+}
+
+void QtTermTCP::MyTimerSlot()
+{
+	// Runs every 10 seconds
+
+	Ui_ListenSession * Sess;
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		//	for (Ui_ListenSession * Sess : _sessions)
+		//	{
+		if (Sess == NULL)
+			continue;
+
+		if (!ChatMode)
+			continue;
+
+		if (Sess->KISSSession ||
+			(Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState))
+		{
+			Sess->SlowTimer++;
+
+			if (Sess->SlowTimer > 54)				// About 9 mins
+			{
+				unsigned char Msg[2] = "";
+
+				Sess->SlowTimer = 0;
+
+				if (Sess->KISSSession)
+				{
+					TAX25Port * ax25 = (TAX25Port *)Sess->KISSSession;
+
+					if (ax25->status == STAT_LINK)
+						SendtoAX25(Sess->KISSSession, Msg, 1);
+				}
+				else
+					Sess->clientSocket->write("\0", 1);
+			}
+		}
+	}
+
+	if (AGWEnable)
+		AGWTimer();
+
+	if (VARAEnable)
+		VARATimer();
+
+	if (KISSEnable)
+		KISSTimer();
+
+}
+
+void QtTermTCP::SlowTimerSlot()
+{
+	// Runs every 60 S
+
+	Ui_ListenSession * Sess;
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		if (Sess->monLogfile)
+		{
+			Sess->monLogfile->close();
+			Sess->monLogfile = nullptr;
+		}
+	}
+
+}
+
+
+
+extern "C" void myBeep(QString * WAV)
+{
+	if (useBeep)
+	{
+		QApplication::beep();
+		return;
+	}
+
+	// Using .wav files
+
+//	QSoundEffect effect;
+//	effect.setSource(QUrl::fromLocalFile(*WAV));
+//	effect.setLoopCount(1);
+//	effect.setVolume(1.0f);
+//	effect.play();
+
+	QSound::play(*WAV);
+}
+
+void QtTermTCP::ListenSlot()
+{
+	// This runs the Listen Configuration dialog
+
+	ListenDialog  * xx = new ListenDialog();
+	xx->exec();
+}
+
+void QtTermTCP::AGWSlot()
+{
+	// This runs the AGW Configuration dialog
+
+	AGWDialog dialog(0);
+	dialog.exec();
+}
+
+Ui_Dialog * Dev;
+Ui_AlertDialog * Alert;
+
+static Ui_KISSDialog * KISS;
+static Ui_ColourDialog * COLOURS;
+
+
+char NewPTTPort[80];
+
+int newSoundMode = 0;
+int oldSoundMode = 0;
+
+#ifdef USESERIAL
+QList<QSerialPortInfo> Ports = QSerialPortInfo::availablePorts();
+#endif
+
+
+void QtTermTCP::KISSSlot()
+{
+	// This runs the KISS Configuration dialog
+
+	KISS = new(Ui_KISSDialog);
+
+	QDialog UI;
+
+	KISS->setupUi(&UI);
+
+	UI.setFont(*menufont);
+
+	deviceUI = &UI;
+	KISS->KISSEnable->setChecked(KISSEnable);
+	KISS->KISSListen->setChecked(KISSListen);
+	KISS->KISSChecksum->setChecked(KISSChecksum);
+	KISS->KISSACKMODE->setChecked(KISSAckMode);
+	KISS->KISSMH->setChecked(KISSMH);
+	KISS->MYCALL->setText(KISSMYCALL);
+
+	KISS->TXDELAY->setText(QString::number(txdelay[0]));
+	KISS->SetTXDelay->setChecked(sendTXDelay[0]);
+
+	//	connect(KISS->SerialPort, SIGNAL(currentIndexChanged(int)), this, SLOT(PTTPortChanged(int)));
+
+	QStringList items;
+
+#ifdef USESERIAL
+
+	for (const QSerialPortInfo &info : Ports)
+	{
+		items.append(info.portName());
+	}
+
+	items.sort();
+	items.insert(0, "TCP");
+
+#endif
+
+	for (const QString &info : items)
+	{
+		KISS->SerialPort->addItem(info);
+	}
+
+	KISS->SerialPort->setCurrentIndex(KISS->SerialPort->findText(SerialPort, Qt::MatchFixedString));
+	KISS->Speed->setText(QString::number(KISSBAUD));
+	KISS->Host->setText(KISSHost);
+	KISS->Port->setText(QString::number(KISSPortNum));
+
+	KISS->Paclen->setText(QString::number(kisspaclen[0]));
+	KISS->Maxframe->setText(QString::number(maxframe[0]));
+	KISS->Frack->setText(QString::number(frack_time[0]));
+	KISS->Retries->setText(QString::number(fracks[0]));
+
+	QObject::connect(KISS->okButton, SIGNAL(clicked()), this, SLOT(KISSaccept()));
+	QObject::connect(KISS->cancelButton, SIGNAL(clicked()), this, SLOT(KISSreject()));
+
+	UI.exec();
+
+}
+
+
+void QtTermTCP::KISSaccept()
+{
+	QVariant Q;
+	int OldEnable = KISSEnable;
+	char oldSerialPort[64];
+	int OldPort = KISSPortNum;
+	char oldHost[128];
+
+	strcpy(oldSerialPort, SerialPort);
+	strcpy(oldHost, KISSHost);
+
+	KISSEnable = KISS->KISSEnable->isChecked();
+	KISSListen = KISS->KISSListen->isChecked();
+	KISSChecksum = KISS->KISSChecksum->isChecked();
+	KISSAckMode = KISS->KISSACKMODE->isChecked();
+	KISSMH = KISS->KISSMH->isChecked();
+	actHost[18]->setVisible(KISSEnable);			// Show KISS Connect Line
+
+	strcpy(KISSMYCALL, KISS->MYCALL->text().toUtf8().toUpper());
+
+	memset(axMYCALL, 0, 7);
+	ConvToAX25(KISSMYCALL, axMYCALL);
+
+	Q = KISS->Port->text();
+	KISSPortNum = Q.toInt();
+
+	Q = KISS->Speed->text();
+	KISSBAUD = Q.toInt();
+
+	strcpy(KISSHost, KISS->Host->text().toUtf8().toUpper());
+
+	Q = KISS->SerialPort->currentText();
+	strcpy(SerialPort, Q.toString().toUtf8());
+
+	Q = KISS->Paclen->text();
+	kisspaclen[0] = Q.toInt();
+	Q = KISS->Maxframe->text();
+	maxframe[0] = Q.toInt();
+	Q = KISS->Frack->text();
+	frack_time[0] = Q.toInt();
+	Q = KISS->Retries->text();
+	fracks[0] = Q.toInt();
+
+	Q = KISS->TXDELAY->text();
+	txdelay[0] = Q.toInt();
+	sendTXDelay[0] = KISS->SetTXDelay->isChecked();
+
+	myStatusBar->setVisible(AGWEnable | VARAEnable | KISSEnable);
+
+	if (KISSEnable != OldEnable || KISSPortNum != OldPort ||
+		strcmp(oldHost, KISSHost) != 0 ||
+		strcmp(oldSerialPort, SerialPort) != 0)
+	{
+		// (re)start connection
+
+		if (OldEnable)
+		{
+			if (KISSEnable)
+				Status3->setText("KISS Closed");
+			else
+				Status3->setText("KISS Disabled");
+
+			KISSConnected = 0;
+
+			if (KISSSock && KISSSock->ConnectedState == QAbstractSocket::ConnectedState)
+				KISSSock->disconnectFromHost();
+			else if (m_serial)
+				closeSerialPort();
+		}
+	}
+
+	if (KISSEnable == 0 && MHWindow)
+	{
+		MHWindow->close();
+		MHWindow = 0;
+	}
+
+	if (KISSEnable && KISSMH && MHWindow == 0)
+	{
+			newMHWindow(this, 0, "KISS MH");
+			QSettings mysettings(GetConfPath(), QSettings::IniFormat);
+			MHWindow->restoreGeometry(mysettings.value("MHgeometry").toByteArray());
+	}
+
+	if (!KISSMH && MHWindow)
+	{
+		MHWindow->close();
+		MHWindow = 0;
+	}
+
+
+	delete(KISS);
+	SaveSettings();
+	deviceUI->accept();
+
+	//	QSize newSize(this->size());
+	//	QSize oldSize(this->size());
+
+	//	QResizeEvent *myResizeEvent = new QResizeEvent(newSize, oldSize);
+
+	//	QCoreApplication::postEvent(this, myResizeEvent);
+}
+
+void QtTermTCP::KISSreject()
+{
+	delete(KISS);
+	deviceUI->reject();
+}
+
+
+void QtTermTCP::AlertSlot()
+{
+	// This runs the VARA Configuration dialog
+
+	Alert = new(Ui_AlertDialog);
+
+	QDialog UI;
+
+	Alert->setupUi(&UI);
+
+	UI.setFont(*menufont);
+
+	deviceUI = &UI;
+
+	Alert->Bells->setChecked(Bells);
+	Alert->InboundBeep->setChecked(ConnectBeep);
+	Alert->InactivityBeep->setChecked(AlertBeep);
+	Alert->Interval->setText(QString::number(AlertInterval));
+	Alert->KeywordBeep->setChecked(UseKeywords);
+	Alert->keywordFile->setText(KeyWordsFile);
+
+	Alert->useBeep->setChecked(useBeep);
+	Alert->useFiles->setChecked(!useBeep);
+
+	Alert->connectFile->setCurrentText(ConnectWAV);
+	Alert->bellsFile->setCurrentText(BellWAV);
+	Alert->intervalFile->setCurrentText(IntervalWAV);
+	Alert->keywordWAV->setCurrentText(AlertWAV);
+
+	QObject::connect(Alert->chooseInbound, SIGNAL(clicked()), this, SLOT(chooseInboundWAV()));
+	QObject::connect(Alert->chooseBells, SIGNAL(clicked()), this, SLOT(chooseBellsWAV()));
+	QObject::connect(Alert->chooseInterval, SIGNAL(clicked()), this, SLOT(chooseIntervalWAV()));
+	QObject::connect(Alert->chooseKeyAlert, SIGNAL(clicked()), this, SLOT(chooseAlertWAV()));
+
+	QObject::connect(Alert->testBells, SIGNAL(clicked()), this, SLOT(testBellsWAV()));
+	QObject::connect(Alert->TestInbound, SIGNAL(clicked()), this, SLOT(testInboundWAV()));
+	QObject::connect(Alert->testInterval, SIGNAL(clicked()), this, SLOT(testIntervalWAV()));
+	QObject::connect(Alert->TestKeyAlert, SIGNAL(clicked()), this, SLOT(testAlertWAV()));
+
+	QObject::connect(Alert->okButton, SIGNAL(clicked()), this, SLOT(alertAccept()));
+	QObject::connect(Alert->cancelButton, SIGNAL(clicked()), this, SLOT(alertReject()));
+
+	UI.exec();
+}
+
+
+
+
+
+
+void QtTermTCP::chooseInboundWAV()
+{
+	ConnectWAV = QFileDialog::getOpenFileName(this,
+		tr("Select Wav"), "", tr("Sound Files (*.wav)"));
+
+	Alert->connectFile->setCurrentText(ConnectWAV);
+
+}
+
+void QtTermTCP::chooseBellsWAV()
+{
+	BellWAV = QFileDialog::getOpenFileName(this,
+		tr("Select Wav"), "", tr("Sound Files (*.wav)"));
+
+	Alert->bellsFile->setCurrentText(BellWAV);
+}
+
+void QtTermTCP::chooseIntervalWAV()
+{
+	IntervalWAV = QFileDialog::getOpenFileName(this,
+		tr("Select Wav"), "", tr("Sound Files (*.wav)"));
+
+	Alert->intervalFile->setCurrentText(IntervalWAV);
+}
+
+void QtTermTCP::chooseAlertWAV()
+{
+	AlertWAV = QFileDialog::getOpenFileName(this,
+		tr("Select Wav"), "", tr("Sound Files (*.wav)"));
+
+	Alert->keywordWAV->setCurrentText(AlertWAV);
+}
+
+void QtTermTCP::testInboundWAV()
+{
+	QSound::play(Alert->connectFile->currentText());
+}
+
+void QtTermTCP::testBellsWAV()
+{
+	QSound::play(Alert->bellsFile->currentText());
+}
+
+void QtTermTCP::testIntervalWAV()
+{
+	QSound::play(Alert->intervalFile->currentText());
+}
+
+void QtTermTCP::testAlertWAV()
+{
+	QSound::play(Alert->keywordWAV->currentText());
+}
+
+
+
+void QtTermTCP::alertAccept()
+{
+	QVariant Q;
+
+	useBeep = Alert->useBeep->isChecked();
+
+	Bells = Alert->Bells->isChecked();
+	ConnectBeep = Alert->InboundBeep->isChecked();
+	AlertBeep = Alert->InactivityBeep->isChecked();
+	AlertInterval = Alert->Interval->text().toInt();
+
+	UseKeywords = Alert->KeywordBeep->isChecked();
+	KeyWordsFile = Alert->keywordFile->text();
+
+	ConnectWAV = Alert->connectFile->currentText();
+	BellWAV = Alert->bellsFile->currentText();
+	IntervalWAV = Alert->intervalFile->currentText();
+	AlertWAV = Alert->keywordWAV->currentText();
+
+	delete(Alert);
+	SaveSettings();
+	deviceUI->accept();
+}
+
+void QtTermTCP::alertReject()
+{
+	delete(Alert);
+	deviceUI->reject();
+}
+
+
+
+void QtTermTCP::VARASlot()
+{
+	// This runs the VARA Configuration dialog
+
+	char valChar[80];
+
+	Dev = new(Ui_Dialog);
+
+	QDialog UI;
+
+	Dev->setupUi(&UI);
+
+	UI.setFont(*menufont);
+
+	deviceUI = &UI;
+
+	Dev->VARAEnable->setChecked(VARAEnable);
+	Dev->TermCall->setText(VARATermCall);
+
+	SetVARAParams();
+
+	connect(Dev->VARAHF, SIGNAL(toggled(bool)), this, SLOT(VARAHFChanged(bool)));
+	connect(Dev->VARAFM, SIGNAL(toggled(bool)), this, SLOT(VARAFMChanged(bool)));
+	connect(Dev->VARASAT, SIGNAL(toggled(bool)), this, SLOT(VARASATChanged(bool)));
+
+	if (VARA500)
+		Dev->VARA500->setChecked(true);
+	else if (VARA2750)
+		Dev->VARA2750->setChecked(true);
+	else
+		Dev->VARA2300->setChecked(true);
+
+	if (VARAHF)
+		Dev->VARAHF->setChecked(true);
+	else if (VARAFM)
+		Dev->VARAFM->setChecked(true);
+	else if (VARASAT)
+		Dev->VARASAT->setChecked(true);
+
+	if (VARAHF == 0)
+		Dev->HFMode->setVisible(false);
+
+	connect(Dev->CAT, SIGNAL(toggled(bool)), this, SLOT(CATChanged(bool)));
+	connect(Dev->PTTPort, SIGNAL(currentIndexChanged(int)), this, SLOT(PTTPortChanged(int)));
+
+	if (PTTMode == PTTCAT)
+		Dev->CAT->setChecked(true);
+	else
+		Dev->RTSDTR->setChecked(true);
+
+	if (CATHex)
+		Dev->CATHex->setChecked(true);
+	else
+		Dev->CATText->setChecked(true);
+
+	sprintf(valChar, "%d", pttGPIOPin);
+	Dev->GPIOLeft->setText(valChar);
+	sprintf(valChar, "%d", pttGPIOPinR);
+	Dev->GPIORight->setText(valChar);
+
+	Dev->VIDPID->setText(CM108Addr);
+
+
+	QStringList items;
+
+#ifdef USESERIAL
+
+	for (const QSerialPortInfo &info : Ports)
+	{
+		items.append(info.portName());
+	}
+
+	items.sort();
+
+#endif
+
+	Dev->PTTPort->addItem("None");
+	Dev->PTTPort->addItem("CM108");
+
+#ifdef __ARM_ARCH
+
+	//	Dev->PTTPort->addItem("GPIO");
+
+#endif
+
+	Dev->PTTPort->addItem("FLRIG");
+	Dev->PTTPort->addItem("HAMLIB");
+
+	for (const QString &info : items)
+	{
+		Dev->PTTPort->addItem(info);
+	}
+
+	Dev->PTTPort->setCurrentIndex(Dev->PTTPort->findText(PTTPort, Qt::MatchFixedString));
+
+	PTTPortChanged(0);				// Force reevaluation
+
+	QObject::connect(Dev->okButton, SIGNAL(clicked()), this, SLOT(deviceaccept()));
+	QObject::connect(Dev->cancelButton, SIGNAL(clicked()), this, SLOT(devicereject()));
+
+	UI.exec();
+
+}
+
+extern QProcess *process;
+
+void ClosePTTPort();
+
+void QtTermTCP::deviceaccept()
+{
+	QVariant Q;
+
+	int OldEnable = VARAEnable;
+	int OldPort = VARAPortNum;
+	char oldHost[128];
+	char oldPath[256];
+
+	strcpy(oldHost, VARAHost);
+	strcpy(oldPath, VARAPath);
+
+	VARAEnable = Dev->VARAEnable->isChecked();
+
+	strcpy(VARATermCall, Dev->TermCall->text().toUtf8().toUpper());
+
+	Q = Dev->Port->text();
+
+	VARAPortNum = Q.toInt();
+	strcpy(VARAHost, Dev->Host->text().toUtf8().toUpper());
+	strcpy(VARAPath, Dev->Path->text().toUtf8());
+	strcpy(VARAInit, Dev->InitCommands->text().toUtf8());
+
+	VARA500 = Dev->VARA500->isChecked();
+	VARA2300 = Dev->VARA2300->isChecked();
+	VARA2750 = Dev->VARA2750->isChecked();
+
+	VARAHF = Dev->VARAHF->isChecked();
+	VARAFM = Dev->VARAFM->isChecked();
+	VARASAT = Dev->VARASAT->isChecked();
+
+	if (VARAHF)
+	{
+		strcpy(VARAHostHF, VARAHost);
+		strcpy(VARAPathHF, VARAPath);
+		VARAPortHF = VARAPortNum;
+	}
+	else if (VARAFM)
+	{
+		strcpy(VARAHostFM, VARAHost);
+		strcpy(VARAPathFM, VARAPath);
+		VARAPortFM = VARAPortNum;
+	}
+	else if (VARASAT)
+	{
+		strcpy(VARAHostSAT, VARAHost);
+		strcpy(VARAPathSAT, VARAPath);
+		VARAPortSAT = VARAPortNum;
+	}
+
+	Q = Dev->PTTPort->currentText();
+	strcpy(PTTPort, Q.toString().toUtf8());
+
+	if (Dev->CAT->isChecked())
+		PTTMode = PTTCAT;
+	else
+		PTTMode = PTTRTS;
+
+	if (Dev->CATHex->isChecked())
+		CATHex = 1;
+	else
+		CATHex = 0;
+
+	Q = Dev->PTTOn->text();
+	strcpy(PTTOnString, Q.toString().toUtf8());
+	Q = Dev->PTTOff->text();
+	strcpy(PTTOffString, Q.toString().toUtf8());
+
+	Q = Dev->CATSpeed->text();
+	PTTBAUD = Q.toInt();
+
+	Q = Dev->GPIOLeft->text();
+	pttGPIOPin = Q.toInt();
+
+	Q = Dev->GPIORight->text();
+	pttGPIOPinR = Q.toInt();
+
+	Q = Dev->VIDPID->text();
+
+	if (strcmp(PTTPort, "CM108") == 0)
+		strcpy(CM108Addr, Q.toString().toUtf8());
+	else if (strcmp(PTTPort, "HAMLIB") == 0)
+	{
+		HamLibPort = Q.toInt();
+		Q = Dev->PTTOn->text();
+		strcpy(HamLibHost, Q.toString().toUtf8());
+	}
+
+	if (VARAEnable != OldEnable || VARAPortNum != OldPort || strcmp(oldHost, VARAHost) != 0)
+	{
+		// (re)start connection
+
+		if (OldEnable && VARASock && VARASock->ConnectedState == QAbstractSocket::ConnectedState)
+		{
+			VARASock->disconnectFromHost();
+			if (VARADataSock)
+				VARADataSock->disconnectFromHost();
+			Status2->setText("VARA Disconnected");
+		}
+	}
+
+	if (process && process->state() == QProcess::Running)
+		if ((VARAEnable == 0 || strcmp(oldPath, VARAPath) != 0))
+			process->close();
+
+	myStatusBar->setVisible(AGWEnable | VARAEnable | KISSEnable);
+
+	ClosePTTPort();
+	OpenPTTPort();
+
+	delete(Dev);
+	SaveSettings();
+	deviceUI->accept();
+
+	QSize newSize(this->size());
+	QSize oldSize(this->size());
+
+	QResizeEvent *myResizeEvent = new QResizeEvent(newSize, oldSize);
+
+	QCoreApplication::postEvent(this, myResizeEvent);
+}
+
+void QtTermTCP::devicereject()
+{
+	delete(Dev);
+	deviceUI->reject();
+}
+
+// This handles incoming connections
+
+void QtTermTCP::onNewConnection()
+{
+	myTcpSocket *clientSocket = (myTcpSocket *)_server->nextPendingConnection();
+
+	clientSocket->Sess = NULL;
+
+	Ui_ListenSession * S;
+	Ui_ListenSession  * Sess = NULL;
+
+	char Title[512];
+	int i = 0;
+
+	QByteArray Host = clientSocket->peerAddress().toString().toUtf8();
+
+	if (TermMode == MDI)
+	{
+		// See if an old session can be reused
+
+		for (int i = 0; i < _sessions.size(); ++i)
+		{
+			S = _sessions.at(i);
+
+			//	for (Ui_ListenSession * S: _sessions)
+			//	{
+			if ((S->SessionType & Listen) && S->clientSocket == NULL)
+			{
+				Sess = S;
+				break;
+			}
+		}
+
+		// Create a window if none found, else reuse old
+
+		if (Sess == NULL)
+		{
+			Sess = newWindow(this, Listen);
+		}
+
+		QByteArray Host = clientSocket->peerAddress().toString().toUtf8();
+	}
+	else
+	{
+		// Single or Tabbed - look for free session
+
+		for (i = 0; i < _sessions.size(); ++i)
+		{
+			S = _sessions.at(i);
+
+			if (S->clientSocket == NULL && S->AGWSession == NULL && S->AGWMonSession == NULL && S->KISSSession == NULL)
+			{
+				Sess = S;
+				break;
+			}
+		}
+
+		if (Sess == NULL)
+		{
+			// Clear connection
+
+			clientSocket->disconnectFromHost();
+			return;
+		}
+	}
+
+	_sockets.push_back(clientSocket);
+
+	clientSocket->Sess = Sess;
+
+	// See if any data from host - first msg should be callsign
+
+	clientSocket->waitForReadyRead(1000);
+
+	QByteArray datas = clientSocket->readAll();
+
+	datas.chop(2);
+	datas.truncate(10);				// Just in case!
+
+	strlop(datas.data(), 13);
+
+	if (datas.data()[0] == 0)
+		datas.append("UNKNOWN\0");
+
+	datas.append('\0');
+
+	sprintf(Title, "Inward Connect from %s:%d Call %s",
+		Host.data(), clientSocket->peerPort(), datas.data());
+
+	if (TermMode == MDI)
+	{
+		Sess->setWindowTitle(Title);
+	}
+	else if (TermMode == Tabbed)
+	{
+		tabWidget->setTabText(i, datas.data());
+		tabWidget->tabBar()->setTabTextColor(i, newTabText);
+	}
+
+	else if (TermMode == Single)
+		this->setWindowTitle(Title);
+
+	connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
+	connect(clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
+
+	Sess->clientSocket = clientSocket;
+
+	// We need to set Connect and Disconnect if the window is active
+
+	if (TermMode == MDI && Sess->sw == ActiveSubWindow)
+		setMenus(true);
+
+	if (TermMode == Tabbed && Sess->Tab == tabWidget->currentIndex())
+		setMenus(true);
+
+	if (TermMode == Single)
+		setMenus(true);			// Single
+
+	// Send CText if defined
+
+	if (listenCText[0])
+		Sess->clientSocket->write(listenCText);
+
+	// Send Message to Terminal
+
+	char Msg[80];
+
+	sprintf(Msg, "Listen Connect from %s\r\r", datas.data());
+
+	WritetoOutputWindow(Sess, (unsigned char *)Msg, (int)strlen(Msg));
+
+	if (ConnectBeep)
+		myBeep(&ConnectWAV);
+
+	QApplication::alert(mythis, 0);
+}
+
+void QtTermTCP::onSocketStateChanged(QAbstractSocket::SocketState socketState)
+{
+	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
+	Ui_ListenSession * Sess = (Ui_ListenSession *)sender->Sess;
+
+	if (socketState == QAbstractSocket::UnconnectedState)
+	{
+		char Msg[] = "Disconnected\r";
+
+		WritetoOutputWindowEx(Sess, (unsigned char *)Msg, (int)strlen(Msg),
+			Sess->termWindow, &Sess->OutputSaveLen, Sess->OutputSave, WarningText);		// Red
+
+		if (TermMode == MDI)
+		{
+			if (Sess->SessionType == Mon)			// Mon Only
+				Sess->setWindowTitle("Monitor Session Disconnected");
+			else
+				Sess->setWindowTitle("Disconnected");
+		}
+		else if (TermMode == Tabbed)
+		{
+			if (Sess->SessionType == Mon)			// Mon Only
+				tabWidget->setTabText(Sess->Tab, "Monitor");
+			else
+			{
+				char Label[16];
+				sprintf(Label, "Sess %d", Sess->Tab + 1);
+				tabWidget->setTabText(Sess->Tab, Label);
+			}
+		}
+		else if (TermMode == Single)
+		{
+			if (Sess->AGWMonSession)
+				mythis->setWindowTitle("AGW Monitor Window");
+			else
+			{
+				if (Sess->SessionType == Mon)			// Mon Only
+					this->setWindowTitle("Monitor Session Disconnected");
+				else
+					this->setWindowTitle("Disconnected");
+			}
+		}
+
+		if (Sess->TTActive)
+		{
+			Sess->TTActive = 0;
+			DoTermResize(Sess);
+		}
+
+		Sess->PortMonString[0] = 0;
+
+		//		delete(Sess->clientSocket);
+		Sess->clientSocket = NULL;
+
+		discAction->setEnabled(false);
+
+		if ((Sess->SessionType & Listen))
+			_sockets.removeOne(sender);
+		else
+		{
+			connectMenu->setEnabled(true);
+			YAPPSend->setEnabled(false);
+		}
+	}
+	else if (socketState == QAbstractSocket::ConnectedState)
+	{
+		char Signon[256];
+		char Title[128];
+
+		// only seems to be triggered for outward connect
+
+		sprintf(Signon, "%s\r%s\rBPQTERMTCP\r", UserName[Sess->CurrentHost], Password[Sess->CurrentHost]);
+
+		Sess->clientSocket->write(Signon);
+
+		discAction->setEnabled(true);
+		YAPPSend->setEnabled(true);
+		connectMenu->setEnabled(false);
+
+		SendTraceOptions(Sess);
+
+		Sess->InputMode = 0;
+		Sess->SlowTimer = 0;
+		Sess->MonData = 0;
+		Sess->OutputSaveLen = 0;			// Clear any part line
+		Sess->MonSaveLen = 0;			// Clear any part line
+
+		if (Sess->SessionType == Mon)		// Mon Only
+			sprintf(Title, "Monitor Session Connected to %s", Host[Sess->CurrentHost]);
+		else
+		{
+			char Label[256];
+
+			if (SessName[Sess->CurrentHost][0])
+				sprintf(Label, "%s(%s)", Host[Sess->CurrentHost], SessName[Sess->CurrentHost]);
+			else
+				strcpy(Label, Host[Sess->CurrentHost]);
+
+			sprintf(Title, "Connected to %s", Label);
+		}
+
+		if (TermMode == MDI)
+			Sess->setWindowTitle(Title);
+		else if (TermMode == Tabbed)
+		{
+			if (SessName[Sess->CurrentHost][0])
+				tabWidget->setTabText(Sess->Tab, SessName[Sess->CurrentHost]);
+			else
+				tabWidget->setTabText(Sess->Tab, Host[Sess->CurrentHost]);
+		}
+		else if (TermMode == Single)
+			this->setWindowTitle(Title);
+	}
+}
+
+void QtTermTCP::updateWindowMenu()
+{
+	if (TermMode == MDI)
+	{
+		windowMenu->clear();
+		windowMenu->addAction(newTermAct);
+		windowMenu->addAction(newMonAct);
+		windowMenu->addAction(newCombinedAct);
+		windowMenu->addSeparator();
+		windowMenu->addAction(closeAct);
+		windowMenu->addAction(closeAllAct);
+		windowMenu->addSeparator();
+		windowMenu->addAction(tileAct);
+		windowMenu->addAction(cascadeAct);
+		windowMenu->addSeparator();
+		windowMenu->addAction(nextAct);
+		windowMenu->addAction(previousAct);
+		windowMenu->addAction(quitAction);
+		windowMenu->addAction(windowMenuSeparatorAct);
+
+		QList<QMdiSubWindow *> windows = mdiArea->subWindowList();
+		windowMenuSeparatorAct->setVisible(!windows.isEmpty());
+
+		Ui_ListenSession * Sess;
+
+		for (int i = 0; i < _sessions.size(); ++i)
+		{
+			Sess = _sessions.at(i);
+			Sess->actActivate = windowMenu->addAction(Sess->sw->windowTitle());
+			QAction::connect(Sess->actActivate, SIGNAL(triggered()), this, SLOT(actActivate()));
+			Sess->actActivate->setCheckable(true);
+			Sess->actActivate->setChecked(ActiveSubWindow == Sess->sw);
+		}
+	}
+	else if (TermMode == Tabbed)
+	{
+		windowMenu->clear();
+
+		Ui_ListenSession * Sess = (Ui_ListenSession *)tabWidget->currentWidget();
+
+		QActionGroup * termGroup = new QActionGroup(this);
+
+		delete(TabSingle);
+		delete(TabBoth);
+		delete(TabMon);
+
+		TabSingle = setupMenuLine(nullptr, (char *)"Terminal Only", this, (Sess->SessionType == Term));
+		TabBoth = setupMenuLine(nullptr, (char *)"Terminal + Monitor", this, (Sess->SessionType == Term + Mon));
+		TabMon = setupMenuLine(nullptr, (char *)"Monitor Only", this, (Sess->SessionType == Mon));
+
+		termGroup->addAction(TabSingle);
+		termGroup->addAction(TabBoth);
+		termGroup->addAction(TabMon);
+
+		windowMenu->addAction(TabSingle);
+		windowMenu->addAction(TabBoth);
+		windowMenu->addAction(TabMon);
+
+	}
+}
+
+Ui_ListenSession::~Ui_ListenSession()
+{
+	if (this->clientSocket)
+	{
+		int loops = 100;
+		this->clientSocket->disconnectFromHost();
+		while (loops-- && this->clientSocket->state() != QAbstractSocket::UnconnectedState)
+			QThread::msleep(10);
+	}
+}
+
+extern "C" void setTraceOff(Ui_ListenSession * Sess)
+{
+	if ((Sess->SessionType & Mon) == 0)
+		return;					// Not Monitor
+
+	if (Sess->AGWMonSession)
+		return;
+
+	char Buffer[80];
+	int Len = sprintf(Buffer, "\\\\\\\\0 0 0 0 0 0 0 0\r");
+
+	SocketFlush(Sess);
+	SocketSend(Sess, Buffer, Len);
+	SocketFlush(Sess);
+}
+
+
+extern "C" void SendTraceOptions(Ui_ListenSession * Sess)
+{
+	if ((Sess->SessionType & Mon) == 0)
+		return;					// Not Monitor
+
+	if (Sess->AGWMonSession)
+		return;
+
+	char Buffer[80];
+	int Len = sprintf(Buffer, "\\\\\\\\%llx %x %x %x %x %x %x %x\r", Sess->portmask, Sess->mtxparam | (Sess->mlocaltime << 7),
+		Sess->mcomparam, Sess->MonitorNODES, Sess->MonitorColour, Sess->monUI, 0, 1);
+
+	strcpy(&MonParams[Sess->CurrentHost][0], &Buffer[4]);
+	SaveSettings();
+	SocketFlush(Sess);
+	SocketSend(Sess, Buffer, Len);
+	SocketFlush(Sess);
+}
+
+void QtTermTCP::doNewTerm()
+{
+	newWindow(this, Term);
+}
+
+void QtTermTCP::doNewMon()
+{
+	newWindow(this, Mon);
+}
+
+void QtTermTCP::doNewCombined()
+{
+	newWindow(this, Term + Mon);
+}
+
+void QtTermTCP::doCascade()
+{
+	// Qt Cascade Minimizes windows so do it ourselves
+
+	int x = 0, y = 0;
+
+	Ui_ListenSession * Sess;
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		Sess->sw->move(x, y);
+		x += 14;
+		y += 30;
+	}
+}
+
+void QtTermTCP::actActivate()
+{
+	QAction * sender = static_cast<QAction*>(QObject::sender());
+
+	Ui_ListenSession * Sess;
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		if (Sess->actActivate == sender)
+		{
+			mdiArea->setActiveSubWindow(Sess->sw);
+			return;
+		}
+	}
+}
+
+
+void QtTermTCP::xon_mdiArea_changed()
+{
+	// This is triggered when the Active MDI window changes
+	// and is used to enable/disable Connect, Disconnect and YAPP Send
+
+
+	QMdiSubWindow *SW = mdiArea->activeSubWindow();
+
+	// Dont waste time if not changed
+
+	if (ActiveSubWindow == SW)
+		return;
+
+	ActiveSubWindow = SW;
+
+	Ui_ListenSession * Sess;
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		//	for (Ui_ListenSession * Sess : _sessions)
+		//	{
+		if (Sess->sw == SW)
+		{
+			ActiveSession = Sess;
+
+			if (Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState)
+			{
+				discAction->setEnabled(true);
+				YAPPSend->setEnabled(true);
+				connectMenu->setEnabled(false);
+			}
+			else if (Sess->AGWMonSession)
+			{
+				// Connected AGW Monitor Session
+
+				discAction->setEnabled(false);
+				YAPPSend->setEnabled(false);
+				connectMenu->setEnabled(false);
+			}
+			else if (Sess->AGWSession || Sess->KISSSession)
+			{
+				// Connected AGW or KISS Terminal Session
+
+				discAction->setEnabled(true);
+				YAPPSend->setEnabled(true);
+				connectMenu->setEnabled(false);
+			}
+			else
+			{
+				// Not connected
+
+				discAction->setEnabled(false);
+				YAPPSend->setEnabled(false);
+
+				if ((Sess->SessionType & Listen))		// Listen Sessions can't connect
+					connectMenu->setEnabled(false);
+				else
+					connectMenu->setEnabled(true);
+			}
+
+			// If a monitor Window, change Monitor config settings
+
+			EnableMonLog->setChecked(Sess->LogMonitor);
+
+			if (AGWUsers && Sess == AGWUsers->MonSess)		// AGW Monitor
+			{
+				for (int i = 0; i < 64; i++)
+					SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
+
+				connectMenu->setEnabled(false);
+				MonTX->setVisible(0);
+				MonSup->setVisible(0);
+				MonUI->setVisible(0);
+				MonColour->setVisible(0);
+
+				EnableMonitor->setVisible(1);
+				EnableMonitor->setChecked(AGWMonEnable);
+
+				MonLocalTime->setChecked(Sess->mlocaltime);
+				MonNodes->setChecked(Sess->MonitorNODES);
+			}
+			else if (Sess == KISSMonSess)				// KISS Monitor
+			{
+				for (int i = 0; i < 64; i++)
+					SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
+
+				connectMenu->setEnabled(false);
+				MonTX->setVisible(0);
+				MonSup->setVisible(0);
+				MonUI->setVisible(0);
+				MonColour->setVisible(0);
+
+				EnableMonitor->setVisible(1);
+				EnableMonitor->setChecked(KISSMonEnable);
+				MonLocalTime->setChecked(Sess->mlocaltime);
+				MonNodes->setChecked(Sess->MonitorNODES);
+			}
+
+			else
+			{
+				EnableMonitor->setVisible(0);
+				MonTX->setVisible(1);
+				MonSup->setVisible(1);
+				MonUI->setVisible(1);
+				MonColour->setVisible(1);
+			}
+
+			if (Sess->PortMonString[0])
+			{
+				char * ptr = (char *)malloc(2048);
+				memcpy(ptr, Sess->PortMonString, 2048);
+
+				int NumberofPorts = atoi((char *)&ptr[2]);
+				char *p, *Context;
+				char msg[80];
+				int portnum;
+				char delim[] = "|";
+
+				// Remove old Monitor menu
+
+				for (int i = 0; i < 64; i++)
+				{
+					SetPortMonLine(i, (char *)"", 0, 0);			// Set all hidden
+				}
+
+				p = strtok_s((char *)&ptr[2], delim, &Context);
+
+				while (NumberofPorts--)
+				{
+					p = strtok_s(NULL, delim, &Context);
+					if (p == NULL)
+						break;
+
+					portnum = atoi(p);
+
+					sprintf(msg, "Port %s", p);
+
+					if (portnum == 0)
+						portnum = 64;
+
+					if (Sess->portmask & (1ll << (portnum - 1)))
+						SetPortMonLine(portnum, msg, 1, 1);
+					else
+						SetPortMonLine(portnum, msg, 1, 0);
+				}
+				free(ptr);
+
+				MonLocalTime->setChecked(Sess->mlocaltime);
+				MonTX->setChecked(Sess->mtxparam);
+				MonSup->setChecked(Sess->mcomparam);
+				MonUI->setChecked(Sess->monUI);
+				MonNodes->setChecked(Sess->MonitorNODES);
+				MonColour->setChecked(Sess->MonitorColour);
+
+			}
+
+			return;
+		}
+	}
+}
+
+void QtTermTCP::doFonts()
+{
+	fontDialog  * xx = new fontDialog(0);
+	xx->exec();
+}
+
+void QtTermTCP::doMFonts()
+{
+	fontDialog  * xx = new fontDialog(1);
+	xx->exec();
+}
+
+QColor TempmonBackground = monBackground;
+QColor TemptermBackground = termBackground;
+QColor TempinputBackground = inputBackground;
+
+QColor TempmonRxText = monRxText;
+QColor TempmonTxText = monTxText;
+QColor TempmonOtherText = monOtherText;
+
+QColor TempoutputText = outputText;
+QColor TempEchoText = EchoText;
+QColor TempWarningText = WarningText;
+
+
+QColor TempinputText = inputText;
+
+
+void setDialogColours()
+{
+	char monStyle[128];
+
+	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		TempmonOtherText.red(), TempmonOtherText.green(), TempmonOtherText.blue(),
+		TempmonBackground.red(), TempmonBackground.green(), TempmonBackground.blue());
+
+	COLOURS->MonitorBG->setStyleSheet(monStyle);
+	COLOURS->MonOther->setStyleSheet(monStyle);
+
+	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		TempmonTxText.red(), TempmonTxText.green(), TempmonTxText.blue(),
+		TempmonBackground.red(), TempmonBackground.green(), TempmonBackground.blue());
+	COLOURS->MonTX->setStyleSheet(monStyle);
+
+	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		TempmonRxText.red(), TempmonRxText.green(), TempmonRxText.blue(),
+		TempmonBackground.red(), TempmonBackground.green(), TempmonBackground.blue());
+
+	COLOURS->MonRX->setStyleSheet(monStyle);
+
+	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		TempoutputText.red(), TempoutputText.green(), TempoutputText.blue(),
+		TemptermBackground.red(), TemptermBackground.green(), TemptermBackground.blue());
+
+	COLOURS->TermBG->setStyleSheet(monStyle);
+	COLOURS->TermNormal->setStyleSheet(monStyle);
+
+	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		TempEchoText.red(), TempEchoText.green(), TempEchoText.blue(),
+		TemptermBackground.red(), TemptermBackground.green(), TemptermBackground.blue());
+
+	COLOURS->Echoed->setStyleSheet(monStyle);
+
+	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		TempWarningText.red(), TempWarningText.green(), TempWarningText.blue(),
+		TemptermBackground.red(), TemptermBackground.green(), TemptermBackground.blue());
+
+	COLOURS->Warning->setStyleSheet(monStyle);
+
+	sprintf(monStyle, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		TempinputText.red(), TempinputText.green(), TempinputText.blue(),
+		TempinputBackground.red(), TempinputBackground.green(), TempinputBackground.blue());
+
+	COLOURS->InputBG->setStyleSheet(monStyle);
+	COLOURS->InputColour->setStyleSheet(monStyle);
+
+}
+
+void QtTermTCP::doColours()
+{
+	COLOURS = new(Ui_ColourDialog);
+
+	QDialog UI;
+
+	COLOURS->setupUi(&UI);
+
+	UI.setFont(*menufont);
+
+	deviceUI = &UI;
+
+	TempmonBackground = monBackground;
+	TempmonRxText = monRxText;
+	TempmonTxText = monTxText;
+	TempmonOtherText = monOtherText;
+
+	TemptermBackground = termBackground;
+	TempoutputText = outputText;
+	TempEchoText = EchoText;
+	TempWarningText = WarningText;
+
+	TempinputBackground = inputBackground;
+	TempinputText = inputText;
+
+	setDialogColours();
+
+	QObject::connect(COLOURS->MonitorBG, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->TermBG, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->InputBG, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->MonRX, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->MonTX, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->MonOther, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->TermNormal, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->Echoed, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->Warning, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+	QObject::connect(COLOURS->InputColour, SIGNAL(clicked()), this, SLOT(ColourPressed()));
+
+	QObject::connect(COLOURS->okButton, SIGNAL(clicked()), this, SLOT(Colouraccept()));
+	QObject::connect(COLOURS->cancelButton, SIGNAL(clicked()), this, SLOT(Colourreject()));
+
+	UI.exec();
+
+}
+
+void QtTermTCP::ColourPressed()
+{
+	char Name[32];
+
+	strcpy(Name, sender()->objectName().toUtf8());
+
+	if (strcmp(Name, "MonitorBG") == 0)
+		TempmonBackground = setColor(TempmonBackground);
+
+	else if (strcmp(Name, "MonTX") == 0)
+		TempmonTxText = setColor(TempmonTxText);
+
+	else if (strcmp(Name, "MonRX") == 0)
+		TempmonRxText = setColor(TempmonRxText);
+
+	else if (strcmp(Name, "MonOther") == 0)
+		TempmonOtherText = setColor(TempmonOtherText);
+
+	else if (strcmp(Name, "TermBG") == 0)
+		TemptermBackground = setColor(TemptermBackground);
+
+	else if (strcmp(Name, "InputBG") == 0)
+		TempinputBackground = setColor(TempinputBackground);
+
+	else if (strcmp(Name, "InputColour") == 0)
+		TempinputText = setColor(TempinputText);
+
+	else if (strcmp(Name, "TermNormal") == 0)
+		TempoutputText = setColor(TempoutputText);
+
+	else if (strcmp(Name, "Echoed") == 0)
+		TempEchoText = setColor(TempEchoText);
+
+	else if (strcmp(Name, "Warning") == 0)
+		TempWarningText = setColor(TempWarningText);
+
+	setDialogColours();
+}
+
+
+void QtTermTCP::Colouraccept()
+{
+	monBackground = TempmonBackground;
+	monRxText = TempmonRxText;
+	monTxText = TempmonTxText;
+	monOtherText = TempmonOtherText;
+
+	termBackground = TemptermBackground;
+	EchoText = TempEchoText;
+	WarningText = TempWarningText;
+	outputText = TempoutputText;
+
+	inputBackground = TempinputBackground;
+	inputText = TempinputText;
+
+	// Set background colour for new windows
+
+	sprintf(monStyleSheet, "background-color: rgb(%d, %d, %d);",
+		monBackground.red(), monBackground.green(), monBackground.blue());
+
+	sprintf(termStyleSheet, "background-color: rgb(%d, %d, %d);",
+		termBackground.red(), termBackground.green(), termBackground.blue());
+
+	sprintf(inputStyleSheet, "color: rgb(%d, %d, %d); background-color: rgb(%d, %d, %d);",
+		inputText.red(), inputText.green(), inputText.blue(),
+		inputBackground.red(), inputBackground.green(), inputBackground.blue());
+
+	// Update existing windows
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Ui_ListenSession * S = _sessions.at(i);
+
+		if (S->monWindow)
+			S->monWindow->setStyleSheet(monStyleSheet);
+
+		if (S->termWindow)
+			S->termWindow->setStyleSheet(termStyleSheet);
+
+		if (S->inputWindow)
+			S->inputWindow->setStyleSheet(inputStyleSheet);
+
+	}
+
+
+	delete(COLOURS);
+
+	SaveSettings();
+	deviceUI->accept();
+}
+
+void QtTermTCP::Colourreject()
+{
+	delete(COLOURS);
+	deviceUI->reject();
+}
+
+
+void QtTermTCP::ConnecttoVARA()
+{
+
+	delete(VARASock);
+
+	VARASock = new myTcpSocket();
+
+	connect(VARASock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(VARAdisplayError(QAbstractSocket::SocketError)));
+	connect(VARASock, SIGNAL(readyRead()), this, SLOT(VARAreadyRead()));
+	connect(VARASock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onVARASocketStateChanged(QAbstractSocket::SocketState)));
+
+	VARASock->connectToHost(VARAHost, VARAPortNum);
+
+	Status2->setText("VARA Control Connecting");
+
+	return;
+}
+
+
+void QtTermTCP::VARATimer()
+{
+	// Runs every 10 Seconds
+
+	if (VARAConnected == 0 && VARAConnecting == 0)
+	{
+		if (process == nullptr || process->state() == QProcess::NotRunning)
+		{
+			if (VARAPath[0])
+			{
+				process = new QProcess(this);
+				QString file = VARAPath;
+				process->start(file);
+			}
+		}
+		QThread::msleep(1000);
+		VARAConnecting = true;
+		ConnecttoVARA();
+	}
+}
+
+
+void QtTermTCP::VARAdisplayError(QAbstractSocket::SocketError socketError)
+{
+	switch (socketError)
+	{
+	case QAbstractSocket::RemoteHostClosedError:
+		break;
+
+	case QAbstractSocket::HostNotFoundError:
+		QMessageBox::information(this, tr("QtTermTCP"),
+			tr("VARA host was not found. Please check the "
+				"host name and portsettings->"));
+
+		Status2->setText("VARA Connection Failed");
+
+		break;
+
+	case QAbstractSocket::ConnectionRefusedError:
+
+		Status2->setText("VARA Connection Refused");
+		break;
+
+	default:
+
+		Status2->setText("VARA Connection Failed");
+	}
+
+	VARAConnecting = 0;
+	VARAConnected = 0;
+}
+
+void QtTermTCP::VARAreadyRead()
+{
+	int Read;
+	char Buffer[4096];
+	char * ptr;
+	char * Msg;
+	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
+
+	// read the data from the socket
+
+	Read = Socket->read((char *)Buffer, 4095);
+
+	Buffer[Read] = 0;
+
+	Msg = Buffer;
+
+	ptr = strchr(Msg, 0x0d);
+
+	while (ptr)
+	{
+		*ptr++ = 0;
+
+		if (strcmp(Msg, "IAMALIVE") == 0)
+		{
+		}
+		else if (strcmp(Msg, "PTT ON") == 0)
+		{
+			RadioPTT(1);
+		}
+		else if (strcmp(Msg, "PTT OFF") == 0)
+		{
+			RadioPTT(0);
+		}
+		else if (strcmp(Msg, "PENDING") == 0)
+		{
+		}
+		else if (strcmp(Msg, "CANCELPENDING") == 0)
+		{
+		}
+		else if (strcmp(Msg, "OK") == 0)
+		{
+		}
+		else if (memcmp(Msg, "CONNECTED ", 10) == 0)
+		{
+			Ui_ListenSession * Sess = (Ui_ListenSession *)VARASock->Sess;
+			char Title[128] = "";
+			char CallFrom[64] = "";
+			char CallTo[64] = "";
+			char Mode[64] = "";
+			char Message[128];
+			int n;
+
+
+			sscanf(&Msg[10], "%s %s %s", CallFrom, CallTo, Mode);
+
+			if (Sess)
+			{
+				if (Mode[0])
+					sprintf(Title, "Connected to %s %s Mode", CallTo, Mode);
+				else
+					sprintf(Title, "Connected to %s", CallTo);
+
+				n = sprintf(Message, "%s\r\n", Title);
+				WritetoOutputWindow(Sess, (unsigned char *)Message, n);
+
+				if (TermMode == MDI)
+					Sess->setWindowTitle(Title);
+				else if (TermMode == Tabbed)
+					tabWidget->setTabText(Sess->Tab, CallTo);
+				else if (TermMode == Single)
+					mythis->setWindowTitle(Title);
+
+				setMenus(true);
+			}
+			else
+			{
+				// Incoming Call
+
+				Ui_ListenSession * S;
+				int i = 0;
+
+				if (TermMode == MDI)
+				{
+					// See if an old session can be reused
+
+					for (int i = 0; i < _sessions.size(); ++i)
+					{
+						S = _sessions.at(i);
+
+						//	for (Ui_ListenSession * S: _sessions)
+						//	{
+						if ((S->SessionType & Listen) && S->clientSocket == NULL)
+						{
+							Sess = S;
+							break;
+						}
+					}
+
+					// Create a window if none found, else reuse old
+
+					if (Sess == NULL)
+					{
+						Sess = newWindow(this, Listen);
+					}
+				}
+				else
+				{
+					// Single or Tabbed - look for free session
+
+					for (i = 0; i < _sessions.size(); ++i)
+					{
+						S = _sessions.at(i);
+
+						if (S->clientSocket == NULL && S->AGWSession == NULL && S->AGWMonSession == NULL && S->KISSSession == NULL)
+						{
+							Sess = S;
+							break;
+						}
+					}
+				}
+
+				if (Sess == NULL)
+				{
+					// Clear connection
+
+					VARASock->write("DISCONNECT\r");
+				}
+				else
+				{
+					if (Mode[0])
+					{
+						sprintf(Title, "Connected to %s Mode %s", CallFrom, Mode);
+						n = sprintf(Message, "Incoming VARA Connect from %s %s Mode\r\n", CallFrom, Mode);
+					}
+					else
+					{
+						sprintf(Title, "Connected to %s", CallFrom);
+						n = sprintf(Message, "Incoming VARA Connect from %s\r\n", CallFrom);
+					}
+
+					WritetoOutputWindow(Sess, (unsigned char *)Message, n);
+
+					VARASock->Sess = Sess;
+					VARADataSock->Sess = Sess;
+
+					if (TermMode == MDI)
+						Sess->setWindowTitle(Title);
+					else if (TermMode == Tabbed)
+					{
+						tabWidget->setTabText(Sess->Tab, CallFrom);
+						tabWidget->tabBar()->setTabTextColor(Sess->Tab, newTabText);
+					}
+					else if (TermMode == Single)
+						mythis->setWindowTitle(Title);
+
+					setMenus(true);
+
+					if (ConnectBeep)
+						myBeep(&ConnectWAV);
+
+					if (listenCText[0])
+						VARADataSock->write(listenCText);
+
+					QApplication::alert(mythis, 0);
+
+				}
+			}
+		}
+		else if (strcmp(Msg, "DISCONNECTED") == 0)
+		{
+			Ui_ListenSession * Sess = (Ui_ListenSession *)VARASock->Sess;
+
+			if (Sess)
+			{
+				WritetoOutputWindow(Sess, (unsigned char *)"Disconnected\r\n", 14);
+				VARASock->Sess = 0;
+				VARADataSock->Sess = 0;
+
+				if (TermMode == MDI)
+				{
+					if (Sess->SessionType == Mon)			// Mon Only
+						Sess->setWindowTitle("Monitor Session Disconnected");
+					else
+						Sess->setWindowTitle("Disconnected");
+				}
+				else if (TermMode == Tabbed)
+				{
+					if (Sess->SessionType == Mon)			// Mon Only
+						tabWidget->setTabText(Sess->Tab, "Monitor");
+					else
+					{
+						char Label[16];
+						sprintf(Label, "Sess %d", Sess->Tab + 1);
+						tabWidget->setTabText(Sess->Tab, Label);
+					}
+				}
+				else if (TermMode == Single)
+				{
+					if (Sess->AGWMonSession)
+						mythis->setWindowTitle("AGW Monitor Window");
+					else
+					{
+						if (Sess->SessionType == Mon)			// Mon Only
+							this->setWindowTitle("Monitor Session Disconnected");
+						else
+							this->setWindowTitle("Disconnected");
+					}
+				}
+
+				setMenus(false);
+			}
+		}
+
+		Msg = ptr;
+
+		ptr = strchr(Msg, 0x0d);
+	}
+
+
+
+}
+
+void QtTermTCP::onVARASocketStateChanged(QAbstractSocket::SocketState socketState)
+{
+	//	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
+
+	if (socketState == QAbstractSocket::UnconnectedState)
+	{
+		// Close any connections
+
+		Status2->setText("VARA Disconnected");
+		actHost[17]->setVisible(0);
+
+		VARAConnecting = VARAConnected = 0;
+	}
+	else if (socketState == QAbstractSocket::ConnectedState)
+	{
+		// Connect Data Session. Leave Connecting till that completes
+
+		VARADataSock = new myTcpSocket();
+
+		connect(VARADataSock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(VARADatadisplayError(QAbstractSocket::SocketError)));
+		connect(VARADataSock, SIGNAL(readyRead()), this, SLOT(VARADatareadyRead()));
+		connect(VARADataSock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onVARADataSocketStateChanged(QAbstractSocket::SocketState)));
+
+		VARADataSock->connectToHost(VARAHost, VARAPortNum + 1);
+		Status2->setText("VARA Data Connecting");
+	}
+}
+
+
+void QtTermTCP::VARADatadisplayError(QAbstractSocket::SocketError socketError)
+{
+	switch (socketError)
+	{
+	case QAbstractSocket::RemoteHostClosedError:
+		break;
+
+	case QAbstractSocket::HostNotFoundError:
+		QMessageBox::information(this, tr("QtTermTCP"),
+			tr("VARA host was not found. Please check the "
+				"host name and portsettings->"));
+
+		Status2->setText("VARA Connection Failed");
+
+		break;
+
+	case QAbstractSocket::ConnectionRefusedError:
+
+		Status2->setText("VARA Connection Refused");
+		break;
+
+	default:
+
+		Status2->setText("VARA Connection Failed");
+	}
+
+	VARAConnecting = 0;
+	VARAConnected = 0;
+}
+
+void QtTermTCP::VARADatareadyRead()
+{
+	int Read;
+	unsigned char Buffer[4096];
+	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
+
+	Ui_ListenSession * Sess = (Ui_ListenSession *)Socket->Sess;
+
+	// read the data from the socket
+
+	Read = Socket->read((char *)Buffer, 2047);
+
+	while (Read > 0)
+	{
+		//		if (InputMode == 'Y')			// Yapp
+		//		{
+		//			QString myString = QString::fromUtf8((char*)Buffer, Read);
+		//			QByteArray ptr = myString.toLocal8Bit();
+		//			memcpy(Buffer, ptr.data(), ptr.length());
+		//			Read = ptr.length();
+		//		}
+
+		ProcessReceivedData(Sess, Buffer, Read);
+
+		QString myString = QString::fromUtf8((char*)Buffer);
+		//		qDebug() << myString;
+		Read = Socket->read((char *)Buffer, 2047);
+	}
+}
+
+
+void QtTermTCP::onVARADataSocketStateChanged(QAbstractSocket::SocketState socketState)
+{
+	//	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
+
+	if (socketState == QAbstractSocket::UnconnectedState)
+	{
+		// Close any connections
+
+		Status2->setText("VARA Disconnected");
+		actHost[17]->setVisible(0);
+
+		VARAConnecting = VARAConnected = 0;
+	}
+	else if (socketState == QAbstractSocket::ConnectedState)
+	{
+		char VARACommand[256];
+
+		VARAConnected = 1;
+		VARAConnecting = 0;
+
+		Status2->setText("VARA Connected");
+
+		actHost[17]->setVisible(1);			// Enable VARA Connect Line
+
+		sprintf(VARACommand, "MYCALL %s\r", VARATermCall);
+		VARASock->write(VARACommand);
+
+		if (VARA500)
+			VARASock->write("BW500\r");
+		else if (VARA2300)
+			VARASock->write("BW2300\r");
+		else if (VARA2750)
+			VARASock->write("BW2750\r");
+
+		VARASock->write("COMPRESSION FILES\r");
+
+		if (VARAInit[0])
+		{
+			char Copy[512];
+			char * param, *context;
+
+			strcpy(Copy, VARAInit);
+
+			param = strtok_s(Copy, ",", &context);
+
+			while (param && param[0])
+			{
+				sprintf(VARACommand, "%s\r", param);
+				VARASock->write(VARACommand);
+				param = strtok_s(nullptr, ",", &context);
+			}
+		}
+
+		if (listenEnable)
+			VARASock->write("LISTEN ON\r");
+	}
+}
+
+// PTT Stuff
+
+#include "hidapi.h"
+
+// Serial Port Stuff
+
+
+QTcpSocket * HAMLIBsock;
+int HAMLIBConnected = 0;
+int HAMLIBConnecting = 0;
+
+void QtTermTCP::HAMLIBdisplayError(QAbstractSocket::SocketError socketError)
+{
+	switch (socketError)
+	{
+	case QAbstractSocket::RemoteHostClosedError:
+		break;
+
+	case QAbstractSocket::HostNotFoundError:
+		QMessageBox::information(nullptr, tr("QtSM"),
+			"HAMLIB host was not found. Please check the "
+			"host name and portsettings->");
+
+		break;
+
+	case QAbstractSocket::ConnectionRefusedError:
+
+		qDebug() << "HAMLIB Connection Refused";
+		break;
+
+	default:
+
+		qDebug() << "HAMLIB Connection Failed";
+		break;
+
+	}
+
+	HAMLIBConnecting = 0;
+	HAMLIBConnected = 0;
+}
+
+void QtTermTCP::HAMLIBreadyRead()
+{
+	unsigned char Buffer[4096];
+	QTcpSocket* Socket = static_cast<QTcpSocket*>(QObject::sender());
+
+	// read the data from the socket. Don't do anyhing with it at the moment
+
+	Socket->read((char *)Buffer, 4095);
+}
+
+void QtTermTCP::onHAMLIBSocketStateChanged(QAbstractSocket::SocketState socketState)
+{
+	if (socketState == QAbstractSocket::UnconnectedState)
+	{
+		// Close any connections
+
+		HAMLIBConnected = 0;
+		HAMLIBConnecting = 0;
+
+		//	delete (HAMLIBsock);
+		//	HAMLIBsock = 0;
+
+		qDebug() << "HAMLIB Connection Closed";
+
+	}
+	else if (socketState == QAbstractSocket::ConnectedState)
+	{
+		HAMLIBConnected = 1;
+		HAMLIBConnecting = 0;
+		qDebug() << "HAMLIB Connected";
+	}
+}
+
+
+void QtTermTCP::ConnecttoHAMLIB()
+{
+	delete(HAMLIBsock);
+
+	HAMLIBConnected = 0;
+	HAMLIBConnecting = 1;
+
+	HAMLIBsock = new QTcpSocket();
+
+	connect(HAMLIBsock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(HAMLIBdisplayError(QAbstractSocket::SocketError)));
+	connect(HAMLIBsock, SIGNAL(readyRead()), this, SLOT(HAMLIBreadyRead()));
+	connect(HAMLIBsock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onHAMLIBSocketStateChanged(QAbstractSocket::SocketState)));
+
+	HAMLIBsock->connectToHost(HamLibHost, HamLibPort);
+
+	return;
+}
+
+void QtTermTCP::HAMLIBSetPTT(int PTTState)
+{
+	char Msg[16];
+
+	if (HAMLIBsock == nullptr || HAMLIBsock->state() != QAbstractSocket::ConnectedState)
+		ConnecttoHAMLIB();
+
+	if (HAMLIBsock == nullptr || HAMLIBsock->state() != QAbstractSocket::ConnectedState)
+		return;
+
+	sprintf(Msg, "T %d\r\n", PTTState);
+	HAMLIBsock->write(Msg);
+
+	HAMLIBsock->waitForBytesWritten(3000);
+
+	QByteArray datas = HAMLIBsock->readAll();
+
+	qDebug(datas.data());
+}
+
+QTcpSocket * FLRigsock;
+int FLRigConnected = 0;
+int FLRigConnecting = 0;
+
+void QtTermTCP::FLRigdisplayError(QAbstractSocket::SocketError socketError)
+{
+	switch (socketError)
+	{
+	case QAbstractSocket::RemoteHostClosedError:
+		break;
+
+	case QAbstractSocket::HostNotFoundError:
+		QMessageBox::information(nullptr, tr("QtSM"),
+			"FLRig host was not found. Please check the "
+			"host name and portsettings->");
+
+		break;
+
+	case QAbstractSocket::ConnectionRefusedError:
+
+		qDebug() << "FLRig Connection Refused";
+		break;
+
+	default:
+
+		qDebug() << "FLRig Connection Failed";
+		break;
+
+	}
+
+	FLRigConnecting = 0;
+	FLRigConnected = 0;
+}
+
+void QtTermTCP::FLRigreadyRead()
+{
+	unsigned char Buffer[4096];
+	QTcpSocket* Socket = static_cast<QTcpSocket*>(QObject::sender());
+
+	// read the data from the socket. Don't do anyhing with it at the moment
+
+	Socket->read((char *)Buffer, 4095);
+}
+
+void QtTermTCP::onFLRigSocketStateChanged(QAbstractSocket::SocketState socketState)
+{
+	if (socketState == QAbstractSocket::UnconnectedState)
+	{
+		// Close any connections
+
+		FLRigConnected = 0;
+		FLRigConnecting = 0;
+
+		//	delete (FLRigsock);
+		//	FLRigsock = 0;
+
+		qDebug() << "FLRig Connection Closed";
+
+	}
+	else if (socketState == QAbstractSocket::ConnectedState)
+	{
+		FLRigConnected = 1;
+		FLRigConnecting = 0;
+		qDebug() << "FLRig Connected";
+	}
+}
+
+
+void QtTermTCP::ConnecttoFLRig()
+{
+	delete(FLRigsock);
+
+	FLRigConnected = 0;
+	FLRigConnecting = 1;
+
+	FLRigsock = new QTcpSocket();
+
+	connect(FLRigsock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(FLRigdisplayError(QAbstractSocket::SocketError)));
+	connect(FLRigsock, SIGNAL(readyRead()), this, SLOT(FLRigreadyRead()));
+	connect(FLRigsock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onFLRigSocketStateChanged(QAbstractSocket::SocketState)));
+
+	FLRigsock->connectToHost(FLRigHost, FLRigPort);
+
+	return;
+}
+
+static char MsgHddr[] = "POST /RPC2 HTTP/1.1\r\n"
+"User-Agent: XMLRPC++ 0.8\r\n"
+"Host: 127.0.0.1:7362\r\n"
+"Content-Type: text/xml\r\n"
+"Content-length: %d\r\n"
+"\r\n%s";
+
+static char Req[] = "<?xml version=\"1.0\"?>\r\n"
+"<methodCall><methodName>%s</methodName>\r\n"
+"%s"
+"</methodCall>\r\n";
+
+void QtTermTCP::FLRigSetPTT(int PTTState)
+{
+	int Len;
+	char ReqBuf[512];
+	char SendBuff[512];
+	char ValueString[256] = "";
+
+	sprintf(ValueString, "<params><param><value><i4>%d</i4></value></param></params\r\n>", PTTState);
+
+	Len = sprintf(ReqBuf, Req, "rig.set_ptt", ValueString);
+	Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
+
+	if (FLRigsock == nullptr || FLRigsock->state() != QAbstractSocket::ConnectedState)
+		ConnecttoFLRig();
+
+	if (FLRigsock == nullptr || FLRigsock->state() != QAbstractSocket::ConnectedState)
+		return;
+
+	FLRigsock->write(SendBuff);
+
+	FLRigsock->waitForBytesWritten(3000);
+
+	QByteArray datas = FLRigsock->readAll();
+
+	qDebug(datas.data());
+}
+
+
+
+void QtTermTCP::CATChanged(bool State)
+{
+	UNUSED(State);
+	PTTPortChanged(0);
+}
+
+void QtTermTCP::VARAHFChanged(bool State)
+{
+	Dev->HFMode->setVisible(State);
+
+	if (State)
+	{
+		Dev->TNCInfo->setTitle("VARA HF Paramters");
+		Dev->Host->setText(VARAHostHF);
+		Dev->Port->setText(QString::number(VARAPortHF));
+		Dev->Path->setText(VARAPathHF);
+	}
+}
+
+void QtTermTCP::VARAFMChanged(bool State)
+{
+	if (State)
+	{
+		Dev->TNCInfo->setTitle("VARA FM Paramters");
+		Dev->Host->setText(VARAHostFM);
+		Dev->Port->setText(QString::number(VARAPortFM));
+		Dev->Path->setText(VARAPathFM);
+	}
+}
+
+void QtTermTCP::VARASATChanged(bool State)
+{
+	if (State)
+	{
+		Dev->TNCInfo->setTitle("VARA SAT Paramters");
+		Dev->Host->setText(VARAHostSAT);
+		Dev->Port->setText(QString::number(VARAPortSAT));
+		Dev->Path->setText(VARAPathSAT);
+	}
+}
+
+void QtTermTCP::SetVARAParams()
+{
+	Dev->Host->setText(VARAHost);
+	Dev->Port->setText(QString::number(VARAPortNum));
+	Dev->Path->setText(VARAPath);
+	Dev->InitCommands->setText(VARAInit);
+}
+
+void QtTermTCP::PTTPortChanged(int Selected)
+{
+	UNUSED(Selected);
+
+	QVariant Q = Dev->PTTPort->currentText();
+	strcpy(NewPTTPort, Q.toString().toUtf8());
+
+	Dev->RTSDTR->setVisible(false);
+	Dev->CAT->setVisible(false);
+
+	Dev->PTTOnLab->setVisible(false);
+	Dev->PTTOn->setVisible(false);
+	Dev->PTTOff->setVisible(false);
+	Dev->PTTOffLab->setVisible(false);
+	Dev->CATLabel->setVisible(false);
+	Dev->CATSpeed->setVisible(false);
+	Dev->CATHex->setVisible(false);
+	Dev->CATText->setVisible(false);
+
+	Dev->GPIOLab->setVisible(false);
+	Dev->GPIOLeft->setVisible(false);
+	Dev->GPIORight->setVisible(false);
+	Dev->GPIOLab2->setVisible(false);
+
+	Dev->CM108Label->setVisible(false);
+	Dev->VIDPID->setVisible(false);
+
+	if (strcmp(NewPTTPort, "None") == 0)
+	{
+	}
+	else if (strcmp(NewPTTPort, "GPIO") == 0)
+	{
+		Dev->GPIOLab->setVisible(true);
+		Dev->GPIOLeft->setVisible(true);
+	}
+
+	else if (strcmp(NewPTTPort, "CM108") == 0)
+	{
+		Dev->CM108Label->setVisible(true);
+#ifdef WIN32
+		Dev->CM108Label->setText("CM108 VID/PID");
+#else
+		Dev->CM108Label->setText("CM108 Device");
+#endif
+		Dev->VIDPID->setText(CM108Addr);
+		Dev->VIDPID->setVisible(true);
+	}
+	else if (strcmp(NewPTTPort, "HAMLIB") == 0)
+	{
+		Dev->CM108Label->setVisible(true);
+		Dev->CM108Label->setText("rigctrld Port");
+		Dev->VIDPID->setText(QString::number(HamLibPort));
+		Dev->VIDPID->setVisible(true);
+		Dev->PTTOnLab->setText("rigctrld Host");
+		Dev->PTTOnLab->setVisible(true);
+		Dev->PTTOn->setText(HamLibHost);
+		Dev->PTTOn->setVisible(true);
+	}
+	else if (strcmp(NewPTTPort, "FLRIG") == 0)
+	{
+		Dev->CM108Label->setVisible(true);
+		Dev->CM108Label->setText("FLRig Port");
+		Dev->VIDPID->setText(QString::number(FLRigPort));
+		Dev->VIDPID->setVisible(true);
+		Dev->PTTOnLab->setText("FLRig Host");
+		Dev->PTTOnLab->setVisible(true);
+		Dev->PTTOn->setText(FLRigHost);
+		Dev->PTTOn->setVisible(true);
+	}
+
+	else
+	{
+		Dev->RTSDTR->setVisible(true);
+		Dev->CAT->setVisible(true);
+
+		if (Dev->CAT->isChecked())
+		{
+			Dev->CATHex->setVisible(true);
+			Dev->CATText->setVisible(true);
+			Dev->PTTOnLab->setVisible(true);
+			Dev->PTTOnLab->setText("PTT On String");
+			Dev->PTTOn->setText(PTTOnString);
+			Dev->PTTOn->setVisible(true);
+			Dev->PTTOff->setVisible(true);
+			Dev->PTTOffLab->setVisible(true);
+			Dev->PTTOff->setVisible(true);
+			Dev->PTTOff->setText(PTTOffString);
+			Dev->CATLabel->setVisible(true);
+			Dev->CATSpeed->setVisible(true);
+			Dev->CATSpeed->setText(QString::number(PTTBAUD));
+		}
+	}
+}
+
+
+
+void DecodeCM108(char * ptr)
+{
+	// Called if Device Name or PTT = Param is CM108
+
+#ifdef WIN32
+
+	// Next Param is VID and PID - 0xd8c:0x8 or Full device name
+	// On Windows device name is very long and difficult to find, so 
+	//	easier to use VID/PID, but allow device in case more than one needed
+
+	char * next;
+	long VID = 0, PID = 0;
+	char product[256] = "Unknown";
+
+	struct hid_device_info *devs, *cur_dev;
+	const char *path_to_open = NULL;
+	hid_device *handle = NULL;
+
+	if (strlen(ptr) > 16)
+		CM108Device = _strdup(ptr);
+	else
+	{
+		VID = strtol(ptr, &next, 0);
+		if (next)
+			PID = strtol(++next, &next, 0);
+
+		// Look for Device
+
+		devs = hid_enumerate((unsigned short)VID, (unsigned short)PID);
+		cur_dev = devs;
+
+		while (cur_dev)
+		{
+			if (cur_dev->product_string)
+				wcstombs(product, cur_dev->product_string, 255);
+
+			printf("HID Device %s VID %X PID %X", product, cur_dev->vendor_id, cur_dev->product_id);
+			if (cur_dev->vendor_id == VID && cur_dev->product_id == PID)
+			{
+				path_to_open = cur_dev->path;
+				break;
+			}
+			cur_dev = cur_dev->next;
+		}
+
+		if (path_to_open)
+		{
+			handle = hid_open_path(path_to_open);
+
+			if (handle)
+			{
+				hid_close(handle);
+				CM108Device = _strdup(path_to_open);
+			}
+			else
+			{
+				printf("Unable to open CM108 device %x %x", VID, PID);
+			}
+		}
+		else
+			printf("Couldn't find CM108 device %x %x", VID, PID);
+
+		hid_free_enumeration(devs);
+	}
+#else
+
+	// Linux - Next Param HID Device, eg /dev/hidraw0
+
+	CM108Device = strdup(ptr);
+#endif
+}
+
+
+void QtTermTCP::OpenPTTPort()
+{
+	PTTMode &= ~PTTCM108;
+	PTTMode &= ~PTTHAMLIB;
+	PTTMode &= ~PTTFLRIG;
+
+	if (PTTPort[0] && strcmp(PTTPort, "None") != 0)
+	{
+		if (PTTMode == PTTCAT)
+		{
+			// convert config strings from Hex
+
+			if (CATHex == 0)		// Ascii Strings
+			{
+				strcpy((char *)PTTOffCmd, PTTOffString);
+				PTTOffCmdLen = strlen(PTTOffString);
+
+				strcpy((char *)PTTOnCmd, PTTOnString);
+				PTTOnCmdLen = strlen(PTTOnString);
+			}
+			else
+			{
+				char * ptr1 = PTTOffString;
+				unsigned char * ptr2 = PTTOffCmd;
+				char c;
+				int val;
+
+				while ((c = *(ptr1++)))
+				{
+					val = c - 0x30;
+					if (val > 15) val -= 7;
+					val <<= 4;
+					c = *(ptr1++) - 0x30;
+					if (c > 15) c -= 7;
+					val |= c;
+					*(ptr2++) = val;
+				}
+
+				PTTOffCmdLen = ptr2 - PTTOffCmd;
+
+				ptr1 = PTTOnString;
+				ptr2 = PTTOnCmd;
+
+				while ((c = *(ptr1++)))
+				{
+					val = c - 0x30;
+					if (val > 15) val -= 7;
+					val <<= 4;
+					c = *(ptr1++) - 0x30;
+					if (c > 15) c -= 7;
+					val |= c;
+					*(ptr2++) = val;
+				}
+
+				PTTOnCmdLen = ptr2 - PTTOnCmd;
+			}
+		}
+
+		if (strcmp(PTTPort, "GPIO") == 0)
+		{
+			// Initialise GPIO for PTT if available
+
+#ifdef __ARM_ARCH
+
+//			if (gpioInitialise() == 0)
+//			{
+//				printf("GPIO interface for PTT available\n");
+//				gotGPIO = TRUE;
+
+//				SetupGPIOPTT();
+//			}
+//			else
+//				printf("Couldn't initialise GPIO interface for PTT\n");
+//
+#else
+			printf("GPIO interface for PTT not available on this platform\n");
+#endif
+
+		}
+		else if (strcmp(PTTPort, "CM108") == 0)
+		{
+			DecodeCM108(CM108Addr);
+			PTTMode |= PTTCM108;
+		}
+
+		else if (strcmp(PTTPort, "HAMLIB") == 0)
+		{
+			PTTMode |= PTTHAMLIB;
+			HAMLIBSetPTT(0);			// to open port
+			return;
+		}
+
+		else if (strcmp(PTTPort, "FLRIG") == 0)
+		{
+			PTTMode |= PTTFLRIG;
+			FLRigSetPTT(0);			// to open port
+			return;
+		}
+
+		else		//  Serial Port
+		{
+#ifdef USESERIAL
+			hPTTDevice = new QSerialPort(this);
+			hPTTDevice->setPortName(PTTPort);
+			hPTTDevice->setBaudRate(PTTBAUD);
+			hPTTDevice->setDataBits(QSerialPort::Data8);
+			hPTTDevice->setParity(QSerialPort::NoParity);
+			hPTTDevice->setStopBits(QSerialPort::OneStop);
+			hPTTDevice->setFlowControl(QSerialPort::NoFlowControl);
+			if (hPTTDevice->open(QIODevice::ReadWrite))
+			{
+				qDebug() << "PTT Port Opened";
+			}
+			else
+			{
+				QMessageBox msgBox;
+				msgBox.setText("PTT COM Port Open Failed.");
+				msgBox.exec();
+				qDebug() << "PTT Port Open failed";
+				delete(hPTTDevice);
+				hPTTDevice = 0;
+			}
+#endif
+		}
+	}
+}
+
+void ClosePTTPort()
+{
+#ifdef USESERIAL
+	if (hPTTDevice)
+		hPTTDevice->close();
+	hPTTDevice = 0;
+#endif
+}
+
+#ifndef ANDRIOD
+
+void CM108_set_ptt(int PTTState)
+{
+	unsigned char io[5];
+	int n;
+
+	io[0] = 0;
+	io[1] = 0;
+	io[2] = 1 << (3 - 1);
+	io[3] = PTTState << (3 - 1);
+	io[4] = 0;
+
+	if (CM108Device == NULL)
+		return;
+
+#ifdef WIN32
+	hid_device *handle;
+
+	handle = hid_open_path(CM108Device);
+
+	if (!handle) {
+		printf("unable to open device\n");
+		return;
+	}
+
+	n = hid_write(handle, io, 5);
+	if (n < 0)
+	{
+		printf("Unable to write()\n");
+		printf("Error: %ls\n", hid_error(handle));
+	}
+
+	hid_close(handle);
+
+#else
+
+	int fd;
+
+	fd = open(CM108Device, O_WRONLY);
+
+	if (fd == -1)
+	{
+		printf("Could not open %s for write, errno=%d\n", CM108Device, errno);
+		return;
+	}
+
+	io[0] = 0;
+	io[1] = 0;
+	io[2] = 1 << (3 - 1);
+	io[3] = PTTState << (3 - 1);
+	io[4] = 0;
+
+	n = write(fd, io, 5);
+	if (n != 5)
+	{
+		printf("Write to %s failed, n=%d, errno=%d\n", CM108Device, n, errno);
+	}
+
+	close(fd);
+#endif
+	return;
+
+}
+
+#endif
+
+void QtTermTCP::RadioPTT(bool PTTState)
+{
+#ifdef __ARM_ARCH
+	if (useGPIO)
+	{
+		//		gpioWrite(pttGPIOPin, (pttGPIOInvert ? (1 - PTTState) : (PTTState)));
+		//		return;
+	}
+
+#endif
+
+	if ((PTTMode & PTTCM108))
+	{
+		CM108_set_ptt(PTTState);
+		return;
+	}
+
+	if ((PTTMode & PTTHAMLIB))
+	{
+		HAMLIBSetPTT(PTTState);
+		return;
+	}
+
+	if ((PTTMode & PTTFLRIG))
+	{
+		FLRigSetPTT(PTTState);
+		return;
+	}
+
+#ifdef USESERIAL
+
+	if (hPTTDevice == 0)
+		return;
+
+	if ((PTTMode & PTTCAT))
+	{
+		if (PTTState)
+			hPTTDevice->write((char *)PTTOnCmd, PTTOnCmdLen);
+		else
+			hPTTDevice->write((char *)PTTOffCmd, PTTOffCmdLen);
+
+		hPTTDevice->flush();
+		//		hPTTDevice->error();
+		return;
+
+	}
+
+
+	if ((PTTMode & PTTRTS))
+	{
+		int n = hPTTDevice->setRequestToSend(PTTState);
+		n = n;
+	}
+
+#endif
+
+}
+
+
+
+extern "C" void WriteDebugLog(char * Mess)
+{
+	qDebug() << Mess;
+}
+
+void QtTermTCP::ConnecttoKISS()
+{
+	if (strcmp(SerialPort, "TCP") == 0)
+	{
+		delete(KISSSock);
+
+		KISSSock = new myTcpSocket();
+		KISSSockCopy[0] = (void *)KISSSock;
+
+
+		connect(KISSSock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(KISSdisplayError(QAbstractSocket::SocketError)));
+		connect(KISSSock, SIGNAL(readyRead()), this, SLOT(KISSreadyRead()));
+		connect(KISSSock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onKISSSocketStateChanged(QAbstractSocket::SocketState)));
+
+		KISSSock->connectToHost(KISSHost, KISSPortNum);
+
+		Status3->setText("KISS Connecting");
+	}
+	else
+		openSerialPort();
+
+	return;
+}
+
+
+void QtTermTCP::KISSTimer()
+{
+	// Runs every 10 Seconds
+
+	if (KISSConnected == 0 && KISSConnecting == 0)
+	{
+		ConnecttoKISS();
+	}
+	else
+	{
+		// Verify Serial port is still ok
+
+ 		if (m_serial && KISSConnected)
+		{
+			m_serial->clearError();
+			boolean rc = m_serial->isDataTerminalReady();
+
+			if (m_serial->error())
+			{
+				Debugprintf("Serial Port Lost - isOpen %d Error %d", m_serial->isOpen(), m_serial->error());
+				closeSerialPort();
+			}
+		}
+	}
+}
+
+
+
+void QtTermTCP::KISSdisplayError(QAbstractSocket::SocketError socketError)
+{
+	switch (socketError)
+	{
+	case QAbstractSocket::RemoteHostClosedError:
+		break;
+
+	case QAbstractSocket::HostNotFoundError:
+		QMessageBox::information(this, tr("QtTermTCP"),
+			tr("KISS host was not found. Please check the "
+				"host name and portsettings->"));
+
+		Status3->setText("KISS Connection Failed");
+
+		break;
+
+	case QAbstractSocket::ConnectionRefusedError:
+
+		Status3->setText("KISS Connection Refused");
+		break;
+
+	default:
+
+		Status3->setText("KISS Connection Failed");
+	}
+
+	KISSConnecting = 0;
+	KISSConnected = 0;
+}
+
+
+extern "C" void KISSSendtoServer(myTcpSocket* Socket, char * Data, int Length)
+{
+	if (m_serial)
+	{
+		if (m_serial->isOpen())
+		{
+			m_serial->clearError();
+
+			int n = m_serial->write(Data, Length);
+
+			n = m_serial->flush();
+
+			if (m_serial->error())
+			{
+				Debugprintf("Serial Flush Error - Requested = %d Actual %d Error %d", Length, n, m_serial->error());
+				closeSerialPort();
+			}
+		}
+	}
+	else if (Socket)
+		Socket->write(Data, Length);
+}
+
+
+
+void QtTermTCP::KISSreadyRead()
+{
+	int Read;
+	unsigned char Buffer[4096];	myTcpSocket* Socket = static_cast<myTcpSocket*>(QObject::sender());
+
+	// read the data from the socket
+
+	Read = Socket->read((char *)Buffer, 4095);
+
+	KISSDataReceived(Socket, Buffer, Read);
+
+}
+
+extern "C" void KISS_del_socket(void * socket);
+extern "C" void KISS_add_stream(void * Socket);
+
+void QtTermTCP::onKISSSocketStateChanged(QAbstractSocket::SocketState socketState)
+{
+	//	myTcpSocket* sender = static_cast<myTcpSocket*>(QObject::sender());
+
+	QTcpSocket* sender = static_cast<QTcpSocket*>(QObject::sender());
+
+	if (socketState == QAbstractSocket::UnconnectedState)
+	{
+		// Close any connections
+
+		Ui_ListenSession * Sess = NULL;
+
+		Status3->setText("KISS Disconnected");
+		actHost[18]->setEnabled(0);
+
+		KISSConnecting = KISSConnected = 0;
+
+		// Free the monitor Window
+
+		if (KISSMonSess)
+		{
+			Sess = KISSMonSess;
+
+			if (TermMode == MDI)
+				Sess->setWindowTitle("Monitor Session Disconnected");
+
+			else if (TermMode == Tabbed)
+				tabWidget->setTabText(Sess->Tab, "Monitor");
+
+			KISSMonSess = nullptr;
+		}
+
+		KISS_del_socket(sender);
+		KISSSock = NULL;
+	}
+	else if (socketState == QAbstractSocket::ConnectedState)
+	{
+		int i;
+
+		KISSConnected = 1;
+		KISSConnecting = 0;
+
+		Status3->setText("KISS Connected");
+		actHost[18]->setEnabled(1);			// Enable KISS Connect Line
+
+		KISS_add_stream(sender);
+
+		// send TXDelay if enabled
+
+		if (sendTXDelay[0])
+		{
+			unsigned char Msg[5] = { FEND, 1, 25 , FEND };
+
+			Msg[2] = txdelay[0] / 10;
+			KISSSock->write((char *)Msg, 4);
+		}
+
+		// Attach a Monitor Window if available
+
+		Ui_ListenSession * Sess = NULL;
+		Ui_ListenSession * S;
+
+		if (TermMode == MDI)
+		{
+			// See if an old session can be reused
+
+			for (int i = 0; i < _sessions.size(); ++i)
+			{
+				S = _sessions.at(i);
+
+				//	for (Ui_ListenSession * S: _sessions)
+				//	{
+				if ((S->SessionType == Mon) && S->clientSocket == NULL && S->KISSSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess))  && S != KISSMonSess)
+				{
+					Sess = S;
+					break;
+				}
+			}
+
+			// Create a window if none found, else reuse old
+
+			if (Sess == NULL)
+			{
+				Sess = newWindow((QObject *)mythis, Mon, "");
+			}
+		}
+		else if (TermMode == Tabbed)
+		{
+			// Tabbed - look for free session
+
+			for (i = 8; i; i--)
+			{
+				S = _sessions.at(i);
+
+				if (S->clientSocket == NULL && S->KISSSession == NULL  && S->AGWSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
+				{
+					Sess = S;
+					break;
+				}
+			}
+		}
+		else if (TermMode == Single && (singlemodeFormat & Mon))
+		{
+			S = _sessions.at(0);
+
+			if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL && (AGWUsers == NULL || (S != AGWUsers->MonSess)) && S != KISSMonSess)
+				Sess = S;
+
+		}
+
+		if (Sess)
+		{
+			KISSMonSess = Sess;			// Flag as in use
+
+			if (TermMode == MDI)
+				Sess->setWindowTitle("KISS Monitor Window");
+			else if (TermMode == Tabbed)
+				tabWidget->setTabText(Sess->Tab, "KISS Mon");
+			else if (TermMode == Single)
+				mythis->setWindowTitle("KISS Monitor Window");
+
+			Sess->mlocaltime = KISSLocalTime;
+			Sess->MonitorNODES = KISSMonNodes;
+
+			//			if (TermMode == Single)	
+			//			{
+			//				discAction->setEnabled(false);
+			//				YAPPSend->setEnabled(false);
+			//				connectMenu->setEnabled(false);
+			//			}
+		}
+	}
+}
+
+
+extern "C" char * frame_monitor(string * frame, char * code, bool tx_stat);
+extern "C" char * ShortDateTime();
+
+extern "C" void monitor_frame(int snd_ch, string * frame, char * code, int  tx, int excluded)
+{
+	UNUSED(excluded);
+	UNUSED(snd_ch);
+
+	int Len;
+	char Msg[1024];
+
+	if (tx)
+		sprintf(Msg, "\x1b\x10%s", frame_monitor(frame, code, tx));
+	else
+		sprintf(Msg, "\x1b\x11%s", frame_monitor(frame, code, tx));
+
+	Len = strlen(Msg);
+
+	if (Len < 10)		// Suppressed NODES
+		return;
+
+	if (Msg[Len - 1] != '\r')
+	{
+		Msg[Len++] = '\r';
+		Msg[Len] = 0;
+	}
+
+	if (KISSMonSess)
+		WritetoMonWindow(KISSMonSess, (unsigned char *)Msg, Len);
+
+}
+
+extern "C" Ui_ListenSession * ax25IncomingConnect(TAX25Port * AX25Sess)
+{
+	// Look for/create Terminal Window for connection
+
+	Ui_ListenSession * Sess = NULL;
+	Ui_ListenSession * S;
+	char Title[80];
+	int i = 0;
+
+	if (TermMode == MDI)
+	{
+		// See if an old session can be reused
+
+		for (int i = 0; i < _sessions.size(); ++i)
+		{
+			S = _sessions.at(i);
+
+			if ((S->SessionType & Listen) && S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL)
+			{
+				Sess = S;
+				break;
+			}
+		}
+
+		// Create a window if none found, else reuse old
+
+		if (Sess == NULL)
+		{
+			Sess = newWindow((QObject *)mythis, Listen, "");
+		}
+	}
+	else
+	{
+		// Single or Tabbed - look for free session
+
+
+		for (i = 0; i < _sessions.size(); ++i)
+		{
+			S = _sessions.at(i);
+
+			if (S->clientSocket == NULL && S->AGWSession == NULL && S->KISSSession == NULL)
+			{
+				Sess = S;
+				break;
+			}
+		}
+
+		if (Sess == NULL)
+		{
+			// Clear connection
+
+			return NULL;
+		}
+	}
+
+	if (Sess)
+	{
+		sprintf(Title, "Connected to %s", AX25Sess->corrcall);
+
+		if (TermMode == MDI)
+		{
+			Sess->setWindowTitle(Title);
+		}
+		else if (TermMode == Tabbed)
+		{
+			tabWidget->setTabText(i, AX25Sess->corrcall);
+			tabWidget->tabBar()->setTabTextColor(i, newTabText);
+		}
+		else if (TermMode == Single)
+			mythis->setWindowTitle(Title);
+
+		AX25Sess->port = 0;
+		AX25Sess->Sess = Sess;				// Crosslink KISS and Term Sessions
+		AX25Sess->PID = 240;;
+
+		Sess->KISSSession = AX25Sess;
+
+		setMenus(true);
+
+		if (ConnectBeep)
+			myBeep(&ConnectWAV);
+
+		QApplication::alert(mythis, 0);
+
+		// Send CText if defined
+
+		if (listenCText[0])
+			SendtoAX25(Sess->KISSSession, (unsigned char *)listenCText, (int)strlen(listenCText));
+	}
+	return Sess;
+}
+
+
+extern "C" void AX25_disc(TAX25Port * AX25Sess, Byte mode)
+{
+	char Msg[128];
+	int Len = 0;
+	Ui_ListenSession * Sess = (Ui_ListenSession *)AX25Sess->Sess;
+
+	if (AX25Sess->status == STAT_TRY_LINK)
+	{
+		// Connect failed
+
+		Len = sprintf(Msg, "Connection to %s failed\r", AX25Sess->corrcall);
+	}
+	else
+	{
+		switch (mode)
+		{
+		case MODE_OTHER:
+		case MODE_OUR:
+
+			Len = sprintf(Msg, "Disconnected from %s\r", AX25Sess->corrcall);
+			break;
+
+		case MODE_RETRY:
+
+			Len = sprintf(Msg, "Disconnected from %s - Retry count exceeded\r", AX25Sess->corrcall);
+			break;
+
+		};
+	}
+
+	SendtoTerm(Sess, Msg, Len);
+	ClearSessLabel(Sess);
+	Sess->KISSSession = NULL;
+	AX25Sess->Sess = 0;
+
+	setMenus(0);
+};
+
+int QtTermTCP::openSerialPort()
+{
+	if (m_serial && m_serial->isOpen())
+	{
+		m_serial->close();
+	}
+
+	m_serial = nullptr;
+	m_serial = new QSerialPort(this);
+
+	m_serial->setPortName(SerialPort);
+	boolean ok = m_serial->setBaudRate(KISSBAUD);
+
+	if (m_serial->open(QIODevice::ReadWrite))
+	{
+		int i;
+
+		ok = m_serial->setRequestToSend(true);
+
+		connect(m_serial, &QSerialPort::readyRead, this, &QtTermTCP::readSerialData);
+		//		connect(m_serial, &QSerialPort::errorOccurred, this, &QtTermTCP::handleError);
+
+		KISSConnected = 1;
+		KISSConnecting = 0;
+
+		Status3->setText("KISS Connected");
+		actHost[18]->setEnabled(1);			// Enable KISS Connect Line
+
+		KISS_add_stream(m_serial);
+
+		// send TXDelay if enabled
+
+		if (sendTXDelay[0])
+		{
+			unsigned char Msg[5] = { FEND, 1, 25 , FEND };
+
+			Msg[2] = txdelay[0] / 10;
+			m_serial->write((char *)Msg, 4);
+		}
+
+		// Attach a Monitor Window if available
+
+		Ui_ListenSession * Sess = NULL;
+		Ui_ListenSession * S;
+
+		if (TermMode == MDI)
+		{
+			// See if an old session can be reused
+
+			for (int i = 0; i < _sessions.size(); ++i)
+			{
+				S = _sessions.at(i);
+
+				//	for (Ui_ListenSession * S: _sessions)
+				//	
+				if ((S->SessionType == Mon) && S->clientSocket == NULL && S->KISSSession == NULL)
+				{
+					Sess = S;
+					break;
+				}
+			}
+
+			// Create a window if none found, else reuse old
+
+			if (Sess == NULL)
+			{
+				Sess = newWindow((QObject *)mythis, Mon, "");
+			}
+		}
+		else if (TermMode == Tabbed)
+		{
+			// Tabbed - look for free session
+
+			for (i = 8; i; i--)
+			{
+				S = _sessions.at(i);
+
+				if (S->clientSocket == NULL && S->KISSSession == NULL)
+				{
+					Sess = S;
+					break;
+				}
+			}
+		}
+		else if (TermMode == Single && (singlemodeFormat & Mon))
+		{
+			S = _sessions.at(0);
+
+			if (S->clientSocket == NULL && S->KISSSession == NULL)
+				Sess = S;
+
+		}
+
+		if (Sess)
+		{
+			KISSMonSess = Sess;			// Flag as in use
+
+			if (TermMode == MDI)
+				Sess->setWindowTitle("KISS Monitor Window");
+			else if (TermMode == Tabbed)
+				tabWidget->setTabText(Sess->Tab, "KISS Mon");
+			else if (TermMode == Single)
+				mythis->setWindowTitle("KISS Monitor Window");
+
+			//			if (TermMode == Single)	
+			//			{
+			//				discAction->setEnabled(false);
+			//				YAPPSend->setEnabled(false);
+			//				connectMenu->setEnabled(false);
+			//			}
+		}
+
+
+
+		return 1;
+	}
+	else
+	{
+		Status3->setText("KISS Open Failed");
+		KISSConnected = 0;
+		KISSConnecting = 0;
+		return 0;
+	}
+}
+
+
+
+void closeSerialPort()
+{
+	if (m_serial && m_serial->isOpen())
+	{
+		m_serial->close();
+		m_serial = nullptr;
+	}
+
+	m_serial = nullptr;
+
+	KISSConnected = 0;
+	KISSConnecting = 0;
+
+	Status3->setText("KISS Closed");
+	actHost[18]->setEnabled(0);			// Enable KISS Connect Line
+}
+
+void QtTermTCP::readSerialData()
+{
+	int Read;
+	unsigned char Buffer[8192];
+
+	// read the data from the socket
+
+	m_serial->clearError();
+
+	Read = m_serial->read((char *)Buffer, 2047);
+
+	if (m_serial->error())
+	{
+		Debugprintf("Serial Read Error - RC %d Error %d", Read, m_serial->error());
+		closeSerialPort();
+		return;
+	}
+
+
+	while (Read > 0)
+	{
+		KISSDataReceived(m_serial, Buffer, Read);
+		Read = m_serial->read((char *)Buffer, 2047);
+	}
+}
+
+void QtTermTCP::handleError(QSerialPort::SerialPortError serialPortError)
+{
+	Debugprintf("Serial port Error %d", serialPortError);
+	closeSerialPort();
+}
+
+extern "C" void CheckUIFrame(unsigned char * path, string * data)
+{
+	// If we have KISS enabled and dest is UIDEST look for a KISS window in UI Mode
+
+	if (KISSSock == 0)
+		return;
+
+	char Dest[10];
+	char From[10];
+
+	Dest[ConvFromAX25(path, Dest)] = 0;
+	From[ConvFromAX25(&path[7], From)] = 0;
+
+	// ok, Find a Kiss Session with this Dest
+
+	Ui_ListenSession * Sess = NULL;
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		if (Sess->KISSMode == 1 && strcmp(Dest, Sess->UIDEST) == 0)
+		{
+			char Msg[512];
+			int Len;
+
+			data->Data[data->Length] = 0;
+
+			Len = sprintf(Msg, "%s:%s", From, data->Data);
+			SendtoTerm(Sess, Msg, Len);
+			return;
+		}
+	}
+
+}
+
+
+QColor QtTermTCP::setColor(QColor Colour)
+{
+	//    const QColorDialog::ColorDialogOptions options = QFlag(colorDialogOptionsWidget->value());
+
+
+	QColor col = Colour;
+
+	QColorDialog dialog;
+	dialog.setCurrentColor(Colour);
+	dialog.setOption(QColorDialog::DontUseNativeDialog);
+
+	if (dialog.exec() == QColorDialog::Accepted)
+		col = QVariant(dialog.currentColor()).toString();
+
+
+	//	const QColor color = QColorDialog::getColor(Qt::green, this, "Select Color", 0);
+
+	return col;
+}
+
+// Experimental Viewdata/Teletext/Prestel/CEEFAX Mode
+
+// Uses ideas and some code from 
+
+/***************************************************************
+ * Name:      wxTEDMain.cpp
+ * Purpose:   Teletext editor Application Frame
+ * Author:    Peter Kwan (peterk.vt80@gmail.com)
+ * Created:   2014-10-30
+ * Copyright: Peter Kwan
+ * License:
+  *
+ * Copyright (C) 2014-2022, Peter Kwan
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that the copyright notice and this
+ * permission notice and warranty disclaimer appear in supporting
+ * documentation, and that the name of the author not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * The author disclaims all warranties with regard to this
+ * software, including all implied warranties of merchantability
+ * and fitness.  In no event shall the author be liable for any
+ * special, indirect or consequential damages or any damages
+ * whatsoever resulting from loss of use, data or profits, whether
+ * in an action of contract, negligence or other tortious action,
+ * arising out of or in connection with the use or performance of
+ * this software.
+ *************************************************************************** **/
+
+
+
+int FontWidth = 16;
+int FontHeight = 16;
+
+bool isMosaic(char ch)
+{
+	ch &= 0x7f;
+	return (ch >= 0x20 && ch < 0x40) || ch >= 0x60;
+}
+
+
+void DecodeTeleText(Ui_ListenSession * Sess, char * page)
+{
+
+	// redraw the whole teletext page
+
+	QColor fg = Qt::white;
+	QColor bg = Qt::black;
+	QColor holdColour;
+	QColor holdfg = fg;			// Colour for held graphic
+	int usehold = 0;
+	int sep = 0;
+
+	QPainter p(Sess->TTBitmap);
+
+	QSettings settings(GetConfPath(), QSettings::IniFormat);
+
+  //p.setFont(QFont("Courier", 14, QFont::Bold));
+
+	p.setFont(QFont(settings.value("FontFamily", "Courier New").value<QString>(), 14));
+
+	p.setPen(QPen(fg));
+
+	bool graphicsMode = false;
+	bool separated = false;
+	bool doubleHeight = false;
+	int skipnextrow = 99;
+	bool flashing = false;
+	bool hold = false;
+	char holdChar = 0;
+	char holdMode = 0;
+	Sess->timer.stop();
+
+	bool concealed = false;
+	char c;
+
+	fg = Qt::white;
+	bg = Qt::black;
+
+	char * ptr = page;
+
+	int col = 0;
+	int line = 0;
+
+	// XXXXXXXXTEEFAX %%# %%a %d %%b C %H:%M.%S
+
+	//p.drawText(0, 19, "P199            HAMFAX");
+
+
+	// interpret data, for now, line by line
+
+
+	while ((c = *(ptr++)))
+	{
+		char ch = c;
+
+		if (c == 0x11)			// Curson On ??
+			continue;
+
+		if (c == 0x14)			// Curson Off ??
+			continue;
+
+		if (c == 9)			// Curson On ??
+		{
+			col++;
+			continue;
+		}
+
+		if (c == 0x0a)
+		{
+			line++;
+
+//			if (doubleHeight)
+//				line++;
+
+			if (line > 24)
+				line = 0;
+
+			continue;
+		}
+
+		if (c == 0x1e)			// Cursor Home
+		{
+			line = col = 0;
+			c = 13;					// So we reset page flags below
+		}
+
+		if (c == 12)
+		{
+			// Clear the page
+
+			Sess->TTBitmap->fill(Qt::black);
+			Sess->TTLabel->setPixmap(QPixmap::fromImage(*Sess->TTBitmap));
+
+			line = col = 0;
+			
+			c = 13;					// So we reset page flags below
+		}
+
+		if (c == 13)
+		{
+			col = 0;
+
+			graphicsMode = false;
+			separated = false;
+			doubleHeight = false;
+			flashing = false;
+			hold = false;
+			holdChar = 0;
+			concealed = false;
+
+			fg = Qt::white;
+			bg = Qt::black;
+
+			continue;			// Next line
+		}
+
+		if (c == 0x1b) // Esc
+		{
+			// I think the control char is displayed as it was before being actioned, sa save current state
+
+			holdfg = holdColour;						// Colour if using held - may be changed before displaying
+			usehold = hold;								// May be changed
+			sep = holdMode;
+
+			char echar = *(ptr++);
+
+			if (echar == 0)
+			{
+				// Esc pair spilt - wait for rest
+
+				Sess->TTLabel->setPixmap(QPixmap::fromImage(*Sess->TTBitmap));
+				return;
+			}
+			
+			switch (echar)
+			{
+			case '@':
+				fg = Qt::black;
+				concealed = false;    // Side effect of colour. It cancels a conceal.
+				graphicsMode = false;
+//				hold = false;
+
+				break;
+			case 'A':
+				fg = Qt::red;
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+
+				break;
+			case 'B':
+				fg = Qt::green;
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+				break;
+			case 'C':
+				fg = Qt::yellow;
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+				break;
+			case 'D':
+				fg = Qt::blue;
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+				break;
+			case 'E':
+				fg = Qt::magenta;
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+				break;
+			case 'F':
+				fg = Qt::cyan;
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+				break;
+			case 'G':
+				fg = Qt::white;
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+				break;
+			case 'H':					// Flash
+				flashing = true;
+				Sess->timer.start(1000, Sess);
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+
+				break;
+
+			case 'I':					// Steady
+				flashing = false;
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+
+				break;
+				//		
+			case 'J':			//ttxCodeEndBox:
+			case 'K':			//ttxCodeStartBox:
+
+				concealed = false;
+				graphicsMode = false;
+				hold = false;
+					
+				break;
+			case 'L': // Normal height
+				doubleHeight = false;
+				hold = false;  
+				break;
+
+			case 'M': // Double height
+				doubleHeight = true;
+				skipnextrow = line + 1;   // ETSI: row to ignore
+				hold = false;
+				holdChar = 0;
+				break;
+			case 'P': // Graphics black
+//				concealed = false;
+				graphicsMode = true;
+				holdColour = fg = Qt::black;
+
+				break;
+			case 'Q': // Graphics red
+//				concealed = false;
+				graphicsMode = true;
+				holdColour = fg = Qt::red;
+
+				break;
+			case 'R': // Graphics green
+//				concealed = false;
+				graphicsMode = true;
+				holdColour = fg = Qt::green;
+
+				break;
+			case 'S': // Graphics yellow
+//				concealed = false;
+				graphicsMode = true;
+				holdColour = fg = Qt::yellow;
+
+				break;
+			case 'T': // Graphics blue
+//				concealed = false;
+				graphicsMode = true;
+				holdColour = fg = Qt::blue;
+
+				break;
+			case 'U': // Graphics magenta
+//				concealed = false;
+				graphicsMode = true;
+				holdColour = fg = Qt::magenta;
+
+				break;
+			case 'V': // Graphics cyan
+//				concealed = false;
+				graphicsMode = true;
+				holdColour = fg = Qt::cyan;
+
+				break;
+			case 'W': // Graphics white
+//				concealed = false;
+				graphicsMode = true;
+				holdColour = fg = Qt::white;
+
+				break;
+
+			case 'X': // Conceal display
+				
+				concealed = 1;
+				break;
+
+			case 'Y': // Contiguous graphics
+
+				separated = false;
+				break;
+
+			case 'Z': // Separated gfx
+
+				separated = true;
+				break;
+
+			case 0x5c: // Background black
+				bg = Qt::black;
+				break;
+
+			case 0x5d: // New background
+
+				bg = fg;
+				break;
+
+			case 0x5e: // Hold gfx
+
+				if (hold == 0)
+				{
+					hold = true;
+					holdColour = fg;
+					holdMode = separated;
+				}
+				break;
+
+			case 0x5f: // Non-hold gfx
+				hold = false;
+				break;
+
+			default:
+				echar++;					// For testign
+				break;
+
+			}  //end of esc case processing
+
+			if (usehold)
+			{
+				// We set sep and color for held char earlier 
+			
+				ch = holdChar;			// Repeat held char
+			}
+			else
+				ch = 0x0;				// Default is space
+
+
+			if (line > skipnextrow)
+				skipnextrow = 99;
+
+			if (line == skipnextrow)
+			{
+				line = line;
+			}
+			else
+			{
+				if (concealed == 0 && (flashing == 0 || Sess->TTFlashToggle == 0))
+				{
+					p.fillRect(col * 15, line * 19, 15, 19, bg);
+
+					// if double height also draw background for next row
+
+					if (doubleHeight)
+						p.fillRect(col * 15, line * 19 + 19, 15, 19, bg);
+
+
+					if (sep)
+					{
+						if (ch & 1)
+							p.fillRect(col * 15 + 2, line * 19 + 2, 5, 4, holdfg);
+						if (ch & 2)
+							p.fillRect(col * 15 + 9, line * 19 + 2, 6, 4, holdfg);
+						if (ch & 4)
+							p.fillRect(col * 15 + 2, line * 19 + 8, 5, 4, holdfg);
+						if (ch & 8)
+							p.fillRect(col * 15 + 9, line * 19 + 8, 6, 4, holdfg);
+						if (ch & 16)
+							p.fillRect(col * 15 + 2, line * 19 + 14, 5, 5, holdfg);
+						if (ch & 32)
+							p.fillRect(col * 15 + 9, line * 19 + 14, 6, 5, holdfg);
+
+					}
+					else
+					{
+						if (ch & 1)
+							p.fillRect(col * 15, line * 19, 7, 6, holdfg);
+						if (ch & 2)
+							p.fillRect(col * 15 + 7, line * 19, 8, 6, holdfg);
+						if (ch & 4)
+							p.fillRect(col * 15, line * 19 + 6, 7, 6, holdfg);
+						if (ch & 8)
+							p.fillRect(col * 15 + 7, line * 19 + 6, 8, 6, holdfg);
+						if (ch & 16)
+							p.fillRect(col * 15, line * 19 + 12, 7, 7, holdfg);
+						if (ch & 32)
+							p.fillRect(col * 15 + 7, line * 19 + 12, 8, 7, holdfg);
+					}
+				}
+			}
+			col++;
+		}
+		else
+		{
+			// Not esc - so normal or graphics
+
+			if (ch < 0x20)
+				continue;
+
+			if (line > skipnextrow)
+				skipnextrow = 99;
+
+			if (line == skipnextrow)
+			{
+				line = line;
+			}
+			else
+			{
+				if (concealed == 0 && (flashing == 0 || Sess->TTFlashToggle == 0))
+				{
+					p.fillRect(col * 15, line * 19, 15, 19, bg);
+
+					if (doubleHeight)
+						p.fillRect(col * 15, line * 19 + 19, 15, 19, bg);
+
+					p.setPen(QPen(fg));;
+
+					if (graphicsMode)
+					{
+						if (ch < 0x40)
+							ch -= 0x20;
+						else
+							if (ch >= 0x60)
+								ch -= 0x40;
+							else
+								goto isText;
+
+						holdChar = ch;
+
+						// Now have 00 - 3f 
+
+
+						// C is bit mask bit posns are
+						// 01
+						// 23
+						// 45
+						// Char cell is 15 * 19 which is a bit asymetrical
+
+						// Chars are 20 - 3f and 60 to 7f but I cant see a logic to the mapping
+
+
+						if (separated)
+						{
+							if (ch & 1)
+								p.fillRect(col * 15 + 2, line * 19 + 2, 5, 4, fg);
+							if (ch & 2)
+								p.fillRect(col * 15 + 9, line * 19 + 2, 6, 4, fg);
+							if (ch & 4)
+								p.fillRect(col * 15 + 2, line * 19 + 8, 5, 4, fg);
+							if (ch & 8)
+								p.fillRect(col * 15 + 9, line * 19 + 8, 6, 4, fg);
+							if (ch & 16)
+								p.fillRect(col * 15 + 2, line * 19 + 14, 5, 5, fg);
+							if (ch & 32)
+								p.fillRect(col * 15 + 9, line * 19 + 14, 6, 5, fg);
+
+						}
+						else
+						{
+							if (ch & 1)
+								p.fillRect(col * 15, line * 19, 7, 6, fg);
+							if (ch & 2)
+								p.fillRect(col * 15 + 7, line * 19, 8, 6, fg);
+							if (ch & 4)
+								p.fillRect(col * 15, line * 19 + 6, 7, 6, fg);
+							if (ch & 8)
+								p.fillRect(col * 15 + 7, line * 19 + 6, 8, 6, fg);
+							if (ch & 16)
+								p.fillRect(col * 15, line * 19 + 12, 7, 7, fg);
+							if (ch & 32)
+								p.fillRect(col * 15 + 7, line * 19 + 12, 8, 7, fg);
+						}
+					}
+					else
+					{
+						// Just write char at current col and line
+
+					isText:
+						char s[5];
+						unsigned char su[5] = "";
+
+						// Some chars are in wrong char set
+
+						su[0] = ch;
+
+						if (ch == '_')
+							su[0] = '#';
+
+						else if (ch == 0x7e)					// division
+						{
+							su[0] = 0xC3;
+							su[1] = 0xB7;
+						}
+						else if (ch == 0x5e)			// up arrow
+						{
+							su[0] = 0xF0;
+							su[1] = 0x9F;
+							su[2] = 0xA0;
+							su[3] = 0x95;
+						}
+						else if (ch == 0x7f)			// up arrow
+						{
+							su[0] = 0xE2;
+							su[1] = 0x96;
+							su[2] = 0x88;
+						}
+
+						memcpy(s, su, 5);
+
+//						if (doubleHeight)
+	//							p.drawText(col * 15, line * 19 + 25, s);
+		//					else
+			//					p.drawText(col * 15, line * 19 + 15, s);
+
+						// if double height draw normally then copy pixels each row of pixels to two scanlines (starting at the bottom)
+
+						if (doubleHeight)
+						{
+							int inscanline = line * 19 + 18;
+							int outscanline = line * 19 + 35;
+							unsigned char * inptr = Sess->TTBitmap->scanLine(inscanline);
+							unsigned char * outptr = Sess->TTBitmap->scanLine(outscanline);
+							int linelen = Sess->TTBitmap->bytesPerLine();
+							int charlen = linelen / 40;			// bytes per char position
+
+							p.drawText(col * 15, line * 19 + 16, s);
+
+							inptr += col * charlen;
+							outptr += col * charlen;
+
+							for (int i = 0; i < 18; i++)
+							{
+								memcpy(outptr, inptr, charlen);
+								outptr -= linelen;
+								memcpy(outptr, inptr, charlen);
+
+								inptr -= linelen;
+								outptr -= linelen;
+
+							}
+						}
+						else
+							p.drawText(col * 15, line * 19 + 15, s);
+
+					}
+				}
+			}
+			col++;
+		}
+
+		if (col > 39)
+		{
+			col = 0;
+			line++;
+			if (line > 24)
+				line = 0;
+
+			graphicsMode = false;
+			separated = false;
+			doubleHeight = false;
+			flashing = false;
+			hold = false;
+			holdChar = 0;
+			concealed = false;
+
+			fg = Qt::white;
+			bg = Qt::black;
+		}
+	}
+	Sess->TTLabel->setPixmap(QPixmap::fromImage(*Sess->TTBitmap));
+	return;
+
+	QFile file("D:/savepage.txt");
+	file.open(QIODevice::WriteOnly);
+	file.write(Sess->pageBuffer);
+	file.close();
+}
+
+
+void Ui_ListenSession::timerEvent(QTimerEvent *event)
+{
+	Ui_ListenSession * Sess = NULL;
+
+	// Used for flashing - resfresh window
+
+	for (int i = 0; i < _sessions.size(); ++i)
+	{
+		Sess = _sessions.at(i);
+
+		if (Sess->timer.timerId() == event->timerId())
+		{
+			if (Sess->TTActive)
+			{
+				Sess->TTFlashToggle ^= 1;
+
+				// if in Tabbed mode only refresh active tab
+
+				if (TermMode == Tabbed && Sess != ActiveSession)
+					return;
+
+				DecodeTeleText(Sess, (char *)Sess->pageBuffer);			// Re-decode same data until we get the end
+			}
+			else
+				Sess->timer.stop();
+
+			return;
+		}
+	}
+	QWidget::timerEvent(event);
+}
+
+// Monitor Log FIle routines
+
+char * doXMLTransparency(char * string)
+{
+	// Make sure string doesn't contain forbidden XML chars (<>"'&)
+
+	char * newstring = (char *)malloc(5 * strlen(string) + 1);		// If len is zero still need null terminator
+
+	char * in = string;
+	char * out = newstring;
+	char c;
+
+	c = *(in++);
+
+	while (c)
+	{
+		switch (c)
+		{
+		case '<':
+
+			strcpy(out, "&lt;");
+			out += 4;
+			break;
+
+		case '>':
+
+			strcpy(out, "&gt;");
+			out += 4;
+			break;
+
+		case '"':
+
+			strcpy(out, "&quot;");
+			out += 6;
+			break;
+
+		case '\'':
+
+			strcpy(out, "&apos;");
+			out += 6;
+			break;
+
+		case '&':
+
+			strcpy(out, "&amp;");
+			out += 5;
+			break;
+
+		default:
+
+			*(out++) = c;
+		}
+		c = *(in++);
+	}
+
+	*(out++) = 0;
+	return newstring;
+}
+
+void WriteMonitorLog(Ui_ListenSession * Sess, char * Msg)
+{
+	// Write as HTML to preserve formatting
+
+	char Line[512];
+	char * HTMLText;
+
+	if (Sess->monLogfile == nullptr)
+	{
+		QString FN = "QTTermMonLog" + timeLoaded + "_" + QString::number(Sess->sessNo) + ".html";
+		Sess->monLogfile = new QFile(FN);
+
+		if (Sess->monLogfile)
+			Sess->monLogfile->open(QIODevice::Append);
+		else
+			return;
+	}
+
+	if (Msg[0] == 0x1b)
+	{
+		// Colour Escape
+
+		if (Msg[1] == 17)
+			Sess->monSpan = (char *)"<span style=\"color:blue; white-space:pre;font-family: monospace\">";// , monRxColour.data());
+		else
+			Sess->monSpan = (char *)"<span style=\"color:red; white-space:pre;font-family: monospace\">";// , monTxColour.data());
+
+		HTMLText = doXMLTransparency(&Msg[2]);
+	}
+	else
+	{
+		// Leave colour at last set value
+
+		HTMLText = doXMLTransparency(Msg);
+	}
+
+	sprintf(Line, "%s%s</span><br>\r\n", Sess->monSpan, HTMLText);
+	
+	Sess->monLogfile->write(Line);
+
+	free(HTMLText);
+
+}
+
+// Create MH Window
+
+
+
+int newMHWindow(QObject * parent, int Type, const char * Label)
+{
+	Ui_ListenSession * Sess = new(Ui_ListenSession);
+
+	MHWindow = Sess;
+
+	// Need to explicity initialise on Qt4
+
+	Sess->termWindow = NULL;
+	Sess->monWindow = NULL;
+	Sess->inputWindow = NULL;
+
+	Sess->StackIndex = 0;
+	Sess->InputMode = 0;
+	Sess->SlowTimer = 0;
+	Sess->MonData = 0;
+	Sess->OutputSaveLen = 0;
+	Sess->MonSaveLen = 0;
+	Sess->PortMonString[0] = 0;
+	Sess->portmask = 0;
+	Sess->portmask = 1;
+	Sess->mtxparam = 1;
+	Sess->mlocaltime = 0;
+	Sess->mcomparam = 1;
+	Sess->monUI = 0;
+	Sess->MonitorNODES = 0;
+	Sess->MonitorColour = 1;
+	Sess->CurrentHost = 0;
+
+	Sess->SessionType = Type;
+	Sess->clientSocket = NULL;
+	Sess->AGWSession = NULL;
+	Sess->AGWMonSession = NULL;
+	Sess->KISSSession = NULL;
+	Sess->KISSMode = 0;
+	Sess->TTActive = 0;
+	Sess->TTFlashToggle = 0;
+	Sess->pageBuffer[0] = 0;
+	Sess->Tab = 0;
+
+	Sess->LogMonitor = false;
+	Sess->monSpan = (char *) "<span style=white-space:pre>";
+	Sess->monLogfile = nullptr;
+	Sess->sessNo = sessNo++;
+
+	QSettings settings(GetConfPath(), QSettings::IniFormat);
+
+#ifdef ANDROID
+	QFont font = QFont(settings.value("FontFamily", "Driod Sans Mono").value<QString>(),
+		settings.value("PointSize", 12).toInt(),
+		settings.value("Weight", 50).toInt());
+#else
+	QFont font = QFont(settings.value("FontFamily", "Courier New").value<QString>(),
+		settings.value("PointSize", 10).toInt(),
+		settings.value("Weight", 50).toInt());
+#endif
+
+	Sess->monWindow = new QTextEdit(Sess);
+	Sess->monWindow->setReadOnly(1);
+	Sess->monWindow->document()->setMaximumBlockCount(10000);
+	Sess->monWindow->setFont(font);
+	Sess->monWindow->setStyleSheet(monStyleSheet);
+
+	Sess->setWindowTitle(Label);
+
+	Sess->installEventFilter(mythis);
+
+	Sess->show();
+
+
+
+	Sess->monWindow->setGeometry(QRect(2, 2, 400, 400));
+	Sess->setGeometry(QRect(400, 400, 400, 400));
+
+
+	QSize Size(800, 602);						// Not actually used, but Event constructor needs it
+
+	QResizeEvent event(Size, Size);
+
+	QApplication::sendEvent(Sess, &event);		// Resize Widgets to fix Window
+
+	return true;
+}
+
+extern "C" void WritetoMHWindow(char * Buffer)
+{
+	unsigned char Copy[8192];
+	unsigned char * ptr1, *ptr2;
+	unsigned char Line[8192];
+	unsigned char out[8192];
+	int outlen;
+
+	int num;
+
+	if (MHWindow == NULL || MHWindow->monWindow == NULL)
+		return;
+
+	MHWindow->monWindow->setText(Buffer);
+}
--- qttermtcp-0.0.0.79.orig/QtTermTCP.h
+++ qttermtcp-0.0.0.79/QtTermTCP.h
@@ -1,312 +1,312 @@
-#pragma once
-
-#include <QMainWindow>
-#include "ui_QtTermTCP.h"
-#include "ui_AlertSetup.h"
-#include "ui_YAPPRxSize.h"
-#include "ui_ColourConfig.h"
-#include "ui_VARAConfig.h"
-#include "ui_KISSConfig.h"
-#include "QTextEdit"
-#include "QSplitter"
-#include "QLineEdit"
-#include "QTcpSocket"
-#include <QDataStream>
-#include <QKeyEvent>
-#include "QThread"
-#include "QTcpServer"
-#include "QMdiArea"
-#include <QMdiSubWindow>
-#include "QMessageBox"
-#include "QTimer"
-#include "QSettings"
-#include "QThread"
-#include <QFontDialog>
-#include <QScrollBar>
-#include <QFileDialog>
-#include <QTabWidget>
-#include <QMenuBar>
-#include <QProcess>
-#include <QtSerialPort/QSerialPort>
-#include <QtMultimedia/QSound>
-#include <QtMultimedia/QSoundEffect>
-
-#define MAXHOSTS 16
-#define MAXPORTS 64
-
-QT_BEGIN_NAMESPACE
-class QComboBox;
-class QLabel;
-class QLineEdit;
-class QPushButton;
-class QTcpSocket;
-class QNetworkSession;
-
-class myTcpSocket : public QTcpSocket
-{
-public:
-	QWidget * Sess;
-};
-
-
-class Ui_ListenSession : public QMainWindow
-{
-	Q_OBJECT
-
-public:
-	explicit Ui_ListenSession(QWidget *Parent = 0) : QMainWindow(Parent) {}
-	~Ui_ListenSession();
-
-	int SessionType;				// Type Mask - Term, Mon, Listen
-	int CurrentWidth;
-	int CurrentHeight;				// Saved so can be restored after Cascade
-
-	QTextEdit *termWindow;
-	QTextEdit *monWindow;
-	QLineEdit *inputWindow;
-	QLabel * TTLabel;
-
-	myTcpSocket *clientSocket;
-
-	QAction * actActivate;			// From active Windows menu
-
-	char * KbdStack[50];
-	int StackIndex;
-
-	QMdiSubWindow *sw;				// The MdiSubwindow is the container for this session
-
-	int InputMode;
-	int SlowTimer;
-	int MonData;
-
-	int OutputSaveLen;
-	char OutputSave[16384];
-
-	int MonSaveLen;
-	char MonSave[4096];
-
-	char PortMonString[2048];		// 64 ports 32 Bytes
-	uint64_t portmask;
-	int EnableMonitor;
-	int mlocaltime;
-	int mtxparam;
-	int mcomparam;
-	int monUI;
-	int MonitorNODES;
-	int MonitorColour;
-	int CurrentHost;
-	int Tab;						// Tab Index if Tabbed Mode
-	void * AGWSession;				// Terinal sess - Need to cast to TAGWPort to use it
-	void * AGWMonSession;
-	void * KISSSession;
-	int KISSMode;					// Connected or UI
-	int UIPORT;
-	char UIDEST[32];
-	char UIPATH[128];
-
-	// For Teletext Emulator
-
-	QImage * TTBitmap;    // TT Image buffer
-	QDialog TTUI;
-
-	int TTActive;
-	int TTFlashToggle;
-	char pageBuffer[4096];
-	QBasicTimer timer;
-
-	int sessNo;			// Used to create unique log filename;
-	bool LogMonitor;
-	QFile * monLogfile;
-	char * monSpan;
-
-protected:
-
-	void timerEvent(QTimerEvent *event) override;
-
-private:
-
-
-
-private slots:
-
-};
-
-
-class QtTermTCP : public QMainWindow
-{
-	Q_OBJECT
-
-public:
-	QtTermTCP(QWidget *parent = NULL);
-	void closeEvent(QCloseEvent * event);
-	static void setFonts();
-
-	~QtTermTCP();
-
-private slots:
-	void Disconnect();
-	void doYAPPSend();
-	void doYAPPSetRX();
-	void doYAPPSetSize();
-	void sizeaccept();
-	void sizereject();
-	void menuChecked();
-	void Connect();
-	void displayError(QAbstractSocket::SocketError socketError);
-	void readyRead();
-	void showContextMenu(const QPoint & point);
-	void autoConnectChecked();
-	void LreturnPressed(Ui_ListenSession * LUI);
-	void LDisconnect(Ui_ListenSession * LUI);
-	void SetupHosts();
-	void MyTimerSlot();
-	void SlowTimerSlot();
-	void KISSTimerSlot();
-	void ListenSlot();
-	void AGWSlot();
-	void AlertSlot();
-	void chooseInboundWAV();
-	void chooseBellsWAV();
-	void chooseIntervalWAV();
-	void chooseAlertWAV();
-	void testInboundWAV();
-	void testBellsWAV();
-	void testIntervalWAV();
-	void testAlertWAV();
-	void alertAccept();
-	void alertReject();
-	void VARASlot();
-	void KISSSlot();
-	void deviceaccept();
-	void KISSaccept();
-	void KISSreject();
-	void devicereject();
-	void showContextMenuM(const QPoint &pt);
-	void showContextMenuT(const QPoint &pt);
-	void showContextMenuL();
-	void doQuit();
-	void onTEselectionChanged();
-	void onLEselectionChanged();
-	void setSplit();
-	void ClearScreen();
-	void setVDMode();
-	void showContextMenuMT(const QPoint & pt);
-	void showContextMenuMOnly(const QPoint & pt);
-	void onNewConnection();
-	void onSocketStateChanged(QAbstractSocket::SocketState socketState);
-	void updateWindowMenu();
-	void doNewTerm();
-	void doNewMon();
-	void doNewCombined();
-	void doCascade();
-	void actActivate();
-	void xon_mdiArea_changed();
-	void doFonts();
-	void doMFonts();
-	void ConnecttoVARA();
-	void VARATimer();
-	void AGWdisplayError(QAbstractSocket::SocketError socketError);
-	void AGWreadyRead();
-	void onAGWSocketStateChanged(QAbstractSocket::SocketState socketState);
-	void VARAdisplayError(QAbstractSocket::SocketError socketError);
-	void VARAreadyRead();
-	void onVARASocketStateChanged(QAbstractSocket::SocketState socketState);
-	void KISSdisplayError(QAbstractSocket::SocketError socketError);
-	void KISSreadyRead();
-	void onKISSSocketStateChanged(QAbstractSocket::SocketState socketState);
-	int openSerialPort();
-	void readSerialData();
-	void handleError(QSerialPort::SerialPortError serialPortError);
-	void doColours();
-	void ColourPressed();
-	void Colouraccept();
-	void Colourreject();
-	QColor setColor(QColor Colour);
-	void VARADatadisplayError(QAbstractSocket::SocketError socketError);
-	void VARADatareadyRead();
-	void onVARADataSocketStateChanged(QAbstractSocket::SocketState socketState);
-	void HAMLIBdisplayError(QAbstractSocket::SocketError socketError);
-	void HAMLIBreadyRead();
-	void onHAMLIBSocketStateChanged(QAbstractSocket::SocketState socketState);
-	void ConnecttoHAMLIB();
-	void HAMLIBSetPTT(int PTTState);
-	void FLRigdisplayError(QAbstractSocket::SocketError socketError);
-	void FLRigreadyRead();
-	void onFLRigSocketStateChanged(QAbstractSocket::SocketState socketState);
-	void ConnecttoFLRig();
-	void FLRigSetPTT(int PTTState);
-	void CATChanged(bool State);
-	void PTTPortChanged(int Selected);
-	void OpenPTTPort();
-	void RadioPTT(bool PTTState);
-	void tabSelected(int);
-	void VARAHFChanged(bool state);
-	void VARAFMChanged(bool State);
-	void VARASATChanged(bool State);
-	void SetVARAParams();
-
-protected:
-	bool eventFilter(QObject* obj, QEvent *event);
-
-private:
-
-	void ConnecttoAGW();
-
-	void AGWTimer();
-
-	Ui::QtTermTCPClass ui;
-	
-	QMenu *hostsubMenu;
-
-	QAction *closeAct;
-	QAction *closeAllAct;
-	QAction *tileAct;
-	QAction *cascadeAct;
-	QAction *nextAct;
-	QAction *previousAct;
-	QAction *windowMenuSeparatorAct;
-	QAction *newTermAct;
-	QAction *newMonAct;
-	QAction *newCombinedAct;
-	QAction *AGWAction;
-	QAction *VARAAction;
-	QAction *KISSAction;
-	QAction *AlertAction;
-	QAction *quitAction;
-
-	QList<myTcpSocket*>  _sockets;
-
-	QWidget *centralWidget;
-	void ConnecttoKISS();
-	void KISSTimer();
-};
-
-extern "C"
-{
-	void EncodeSettingsLine(int n, char * String);
-	void DecodeSettingsLine(int n, char * String);
-	void WritetoOutputWindow(Ui_ListenSession * Sess, unsigned char * Buffer, int Len);
-	void WritetoOutputWindowEx(Ui_ListenSession * Sess, unsigned char * Buffer, int len, QTextEdit * termWindow, int *OutputSaveLen, char * OutputSave, QColor Colour);
-	void WritetoMonWindow(Ui_ListenSession * Sess, unsigned char * Buffer, int Len);
-	void ProcessReceivedData(Ui_ListenSession * Sess, unsigned char * Buffer, int len);
-	void SendTraceOptions(Ui_ListenSession * LUI);
-	void setTraceOff(Ui_ListenSession * Sess);
-	void SetPortMonLine(int i, char * Text, int visible, int enabled);
-	void SaveSettings();
-	void myBeep(QString * WAV);
-	void YAPPSendFile(Ui_ListenSession *  Sess, char * FN);
-	int SocketSend(Ui_ListenSession * Sess, char * Buffer, int len);
-	void SendTraceOptions(Ui_ListenSession * Sess);
-	int SocketFlush(Ui_ListenSession * Sess);
-	extern void mySleep(int ms);
-	extern void setTraceOff(Ui_ListenSession * Sess);
-	void GetKeyWordFile();
-}
-
-extern QString ConnectWAV;
-extern QString BellWAV;
-extern QString AlertWAV;
-
-char * strlop(char * buf, char delim);
-extern "C" void setMenus(int State);
-void Send_AGW_Ds_Frame(void * AGW);
+#pragma once
+
+#include <QMainWindow>
+#include "ui_QtTermTCP.h"
+#include "ui_AlertSetup.h"
+#include "ui_YAPPRxSize.h"
+#include "ui_ColourConfig.h"
+#include "ui_VARAConfig.h"
+#include "ui_KISSConfig.h"
+#include "QTextEdit"
+#include "QSplitter"
+#include "QLineEdit"
+#include "QTcpSocket"
+#include <QDataStream>
+#include <QKeyEvent>
+#include "QThread"
+#include "QTcpServer"
+#include "QMdiArea"
+#include <QMdiSubWindow>
+#include "QMessageBox"
+#include "QTimer"
+#include "QSettings"
+#include "QThread"
+#include <QFontDialog>
+#include <QScrollBar>
+#include <QFileDialog>
+#include <QTabWidget>
+#include <QMenuBar>
+#include <QProcess>
+#include <QtSerialPort/QSerialPort>
+#include <QtMultimedia/QSound>
+#include <QtMultimedia/QSoundEffect>
+
+#define MAXHOSTS 16
+#define MAXPORTS 64
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QTcpSocket;
+class QNetworkSession;
+
+class myTcpSocket : public QTcpSocket
+{
+public:
+	QWidget * Sess;
+};
+
+
+class Ui_ListenSession : public QMainWindow
+{
+	Q_OBJECT
+
+public:
+	explicit Ui_ListenSession(QWidget *Parent = 0) : QMainWindow(Parent) {}
+	~Ui_ListenSession();
+
+	int SessionType;				// Type Mask - Term, Mon, Listen
+	int CurrentWidth;
+	int CurrentHeight;				// Saved so can be restored after Cascade
+
+	QTextEdit *termWindow;
+	QTextEdit *monWindow;
+	QLineEdit *inputWindow;
+	QLabel * TTLabel;
+
+	myTcpSocket *clientSocket;
+
+	QAction * actActivate;			// From active Windows menu
+
+	char * KbdStack[50];
+	int StackIndex;
+
+	QMdiSubWindow *sw;				// The MdiSubwindow is the container for this session
+
+	int InputMode;
+	int SlowTimer;
+	int MonData;
+
+	int OutputSaveLen;
+	char OutputSave[16384];
+
+	int MonSaveLen;
+	char MonSave[4096];
+
+	char PortMonString[2048];		// 64 ports 32 Bytes
+	uint64_t portmask;
+	int EnableMonitor;
+	int mlocaltime;
+	int mtxparam;
+	int mcomparam;
+	int monUI;
+	int MonitorNODES;
+	int MonitorColour;
+	int CurrentHost;
+	int Tab;						// Tab Index if Tabbed Mode
+	void * AGWSession;				// Terinal sess - Need to cast to TAGWPort to use it
+	void * AGWMonSession;
+	void * KISSSession;
+	int KISSMode;					// Connected or UI
+	int UIPORT;
+	char UIDEST[32];
+	char UIPATH[128];
+
+	// For Teletext Emulator
+
+	QImage * TTBitmap;    // TT Image buffer
+	QDialog TTUI;
+
+	int TTActive;
+	int TTFlashToggle;
+	char pageBuffer[4096];
+	QBasicTimer timer;
+
+	int sessNo;			// Used to create unique log filename;
+	bool LogMonitor;
+	QFile * monLogfile;
+	char * monSpan;
+
+protected:
+
+	void timerEvent(QTimerEvent *event) override;
+
+private:
+
+
+
+private slots:
+
+};
+
+
+class QtTermTCP : public QMainWindow
+{
+	Q_OBJECT
+
+public:
+	QtTermTCP(QWidget *parent = NULL);
+	void closeEvent(QCloseEvent * event);
+	static void setFonts();
+
+	~QtTermTCP();
+
+private slots:
+	void Disconnect();
+	void doYAPPSend();
+	void doYAPPSetRX();
+	void doYAPPSetSize();
+	void sizeaccept();
+	void sizereject();
+	void menuChecked();
+	void Connect();
+	void displayError(QAbstractSocket::SocketError socketError);
+	void readyRead();
+	void showContextMenu(const QPoint & point);
+	void autoConnectChecked();
+	void LreturnPressed(Ui_ListenSession * LUI);
+	void LDisconnect(Ui_ListenSession * LUI);
+	void SetupHosts();
+	void MyTimerSlot();
+	void SlowTimerSlot();
+	void KISSTimerSlot();
+	void ListenSlot();
+	void AGWSlot();
+	void AlertSlot();
+	void chooseInboundWAV();
+	void chooseBellsWAV();
+	void chooseIntervalWAV();
+	void chooseAlertWAV();
+	void testInboundWAV();
+	void testBellsWAV();
+	void testIntervalWAV();
+	void testAlertWAV();
+	void alertAccept();
+	void alertReject();
+	void VARASlot();
+	void KISSSlot();
+	void deviceaccept();
+	void KISSaccept();
+	void KISSreject();
+	void devicereject();
+	void showContextMenuM(const QPoint &pt);
+	void showContextMenuT(const QPoint &pt);
+	void showContextMenuL();
+	void doQuit();
+	void onTEselectionChanged();
+	void onLEselectionChanged();
+	void setSplit();
+	void ClearScreen();
+	void setVDMode();
+	void showContextMenuMT(const QPoint & pt);
+	void showContextMenuMOnly(const QPoint & pt);
+	void onNewConnection();
+	void onSocketStateChanged(QAbstractSocket::SocketState socketState);
+	void updateWindowMenu();
+	void doNewTerm();
+	void doNewMon();
+	void doNewCombined();
+	void doCascade();
+	void actActivate();
+	void xon_mdiArea_changed();
+	void doFonts();
+	void doMFonts();
+	void ConnecttoVARA();
+	void VARATimer();
+	void AGWdisplayError(QAbstractSocket::SocketError socketError);
+	void AGWreadyRead();
+	void onAGWSocketStateChanged(QAbstractSocket::SocketState socketState);
+	void VARAdisplayError(QAbstractSocket::SocketError socketError);
+	void VARAreadyRead();
+	void onVARASocketStateChanged(QAbstractSocket::SocketState socketState);
+	void KISSdisplayError(QAbstractSocket::SocketError socketError);
+	void KISSreadyRead();
+	void onKISSSocketStateChanged(QAbstractSocket::SocketState socketState);
+	int openSerialPort();
+	void readSerialData();
+	void handleError(QSerialPort::SerialPortError serialPortError);
+	void doColours();
+	void ColourPressed();
+	void Colouraccept();
+	void Colourreject();
+	QColor setColor(QColor Colour);
+	void VARADatadisplayError(QAbstractSocket::SocketError socketError);
+	void VARADatareadyRead();
+	void onVARADataSocketStateChanged(QAbstractSocket::SocketState socketState);
+	void HAMLIBdisplayError(QAbstractSocket::SocketError socketError);
+	void HAMLIBreadyRead();
+	void onHAMLIBSocketStateChanged(QAbstractSocket::SocketState socketState);
+	void ConnecttoHAMLIB();
+	void HAMLIBSetPTT(int PTTState);
+	void FLRigdisplayError(QAbstractSocket::SocketError socketError);
+	void FLRigreadyRead();
+	void onFLRigSocketStateChanged(QAbstractSocket::SocketState socketState);
+	void ConnecttoFLRig();
+	void FLRigSetPTT(int PTTState);
+	void CATChanged(bool State);
+	void PTTPortChanged(int Selected);
+	void OpenPTTPort();
+	void RadioPTT(bool PTTState);
+	void tabSelected(int);
+	void VARAHFChanged(bool state);
+	void VARAFMChanged(bool State);
+	void VARASATChanged(bool State);
+	void SetVARAParams();
+
+protected:
+	bool eventFilter(QObject* obj, QEvent *event);
+
+private:
+
+	void ConnecttoAGW();
+
+	void AGWTimer();
+
+	Ui::QtTermTCPClass ui;
+	
+	QMenu *hostsubMenu;
+
+	QAction *closeAct;
+	QAction *closeAllAct;
+	QAction *tileAct;
+	QAction *cascadeAct;
+	QAction *nextAct;
+	QAction *previousAct;
+	QAction *windowMenuSeparatorAct;
+	QAction *newTermAct;
+	QAction *newMonAct;
+	QAction *newCombinedAct;
+	QAction *AGWAction;
+	QAction *VARAAction;
+	QAction *KISSAction;
+	QAction *AlertAction;
+	QAction *quitAction;
+
+	QList<myTcpSocket*>  _sockets;
+
+	QWidget *centralWidget;
+	void ConnecttoKISS();
+	void KISSTimer();
+};
+
+extern "C"
+{
+	void EncodeSettingsLine(int n, char * String);
+	void DecodeSettingsLine(int n, char * String);
+	void WritetoOutputWindow(Ui_ListenSession * Sess, unsigned char * Buffer, int Len);
+	void WritetoOutputWindowEx(Ui_ListenSession * Sess, unsigned char * Buffer, int len, QTextEdit * termWindow, int *OutputSaveLen, char * OutputSave, QColor Colour);
+	void WritetoMonWindow(Ui_ListenSession * Sess, unsigned char * Buffer, int Len);
+	void ProcessReceivedData(Ui_ListenSession * Sess, unsigned char * Buffer, int len);
+	void SendTraceOptions(Ui_ListenSession * LUI);
+	void setTraceOff(Ui_ListenSession * Sess);
+	void SetPortMonLine(int i, char * Text, int visible, int enabled);
+	void SaveSettings();
+	void myBeep(QString * WAV);
+	void YAPPSendFile(Ui_ListenSession *  Sess, char * FN);
+	int SocketSend(Ui_ListenSession * Sess, char * Buffer, int len);
+	void SendTraceOptions(Ui_ListenSession * Sess);
+	int SocketFlush(Ui_ListenSession * Sess);
+	extern void mySleep(int ms);
+	extern void setTraceOff(Ui_ListenSession * Sess);
+	void GetKeyWordFile();
+}
+
+extern QString ConnectWAV;
+extern QString BellWAV;
+extern QString AlertWAV;
+
+char * strlop(char * buf, char delim);
+extern "C" void setMenus(int State);
+void Send_AGW_Ds_Frame(void * AGW);
--- qttermtcp-0.0.0.79.orig/QtTermTCP.sln
+++ qttermtcp-0.0.0.79/QtTermTCP.sln
@@ -1,25 +1,25 @@
-﻿
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28307.102
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtTermTCP", "D:\BT Cloud\ActiveSource\QtTermTCP\QtTermTCP.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|x86 = Debug|x86
-		Release|x86 = Release|x86
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.ActiveCfg = Debug|Win32
-		{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.Build.0 = Debug|Win32
-		{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.ActiveCfg = Release|Win32
-		{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {DD1F8FD5-5375-4EFC-BBEE-8E35ABA15C82}
-	EndGlobalSection
-EndGlobal
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.102
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtTermTCP", "D:\BT Cloud\ActiveSource\QtTermTCP\QtTermTCP.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x86 = Debug|x86
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.ActiveCfg = Debug|Win32
+		{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.Build.0 = Debug|Win32
+		{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.ActiveCfg = Release|Win32
+		{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {DD1F8FD5-5375-4EFC-BBEE-8E35ABA15C82}
+	EndGlobalSection
+EndGlobal
--- qttermtcp-0.0.0.79.orig/QtTermTCP.ui
+++ qttermtcp-0.0.0.79/QtTermTCP.ui
@@ -1,66 +1,66 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QtTermTCPClass</class>
- <widget class="QMainWindow" name="QtTermTCPClass">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>781</width>
-    <height>698</height>
-   </rect>
-  </property>
-  <property name="font">
-   <font>
-    <family>Arial</family>
-    <pointsize>12</pointsize>
-   </font>
-  </property>
-  <property name="windowTitle">
-   <string>QtTermTCP</string>
-  </property>
-  <property name="windowIcon">
-   <iconset resource="QtTermTCP.qrc">
-    <normaloff>:/QtTermTCP/QtTermTCP.ico</normaloff>:/QtTermTCP/QtTermTCP.ico</iconset>
-  </property>
-  <widget class="QWidget" name="centralWidget">
-   <layout class="QGridLayout" name="gridLayout">
-    <property name="leftMargin">
-     <number>5</number>
-    </property>
-    <property name="topMargin">
-     <number>5</number>
-    </property>
-    <property name="rightMargin">
-     <number>5</number>
-    </property>
-    <property name="bottomMargin">
-     <number>5</number>
-    </property>
-    <item row="0" column="0">
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <property name="spacing">
-       <number>6</number>
-      </property>
-     </layout>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QStatusBar" name="statusBar"/>
-  <action name="actionListen">
-   <property name="text">
-    <string>Listen</string>
-   </property>
-  </action>
-  <action name="actionDisconnect">
-   <property name="text">
-    <string>Disconnect</string>
-   </property>
-  </action>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <resources>
-  <include location="QtTermTCP.qrc"/>
- </resources>
- <connections/>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtTermTCPClass</class>
+ <widget class="QMainWindow" name="QtTermTCPClass">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>781</width>
+    <height>698</height>
+   </rect>
+  </property>
+  <property name="font">
+   <font>
+    <family>Arial</family>
+    <pointsize>12</pointsize>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>QtTermTCP</string>
+  </property>
+  <property name="windowIcon">
+   <iconset resource="QtTermTCP.qrc">
+    <normaloff>:/QtTermTCP/QtTermTCP.ico</normaloff>:/QtTermTCP/QtTermTCP.ico</iconset>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <layout class="QGridLayout" name="gridLayout">
+    <property name="leftMargin">
+     <number>5</number>
+    </property>
+    <property name="topMargin">
+     <number>5</number>
+    </property>
+    <property name="rightMargin">
+     <number>5</number>
+    </property>
+    <property name="bottomMargin">
+     <number>5</number>
+    </property>
+    <item row="0" column="0">
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <property name="spacing">
+       <number>6</number>
+      </property>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QStatusBar" name="statusBar"/>
+  <action name="actionListen">
+   <property name="text">
+    <string>Listen</string>
+   </property>
+  </action>
+  <action name="actionDisconnect">
+   <property name="text">
+    <string>Disconnect</string>
+   </property>
+  </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+  <include location="QtTermTCP.qrc"/>
+ </resources>
+ <connections/>
+</ui>
--- qttermtcp-0.0.0.79.orig/QtTermTCP.vcxproj
+++ qttermtcp-0.0.0.79/QtTermTCP.vcxproj
@@ -1,463 +1,463 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{14F3B24E-473C-324E-A99D-3B679FCF5F67}</ProjectGuid>
-    <RootNamespace>QtTermTCP</RootNamespace>
-    <Keyword>QtVS_v304</Keyword>
-    <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
-    <WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
-    <QtMsBuild Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <PlatformToolset>v141</PlatformToolset>
-    <OutputDirectory>release\</OutputDirectory>
-    <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
-    <CharacterSet>NotSet</CharacterSet>
-    <ConfigurationType>Application</ConfigurationType>
-    <IntermediateDirectory>release\</IntermediateDirectory>
-    <PrimaryOutput>QtTermTCP</PrimaryOutput>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <PlatformToolset>v141</PlatformToolset>
-    <OutputDirectory>release\</OutputDirectory>
-    <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
-    <CharacterSet>NotSet</CharacterSet>
-    <ConfigurationType>Application</ConfigurationType>
-    <IntermediateDirectory>release\</IntermediateDirectory>
-    <PrimaryOutput>QtTermTCP</PrimaryOutput>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <PlatformToolset>v141</PlatformToolset>
-    <OutputDirectory>debug\</OutputDirectory>
-    <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
-    <CharacterSet>NotSet</CharacterSet>
-    <ConfigurationType>Application</ConfigurationType>
-    <IntermediateDirectory>debug\</IntermediateDirectory>
-    <PrimaryOutput>QtTermTCP</PrimaryOutput>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <PlatformToolset>v141</PlatformToolset>
-    <OutputDirectory>debug\</OutputDirectory>
-    <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
-    <CharacterSet>NotSet</CharacterSet>
-    <ConfigurationType>Application</ConfigurationType>
-    <IntermediateDirectory>debug\</IntermediateDirectory>
-    <PrimaryOutput>QtTermTCP</PrimaryOutput>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
-    <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
-  </Target>
-  <ImportGroup Label="ExtensionSettings" />
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
-    <Import Project="$(QtMsBuild)\qt_defaults.props" />
-  </ImportGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
-    <TargetName>QtTermTCP</TargetName>
-    <IgnoreImportLibrary>true</IgnoreImportLibrary>
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
-    <TargetName>QtTermTCP</TargetName>
-    <IgnoreImportLibrary>true</IgnoreImportLibrary>
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
-    <TargetName>QtTermTCP</TargetName>
-    <IgnoreImportLibrary>true</IgnoreImportLibrary>
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
-    <TargetName>QtTermTCP</TargetName>
-    <IgnoreImportLibrary>true</IgnoreImportLibrary>
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <QtInstall>5.14.2</QtInstall>
-    <QtModules>core;network;gui;widgets;serialport;multimedia</QtModules>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
-    <QtInstall>5.14.2_msvc2017</QtInstall>
-    <QtModules>core;network;gui;widgets;serialport</QtModules>
-  </PropertyGroup>
-  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <QtInstall>5.14.2</QtInstall>
-    <QtModules>core;network;gui;widgets;serialport;multimedia</QtModules>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
-    <QtInstall>5.14.2_msvc2017_64</QtInstall>
-    <QtModules>core;network;gui;widgets;serialport</QtModules>
-  </PropertyGroup>
-  <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
-    <Import Project="$(QtMsBuild)\qt.props" />
-  </ImportGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
-      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
-      <BrowseInformation>false</BrowseInformation>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
-      <ExceptionHandling>Sync</ExceptionHandling>
-      <ObjectFileName>$(IntDir)</ObjectFileName>
-      <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <PreprocessToFile>false</PreprocessToFile>
-      <ProgramDataBaseFileName>
-      </ProgramDataBaseFileName>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
-      <WarningLevel>Level3</WarningLevel>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>shell32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalOptions>-no-pie "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
-      <DataExecutionPrevention>true</DataExecutionPrevention>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <IgnoreImportLibrary>true</IgnoreImportLibrary>
-      <LinkIncremental>false</LinkIncremental>
-      <OptimizeReferences>true</OptimizeReferences>
-      <OutputFile>$(OutDir)\QtTermTCP.exe</OutputFile>
-      <RandomizedBaseAddress>true</RandomizedBaseAddress>
-      <SubSystem>Windows</SubSystem>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-    </Link>
-    <Midl>
-      <DefaultCharType>Unsigned</DefaultCharType>
-      <EnableErrorChecks>None</EnableErrorChecks>
-      <WarningLevel>0</WarningLevel>
-    </Midl>
-    <ResourceCompile>
-      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <QtMoc>
-      <CompilerFlavor>msvc</CompilerFlavor>
-      <Include>./$(Configuration)/moc_predefs.h</Include>
-      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
-      <DynamicSource>output</DynamicSource>
-      <QtMocDir>$(IntDir)</QtMocDir>
-      <QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
-    </QtMoc>
-    <QtRcc>
-      <InitFuncName>QtTermTCP</InitFuncName>
-      <Compression>default</Compression>
-      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
-      <QtRccDir>$(IntDir)</QtRccDir>
-      <QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
-    </QtRcc>
-    <QtUic>
-      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
-      <QtUicDir>$(IntDir)</QtUicDir>
-      <QtUicFileName>ui_%(Filename).h</QtUicFileName>
-    </QtUic>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
-      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
-      <BrowseInformation>false</BrowseInformation>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
-      <ExceptionHandling>Sync</ExceptionHandling>
-      <ObjectFileName>$(IntDir)</ObjectFileName>
-      <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <PreprocessToFile>false</PreprocessToFile>
-      <ProgramDataBaseFileName>
-      </ProgramDataBaseFileName>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
-      <WarningLevel>Level3</WarningLevel>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>shell32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalOptions>-no-pie "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
-      <DataExecutionPrevention>true</DataExecutionPrevention>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <IgnoreImportLibrary>true</IgnoreImportLibrary>
-      <LinkIncremental>false</LinkIncremental>
-      <OptimizeReferences>true</OptimizeReferences>
-      <OutputFile>$(OutDir)\QtTermTCP.exe</OutputFile>
-      <RandomizedBaseAddress>true</RandomizedBaseAddress>
-      <SubSystem>Windows</SubSystem>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-    </Link>
-    <Midl>
-      <DefaultCharType>Unsigned</DefaultCharType>
-      <EnableErrorChecks>None</EnableErrorChecks>
-      <WarningLevel>0</WarningLevel>
-    </Midl>
-    <ResourceCompile>
-      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <QtMoc>
-      <CompilerFlavor>msvc</CompilerFlavor>
-      <Include>./$(Configuration)/moc_predefs.h</Include>
-      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
-      <DynamicSource>output</DynamicSource>
-      <QtMocDir>$(IntDir)</QtMocDir>
-      <QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
-    </QtMoc>
-    <QtRcc>
-      <InitFuncName>QtTermTCP</InitFuncName>
-      <Compression>default</Compression>
-      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
-      <QtRccDir>$(IntDir)</QtRccDir>
-      <QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
-    </QtRcc>
-    <QtUic>
-      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
-      <QtUicDir>$(IntDir)</QtUicDir>
-      <QtUicFileName>ui_%(Filename).h</QtUicFileName>
-    </QtUic>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;debug;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
-      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
-      <BrowseInformation>false</BrowseInformation>
-      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
-      <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
-      <ExceptionHandling>Sync</ExceptionHandling>
-      <ObjectFileName>$(intdir)</ObjectFileName>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <PreprocessToFile>false</PreprocessToFile>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
-      <WarningLevel>Level3</WarningLevel>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>shell32.lib;setupapi.lib;%(AdditionalDependencies);</AdditionalDependencies>
-      <AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalOptions>-no-pie "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
-      <DataExecutionPrevention>true</DataExecutionPrevention>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <IgnoreImportLibrary>true</IgnoreImportLibrary>
-      <OutputFile>$(OutDir)\QtTermTCP.exe</OutputFile>
-      <RandomizedBaseAddress>true</RandomizedBaseAddress>
-      <SubSystem>Windows</SubSystem>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-    </Link>
-    <Midl>
-      <DefaultCharType>Unsigned</DefaultCharType>
-      <EnableErrorChecks>None</EnableErrorChecks>
-      <WarningLevel>0</WarningLevel>
-    </Midl>
-    <ResourceCompile>
-      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <QtMoc>
-      <CompilerFlavor>msvc</CompilerFlavor>
-      <Include>./$(Configuration)/moc_predefs.h</Include>
-      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
-      <DynamicSource>output</DynamicSource>
-      <QtMocDir>$(IntDir)</QtMocDir>
-      <QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
-    </QtMoc>
-    <QtRcc>
-      <InitFuncName>QtTermTCP</InitFuncName>
-      <Compression>default</Compression>
-      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
-      <QtRccDir>$(IntDir)</QtRccDir>
-      <QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
-    </QtRcc>
-    <QtUic>
-      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
-      <QtUicDir>$(IntDir)</QtUicDir>
-      <QtUicFileName>ui_%(Filename).h</QtUicFileName>
-    </QtUic>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;debug;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
-      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
-      <BrowseInformation>false</BrowseInformation>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
-      <ExceptionHandling>Sync</ExceptionHandling>
-      <ObjectFileName>$(intdir)</ObjectFileName>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <PreprocessToFile>false</PreprocessToFile>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
-      <WarningLevel>Level3</WarningLevel>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>shell32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalOptions>-no-pie "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
-      <DataExecutionPrevention>true</DataExecutionPrevention>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <IgnoreImportLibrary>true</IgnoreImportLibrary>
-      <OutputFile>$(OutDir)\QtTermTCP.exe</OutputFile>
-      <RandomizedBaseAddress>true</RandomizedBaseAddress>
-      <SubSystem>Windows</SubSystem>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-    </Link>
-    <Midl>
-      <DefaultCharType>Unsigned</DefaultCharType>
-      <EnableErrorChecks>None</EnableErrorChecks>
-      <WarningLevel>0</WarningLevel>
-    </Midl>
-    <ResourceCompile>
-      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <QtMoc>
-      <CompilerFlavor>msvc</CompilerFlavor>
-      <Include>./$(Configuration)/moc_predefs.h</Include>
-      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
-      <DynamicSource>output</DynamicSource>
-      <QtMocDir>$(IntDir)</QtMocDir>
-      <QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
-    </QtMoc>
-    <QtRcc>
-      <InitFuncName>QtTermTCP</InitFuncName>
-      <Compression>default</Compression>
-      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
-      <QtRccDir>$(IntDir)</QtRccDir>
-      <QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
-    </QtRcc>
-    <QtUic>
-      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
-      <QtUicDir>$(IntDir)</QtUicDir>
-      <QtUicFileName>ui_%(Filename).h</QtUicFileName>
-    </QtUic>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="AGWCode.cpp" />
-    <ClCompile Include="hid.c" />
-    <ClCompile Include="QtTermTCP.cpp">
-      <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EditAndContinue</DebugInformationFormat>
-      <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ProgramDatabase</DebugInformationFormat>
-    </ClCompile>
-    <ClCompile Include="TabDialog.cpp" />
-    <ClCompile Include="TermTCPCommon.cpp" />
-    <ClCompile Include="UZ7HOUtils.c" />
-    <ClCompile Include="ax25.c" />
-    <ClCompile Include="ax25_l2.c" />
-    <ClCompile Include="main.cpp" />
-    <ClCompile Include="utf8Routines.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <QtMoc Include="QtTermTCP.h">
-    </QtMoc>
-    <QtMoc Include="TabDialog.h">
-    </QtMoc>
-  </ItemGroup>
-  <ItemGroup>
-    <CustomBuild Include="debug\moc_predefs.h.cbt">
-      <FileType>Document</FileType>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
-      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
-      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;debug\moc_predefs.h</Command>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;debug\moc_predefs.h</Command>
-      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Generate moc_predefs.h</Message>
-      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">debug\moc_predefs.h;%(Outputs)</Outputs>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_predefs.h;%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="release\moc_predefs.h.cbt">
-      <FileType>Document</FileType>
-      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
-      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;release\moc_predefs.h</Command>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;release\moc_predefs.h</Command>
-      <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Generate moc_predefs.h</Message>
-      <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generate moc_predefs.h</Message>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">release\moc_predefs.h;%(Outputs)</Outputs>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_predefs.h;%(Outputs)</Outputs>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
-    </CustomBuild>
-  </ItemGroup>
-  <ItemGroup>
-    <QtUic Include="AGWConnect.ui">
-    </QtUic>
-    <QtUic Include="AGWParams.ui">
-    </QtUic>
-    <QtUic Include="AlertSetup.ui" />
-    <QtUic Include="ColourConfig.ui" />
-    <QtUic Include="KISSConfig.ui">
-    </QtUic>
-    <QtUic Include="ListenPort.ui">
-    </QtUic>
-    <QtUic Include="QtTermTCP.ui">
-    </QtUic>
-    <QtUic Include="VARAConfig.ui">
-    </QtUic>
-    <QtUic Include="YAPPRxSize.ui" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="QtTermTCP.ico" />
-    <QtRcc Include="QtTermTCP.qrc">
-    </QtRcc>
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include=".\QtTermTCP_resource.rc" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
-    <Import Project="$(QtMsBuild)\qt.targets" />
-  </ImportGroup>
-  <ImportGroup Label="ExtensionTargets" />
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{14F3B24E-473C-324E-A99D-3B679FCF5F67}</ProjectGuid>
+    <RootNamespace>QtTermTCP</RootNamespace>
+    <Keyword>QtVS_v304</Keyword>
+    <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
+    <QtMsBuild Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <PlatformToolset>v141</PlatformToolset>
+    <OutputDirectory>release\</OutputDirectory>
+    <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
+    <CharacterSet>NotSet</CharacterSet>
+    <ConfigurationType>Application</ConfigurationType>
+    <IntermediateDirectory>release\</IntermediateDirectory>
+    <PrimaryOutput>QtTermTCP</PrimaryOutput>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <PlatformToolset>v141</PlatformToolset>
+    <OutputDirectory>release\</OutputDirectory>
+    <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
+    <CharacterSet>NotSet</CharacterSet>
+    <ConfigurationType>Application</ConfigurationType>
+    <IntermediateDirectory>release\</IntermediateDirectory>
+    <PrimaryOutput>QtTermTCP</PrimaryOutput>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <PlatformToolset>v141</PlatformToolset>
+    <OutputDirectory>debug\</OutputDirectory>
+    <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
+    <CharacterSet>NotSet</CharacterSet>
+    <ConfigurationType>Application</ConfigurationType>
+    <IntermediateDirectory>debug\</IntermediateDirectory>
+    <PrimaryOutput>QtTermTCP</PrimaryOutput>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <PlatformToolset>v141</PlatformToolset>
+    <OutputDirectory>debug\</OutputDirectory>
+    <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
+    <CharacterSet>NotSet</CharacterSet>
+    <ConfigurationType>Application</ConfigurationType>
+    <IntermediateDirectory>debug\</IntermediateDirectory>
+    <PrimaryOutput>QtTermTCP</PrimaryOutput>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+    <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+  </Target>
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+    <Import Project="$(QtMsBuild)\qt_defaults.props" />
+  </ImportGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>QtTermTCP</TargetName>
+    <IgnoreImportLibrary>true</IgnoreImportLibrary>
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>QtTermTCP</TargetName>
+    <IgnoreImportLibrary>true</IgnoreImportLibrary>
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>QtTermTCP</TargetName>
+    <IgnoreImportLibrary>true</IgnoreImportLibrary>
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>QtTermTCP</TargetName>
+    <IgnoreImportLibrary>true</IgnoreImportLibrary>
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <QtInstall>5.14.2</QtInstall>
+    <QtModules>core;network;gui;widgets;serialport;multimedia</QtModules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
+    <QtInstall>5.14.2_msvc2017</QtInstall>
+    <QtModules>core;network;gui;widgets;serialport</QtModules>
+  </PropertyGroup>
+  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <QtInstall>5.14.2</QtInstall>
+    <QtModules>core;network;gui;widgets;serialport;multimedia</QtModules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
+    <QtInstall>5.14.2_msvc2017_64</QtInstall>
+    <QtModules>core;network;gui;widgets;serialport</QtModules>
+  </PropertyGroup>
+  <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+    <Import Project="$(QtMsBuild)\qt.props" />
+  </ImportGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <BrowseInformation>false</BrowseInformation>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessToFile>false</PreprocessToFile>
+      <ProgramDataBaseFileName>
+      </ProgramDataBaseFileName>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+      <WarningLevel>Level3</WarningLevel>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>shell32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-no-pie "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <IgnoreImportLibrary>true</IgnoreImportLibrary>
+      <LinkIncremental>false</LinkIncremental>
+      <OptimizeReferences>true</OptimizeReferences>
+      <OutputFile>$(OutDir)\QtTermTCP.exe</OutputFile>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <SubSystem>Windows</SubSystem>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Link>
+    <Midl>
+      <DefaultCharType>Unsigned</DefaultCharType>
+      <EnableErrorChecks>None</EnableErrorChecks>
+      <WarningLevel>0</WarningLevel>
+    </Midl>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <QtMoc>
+      <CompilerFlavor>msvc</CompilerFlavor>
+      <Include>./$(Configuration)/moc_predefs.h</Include>
+      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
+      <DynamicSource>output</DynamicSource>
+      <QtMocDir>$(IntDir)</QtMocDir>
+      <QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
+    </QtMoc>
+    <QtRcc>
+      <InitFuncName>QtTermTCP</InitFuncName>
+      <Compression>default</Compression>
+      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
+      <QtRccDir>$(IntDir)</QtRccDir>
+      <QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
+    </QtRcc>
+    <QtUic>
+      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
+      <QtUicDir>$(IntDir)</QtUicDir>
+      <QtUicFileName>ui_%(Filename).h</QtUicFileName>
+    </QtUic>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <BrowseInformation>false</BrowseInformation>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessToFile>false</PreprocessToFile>
+      <ProgramDataBaseFileName>
+      </ProgramDataBaseFileName>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+      <WarningLevel>Level3</WarningLevel>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>shell32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-no-pie "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <IgnoreImportLibrary>true</IgnoreImportLibrary>
+      <LinkIncremental>false</LinkIncremental>
+      <OptimizeReferences>true</OptimizeReferences>
+      <OutputFile>$(OutDir)\QtTermTCP.exe</OutputFile>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <SubSystem>Windows</SubSystem>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Link>
+    <Midl>
+      <DefaultCharType>Unsigned</DefaultCharType>
+      <EnableErrorChecks>None</EnableErrorChecks>
+      <WarningLevel>0</WarningLevel>
+    </Midl>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <QtMoc>
+      <CompilerFlavor>msvc</CompilerFlavor>
+      <Include>./$(Configuration)/moc_predefs.h</Include>
+      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
+      <DynamicSource>output</DynamicSource>
+      <QtMocDir>$(IntDir)</QtMocDir>
+      <QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
+    </QtMoc>
+    <QtRcc>
+      <InitFuncName>QtTermTCP</InitFuncName>
+      <Compression>default</Compression>
+      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
+      <QtRccDir>$(IntDir)</QtRccDir>
+      <QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
+    </QtRcc>
+    <QtUic>
+      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
+      <QtUicDir>$(IntDir)</QtUicDir>
+      <QtUicFileName>ui_%(Filename).h</QtUicFileName>
+    </QtUic>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;debug;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <BrowseInformation>false</BrowseInformation>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <ObjectFileName>$(intdir)</ObjectFileName>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessToFile>false</PreprocessToFile>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+      <WarningLevel>Level3</WarningLevel>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>shell32.lib;setupapi.lib;%(AdditionalDependencies);</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-no-pie "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <IgnoreImportLibrary>true</IgnoreImportLibrary>
+      <OutputFile>$(OutDir)\QtTermTCP.exe</OutputFile>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <SubSystem>Windows</SubSystem>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+    <Midl>
+      <DefaultCharType>Unsigned</DefaultCharType>
+      <EnableErrorChecks>None</EnableErrorChecks>
+      <WarningLevel>0</WarningLevel>
+    </Midl>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <QtMoc>
+      <CompilerFlavor>msvc</CompilerFlavor>
+      <Include>./$(Configuration)/moc_predefs.h</Include>
+      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
+      <DynamicSource>output</DynamicSource>
+      <QtMocDir>$(IntDir)</QtMocDir>
+      <QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
+    </QtMoc>
+    <QtRcc>
+      <InitFuncName>QtTermTCP</InitFuncName>
+      <Compression>default</Compression>
+      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
+      <QtRccDir>$(IntDir)</QtRccDir>
+      <QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
+    </QtRcc>
+    <QtUic>
+      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
+      <QtUicDir>$(IntDir)</QtUicDir>
+      <QtUicFileName>ui_%(Filename).h</QtUicFileName>
+    </QtUic>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;debug;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <BrowseInformation>false</BrowseInformation>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <ObjectFileName>$(intdir)</ObjectFileName>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessToFile>false</PreprocessToFile>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+      <WarningLevel>Level3</WarningLevel>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>shell32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-no-pie "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <IgnoreImportLibrary>true</IgnoreImportLibrary>
+      <OutputFile>$(OutDir)\QtTermTCP.exe</OutputFile>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <SubSystem>Windows</SubSystem>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+    <Midl>
+      <DefaultCharType>Unsigned</DefaultCharType>
+      <EnableErrorChecks>None</EnableErrorChecks>
+      <WarningLevel>0</WarningLevel>
+    </Midl>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_DEPRECATED_WARNINGS;QT_DISABLE_DEPRECATED_BEFORE=0x050000;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <QtMoc>
+      <CompilerFlavor>msvc</CompilerFlavor>
+      <Include>./$(Configuration)/moc_predefs.h</Include>
+      <ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
+      <DynamicSource>output</DynamicSource>
+      <QtMocDir>$(IntDir)</QtMocDir>
+      <QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
+    </QtMoc>
+    <QtRcc>
+      <InitFuncName>QtTermTCP</InitFuncName>
+      <Compression>default</Compression>
+      <ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
+      <QtRccDir>$(IntDir)</QtRccDir>
+      <QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
+    </QtRcc>
+    <QtUic>
+      <ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
+      <QtUicDir>$(IntDir)</QtUicDir>
+      <QtUicFileName>ui_%(Filename).h</QtUicFileName>
+    </QtUic>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="AGWCode.cpp" />
+    <ClCompile Include="hid.c" />
+    <ClCompile Include="QtTermTCP.cpp">
+      <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EditAndContinue</DebugInformationFormat>
+      <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ClCompile Include="TabDialog.cpp" />
+    <ClCompile Include="TermTCPCommon.cpp" />
+    <ClCompile Include="UZ7HOUtils.c" />
+    <ClCompile Include="ax25.c" />
+    <ClCompile Include="ax25_l2.c" />
+    <ClCompile Include="main.cpp" />
+    <ClCompile Include="utf8Routines.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <QtMoc Include="QtTermTCP.h">
+    </QtMoc>
+    <QtMoc Include="TabDialog.h">
+    </QtMoc>
+  </ItemGroup>
+  <ItemGroup>
+    <CustomBuild Include="debug\moc_predefs.h.cbt">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;debug\moc_predefs.h</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;debug\moc_predefs.h</Command>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Generate moc_predefs.h</Message>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">debug\moc_predefs.h;%(Outputs)</Outputs>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_predefs.h;%(Outputs)</Outputs>
+    </CustomBuild>
+    <CustomBuild Include="release\moc_predefs.h.cbt">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;release\moc_predefs.h</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;release\moc_predefs.h</Command>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Generate moc_predefs.h</Message>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generate moc_predefs.h</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">release\moc_predefs.h;%(Outputs)</Outputs>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_predefs.h;%(Outputs)</Outputs>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+    </CustomBuild>
+  </ItemGroup>
+  <ItemGroup>
+    <QtUic Include="AGWConnect.ui">
+    </QtUic>
+    <QtUic Include="AGWParams.ui">
+    </QtUic>
+    <QtUic Include="AlertSetup.ui" />
+    <QtUic Include="ColourConfig.ui" />
+    <QtUic Include="KISSConfig.ui">
+    </QtUic>
+    <QtUic Include="ListenPort.ui">
+    </QtUic>
+    <QtUic Include="QtTermTCP.ui">
+    </QtUic>
+    <QtUic Include="VARAConfig.ui">
+    </QtUic>
+    <QtUic Include="YAPPRxSize.ui" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="QtTermTCP.ico" />
+    <QtRcc Include="QtTermTCP.qrc">
+    </QtRcc>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include=".\QtTermTCP_resource.rc" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+    <Import Project="$(QtMsBuild)\qt.targets" />
+  </ImportGroup>
+  <ImportGroup Label="ExtensionTargets" />
 </Project>
\ No newline at end of file
--- qttermtcp-0.0.0.79.orig/QtTermTCP.vcxproj.filters
+++ qttermtcp-0.0.0.79/QtTermTCP.vcxproj.filters
@@ -1,137 +1,137 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Form Files">
-      <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
-      <Extensions>ui</Extensions>
-      <ParseFiles>false</ParseFiles>
-    </Filter>
-    <Filter Include="Form Files">
-      <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
-      <Extensions>ui</Extensions>
-      <ParseFiles>false</ParseFiles>
-    </Filter>
-    <Filter Include="Generated Files">
-      <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
-      <Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
-      <Extensions>qrc;*</Extensions>
-      <ParseFiles>false</ParseFiles>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
-      <Extensions>qrc;*</Extensions>
-      <ParseFiles>false</ParseFiles>
-    </Filter>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Form Files\Generated Files">
-      <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
-      <Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="AGWCode.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="QtTermTCP.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="TabDialog.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="TermTCPCommon.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="UZ7HOUtils.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="ax25.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="ax25_l2.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="main.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="utf8Routines.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="hid.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <QtMoc Include="QtTermTCP.h">
-      <Filter>Header Files</Filter>
-    </QtMoc>
-    <QtMoc Include="TabDialog.h">
-      <Filter>Form Files\Generated Files</Filter>
-    </QtMoc>
-  </ItemGroup>
-  <ItemGroup>
-    <CustomBuild Include="debug\moc_predefs.h.cbt">
-      <Filter>Form Files\Generated Files</Filter>
-    </CustomBuild>
-    <CustomBuild Include="release\moc_predefs.h.cbt">
-      <Filter>Form Files\Generated Files</Filter>
-    </CustomBuild>
-  </ItemGroup>
-  <ItemGroup>
-    <QtUic Include="AGWParams.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-    <QtUic Include="QtTermTCP.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-    <QtUic Include="VARAConfig.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-    <QtUic Include="ColourConfig.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-    <QtUic Include="YAPPRxSize.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-    <QtUic Include="AGWConnect.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-    <QtUic Include="ListenPort.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-    <QtUic Include="KISSConfig.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-    <QtUic Include="AlertSetup.ui">
-      <Filter>Form Files</Filter>
-    </QtUic>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="QtTermTCP.ico">
-      <Filter>Resource Files</Filter>
-    </None>
-    <QtRcc Include="QtTermTCP.qrc">
-      <Filter>Resource Files</Filter>
-    </QtRcc>
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include=".\QtTermTCP_resource.rc" />
-  </ItemGroup>
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Form Files">
+      <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+      <Extensions>ui</Extensions>
+      <ParseFiles>false</ParseFiles>
+    </Filter>
+    <Filter Include="Form Files">
+      <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+      <Extensions>ui</Extensions>
+      <ParseFiles>false</ParseFiles>
+    </Filter>
+    <Filter Include="Generated Files">
+      <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+      <Extensions>qrc;*</Extensions>
+      <ParseFiles>false</ParseFiles>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+      <Extensions>qrc;*</Extensions>
+      <ParseFiles>false</ParseFiles>
+    </Filter>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Form Files\Generated Files">
+      <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="AGWCode.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="QtTermTCP.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="TabDialog.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="TermTCPCommon.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="UZ7HOUtils.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="ax25.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="ax25_l2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="main.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="utf8Routines.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="hid.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <QtMoc Include="QtTermTCP.h">
+      <Filter>Header Files</Filter>
+    </QtMoc>
+    <QtMoc Include="TabDialog.h">
+      <Filter>Form Files\Generated Files</Filter>
+    </QtMoc>
+  </ItemGroup>
+  <ItemGroup>
+    <CustomBuild Include="debug\moc_predefs.h.cbt">
+      <Filter>Form Files\Generated Files</Filter>
+    </CustomBuild>
+    <CustomBuild Include="release\moc_predefs.h.cbt">
+      <Filter>Form Files\Generated Files</Filter>
+    </CustomBuild>
+  </ItemGroup>
+  <ItemGroup>
+    <QtUic Include="AGWParams.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+    <QtUic Include="QtTermTCP.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+    <QtUic Include="VARAConfig.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+    <QtUic Include="ColourConfig.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+    <QtUic Include="YAPPRxSize.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+    <QtUic Include="AGWConnect.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+    <QtUic Include="ListenPort.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+    <QtUic Include="KISSConfig.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+    <QtUic Include="AlertSetup.ui">
+      <Filter>Form Files</Filter>
+    </QtUic>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="QtTermTCP.ico">
+      <Filter>Resource Files</Filter>
+    </None>
+    <QtRcc Include="QtTermTCP.qrc">
+      <Filter>Resource Files</Filter>
+    </QtRcc>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include=".\QtTermTCP_resource.rc" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
--- qttermtcp-0.0.0.79.orig/QtTermTCP.vcxproj.user
+++ qttermtcp-0.0.0.79/QtTermTCP.vcxproj.user
@@ -1,31 +1,31 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LocalDebuggerWorkingDirectory>C:\DevProgs\BPQ32\Release</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommand>C:\Dev\Msdev2005\Projects\QtTermTCP\Win32\Debug\QtTermTCP.exe</LocalDebuggerCommand>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerWorkingDirectory>C:\DevProgs\BPQ32\Release</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommand>C:\Dev\Msdev2005\Projects\QtTermTCP\Win32\Debug\QtTermTCP.exe</LocalDebuggerCommand>
-  </PropertyGroup>
-  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <QtLastBackgroundBuild>2022-05-19T07:28:47.9186341Z</QtLastBackgroundBuild>
-  </PropertyGroup>
-  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <QtLastBackgroundBuild>2022-05-19T07:28:58.9302359Z</QtLastBackgroundBuild>
-  </PropertyGroup>
-  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <QtLastBackgroundBuild>2025-02-19T10:20:19.7224236Z</QtLastBackgroundBuild>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
-    <QtLastBackgroundBuild>2025-02-19T10:20:19.9860750Z</QtLastBackgroundBuild>
-  </PropertyGroup>
-  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <QtLastBackgroundBuild>2025-02-19T10:20:19.2704826Z</QtLastBackgroundBuild>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
-    <QtLastBackgroundBuild>2025-02-19T10:20:19.4132585Z</QtLastBackgroundBuild>
-  </PropertyGroup>
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerWorkingDirectory>C:\DevProgs\BPQ32\Release</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommand>C:\Dev\Msdev2005\Projects\QtTermTCP\Win32\Debug\QtTermTCP.exe</LocalDebuggerCommand>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LocalDebuggerWorkingDirectory>C:\DevProgs\BPQ32\Release</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommand>C:\Dev\Msdev2005\Projects\QtTermTCP\Win32\Debug\QtTermTCP.exe</LocalDebuggerCommand>
+  </PropertyGroup>
+  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <QtLastBackgroundBuild>2022-05-19T07:28:47.9186341Z</QtLastBackgroundBuild>
+  </PropertyGroup>
+  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <QtLastBackgroundBuild>2022-05-19T07:28:58.9302359Z</QtLastBackgroundBuild>
+  </PropertyGroup>
+  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <QtLastBackgroundBuild>2025-02-19T10:20:19.7224236Z</QtLastBackgroundBuild>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
+    <QtLastBackgroundBuild>2025-02-19T10:20:19.9860750Z</QtLastBackgroundBuild>
+  </PropertyGroup>
+  <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <QtLastBackgroundBuild>2025-02-19T10:20:19.2704826Z</QtLastBackgroundBuild>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
+    <QtLastBackgroundBuild>2025-02-19T10:20:19.4132585Z</QtLastBackgroundBuild>
+  </PropertyGroup>
 </Project>
\ No newline at end of file
--- qttermtcp-0.0.0.79.orig/TCPHostConfig.ui
+++ qttermtcp-0.0.0.79/TCPHostConfig.ui
@@ -1,85 +1,85 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Dialog</class>
- <widget class="QDialog" name="Dialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>400</width>
-    <height>300</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>TCP Host Config</string>
-  </property>
-  <property name="windowIcon">
-   <iconset>
-    <normaloff>QtTermTCP.ico</normaloff>QtTermTCP.ico</iconset>
-  </property>
-  <widget class="QDialogButtonBox" name="buttonBox">
-   <property name="geometry">
-    <rect>
-     <x>30</x>
-     <y>240</y>
-     <width>341</width>
-     <height>32</height>
-    </rect>
-   </property>
-   <property name="orientation">
-    <enum>Qt::Horizontal</enum>
-   </property>
-   <property name="standardButtons">
-    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
-   </property>
-   <property name="centerButtons">
-    <bool>true</bool>
-   </property>
-  </widget>
-  <widget class="QTextEdit" name="Host">
-   <property name="geometry">
-    <rect>
-     <x>184</x>
-     <y>44</y>
-     <width>104</width>
-     <height>23</height>
-    </rect>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>Dialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>Dialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>TCP Host Config</string>
+  </property>
+  <property name="windowIcon">
+   <iconset>
+    <normaloff>QtTermTCP.ico</normaloff>QtTermTCP.ico</iconset>
+  </property>
+  <widget class="QDialogButtonBox" name="buttonBox">
+   <property name="geometry">
+    <rect>
+     <x>30</x>
+     <y>240</y>
+     <width>341</width>
+     <height>32</height>
+    </rect>
+   </property>
+   <property name="orientation">
+    <enum>Qt::Horizontal</enum>
+   </property>
+   <property name="standardButtons">
+    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
+   </property>
+   <property name="centerButtons">
+    <bool>true</bool>
+   </property>
+  </widget>
+  <widget class="QTextEdit" name="Host">
+   <property name="geometry">
+    <rect>
+     <x>184</x>
+     <y>44</y>
+     <width>104</width>
+     <height>23</height>
+    </rect>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Dialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Dialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- qttermtcp-0.0.0.79.orig/TabDialog.cpp
+++ qttermtcp-0.0.0.79/TabDialog.cpp
@@ -1,1199 +1,1199 @@
-
-#define _CRT_SECURE_NO_WARNINGS
-
-#include "TabDialog.h"
-#include "QtTermTCP.h"
-#include <QTcpServer>
-#include "QSettings"
-#include "QLineEdit"
-#include "QTabWidget"
-#include "QDialogButtonBox"
-#include "QVBoxLayout"
-#include "QLabel"
-#include "QAction"
-#include "QGroupBox"
-#include "QPlainTextEdit"
-#include "QCheckBox"
-#include "QFormLayout"
-#include "QScrollArea"
-
-#include "ax25.h"
-
-#ifndef WIN32
-#define strtok_s strtok_r
-#endif
-
-extern "C" void SaveSettings();
-
-extern int screenHeight;
-extern int screenWidth;
-
-extern QList<Ui_ListenSession *> _sessions;
-extern QTcpServer * _server;
-
-extern myTcpSocket * AGWSock;
-extern myTcpSocket * KISSSock;
-extern QLabel * Status1;
-extern QFont * menufont;
-extern QStatusBar * myStatusBar;
-
-QLineEdit *hostEdit;
-QLineEdit *portEdit;
-QLineEdit *userEdit;
-QLineEdit *passEdit;
-QLineEdit *SNameEdit;
-
-extern QAction *actHost[17];
-extern QAction *actSetup[16];
-
-extern int ConfigHost;
-
-#define MAXHOSTS 16
-
-extern char Host[MAXHOSTS + 1][100];
-extern int Port[MAXHOSTS + 1];
-extern char UserName[MAXHOSTS + 1][80];
-extern char Password[MAXHOSTS + 1][80];
-extern char SessName[MAXHOSTS + 1][80];
-
-extern char KISSMYCALL[32];
-
-QLineEdit *TermCall;
-QGroupBox *groupBox;
-QLineEdit *beaconDest;
-QLineEdit *beaconPath;
-QLineEdit *beaconInterval;
-QLineEdit *beaconPorts;
-QLabel *label_2;
-QLabel *label_3;
-QLabel *label_4;
-QLabel *label_5;
-QLabel *label_6;
-QLabel *label_7;
-QLabel *label_11;
-QPlainTextEdit *beaconText;
-QLabel *label_12;
-QGroupBox *groupBox_2;
-QLineEdit *AHost;
-QLineEdit *APort;
-QLineEdit *APath;
-QLineEdit *Paclen;
-QLabel *label_8;
-QLabel *label_9;
-QLabel *label_10;
-QLabel *label;
-QCheckBox *AAGWEnable;
-QLabel *label_13;
-QCheckBox *AAGWMonEnable;
-
-QLineEdit *AVARATermCall;
-QLineEdit *AVARAHost;
-QLineEdit *AVARAPort;
-QCheckBox *AVARAEnable;
-
-
-extern int AGWEnable;
-extern int VARAEnable;
-extern int KISSEnable;
-extern int AGWMonEnable;
-extern char AGWTermCall[12];
-extern char AGWBeaconDest[12];
-extern char AGWBeaconPath[80];
-extern int AGWBeaconInterval;
-extern char AGWBeaconPorts[80];
-extern char AGWBeaconMsg[260];
-
-extern char VARATermCall[12];
-
-extern char AGWHost[128];
-extern int AGWPortNum;
-extern int AGWPaclen;
-extern char * AGWPortList;
-extern myTcpSocket * AGWSock; 
-extern char * AGWPortList;
-extern QStringList AGWToCalls;
-
-extern int KISSMode;
-extern char KISSVia[128];				// Digi String
-
-extern Ui_ListenSession * ActiveSession;
-
-extern int TermMode;
-
-#define Single 0
-#define MDI 1
-#define Tabbed 2
-
-extern int listenPort;
-extern "C" int listenEnable;
-extern char listenCText[4096];
-
-void Send_AGW_C_Frame(Ui_ListenSession * Sess, int Port, char * CallFrom, char * CallTo, char * Data, int DataLen);
-extern "C" void SetSessLabel(Ui_ListenSession * Sess, char * label);
-extern "C" void SendtoTerm(Ui_ListenSession * Sess, char * Msg, int Len);
-
-QString GetConfPath();
-
-QScrollArea *scrollArea;
-QWidget *scrollAreaWidgetContents;
-
-bool myResize::eventFilter(QObject *obj, QEvent *event)
-{
-	if (event->type() == QEvent::Resize)
-	{
-		QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event);
-		QSize size = resizeEvent->size();
-		int h = size.height();
-		int w = size.width();
-
-		scrollArea->setGeometry(QRect(5, 5, w - 10, h - 10));
-		return true;
-	}
-	return QObject::eventFilter(obj, event);
-}
-
-AGWConnect::AGWConnect(QWidget *parent) : QDialog(parent)
-{
-	this->setFont(*menufont);
-
-	setWindowTitle(tr("AGW Connection"));
-
-	myResize *resize = new myResize();
-	installEventFilter(resize);
-
-	scrollArea = new QScrollArea(this);
-	scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
-	scrollArea->setGeometry(QRect(5, 5, 562, 681));
-	scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-	scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-	scrollArea->setWidgetResizable(false);
-	scrollAreaWidgetContents = new QWidget();
-	scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
-
-	QVBoxLayout *layout = new QVBoxLayout();
-	layout->setContentsMargins(10, 10, 10, 10);
-
-	setLayout(layout);
-
-	QFormLayout *formLayout2 = new QFormLayout();
-	layout->addLayout(formLayout2);
-
-	wCallFrom = new QLineEdit();
-	formLayout2->addRow(new QLabel("Call From"), wCallFrom);
-
-	wCallTo = new QComboBox();
-	wCallTo->setEditable(true);
-	wCallTo->setInsertPolicy(QComboBox::NoInsert);
-
-	formLayout2->addRow(new QLabel("Call To"), wCallTo);
-
-	Digis = new QLineEdit();
-	formLayout2->addRow(new QLabel("Digis"), Digis);
-
-	layout->addSpacing(2);
-	layout->addWidget(new QLabel("Radio Ports"));
-
-	RadioPorts = new QListWidget();
-
-	layout->addWidget(RadioPorts);
-
-	QString str;
-	int count;
-
-	char * Context;
-	char * ptr;
-
-	wCallFrom->setText(AGWTermCall);
-
-	wCallTo->addItems(AGWToCalls);
-
-	if (AGWPortList)
-	{
-		char * Temp = strdup(AGWPortList);		// Need copy as strtok messes with it
-
-		count = atoi(Temp);
-
-		ptr = strtok_s(Temp, ";", &Context);
-
-		for (int n = 0; n < count; n++)
-		{
-			ptr = strtok_s(NULL, ";", &Context);
-			new QListWidgetItem(ptr, RadioPorts);
-		}
-
-		free(Temp);
-
-		// calculate scrollarea height from count
-
-		scrollAreaWidgetContents->setGeometry(QRect(0, 0, 400, 220 + 22 * count));
-		this->resize(420, 240 + 22 * count);
-
-	}
-
-	RadioPorts->setFont(*menufont);
-
-	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
-	buttonBox->setFont(*menufont);
-	layout->addWidget(buttonBox);
-
-	scrollAreaWidgetContents->setLayout(layout);
-	scrollArea->setWidget(scrollAreaWidgetContents);
-
-	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
-	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
-}
-
-AGWConnect::~AGWConnect()
-{
-}
-
-extern QAction *discAction;
-
-void AGWConnect::myaccept()
-{
-	QVariant Q;
-
-	int port = RadioPorts->currentRow();
-	char CallFrom[32];
-	char CallTo[32];
-	char Via[128];
-	char DigiMsg[128] = "";
-	int DigiLen = 0;
-	char * digiptr = &DigiMsg[1];
-
-	strcpy(CallFrom, wCallFrom->text().toUpper().toUtf8());
-	strcpy(CallTo, wCallTo->currentText().toUpper().toUtf8());
-	strcpy(Via, Digis->text().toUpper().toUtf8());
-
-	if (CallFrom[0] == 0)
-	{
-		QMessageBox msgBox;
-		msgBox.setText("Call From missing");
-		msgBox.exec();
-		return;
-	}
-
-	if (CallTo[0] == 0)
-	{
-		QMessageBox msgBox;
-		msgBox.setText("Call To missing");
-		msgBox.exec();
-		return;
-	}
-
-	// if digis have to form block with byte count followed by n 10 byte calls
-
-	if (Via[0])
-	{
-		char * context;
-		char * ptr = strtok_s(Via, ", ", &context);
-
-		while (ptr)
-		{
-			DigiMsg[0]++;
-			strcpy(digiptr, ptr);
-			digiptr += 10;
-
-			ptr = strtok_s(NULL, ", ", &context);
-		}
-		DigiLen = digiptr - DigiMsg;
-	}
-
-	// Add CallTo if not already in list
-
-	if (AGWToCalls.contains(CallTo))
-		AGWToCalls.removeOne(CallTo);
-
-	AGWToCalls.insert(-1, CallTo);
-
-	if (port == -1)
-	{
-		// Port not set. If connecting to SWITCH use any, otherwise tell user
-
-		if (strcmp(CallTo, "SWITCH") == 0)
-		{
-			port = 0;
-		}
-		else
-		{
-			QMessageBox msgBox;
-			msgBox.setText("Select a port to call on");
-			msgBox.exec();
-			return;
-		}
-	}
-
-	Send_AGW_C_Frame(ActiveSession, port, CallFrom, CallTo, DigiMsg, DigiLen);
-
-	discAction->setEnabled(true);
-
-
-	AGWConnect::accept();
-}
-
-void AGWConnect::myreject()
-{
-	AGWConnect::reject();
-}
-
-
-AGWDialog::AGWDialog(QWidget *parent) : QDialog(parent)
-{
-	this->setFont(*menufont);
-
-	setWindowTitle(tr("TermTCP AGW Configuration"));
-
-	myResize *resize = new myResize();
-	installEventFilter(resize);
-
-
-	scrollArea = new QScrollArea(this);
-	scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
-	scrollArea->setGeometry(QRect(5, 5, 562, 681));
-	scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-	scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-	scrollArea->setWidgetResizable(false);
-	scrollAreaWidgetContents = new QWidget();
-	scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
-	scrollAreaWidgetContents->setGeometry(QRect(0, 0, 552, 581));
-
-	this->resize(572, 601);
-
-	QVBoxLayout *layout = new QVBoxLayout;
-	QHBoxLayout *hlayout = new QHBoxLayout;
-
-	layout->addLayout(hlayout);
-	AAGWEnable = new QCheckBox("Enable AGW Interface");
-	AAGWEnable->setLayoutDirection(Qt::LeftToRight);
-
-	AAGWMonEnable = new QCheckBox("Enable Monitor");
-	AAGWMonEnable->setGeometry(QRect(255, 18, 216, 21));
-	AAGWMonEnable->setLayoutDirection(Qt::RightToLeft);
-
-	hlayout->addWidget(AAGWEnable);
-	hlayout->addWidget(AAGWMonEnable);
-
-	QFormLayout *flayout = new QFormLayout;
-	layout->addLayout(flayout);
-
-	label = new QLabel("Terminal Call");
-	TermCall = new QLineEdit(this);
-
-	flayout->addRow(label, TermCall);
-	
-	layout->addWidget(new QLabel("Beacon Setup"));
-
-	QFormLayout *flayout1 = new QFormLayout;
-	layout->addLayout(flayout1);
-
-	label_2 = new QLabel("Destination");
-	beaconDest = new QLineEdit();
-	label_3 = new QLabel("Digipeaters");
-	beaconPath = new QLineEdit();
-
-	flayout1->addRow(label_2, beaconDest);
-	flayout1->addRow(label_3, beaconPath);
-
-	label_4 = new QLabel("Interval");
-	beaconInterval = new QLineEdit();
-	label_5 = new QLabel("Ports");
-	beaconPorts = new QLineEdit();
-
-	flayout1->addRow(label_4, beaconInterval);
-	flayout1->addRow(label_5, beaconPorts);
-
-//	label_6 = new QLabel("Minutes", groupBox);
-
-//	label_7 = new QLabel("(Separate with commas)", groupBox);
-	label_11 = new QLabel("Message");
-	beaconText = new QPlainTextEdit();
-
-	flayout1->addRow(label_11, beaconText);
-
-
-
-//	label_12 = new QLabel("(max 256 chars)");
-//	label_12->setGeometry(QRect(14, 158, 95, 21));
-
-	layout->addWidget(new QLabel("TNC Setup"));
-
-	QFormLayout *flayout2 = new QFormLayout;
-	layout->addLayout(flayout2);
-
-	AHost = new QLineEdit();
-	APort = new QLineEdit();
-	Paclen = new QLineEdit();
-	label_8 = new QLabel("host");
-	label_9 = new QLabel("Port");
-	label_10 = new QLabel("Paclen  ");
-
-	flayout2->addRow(label_8, AHost);
-	flayout2->addRow(label_9, APort);
-	flayout2->addRow(label_10, Paclen);
-
-	AAGWEnable->setChecked(AGWEnable);
-	AAGWMonEnable->setChecked(AGWMonEnable);
-	TermCall->setText(AGWTermCall);
-	beaconDest->setText(AGWBeaconDest);
-	beaconPath->setText(AGWBeaconPath);
-	beaconPorts->setText(AGWBeaconPorts);
-	beaconText->setPlainText(AGWBeaconMsg);
-	beaconInterval->setText(QString::number(AGWBeaconInterval));
-	AHost->setText(AGWHost);
-	APort->setText(QString::number(AGWPortNum));
-	Paclen->setText(QString::number(AGWPaclen));
-
-	buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel, this);
-	buttonBox->setFont(*menufont);
-	layout->addWidget(buttonBox);
-	scrollAreaWidgetContents->setLayout(layout);
-	scrollArea->setWidget(scrollAreaWidgetContents);
-
-	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
-	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
-
-}
-
-
-AGWDialog::~AGWDialog()
-{
-}
-
-
-KISSConnect::KISSConnect(QWidget *parent) : QDialog(parent)
-{
-	this->setFont(*menufont);
-
-	setWindowTitle(tr("KISS Connection"));
-
-	myResize *resize = new myResize();
-	installEventFilter(resize);
-
-	scrollArea = new QScrollArea(this);
-	scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
-	scrollArea->setGeometry(QRect(5, 5, 260, 200));
-	scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-	scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-	scrollArea->setWidgetResizable(false);
-	scrollAreaWidgetContents = new QWidget();
-	scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
-
-	// layout is top level.
-	// Add a Horizontal layout for Mode and Verical Layout for Call and Digis
-
-	QVBoxLayout *layout = new QVBoxLayout();
-	layout->setContentsMargins(10, 10, 10, 10);
-	setLayout(layout);
-
-	QHBoxLayout *mylayout = new QHBoxLayout();
-
-	Connected = new QRadioButton("Sesion");
-	UIMode = new QRadioButton("UI");
-	
-	mylayout->addWidget(new QLabel("Connection Mode"));
-	mylayout->addWidget(Connected);
-	mylayout->addWidget(UIMode);
-
-	if (KISSMode)			// UI = 1
-		UIMode->setChecked(1);
-	else
-		Connected->setChecked(1);
-
-	QFormLayout *formLayout2 = new QFormLayout();
-	layout->addLayout(mylayout);
-	layout->addSpacing(10);
-	layout->addLayout(formLayout2);
-
-	Chan = new QComboBox();
-	Chan->setEditable(false);
-	Chan->setInsertPolicy(QComboBox::NoInsert);
-	Chan->addItems(QStringList() << "A" << "B" << "C" << "D");
-
-	formLayout2->addRow(new QLabel("Modem Channel"), Chan);
-
-	wCallTo = new QComboBox();
-	wCallTo->setEditable(true);
-	wCallTo->setInsertPolicy(QComboBox::NoInsert);
-
-	formLayout2->addRow(new QLabel("Call To"), wCallTo);
-
-	Digis = new QLineEdit();
-
-	formLayout2->addRow(new QLabel("Digis"), Digis);
-
-	layout->addSpacing(2);
-
-	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
-	buttonBox->setFont(*menufont);
-	layout->addWidget(buttonBox);
-
-	scrollAreaWidgetContents->setLayout(layout);
-	scrollArea->setWidget(scrollAreaWidgetContents);
-
-	wCallTo->addItems(AGWToCalls);
-
-	Digis->setText(KISSVia);
-	Digis->resize(400, 20);
-
-	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
-	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
-}
-
-extern "C" void * KISSConnectOut(void * Sess, char * CallFrom, char * CallTo, char * Digis, int Chan, void * Socket);
-
-KISSConnect::~KISSConnect()
-{
-}
-
-extern QAction * YAPPSend;
-extern QMenu * connectMenu;
-extern QMenu * disconnectMenu;
-
-TAX25Port DummyPort;
-extern "C" TAX25Port * get_user_port_by_calls(int snd_ch, char *  CallFrom, char *  CallTo);
-
-void KISSConnect::myaccept()
-{
-	QVariant Q;
-
-	char CallTo[128];;
-	char Port[3];
-
-	strcpy(CallTo, wCallTo->currentText().toUpper().toUtf8());
-	strcpy(KISSVia, Digis->text().toUpper().toUtf8());
-	memcpy(Port, Chan->currentText().toUpper().toUtf8(), 1);
-
-	int PortNo = Port[0] - 'A';
-
-	TAX25Port * AX25Sess = 0;
-
-	// Check for duplicate session
-
-	AX25Sess = get_user_port_by_calls(0, KISSMYCALL, CallTo);
-
-	if (AX25Sess)
-	{
-		// Duplicate
-
-		char Msg[256];
-
-		int Len = sprintf(Msg, "You already have a session between %s and %s so can't connect\r", KISSMYCALL, CallTo);
-
-		WritetoOutputWindow(ActiveSession, (unsigned char *)Msg, Len);
-//		KISSConnect::accept();
-		return;
-	}
-
-	KISSMode = UIMode->isChecked();
-
-	// Add CallTo if not already in list
-
-	if (AGWToCalls.contains(CallTo))
-		AGWToCalls.removeOne(CallTo);
-
-	AGWToCalls.insert(-1, CallTo);
-
-	ActiveSession->KISSMode = KISSMode;
-
-	if (KISSMode == 0)
-	{
-		ActiveSession->KISSSession = KISSConnectOut(ActiveSession, KISSMYCALL, CallTo, KISSVia, PortNo, (void *)KISSSock);
-		WritetoOutputWindow(ActiveSession, (unsigned char *)"Connecting...\r", 14);
-		discAction->setEnabled(true);
-	}
-	else
-	{
-		// UI
-
-		char Msg[128];
-		int Len = 0;
-
-		memset(&DummyPort, 0, sizeof(DummyPort));
-
-		ActiveSession->KISSSession = (void *)&DummyPort;		// Dummy marker to show session in use
-
-		strcpy(ActiveSession->UIDEST, CallTo);
-		strcpy(ActiveSession->UIPATH, KISSVia);
-		ActiveSession->UIPORT = PortNo;
-
-		if (TermMode == Tabbed)
-			Len = sprintf(Msg, "UI %s", CallTo);
-		else
-			Len = sprintf(Msg, "UI Session with %s\r", CallTo);
-
-		SetSessLabel(ActiveSession, Msg);
-
-		Len = sprintf(Msg, "UI Session with %s\r", CallTo);
-		SendtoTerm(ActiveSession, Msg, Len);
-		connectMenu->setEnabled(false);
-		discAction->setEnabled(true);
-		YAPPSend->setEnabled(false);
-	}
-
-	KISSConnect::accept();
-}
-
-void KISSConnect::myreject()
-{
-	KISSConnect::reject();
-}
-
-
-
-VARAConnect::VARAConnect(QWidget *parent) : QDialog(parent)
-{
-	this->setFont(*menufont);
-
-	setWindowTitle(tr("VARA Connection"));
-
-	myResize *resize = new myResize();
-	installEventFilter(resize);
-
-	scrollArea = new QScrollArea(this);
-	scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
-	scrollArea->setGeometry(QRect(5, 5, 250, 150));
-	scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-	scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-	scrollArea->setWidgetResizable(false);
-	scrollAreaWidgetContents = new QWidget();
-	scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
-
-	QVBoxLayout *layout = new QVBoxLayout();
-	layout->setContentsMargins(10, 10, 10, 10);
-
-	setLayout(layout);
-
-	QFormLayout *formLayout2 = new QFormLayout();
-	layout->addLayout(formLayout2);
-
-	wCallFrom = new QLineEdit();
-	formLayout2->addRow(new QLabel("Call From"), wCallFrom);
-
-	wCallTo = new QComboBox();
-	wCallTo->setEditable(true);
-	wCallTo->setInsertPolicy(QComboBox::NoInsert);
-
-	formLayout2->addRow(new QLabel("Call To"), wCallTo);
-
-	Digis = new QLineEdit();
-	formLayout2->addRow(new QLabel("Digis"), Digis);
-
-	layout->addSpacing(2);
-
-	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
-	buttonBox->setFont(*menufont);
-	layout->addWidget(buttonBox);
-
-	scrollAreaWidgetContents->setLayout(layout);
-	scrollArea->setWidget(scrollAreaWidgetContents);
-
-	wCallFrom->setText(VARATermCall);
-	wCallTo->addItems(AGWToCalls);
-
-	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
-	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
-}
-
-VARAConnect::~VARAConnect()
-{
-}
-
-extern myTcpSocket * VARASock;
-extern myTcpSocket * VARADataSock;
-
-void VARAConnect::myaccept()
-{
-	QVariant Q;
-
-	char CallFrom[32];
-	char CallTo[32];
-	char Via[128];
-	char Msg[256];
-	int Len;
-
-	strcpy(CallFrom, wCallFrom->text().toUpper().toUtf8());
-	strcpy(CallTo, wCallTo->currentText().toUpper().toUtf8());
-	strcpy(Via, Digis->text().toUpper().toUtf8());
-
-// if digis have to form block with byte count followed by n 10 byte calls
-
-
-// Add CallTo if not already in list
-
-	if (AGWToCalls.contains(CallTo))
-		AGWToCalls.removeOne(CallTo);
-
-	AGWToCalls.insert(-1, CallTo);
-
-
-	if (Via[0])
-		Len = sprintf(Msg, "CONNECT %s %s VIA %s\r", CallFrom, CallTo, Via);
-	else 
-		Len = sprintf(Msg, "CONNECT %s %s\r", CallFrom, CallTo);
-
-	VARASock->write(Msg, Len);
-
-	discAction->setEnabled(true);
-	VARAConnect::accept();
-}
-
-void VARAConnect::myreject()
-{
-	VARAConnect::reject();
-}
-
-
-extern QProcess *process;
-
-
-
-TabDialog::TabDialog(QWidget *parent) : QDialog(parent)
-{
-	char portnum[10];
-
-	buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
-
-	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
-	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
-
-	QVBoxLayout *layout = new QVBoxLayout;
-	QLabel *hostLabel = new QLabel(tr("Host Name:"));
-	hostEdit = new QLineEdit(Host[ConfigHost]);
-
-	QLabel *portLabel = new QLabel(tr("Port:"));
-	sprintf(portnum, "%d", Port[ConfigHost]);
-	portEdit = new QLineEdit(portnum);
-
-	QLabel *userLabel = new QLabel(tr("User:"));
-	userEdit = new QLineEdit(UserName[ConfigHost]);
-
-	QLabel *passLabel = new QLabel(tr("Password:"));
-	passEdit = new QLineEdit(Password[ConfigHost]);
-
-	QLabel *SNameLabel = new QLabel(tr("Session Name"));
-	SNameEdit = new QLineEdit(SessName[ConfigHost]);
-
-	layout->addWidget(hostLabel);
-	layout->addWidget(hostEdit);
-	layout->addWidget(portLabel);
-	layout->addWidget(portEdit);
-	layout->addWidget(userLabel);
-	layout->addWidget(userEdit);
-	layout->addWidget(passLabel);
-	layout->addWidget(passEdit);
-	layout->addWidget(SNameLabel);
-	layout->addWidget(SNameEdit);
-
-	layout->addStretch(1);
-	layout->addWidget(buttonBox);
-	setLayout(layout);
-
-	setWindowTitle(tr("TermTCP Host Configuration"));
-}
-
-void AGWDialog::myaccept()
-{
-	QVariant Q;
-
-	int OldEnable = AGWEnable;
-	int OldPort = AGWPortNum;
-	char oldHost[128];
-	strcpy(oldHost, AGWHost);
-
-	//	QString val = Sess->portNo->text();A
-	//	QByteArray qb = val.toLatin1();
-	//	char * ptr = qb.data();
-
-	AGWEnable = AAGWEnable->isChecked();
-	AGWMonEnable = AAGWMonEnable->isChecked();
-
-	strcpy(AGWTermCall, TermCall->text().toUtf8().toUpper());
-	strcpy(AGWBeaconDest, beaconDest->text().toUtf8().toUpper());
-	strcpy(AGWBeaconPath, beaconPath->text().toUtf8().toUpper());
-	strcpy(AGWBeaconPorts, beaconPorts->text().toUtf8().toUpper());
-
-	if (beaconText->toPlainText().length() > 256)
-	{
-		QMessageBox msgBox;
-		msgBox.setText("Beacon Text Too Long");
-		msgBox.exec();
-	}
-	else
-		strcpy(AGWBeaconMsg, beaconText->toPlainText().toUtf8().toUpper());
-
-	Q = beaconInterval->text();
-	AGWBeaconInterval = Q.toInt();
-
-	strcpy(AGWHost, AHost->text().toUtf8());
-
-	Q = APort->text();
-	AGWPortNum = Q.toInt();
-
-	Q = Paclen->text();
-	AGWPaclen = Q.toInt();
-		
-	SaveSettings();
-
-	if (AGWEnable != OldEnable || AGWPortNum != OldPort || strcmp(oldHost, AGWHost) != 0)
-	{
-		// (re)start connection
-
-		if (OldEnable && AGWSock && AGWSock->ConnectedState == QAbstractSocket::ConnectedState)
-		{
-			AGWSock->disconnectFromHost();
-			Status1->setText("AGW Disconnected");
-		}
-		// AGWTimer will reopen connection
-	}
-
-	myStatusBar->setVisible(AGWEnable | VARAEnable | KISSEnable);
-
-	AGWDialog::accept();
-
-}
-
-void AGWDialog::myreject()
-{
-	AGWDialog::reject();
-}
-
-void TabDialog::myaccept()
-{
-	QString val = hostEdit->text();
-	QByteArray qb = val.toLatin1();
-	char * ptr = qb.data();
-	strcpy(Host[ConfigHost], ptr);
-		
-	val = portEdit->text();
-	qb = val.toLatin1();
-	ptr = qb.data();
-	Port[ConfigHost] = atoi(ptr);
-
-	val = userEdit->text();
-	qb = val.toLatin1();
-	ptr = qb.data();
-	strcpy(UserName[ConfigHost], ptr);
-
-	val = passEdit->text();
-	qb = val.toLatin1();
-	ptr = qb.data();
-	strcpy(Password[ConfigHost], ptr);
-
-	val = SNameEdit->text();
-	qb = val.toLatin1();
-	ptr = qb.data();
-	strcpy(SessName[ConfigHost], ptr);
-
-	char Label[256];
-
-	if (ptr[0])
-		sprintf(Label, "%s(%s)", Host[ConfigHost], SessName[ConfigHost]);
-	else
-		strcpy(Label, Host[ConfigHost]);
-
-	actHost[ConfigHost]->setText(Label);
-	actSetup[ConfigHost]->setText(Label);
-
-	SaveSettings();
-
-	TabDialog::accept();
-
-}
-
-void TabDialog::myreject()
-{
-	TabDialog::reject();
-}
-
-TabDialog::~TabDialog()
-{
-}
-
-// Menu dialog
-
-
-fontDialog::fontDialog(int Menu, QWidget *parent) : QDialog(parent)
-{
-	// Menu is set if setting Menufont, zero for setting terminal font.
-
-	int i;
-	char valChar[16];
-
-	QString family;
-	int csize;
-    QFont::Weight weight;
-
-#ifdef ANDROID
-	this->resize((screenWidth * 7) / 8, 200);
-	this->setMaximumWidth((screenWidth * 7) / 8);
-#endif
-	this->setFont(*menufont);
-
-	Menuflag = Menu;
-
-	if (Menu)
-	{
-		workingFont = *menufont;
-
-		QFontInfo info(*menufont);
-		family = info.family();
-		csize = info.pointSize();
-
-		setWindowTitle("Menu Font Dialog");
-	}
-	else
-	{
-		// get current term font
-
-		QSettings settings(GetConfPath(), QSettings::IniFormat);
-
-#ifdef ANDROID
-		family = settings.value("FontFamily", "Driod Sans Mono").toString();
-		csize = settings.value("PointSize", 12).toInt();
-        weight = (QFont::Weight)settings.value("Weight", 50).toInt();
-#else
-		family = settings.value("FontFamily", "Courier New").toString();
-		csize = settings.value("PointSize", 10).toInt();
-		weight = (QFont::Weight)settings.value("Weight", 50).toInt();
-#endif
-
-		workingFont = QFont(family);
-		workingFont.setPointSize(csize);
-		workingFont.setWeight(weight);
-
-		setWindowTitle("Terminal Font Dialog");
-	}
-
-	QVBoxLayout *layout = new QVBoxLayout();
-	layout->setContentsMargins(10, 10, 10, 10);
-
-	setLayout(layout);
-
-	QHBoxLayout *hlayout = new QHBoxLayout();
-	layout->addLayout(hlayout);
-
-	font = new QFontComboBox();
-
-	if (Menu == 0)
-		font->setFontFilters(QFontComboBox::MonospacedFonts);
-
-	font->setMaximumWidth((screenWidth * 5) / 8);
-	font->view()->setMaximumWidth((7 * screenWidth) / 8);
-
-	style = new QComboBox();
-	style->setMaximumWidth(screenWidth / 4);
-	size = new QComboBox();
-	sample = new QTextEdit();
-	sample->setText("ABCDabcd1234");
-	sample->setFont(workingFont);
-
-	hlayout->addWidget(font);
-	hlayout->addWidget(style);
-	hlayout->addWidget(size);
-	layout->addWidget(sample);
-
-	QFontDatabase database;
-
-	const QStringList styles = database.styles(family);
-
-	const QList<int> smoothSizes = database.smoothSizes(family, styles[0]);
-
-	for (int points : smoothSizes)
-		size->addItem(QString::number(points));
-
-	for (QString xstyle : styles)
-		style->addItem(xstyle);
-
-	i = font->findText(family, Qt::MatchExactly);
-	font->setCurrentIndex(i);
-
-	sprintf(valChar, "%d", csize);
-	i = size->findText(valChar, Qt::MatchExactly);
-	size->setCurrentIndex(i);
-
-	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
-	buttonBox->setFont(*menufont);
-	layout->addWidget(buttonBox);
-	setLayout(layout);
-
-	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
-	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
-	connect(font, SIGNAL(currentFontChanged(QFont)), this, SLOT(fontchanged(QFont)));
-	connect(style, SIGNAL(currentIndexChanged(int)), this, SLOT(stylechanged()));
-	connect(size, SIGNAL(currentIndexChanged(int)), this, SLOT(sizechanged()));
-}
-
-void fontDialog::fontchanged(QFont newfont)
-{
-	QFontDatabase database;
-	QString family = newfont.family();
-
-	workingFont = newfont;
-
-	const QStringList styles = database.styles(family);
-	const QList<int> smoothSizes = database.smoothSizes(family, styles[0]);
-
-	size->clear();
-	style->clear();
-
-	for (int points : smoothSizes)
-		size->addItem(QString::number(points));
-
-	for (QString xstyle : styles)
-		style->addItem(xstyle);
-
-	sample->setFont(workingFont);
-}
-
-void fontDialog::stylechanged()
-{
-	QFontDatabase database;
-
-	QString family = font->currentFont().family();
-
-	bool italic = database.italic(family, style->currentText());
-	int weight = database.weight(family, style->currentText());
-
-	if (weight < 0)
-		weight = 50;				// Normal
-
-	workingFont.setItalic(italic);
-    workingFont.setWeight((QFont::Weight) weight);
-
-	sample->setFont(workingFont);
-}
-
-void fontDialog::sizechanged()
-{
-	int newsize = size->currentText().toInt();
-	workingFont.setPointSize(newsize);
-	sample->setFont(workingFont);
-}
-fontDialog::~fontDialog()
-{
-}
-
-void fontDialog::myaccept()
-{
-	QSettings settings(GetConfPath(), QSettings::IniFormat);
-
-	if (Menuflag)
-	{
-		delete menufont;
-		menufont = new QFont(workingFont);
-
-		QtTermTCP::setFonts();
-
-		settings.setValue("MFontFamily", workingFont.family());
-		settings.setValue("MPointSize", workingFont.pointSize());
-		settings.setValue("MWeight", workingFont.weight());
-	}
-	else
-	{
-		Ui_ListenSession * Sess;
-
-		for (int i = 0; i < _sessions.size(); ++i)
-		{
-			Sess = _sessions.at(i);
-
-			if (Sess->termWindow)
-				Sess->termWindow->setFont(workingFont);
-
-			if (Sess->inputWindow)
-				Sess->inputWindow->setFont(workingFont);
-
-			if (Sess->monWindow)
-				Sess->monWindow->setFont(workingFont);
-		}
-
-		settings.setValue("FontFamily", workingFont.family());
-		settings.setValue("PointSize", workingFont.pointSize());
-		settings.setValue("Weight", workingFont.weight());
-	}
-
-	fontDialog::accept();
-}
-
-void fontDialog::myreject()
-{
-	fontDialog::reject();
-}
-
-
-
-ListenDialog::ListenDialog(QWidget *parent) : QDialog(parent)
-{
-#ifdef ANDROID
-	this->resize((screenWidth * 3) / 4 , 500);
-#endif
-	verticalLayout = new QVBoxLayout();
-	verticalLayout->setContentsMargins(10, 10, 10, 10);
-
-	setLayout(verticalLayout);
-
-	Enabled = new QCheckBox();
-	Enabled->setText(QString::fromUtf8("Enable Listen"));
-	Enabled->setLayoutDirection(Qt::LeftToRight);
-
-	verticalLayout->addWidget(Enabled);
-
-	formLayout = new QFormLayout();
-
-	portNo = new QLineEdit();
-//	portNo->setMaximumSize(QSize(100, 30));
-
-	formLayout->addRow(new QLabel("Port"), portNo);
-
-	CText = new QTextEdit();
-	CText->setMinimumSize(QSize(0, 150));
-	CText->setMaximumSize(QSize(401, 150));
-
-	formLayout->addRow(new QLabel("CText"), CText);
-	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
-	buttonBox->setFont(*menufont);
-	verticalLayout->addWidget(buttonBox);
-
-	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
-	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
-
-	verticalLayout->addLayout(formLayout);
-	verticalLayout->addWidget(buttonBox);
-
-	portNo->setText(QString::number(listenPort));
-	Enabled->setChecked(listenEnable);
-	CText->setText(listenCText);
-
-}
-
-ListenDialog::~ListenDialog()
-{
-}
-
-void ListenDialog::myaccept()
-{
-	QString val = portNo->text();
-	QByteArray qb = val.toLatin1();
-	char * ptr = qb.data();
-
-	listenPort = atoi(ptr);
-	listenEnable = Enabled->isChecked();
-	strcpy(listenCText, CText->toPlainText().toUtf8());
-
-	while ((ptr = strchr(listenCText, '\n')))
-		*ptr = '\r';
-
-	if (_server->isListening())
-		_server->close();
-
-	SaveSettings();
-
-	if (listenEnable)
-		_server->listen(QHostAddress::Any, listenPort);
-
-	ListenDialog::accept();
-}
-
-void ListenDialog::myreject()
-{
-	ListenDialog::reject();
-}
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include "TabDialog.h"
+#include "QtTermTCP.h"
+#include <QTcpServer>
+#include "QSettings"
+#include "QLineEdit"
+#include "QTabWidget"
+#include "QDialogButtonBox"
+#include "QVBoxLayout"
+#include "QLabel"
+#include "QAction"
+#include "QGroupBox"
+#include "QPlainTextEdit"
+#include "QCheckBox"
+#include "QFormLayout"
+#include "QScrollArea"
+
+#include "ax25.h"
+
+#ifndef WIN32
+#define strtok_s strtok_r
+#endif
+
+extern "C" void SaveSettings();
+
+extern int screenHeight;
+extern int screenWidth;
+
+extern QList<Ui_ListenSession *> _sessions;
+extern QTcpServer * _server;
+
+extern myTcpSocket * AGWSock;
+extern myTcpSocket * KISSSock;
+extern QLabel * Status1;
+extern QFont * menufont;
+extern QStatusBar * myStatusBar;
+
+QLineEdit *hostEdit;
+QLineEdit *portEdit;
+QLineEdit *userEdit;
+QLineEdit *passEdit;
+QLineEdit *SNameEdit;
+
+extern QAction *actHost[17];
+extern QAction *actSetup[16];
+
+extern int ConfigHost;
+
+#define MAXHOSTS 16
+
+extern char Host[MAXHOSTS + 1][100];
+extern int Port[MAXHOSTS + 1];
+extern char UserName[MAXHOSTS + 1][80];
+extern char Password[MAXHOSTS + 1][80];
+extern char SessName[MAXHOSTS + 1][80];
+
+extern char KISSMYCALL[32];
+
+QLineEdit *TermCall;
+QGroupBox *groupBox;
+QLineEdit *beaconDest;
+QLineEdit *beaconPath;
+QLineEdit *beaconInterval;
+QLineEdit *beaconPorts;
+QLabel *label_2;
+QLabel *label_3;
+QLabel *label_4;
+QLabel *label_5;
+QLabel *label_6;
+QLabel *label_7;
+QLabel *label_11;
+QPlainTextEdit *beaconText;
+QLabel *label_12;
+QGroupBox *groupBox_2;
+QLineEdit *AHost;
+QLineEdit *APort;
+QLineEdit *APath;
+QLineEdit *Paclen;
+QLabel *label_8;
+QLabel *label_9;
+QLabel *label_10;
+QLabel *label;
+QCheckBox *AAGWEnable;
+QLabel *label_13;
+QCheckBox *AAGWMonEnable;
+
+QLineEdit *AVARATermCall;
+QLineEdit *AVARAHost;
+QLineEdit *AVARAPort;
+QCheckBox *AVARAEnable;
+
+
+extern int AGWEnable;
+extern int VARAEnable;
+extern int KISSEnable;
+extern int AGWMonEnable;
+extern char AGWTermCall[12];
+extern char AGWBeaconDest[12];
+extern char AGWBeaconPath[80];
+extern int AGWBeaconInterval;
+extern char AGWBeaconPorts[80];
+extern char AGWBeaconMsg[260];
+
+extern char VARATermCall[12];
+
+extern char AGWHost[128];
+extern int AGWPortNum;
+extern int AGWPaclen;
+extern char * AGWPortList;
+extern myTcpSocket * AGWSock; 
+extern char * AGWPortList;
+extern QStringList AGWToCalls;
+
+extern int KISSMode;
+extern char KISSVia[128];				// Digi String
+
+extern Ui_ListenSession * ActiveSession;
+
+extern int TermMode;
+
+#define Single 0
+#define MDI 1
+#define Tabbed 2
+
+extern int listenPort;
+extern "C" int listenEnable;
+extern char listenCText[4096];
+
+void Send_AGW_C_Frame(Ui_ListenSession * Sess, int Port, char * CallFrom, char * CallTo, char * Data, int DataLen);
+extern "C" void SetSessLabel(Ui_ListenSession * Sess, char * label);
+extern "C" void SendtoTerm(Ui_ListenSession * Sess, char * Msg, int Len);
+
+QString GetConfPath();
+
+QScrollArea *scrollArea;
+QWidget *scrollAreaWidgetContents;
+
+bool myResize::eventFilter(QObject *obj, QEvent *event)
+{
+	if (event->type() == QEvent::Resize)
+	{
+		QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event);
+		QSize size = resizeEvent->size();
+		int h = size.height();
+		int w = size.width();
+
+		scrollArea->setGeometry(QRect(5, 5, w - 10, h - 10));
+		return true;
+	}
+	return QObject::eventFilter(obj, event);
+}
+
+AGWConnect::AGWConnect(QWidget *parent) : QDialog(parent)
+{
+	this->setFont(*menufont);
+
+	setWindowTitle(tr("AGW Connection"));
+
+	myResize *resize = new myResize();
+	installEventFilter(resize);
+
+	scrollArea = new QScrollArea(this);
+	scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
+	scrollArea->setGeometry(QRect(5, 5, 562, 681));
+	scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+	scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+	scrollArea->setWidgetResizable(false);
+	scrollAreaWidgetContents = new QWidget();
+	scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
+
+	QVBoxLayout *layout = new QVBoxLayout();
+	layout->setContentsMargins(10, 10, 10, 10);
+
+	setLayout(layout);
+
+	QFormLayout *formLayout2 = new QFormLayout();
+	layout->addLayout(formLayout2);
+
+	wCallFrom = new QLineEdit();
+	formLayout2->addRow(new QLabel("Call From"), wCallFrom);
+
+	wCallTo = new QComboBox();
+	wCallTo->setEditable(true);
+	wCallTo->setInsertPolicy(QComboBox::NoInsert);
+
+	formLayout2->addRow(new QLabel("Call To"), wCallTo);
+
+	Digis = new QLineEdit();
+	formLayout2->addRow(new QLabel("Digis"), Digis);
+
+	layout->addSpacing(2);
+	layout->addWidget(new QLabel("Radio Ports"));
+
+	RadioPorts = new QListWidget();
+
+	layout->addWidget(RadioPorts);
+
+	QString str;
+	int count;
+
+	char * Context;
+	char * ptr;
+
+	wCallFrom->setText(AGWTermCall);
+
+	wCallTo->addItems(AGWToCalls);
+
+	if (AGWPortList)
+	{
+		char * Temp = strdup(AGWPortList);		// Need copy as strtok messes with it
+
+		count = atoi(Temp);
+
+		ptr = strtok_s(Temp, ";", &Context);
+
+		for (int n = 0; n < count; n++)
+		{
+			ptr = strtok_s(NULL, ";", &Context);
+			new QListWidgetItem(ptr, RadioPorts);
+		}
+
+		free(Temp);
+
+		// calculate scrollarea height from count
+
+		scrollAreaWidgetContents->setGeometry(QRect(0, 0, 400, 220 + 22 * count));
+		this->resize(420, 240 + 22 * count);
+
+	}
+
+	RadioPorts->setFont(*menufont);
+
+	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+	buttonBox->setFont(*menufont);
+	layout->addWidget(buttonBox);
+
+	scrollAreaWidgetContents->setLayout(layout);
+	scrollArea->setWidget(scrollAreaWidgetContents);
+
+	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
+	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
+}
+
+AGWConnect::~AGWConnect()
+{
+}
+
+extern QAction *discAction;
+
+void AGWConnect::myaccept()
+{
+	QVariant Q;
+
+	int port = RadioPorts->currentRow();
+	char CallFrom[32];
+	char CallTo[32];
+	char Via[128];
+	char DigiMsg[128] = "";
+	int DigiLen = 0;
+	char * digiptr = &DigiMsg[1];
+
+	strcpy(CallFrom, wCallFrom->text().toUpper().toUtf8());
+	strcpy(CallTo, wCallTo->currentText().toUpper().toUtf8());
+	strcpy(Via, Digis->text().toUpper().toUtf8());
+
+	if (CallFrom[0] == 0)
+	{
+		QMessageBox msgBox;
+		msgBox.setText("Call From missing");
+		msgBox.exec();
+		return;
+	}
+
+	if (CallTo[0] == 0)
+	{
+		QMessageBox msgBox;
+		msgBox.setText("Call To missing");
+		msgBox.exec();
+		return;
+	}
+
+	// if digis have to form block with byte count followed by n 10 byte calls
+
+	if (Via[0])
+	{
+		char * context;
+		char * ptr = strtok_s(Via, ", ", &context);
+
+		while (ptr)
+		{
+			DigiMsg[0]++;
+			strcpy(digiptr, ptr);
+			digiptr += 10;
+
+			ptr = strtok_s(NULL, ", ", &context);
+		}
+		DigiLen = digiptr - DigiMsg;
+	}
+
+	// Add CallTo if not already in list
+
+	if (AGWToCalls.contains(CallTo))
+		AGWToCalls.removeOne(CallTo);
+
+	AGWToCalls.insert(-1, CallTo);
+
+	if (port == -1)
+	{
+		// Port not set. If connecting to SWITCH use any, otherwise tell user
+
+		if (strcmp(CallTo, "SWITCH") == 0)
+		{
+			port = 0;
+		}
+		else
+		{
+			QMessageBox msgBox;
+			msgBox.setText("Select a port to call on");
+			msgBox.exec();
+			return;
+		}
+	}
+
+	Send_AGW_C_Frame(ActiveSession, port, CallFrom, CallTo, DigiMsg, DigiLen);
+
+	discAction->setEnabled(true);
+
+
+	AGWConnect::accept();
+}
+
+void AGWConnect::myreject()
+{
+	AGWConnect::reject();
+}
+
+
+AGWDialog::AGWDialog(QWidget *parent) : QDialog(parent)
+{
+	this->setFont(*menufont);
+
+	setWindowTitle(tr("TermTCP AGW Configuration"));
+
+	myResize *resize = new myResize();
+	installEventFilter(resize);
+
+
+	scrollArea = new QScrollArea(this);
+	scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
+	scrollArea->setGeometry(QRect(5, 5, 562, 681));
+	scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+	scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+	scrollArea->setWidgetResizable(false);
+	scrollAreaWidgetContents = new QWidget();
+	scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
+	scrollAreaWidgetContents->setGeometry(QRect(0, 0, 552, 581));
+
+	this->resize(572, 601);
+
+	QVBoxLayout *layout = new QVBoxLayout;
+	QHBoxLayout *hlayout = new QHBoxLayout;
+
+	layout->addLayout(hlayout);
+	AAGWEnable = new QCheckBox("Enable AGW Interface");
+	AAGWEnable->setLayoutDirection(Qt::LeftToRight);
+
+	AAGWMonEnable = new QCheckBox("Enable Monitor");
+	AAGWMonEnable->setGeometry(QRect(255, 18, 216, 21));
+	AAGWMonEnable->setLayoutDirection(Qt::RightToLeft);
+
+	hlayout->addWidget(AAGWEnable);
+	hlayout->addWidget(AAGWMonEnable);
+
+	QFormLayout *flayout = new QFormLayout;
+	layout->addLayout(flayout);
+
+	label = new QLabel("Terminal Call");
+	TermCall = new QLineEdit(this);
+
+	flayout->addRow(label, TermCall);
+	
+	layout->addWidget(new QLabel("Beacon Setup"));
+
+	QFormLayout *flayout1 = new QFormLayout;
+	layout->addLayout(flayout1);
+
+	label_2 = new QLabel("Destination");
+	beaconDest = new QLineEdit();
+	label_3 = new QLabel("Digipeaters");
+	beaconPath = new QLineEdit();
+
+	flayout1->addRow(label_2, beaconDest);
+	flayout1->addRow(label_3, beaconPath);
+
+	label_4 = new QLabel("Interval");
+	beaconInterval = new QLineEdit();
+	label_5 = new QLabel("Ports");
+	beaconPorts = new QLineEdit();
+
+	flayout1->addRow(label_4, beaconInterval);
+	flayout1->addRow(label_5, beaconPorts);
+
+//	label_6 = new QLabel("Minutes", groupBox);
+
+//	label_7 = new QLabel("(Separate with commas)", groupBox);
+	label_11 = new QLabel("Message");
+	beaconText = new QPlainTextEdit();
+
+	flayout1->addRow(label_11, beaconText);
+
+
+
+//	label_12 = new QLabel("(max 256 chars)");
+//	label_12->setGeometry(QRect(14, 158, 95, 21));
+
+	layout->addWidget(new QLabel("TNC Setup"));
+
+	QFormLayout *flayout2 = new QFormLayout;
+	layout->addLayout(flayout2);
+
+	AHost = new QLineEdit();
+	APort = new QLineEdit();
+	Paclen = new QLineEdit();
+	label_8 = new QLabel("host");
+	label_9 = new QLabel("Port");
+	label_10 = new QLabel("Paclen  ");
+
+	flayout2->addRow(label_8, AHost);
+	flayout2->addRow(label_9, APort);
+	flayout2->addRow(label_10, Paclen);
+
+	AAGWEnable->setChecked(AGWEnable);
+	AAGWMonEnable->setChecked(AGWMonEnable);
+	TermCall->setText(AGWTermCall);
+	beaconDest->setText(AGWBeaconDest);
+	beaconPath->setText(AGWBeaconPath);
+	beaconPorts->setText(AGWBeaconPorts);
+	beaconText->setPlainText(AGWBeaconMsg);
+	beaconInterval->setText(QString::number(AGWBeaconInterval));
+	AHost->setText(AGWHost);
+	APort->setText(QString::number(AGWPortNum));
+	Paclen->setText(QString::number(AGWPaclen));
+
+	buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel, this);
+	buttonBox->setFont(*menufont);
+	layout->addWidget(buttonBox);
+	scrollAreaWidgetContents->setLayout(layout);
+	scrollArea->setWidget(scrollAreaWidgetContents);
+
+	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
+	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
+
+}
+
+
+AGWDialog::~AGWDialog()
+{
+}
+
+
+KISSConnect::KISSConnect(QWidget *parent) : QDialog(parent)
+{
+	this->setFont(*menufont);
+
+	setWindowTitle(tr("KISS Connection"));
+
+	myResize *resize = new myResize();
+	installEventFilter(resize);
+
+	scrollArea = new QScrollArea(this);
+	scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
+	scrollArea->setGeometry(QRect(5, 5, 260, 200));
+	scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+	scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+	scrollArea->setWidgetResizable(false);
+	scrollAreaWidgetContents = new QWidget();
+	scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
+
+	// layout is top level.
+	// Add a Horizontal layout for Mode and Verical Layout for Call and Digis
+
+	QVBoxLayout *layout = new QVBoxLayout();
+	layout->setContentsMargins(10, 10, 10, 10);
+	setLayout(layout);
+
+	QHBoxLayout *mylayout = new QHBoxLayout();
+
+	Connected = new QRadioButton("Sesion");
+	UIMode = new QRadioButton("UI");
+	
+	mylayout->addWidget(new QLabel("Connection Mode"));
+	mylayout->addWidget(Connected);
+	mylayout->addWidget(UIMode);
+
+	if (KISSMode)			// UI = 1
+		UIMode->setChecked(1);
+	else
+		Connected->setChecked(1);
+
+	QFormLayout *formLayout2 = new QFormLayout();
+	layout->addLayout(mylayout);
+	layout->addSpacing(10);
+	layout->addLayout(formLayout2);
+
+	Chan = new QComboBox();
+	Chan->setEditable(false);
+	Chan->setInsertPolicy(QComboBox::NoInsert);
+	Chan->addItems(QStringList() << "A" << "B" << "C" << "D");
+
+	formLayout2->addRow(new QLabel("Modem Channel"), Chan);
+
+	wCallTo = new QComboBox();
+	wCallTo->setEditable(true);
+	wCallTo->setInsertPolicy(QComboBox::NoInsert);
+
+	formLayout2->addRow(new QLabel("Call To"), wCallTo);
+
+	Digis = new QLineEdit();
+
+	formLayout2->addRow(new QLabel("Digis"), Digis);
+
+	layout->addSpacing(2);
+
+	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+	buttonBox->setFont(*menufont);
+	layout->addWidget(buttonBox);
+
+	scrollAreaWidgetContents->setLayout(layout);
+	scrollArea->setWidget(scrollAreaWidgetContents);
+
+	wCallTo->addItems(AGWToCalls);
+
+	Digis->setText(KISSVia);
+	Digis->resize(400, 20);
+
+	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
+	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
+}
+
+extern "C" void * KISSConnectOut(void * Sess, char * CallFrom, char * CallTo, char * Digis, int Chan, void * Socket);
+
+KISSConnect::~KISSConnect()
+{
+}
+
+extern QAction * YAPPSend;
+extern QMenu * connectMenu;
+extern QMenu * disconnectMenu;
+
+TAX25Port DummyPort;
+extern "C" TAX25Port * get_user_port_by_calls(int snd_ch, char *  CallFrom, char *  CallTo);
+
+void KISSConnect::myaccept()
+{
+	QVariant Q;
+
+	char CallTo[128];;
+	char Port[3];
+
+	strcpy(CallTo, wCallTo->currentText().toUpper().toUtf8());
+	strcpy(KISSVia, Digis->text().toUpper().toUtf8());
+	memcpy(Port, Chan->currentText().toUpper().toUtf8(), 1);
+
+	int PortNo = Port[0] - 'A';
+
+	TAX25Port * AX25Sess = 0;
+
+	// Check for duplicate session
+
+	AX25Sess = get_user_port_by_calls(0, KISSMYCALL, CallTo);
+
+	if (AX25Sess)
+	{
+		// Duplicate
+
+		char Msg[256];
+
+		int Len = sprintf(Msg, "You already have a session between %s and %s so can't connect\r", KISSMYCALL, CallTo);
+
+		WritetoOutputWindow(ActiveSession, (unsigned char *)Msg, Len);
+//		KISSConnect::accept();
+		return;
+	}
+
+	KISSMode = UIMode->isChecked();
+
+	// Add CallTo if not already in list
+
+	if (AGWToCalls.contains(CallTo))
+		AGWToCalls.removeOne(CallTo);
+
+	AGWToCalls.insert(-1, CallTo);
+
+	ActiveSession->KISSMode = KISSMode;
+
+	if (KISSMode == 0)
+	{
+		ActiveSession->KISSSession = KISSConnectOut(ActiveSession, KISSMYCALL, CallTo, KISSVia, PortNo, (void *)KISSSock);
+		WritetoOutputWindow(ActiveSession, (unsigned char *)"Connecting...\r", 14);
+		discAction->setEnabled(true);
+	}
+	else
+	{
+		// UI
+
+		char Msg[128];
+		int Len = 0;
+
+		memset(&DummyPort, 0, sizeof(DummyPort));
+
+		ActiveSession->KISSSession = (void *)&DummyPort;		// Dummy marker to show session in use
+
+		strcpy(ActiveSession->UIDEST, CallTo);
+		strcpy(ActiveSession->UIPATH, KISSVia);
+		ActiveSession->UIPORT = PortNo;
+
+		if (TermMode == Tabbed)
+			Len = sprintf(Msg, "UI %s", CallTo);
+		else
+			Len = sprintf(Msg, "UI Session with %s\r", CallTo);
+
+		SetSessLabel(ActiveSession, Msg);
+
+		Len = sprintf(Msg, "UI Session with %s\r", CallTo);
+		SendtoTerm(ActiveSession, Msg, Len);
+		connectMenu->setEnabled(false);
+		discAction->setEnabled(true);
+		YAPPSend->setEnabled(false);
+	}
+
+	KISSConnect::accept();
+}
+
+void KISSConnect::myreject()
+{
+	KISSConnect::reject();
+}
+
+
+
+VARAConnect::VARAConnect(QWidget *parent) : QDialog(parent)
+{
+	this->setFont(*menufont);
+
+	setWindowTitle(tr("VARA Connection"));
+
+	myResize *resize = new myResize();
+	installEventFilter(resize);
+
+	scrollArea = new QScrollArea(this);
+	scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
+	scrollArea->setGeometry(QRect(5, 5, 250, 150));
+	scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+	scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+	scrollArea->setWidgetResizable(false);
+	scrollAreaWidgetContents = new QWidget();
+	scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
+
+	QVBoxLayout *layout = new QVBoxLayout();
+	layout->setContentsMargins(10, 10, 10, 10);
+
+	setLayout(layout);
+
+	QFormLayout *formLayout2 = new QFormLayout();
+	layout->addLayout(formLayout2);
+
+	wCallFrom = new QLineEdit();
+	formLayout2->addRow(new QLabel("Call From"), wCallFrom);
+
+	wCallTo = new QComboBox();
+	wCallTo->setEditable(true);
+	wCallTo->setInsertPolicy(QComboBox::NoInsert);
+
+	formLayout2->addRow(new QLabel("Call To"), wCallTo);
+
+	Digis = new QLineEdit();
+	formLayout2->addRow(new QLabel("Digis"), Digis);
+
+	layout->addSpacing(2);
+
+	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+	buttonBox->setFont(*menufont);
+	layout->addWidget(buttonBox);
+
+	scrollAreaWidgetContents->setLayout(layout);
+	scrollArea->setWidget(scrollAreaWidgetContents);
+
+	wCallFrom->setText(VARATermCall);
+	wCallTo->addItems(AGWToCalls);
+
+	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
+	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
+}
+
+VARAConnect::~VARAConnect()
+{
+}
+
+extern myTcpSocket * VARASock;
+extern myTcpSocket * VARADataSock;
+
+void VARAConnect::myaccept()
+{
+	QVariant Q;
+
+	char CallFrom[32];
+	char CallTo[32];
+	char Via[128];
+	char Msg[256];
+	int Len;
+
+	strcpy(CallFrom, wCallFrom->text().toUpper().toUtf8());
+	strcpy(CallTo, wCallTo->currentText().toUpper().toUtf8());
+	strcpy(Via, Digis->text().toUpper().toUtf8());
+
+// if digis have to form block with byte count followed by n 10 byte calls
+
+
+// Add CallTo if not already in list
+
+	if (AGWToCalls.contains(CallTo))
+		AGWToCalls.removeOne(CallTo);
+
+	AGWToCalls.insert(-1, CallTo);
+
+
+	if (Via[0])
+		Len = sprintf(Msg, "CONNECT %s %s VIA %s\r", CallFrom, CallTo, Via);
+	else 
+		Len = sprintf(Msg, "CONNECT %s %s\r", CallFrom, CallTo);
+
+	VARASock->write(Msg, Len);
+
+	discAction->setEnabled(true);
+	VARAConnect::accept();
+}
+
+void VARAConnect::myreject()
+{
+	VARAConnect::reject();
+}
+
+
+extern QProcess *process;
+
+
+
+TabDialog::TabDialog(QWidget *parent) : QDialog(parent)
+{
+	char portnum[10];
+
+	buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
+
+	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
+	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
+
+	QVBoxLayout *layout = new QVBoxLayout;
+	QLabel *hostLabel = new QLabel(tr("Host Name:"));
+	hostEdit = new QLineEdit(Host[ConfigHost]);
+
+	QLabel *portLabel = new QLabel(tr("Port:"));
+	sprintf(portnum, "%d", Port[ConfigHost]);
+	portEdit = new QLineEdit(portnum);
+
+	QLabel *userLabel = new QLabel(tr("User:"));
+	userEdit = new QLineEdit(UserName[ConfigHost]);
+
+	QLabel *passLabel = new QLabel(tr("Password:"));
+	passEdit = new QLineEdit(Password[ConfigHost]);
+
+	QLabel *SNameLabel = new QLabel(tr("Session Name"));
+	SNameEdit = new QLineEdit(SessName[ConfigHost]);
+
+	layout->addWidget(hostLabel);
+	layout->addWidget(hostEdit);
+	layout->addWidget(portLabel);
+	layout->addWidget(portEdit);
+	layout->addWidget(userLabel);
+	layout->addWidget(userEdit);
+	layout->addWidget(passLabel);
+	layout->addWidget(passEdit);
+	layout->addWidget(SNameLabel);
+	layout->addWidget(SNameEdit);
+
+	layout->addStretch(1);
+	layout->addWidget(buttonBox);
+	setLayout(layout);
+
+	setWindowTitle(tr("TermTCP Host Configuration"));
+}
+
+void AGWDialog::myaccept()
+{
+	QVariant Q;
+
+	int OldEnable = AGWEnable;
+	int OldPort = AGWPortNum;
+	char oldHost[128];
+	strcpy(oldHost, AGWHost);
+
+	//	QString val = Sess->portNo->text();A
+	//	QByteArray qb = val.toLatin1();
+	//	char * ptr = qb.data();
+
+	AGWEnable = AAGWEnable->isChecked();
+	AGWMonEnable = AAGWMonEnable->isChecked();
+
+	strcpy(AGWTermCall, TermCall->text().toUtf8().toUpper());
+	strcpy(AGWBeaconDest, beaconDest->text().toUtf8().toUpper());
+	strcpy(AGWBeaconPath, beaconPath->text().toUtf8().toUpper());
+	strcpy(AGWBeaconPorts, beaconPorts->text().toUtf8().toUpper());
+
+	if (beaconText->toPlainText().length() > 256)
+	{
+		QMessageBox msgBox;
+		msgBox.setText("Beacon Text Too Long");
+		msgBox.exec();
+	}
+	else
+		strcpy(AGWBeaconMsg, beaconText->toPlainText().toUtf8().toUpper());
+
+	Q = beaconInterval->text();
+	AGWBeaconInterval = Q.toInt();
+
+	strcpy(AGWHost, AHost->text().toUtf8());
+
+	Q = APort->text();
+	AGWPortNum = Q.toInt();
+
+	Q = Paclen->text();
+	AGWPaclen = Q.toInt();
+		
+	SaveSettings();
+
+	if (AGWEnable != OldEnable || AGWPortNum != OldPort || strcmp(oldHost, AGWHost) != 0)
+	{
+		// (re)start connection
+
+		if (OldEnable && AGWSock && AGWSock->ConnectedState == QAbstractSocket::ConnectedState)
+		{
+			AGWSock->disconnectFromHost();
+			Status1->setText("AGW Disconnected");
+		}
+		// AGWTimer will reopen connection
+	}
+
+	myStatusBar->setVisible(AGWEnable | VARAEnable | KISSEnable);
+
+	AGWDialog::accept();
+
+}
+
+void AGWDialog::myreject()
+{
+	AGWDialog::reject();
+}
+
+void TabDialog::myaccept()
+{
+	QString val = hostEdit->text();
+	QByteArray qb = val.toLatin1();
+	char * ptr = qb.data();
+	strcpy(Host[ConfigHost], ptr);
+		
+	val = portEdit->text();
+	qb = val.toLatin1();
+	ptr = qb.data();
+	Port[ConfigHost] = atoi(ptr);
+
+	val = userEdit->text();
+	qb = val.toLatin1();
+	ptr = qb.data();
+	strcpy(UserName[ConfigHost], ptr);
+
+	val = passEdit->text();
+	qb = val.toLatin1();
+	ptr = qb.data();
+	strcpy(Password[ConfigHost], ptr);
+
+	val = SNameEdit->text();
+	qb = val.toLatin1();
+	ptr = qb.data();
+	strcpy(SessName[ConfigHost], ptr);
+
+	char Label[256];
+
+	if (ptr[0])
+		sprintf(Label, "%s(%s)", Host[ConfigHost], SessName[ConfigHost]);
+	else
+		strcpy(Label, Host[ConfigHost]);
+
+	actHost[ConfigHost]->setText(Label);
+	actSetup[ConfigHost]->setText(Label);
+
+	SaveSettings();
+
+	TabDialog::accept();
+
+}
+
+void TabDialog::myreject()
+{
+	TabDialog::reject();
+}
+
+TabDialog::~TabDialog()
+{
+}
+
+// Menu dialog
+
+
+fontDialog::fontDialog(int Menu, QWidget *parent) : QDialog(parent)
+{
+	// Menu is set if setting Menufont, zero for setting terminal font.
+
+	int i;
+	char valChar[16];
+
+	QString family;
+	int csize;
+    QFont::Weight weight;
+
+#ifdef ANDROID
+	this->resize((screenWidth * 7) / 8, 200);
+	this->setMaximumWidth((screenWidth * 7) / 8);
+#endif
+	this->setFont(*menufont);
+
+	Menuflag = Menu;
+
+	if (Menu)
+	{
+		workingFont = *menufont;
+
+		QFontInfo info(*menufont);
+		family = info.family();
+		csize = info.pointSize();
+
+		setWindowTitle("Menu Font Dialog");
+	}
+	else
+	{
+		// get current term font
+
+		QSettings settings(GetConfPath(), QSettings::IniFormat);
+
+#ifdef ANDROID
+		family = settings.value("FontFamily", "Driod Sans Mono").toString();
+		csize = settings.value("PointSize", 12).toInt();
+        weight = (QFont::Weight)settings.value("Weight", 50).toInt();
+#else
+		family = settings.value("FontFamily", "Courier New").toString();
+		csize = settings.value("PointSize", 10).toInt();
+		weight = (QFont::Weight)settings.value("Weight", 50).toInt();
+#endif
+
+		workingFont = QFont(family);
+		workingFont.setPointSize(csize);
+		workingFont.setWeight(weight);
+
+		setWindowTitle("Terminal Font Dialog");
+	}
+
+	QVBoxLayout *layout = new QVBoxLayout();
+	layout->setContentsMargins(10, 10, 10, 10);
+
+	setLayout(layout);
+
+	QHBoxLayout *hlayout = new QHBoxLayout();
+	layout->addLayout(hlayout);
+
+	font = new QFontComboBox();
+
+	if (Menu == 0)
+		font->setFontFilters(QFontComboBox::MonospacedFonts);
+
+	font->setMaximumWidth((screenWidth * 5) / 8);
+	font->view()->setMaximumWidth((7 * screenWidth) / 8);
+
+	style = new QComboBox();
+	style->setMaximumWidth(screenWidth / 4);
+	size = new QComboBox();
+	sample = new QTextEdit();
+	sample->setText("ABCDabcd1234");
+	sample->setFont(workingFont);
+
+	hlayout->addWidget(font);
+	hlayout->addWidget(style);
+	hlayout->addWidget(size);
+	layout->addWidget(sample);
+
+	QFontDatabase database;
+
+	const QStringList styles = database.styles(family);
+
+	const QList<int> smoothSizes = database.smoothSizes(family, styles[0]);
+
+	for (int points : smoothSizes)
+		size->addItem(QString::number(points));
+
+	for (QString xstyle : styles)
+		style->addItem(xstyle);
+
+	i = font->findText(family, Qt::MatchExactly);
+	font->setCurrentIndex(i);
+
+	sprintf(valChar, "%d", csize);
+	i = size->findText(valChar, Qt::MatchExactly);
+	size->setCurrentIndex(i);
+
+	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+	buttonBox->setFont(*menufont);
+	layout->addWidget(buttonBox);
+	setLayout(layout);
+
+	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
+	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
+	connect(font, SIGNAL(currentFontChanged(QFont)), this, SLOT(fontchanged(QFont)));
+	connect(style, SIGNAL(currentIndexChanged(int)), this, SLOT(stylechanged()));
+	connect(size, SIGNAL(currentIndexChanged(int)), this, SLOT(sizechanged()));
+}
+
+void fontDialog::fontchanged(QFont newfont)
+{
+	QFontDatabase database;
+	QString family = newfont.family();
+
+	workingFont = newfont;
+
+	const QStringList styles = database.styles(family);
+	const QList<int> smoothSizes = database.smoothSizes(family, styles[0]);
+
+	size->clear();
+	style->clear();
+
+	for (int points : smoothSizes)
+		size->addItem(QString::number(points));
+
+	for (QString xstyle : styles)
+		style->addItem(xstyle);
+
+	sample->setFont(workingFont);
+}
+
+void fontDialog::stylechanged()
+{
+	QFontDatabase database;
+
+	QString family = font->currentFont().family();
+
+	bool italic = database.italic(family, style->currentText());
+	int weight = database.weight(family, style->currentText());
+
+	if (weight < 0)
+		weight = 50;				// Normal
+
+	workingFont.setItalic(italic);
+    workingFont.setWeight((QFont::Weight) weight);
+
+	sample->setFont(workingFont);
+}
+
+void fontDialog::sizechanged()
+{
+	int newsize = size->currentText().toInt();
+	workingFont.setPointSize(newsize);
+	sample->setFont(workingFont);
+}
+fontDialog::~fontDialog()
+{
+}
+
+void fontDialog::myaccept()
+{
+	QSettings settings(GetConfPath(), QSettings::IniFormat);
+
+	if (Menuflag)
+	{
+		delete menufont;
+		menufont = new QFont(workingFont);
+
+		QtTermTCP::setFonts();
+
+		settings.setValue("MFontFamily", workingFont.family());
+		settings.setValue("MPointSize", workingFont.pointSize());
+		settings.setValue("MWeight", workingFont.weight());
+	}
+	else
+	{
+		Ui_ListenSession * Sess;
+
+		for (int i = 0; i < _sessions.size(); ++i)
+		{
+			Sess = _sessions.at(i);
+
+			if (Sess->termWindow)
+				Sess->termWindow->setFont(workingFont);
+
+			if (Sess->inputWindow)
+				Sess->inputWindow->setFont(workingFont);
+
+			if (Sess->monWindow)
+				Sess->monWindow->setFont(workingFont);
+		}
+
+		settings.setValue("FontFamily", workingFont.family());
+		settings.setValue("PointSize", workingFont.pointSize());
+		settings.setValue("Weight", workingFont.weight());
+	}
+
+	fontDialog::accept();
+}
+
+void fontDialog::myreject()
+{
+	fontDialog::reject();
+}
+
+
+
+ListenDialog::ListenDialog(QWidget *parent) : QDialog(parent)
+{
+#ifdef ANDROID
+	this->resize((screenWidth * 3) / 4 , 500);
+#endif
+	verticalLayout = new QVBoxLayout();
+	verticalLayout->setContentsMargins(10, 10, 10, 10);
+
+	setLayout(verticalLayout);
+
+	Enabled = new QCheckBox();
+	Enabled->setText(QString::fromUtf8("Enable Listen"));
+	Enabled->setLayoutDirection(Qt::LeftToRight);
+
+	verticalLayout->addWidget(Enabled);
+
+	formLayout = new QFormLayout();
+
+	portNo = new QLineEdit();
+//	portNo->setMaximumSize(QSize(100, 30));
+
+	formLayout->addRow(new QLabel("Port"), portNo);
+
+	CText = new QTextEdit();
+	CText->setMinimumSize(QSize(0, 150));
+	CText->setMaximumSize(QSize(401, 150));
+
+	formLayout->addRow(new QLabel("CText"), CText);
+	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+	buttonBox->setFont(*menufont);
+	verticalLayout->addWidget(buttonBox);
+
+	connect(buttonBox, SIGNAL(accepted()), this, SLOT(myaccept()));
+	connect(buttonBox, SIGNAL(rejected()), this, SLOT(myreject()));
+
+	verticalLayout->addLayout(formLayout);
+	verticalLayout->addWidget(buttonBox);
+
+	portNo->setText(QString::number(listenPort));
+	Enabled->setChecked(listenEnable);
+	CText->setText(listenCText);
+
+}
+
+ListenDialog::~ListenDialog()
+{
+}
+
+void ListenDialog::myaccept()
+{
+	QString val = portNo->text();
+	QByteArray qb = val.toLatin1();
+	char * ptr = qb.data();
+
+	listenPort = atoi(ptr);
+	listenEnable = Enabled->isChecked();
+	strcpy(listenCText, CText->toPlainText().toUtf8());
+
+	while ((ptr = strchr(listenCText, '\n')))
+		*ptr = '\r';
+
+	if (_server->isListening())
+		_server->close();
+
+	SaveSettings();
+
+	if (listenEnable)
+		_server->listen(QHostAddress::Any, listenPort);
+
+	ListenDialog::accept();
+}
+
+void ListenDialog::myreject()
+{
+	ListenDialog::reject();
+}
--- qttermtcp-0.0.0.79.orig/TabDialog.h
+++ qttermtcp-0.0.0.79/TabDialog.h
@@ -1,209 +1,209 @@
-
-#ifndef TABDIALOG_H
-#define TABDIALOG_H
-
-#include <QDialog>
-#include <QLineEdit>
-#include <QComboBox>
-#include <QListWidget>
-#include <QFontComboBox>
-#include <QTextEdit>
-#include <QCheckBox>
-#include <QFormLayout>
-#include <QVBoxLayout>
-#include <QGroupBox>
-#include <QRadioButton>
-
-class QDialogButtonBox;
-class QFileInfo;
-class QTabWidget;
-
-namespace Ui {
-class TabDialog;
-}
-
-class ListenDialog: public QDialog
-{
-	Q_OBJECT
-
-public:
-	explicit ListenDialog(QWidget *parent = 0);
-	~ListenDialog();
-
-private slots:
-	void myaccept();
-	void myreject();
-
-public:
-	QVBoxLayout *verticalLayout;
-	QFormLayout *formLayout;
-	QLineEdit *portNo;
-	QTextEdit *CText;
-	QVBoxLayout *verticalLayout_2;
-	QDialogButtonBox *buttonBox;
-	QCheckBox *Enabled;
-
-
-};
-
-
-
-class TabDialog : public QDialog
-{
-	Q_OBJECT
-
-public:
-	explicit TabDialog(QWidget *parent = 0);
-	~TabDialog();
-
-private slots:
-	void myaccept();
-	void myreject();
-
-private:
-	//   Ui::TabDialog *ui;
-	QDialogButtonBox *buttonBox;
-};
-
-class AGWDialog : public QDialog
-{
-	Q_OBJECT
-
-public:
-	explicit AGWDialog(QWidget *parent = 0);
-	~AGWDialog();
-
-public:
-	QPushButton *okButton;
-	QPushButton *cancelButton;
-
-private slots:
-	void myaccept();
-	void myreject();
-
-private:
-	//   Ui::TabDialog *ui;
-	QDialogButtonBox *buttonBox;
-};
-
-class AGWConnect : public QDialog
-{
-	Q_OBJECT
-
-public:
-	explicit AGWConnect(QWidget *parent = 0);
-	~AGWConnect();
-
-public:
-	QLineEdit * wCallFrom;
-	QComboBox * wCallTo;
-	QLineEdit * Digis;
-	QListWidget * RadioPorts;
-
-private slots:
-	void myaccept();
-	void myreject();
-
-private:
-	//   Ui::TabDialog *ui;
-	QDialogButtonBox *buttonBox;
-};
-
-
-
-class VARAConnect : public QDialog
-{
-	Q_OBJECT
-
-public:
-	explicit VARAConnect(QWidget *parent = 0);
-	~VARAConnect();
-
-public:
-	QLineEdit * wCallFrom;
-	QComboBox * wCallTo;
-	QLineEdit * Digis;
-	QListWidget * RadioPorts;
-
-private slots:
-	void myaccept();
-	void myreject();
-
-private:
-	//   Ui::TabDialog *ui;
-	QDialogButtonBox *buttonBox;
-};
-
-
-class KISSConnect : public QDialog
-{
-	Q_OBJECT
-
-public:
-	explicit KISSConnect(QWidget *parent = 0);
-	~KISSConnect();
-
-public:
-	QLineEdit * wCallFrom;
-	QComboBox * wCallTo;
-	QComboBox * Chan;
-	QLineEdit * Digis;
-	QLineEdit * UIDest;
-	QListWidget * RadioPorts;
-	QHBoxLayout *mylayout;
-	QRadioButton * Connected;
-	QRadioButton * UIMode;
-
-private slots:
-	void myaccept();
-	void myreject();
-
-private:
-	//   Ui::TabDialog *ui;
-	QDialogButtonBox *buttonBox;
-};
-
-
-
-class fontDialog : public QDialog
-{
-	Q_OBJECT
-
-public:
-	explicit fontDialog(int Menu, QWidget *parent = 0);
-	~fontDialog();
-
-public:
-	QFontComboBox *font;
-	QComboBox *style;
-	QComboBox *size;
-	QTextEdit * sample;
-	QFont workingFont;
-	int workingSize;
-	int Menuflag;			// Set if menu font
-
-private slots:
-	void myaccept();
-	void myreject();
-	void fontchanged(QFont);
-	void stylechanged();
-	void sizechanged();
-
-private:
-	
-	QDialogButtonBox *buttonBox;
-};
-
-#endif
-
-class myResize : public QObject
-{
-	Q_OBJECT
-
-protected:
-	bool eventFilter(QObject *obj, QEvent *event) override;
-};
-
-
-
-
+
+#ifndef TABDIALOG_H
+#define TABDIALOG_H
+
+#include <QDialog>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QListWidget>
+#include <QFontComboBox>
+#include <QTextEdit>
+#include <QCheckBox>
+#include <QFormLayout>
+#include <QVBoxLayout>
+#include <QGroupBox>
+#include <QRadioButton>
+
+class QDialogButtonBox;
+class QFileInfo;
+class QTabWidget;
+
+namespace Ui {
+class TabDialog;
+}
+
+class ListenDialog: public QDialog
+{
+	Q_OBJECT
+
+public:
+	explicit ListenDialog(QWidget *parent = 0);
+	~ListenDialog();
+
+private slots:
+	void myaccept();
+	void myreject();
+
+public:
+	QVBoxLayout *verticalLayout;
+	QFormLayout *formLayout;
+	QLineEdit *portNo;
+	QTextEdit *CText;
+	QVBoxLayout *verticalLayout_2;
+	QDialogButtonBox *buttonBox;
+	QCheckBox *Enabled;
+
+
+};
+
+
+
+class TabDialog : public QDialog
+{
+	Q_OBJECT
+
+public:
+	explicit TabDialog(QWidget *parent = 0);
+	~TabDialog();
+
+private slots:
+	void myaccept();
+	void myreject();
+
+private:
+	//   Ui::TabDialog *ui;
+	QDialogButtonBox *buttonBox;
+};
+
+class AGWDialog : public QDialog
+{
+	Q_OBJECT
+
+public:
+	explicit AGWDialog(QWidget *parent = 0);
+	~AGWDialog();
+
+public:
+	QPushButton *okButton;
+	QPushButton *cancelButton;
+
+private slots:
+	void myaccept();
+	void myreject();
+
+private:
+	//   Ui::TabDialog *ui;
+	QDialogButtonBox *buttonBox;
+};
+
+class AGWConnect : public QDialog
+{
+	Q_OBJECT
+
+public:
+	explicit AGWConnect(QWidget *parent = 0);
+	~AGWConnect();
+
+public:
+	QLineEdit * wCallFrom;
+	QComboBox * wCallTo;
+	QLineEdit * Digis;
+	QListWidget * RadioPorts;
+
+private slots:
+	void myaccept();
+	void myreject();
+
+private:
+	//   Ui::TabDialog *ui;
+	QDialogButtonBox *buttonBox;
+};
+
+
+
+class VARAConnect : public QDialog
+{
+	Q_OBJECT
+
+public:
+	explicit VARAConnect(QWidget *parent = 0);
+	~VARAConnect();
+
+public:
+	QLineEdit * wCallFrom;
+	QComboBox * wCallTo;
+	QLineEdit * Digis;
+	QListWidget * RadioPorts;
+
+private slots:
+	void myaccept();
+	void myreject();
+
+private:
+	//   Ui::TabDialog *ui;
+	QDialogButtonBox *buttonBox;
+};
+
+
+class KISSConnect : public QDialog
+{
+	Q_OBJECT
+
+public:
+	explicit KISSConnect(QWidget *parent = 0);
+	~KISSConnect();
+
+public:
+	QLineEdit * wCallFrom;
+	QComboBox * wCallTo;
+	QComboBox * Chan;
+	QLineEdit * Digis;
+	QLineEdit * UIDest;
+	QListWidget * RadioPorts;
+	QHBoxLayout *mylayout;
+	QRadioButton * Connected;
+	QRadioButton * UIMode;
+
+private slots:
+	void myaccept();
+	void myreject();
+
+private:
+	//   Ui::TabDialog *ui;
+	QDialogButtonBox *buttonBox;
+};
+
+
+
+class fontDialog : public QDialog
+{
+	Q_OBJECT
+
+public:
+	explicit fontDialog(int Menu, QWidget *parent = 0);
+	~fontDialog();
+
+public:
+	QFontComboBox *font;
+	QComboBox *style;
+	QComboBox *size;
+	QTextEdit * sample;
+	QFont workingFont;
+	int workingSize;
+	int Menuflag;			// Set if menu font
+
+private slots:
+	void myaccept();
+	void myreject();
+	void fontchanged(QFont);
+	void stylechanged();
+	void sizechanged();
+
+private:
+	
+	QDialogButtonBox *buttonBox;
+};
+
+#endif
+
+class myResize : public QObject
+{
+	Q_OBJECT
+
+protected:
+	bool eventFilter(QObject *obj, QEvent *event) override;
+};
+
+
+
+
--- qttermtcp-0.0.0.79.orig/TermTCPCommon.cpp
+++ qttermtcp-0.0.0.79/TermTCPCommon.cpp
@@ -1,1239 +1,1239 @@
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#include "QtTermTCP.h"
-
-#define _CRT_SECURE_NO_WARNINGS
-
-#define TRUE 1
-#define FALSE 0
-#define UCHAR unsigned char
-#define MAX_PATH 256
-#define WCHAR char
-
-#ifndef WIN32
-#define strtok_s strtok_r
-#endif
-
-
-typedef unsigned long       DWORD;
-typedef int                 BOOL;
-typedef unsigned char       BYTE;
-typedef unsigned short      WORD;
-
-#define MAXHOSTS 16
-
-#define TCHAR char
-
-void QueueMsg(Ui_ListenSession * Sess, char * Msg, int Len);
-int ProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len);
-void SetPortMonLine(int i, char * Text, int visible, int enabled);
-void AGW_AX25_data_in(void  * Sess, UCHAR * data, int Len);
-int checkUTF8(unsigned char * Msg, int Len, unsigned char * out);
-void DoTermResize(Ui_ListenSession * Sess);
-void DecodeTeleText(Ui_ListenSession * Sess, char * page);
-
-int Bells = TRUE;
-int StripLF = FALSE;
-int LogOutput = FALSE;
-int SendDisconnected = TRUE;
-int ChatMode = TRUE;
-int AutoTeletext = 1;
-
-int MonPorts = 1;
-int ListenOn = FALSE;
-
-time_t LastWrite = 0xffffffff;
-int AlertInterval = 300;
-int AlertBeep = TRUE;
-int AlertFreq = 600;
-int AlertDuration = 250;
-TCHAR AlertFileName[256] = { 0 };
-int ConnectBeep = TRUE;
-int UseKeywords = TRUE;
-
-QString KeyWordsFile = "Keywords.sys";
-
-char ** KeyWords = NULL;
-int NumberofKeyWords = 0;
-
-
-// YAPP stuff
-
-#define SOH 1
-#define STX 2
-#define ETX 3
-#define EOT 4
-#define ENQ 5
-#define ACK 6
-#define DLE	0x10
-#define NAK 0x15
-#define CAN 0x18
-
-#define YAPPTX	32768					// Sending YAPP file
-
-int MaxRXSize = 100000;
-char BaseDir[256] = "";
-
-unsigned char InputBuffer[1024];
-
-char  YAPPPath[MAX_PATH] = "";	// Path for saving YAPP Files
-
-int paclen = 128;
-
-int InputLen;				// Data we have already = Offset of end of an incomplete packet;
-
-unsigned char * MailBuffer;			// Yapp Message being received
-int MailBufferSize;
-int YAPPLen;				// Bytes sent/received of YAPP Message
-long YAPPDate;				// Date for received file - if set enables YAPPC
-char ARQFilename[200];		// Filename from YAPP Header
-
-unsigned char SavedData[8192];		// Max receive is 4096 is should never get more that 8k
-int SaveLen = 0;
-
-void YAPPSendData(Ui_ListenSession * Sess);
-
-
-char * strlop(char * buf, char delim)
-{
-	// Terminate buf at delim, and return rest of string
-
-	char * ptr = strchr(buf, delim);
-
-	if (ptr == NULL) return NULL;
-
-	*(ptr)++ = 0;
-
-	return ptr;
-}
-
-#ifdef WIN32
-
-char * strcasestr(char *ch1, char *ch2)
-{
-	char	*chN1, *chN2;
-	char	*chNdx;
-	char	*chRet = NULL;
-
-	chN1 = _strdup(ch1);
-	chN2 = _strdup(ch2);
-
-	if (chN1 && chN2)
-	{
-		chNdx = chN1;
-		while (*chNdx)
-		{
-			*chNdx = (char)tolower(*chNdx);
-			chNdx++;
-		}
-		chNdx = chN2;
-
-		while (*chNdx)
-		{
-			*chNdx = (char)tolower(*chNdx);
-			chNdx++;
-		}
-
-		chNdx = strstr(chN1, chN2);
-
-		if (chNdx)
-			chRet = ch1 + (chNdx - chN1);
-	}
-
-	free(chN1);
-	free(chN2);
-	return chRet;
-}
-
-#endif
-
-void GetKeyWordFile()
-{
-	DWORD FileSize;
-	char * ptr1, *ptr2;
-	char * KeyWordFile;
-
-	QFile file(KeyWordsFile);
-	
-	if (!file.open(QIODevice::ReadOnly))
-	{
-		if (UseKeywords)				// Don't need to alert if not being used
-		{
-			QMessageBox msgBox;
-			msgBox.setText("Keyword File " + KeyWordsFile + " not found");
-			msgBox.exec();
-		}
-		return;
-	}
-
-	FileSize = file.size();
-
-	KeyWordFile = (char *)malloc(FileSize + 1);
-
-	file.read(KeyWordFile, FileSize);
-
-	file.close();
-
-	KeyWordFile[FileSize] = 0;
- 
-	ptr1 = KeyWordFile;
-
-	while (ptr1)
-	{
-		if (*ptr1 == '\n') ptr1++;
-
-		ptr2 = strtok_s(NULL, "\r\n", &ptr1);
-		if (ptr2)
-		{
-			if (*ptr2 != '#')
-			{
-				KeyWords = (char **)realloc(KeyWords, (++NumberofKeyWords + 1) * 4);
-				KeyWords[NumberofKeyWords] = ptr2;
-			}
-		}
-		else
-			break;
-	}
-}
-
-
-int CheckKeyWord(char * Word, char * Msg)
-{
-	char * ptr1 = Msg, *ptr2;
-	int len = (int)strlen(Word);
-
-	while (*ptr1)					// Stop at end
-	{
-		ptr2 = strcasestr(ptr1, Word);
-
-		if (ptr2 == NULL)
-			return FALSE;				// OK
-
-		// Only bad if it ia not part of a longer word
-
-		if ((ptr2 == Msg) || !(isalpha(*(ptr2 - 1))))	// No alpha before
-			if (!(isalpha(*(ptr2 + len))))			// No alpha after
-				return TRUE;					// Bad word
-
-		// Keep searching
-
-		ptr1 = ptr2 + len;
-	}
-
-	return FALSE;					// OK
-}
-
-int CheckKeyWords(UCHAR * Msg, int len)
-{
-	int i;
-
-	if (UseKeywords == 0 || NumberofKeyWords == 0)
-		return FALSE;
-
-	// we need to null terminate Msg, so create a copy
-
-	unsigned char * copy = (unsigned char *)malloc(len + 1);
-
-	memcpy(copy, Msg, len);
-	copy[len] = 0;
-
-	for (i = 1; i <= NumberofKeyWords; i++)
-	{
-		if (CheckKeyWord(KeyWords[i], (char *)copy))
-		{
-			myBeep(&AlertWAV);
-			free (copy);
-			return TRUE;			// Alert
-		}
-	}
-
-	free(copy);
-	return FALSE;					// OK
-
-}
-
-
-void ProcessReceivedData(Ui_ListenSession * Sess, unsigned char * Buffer, int len)
-{
-	int MonLen = 0;
-	unsigned char * ptr;
-	unsigned char * Buffptr;
-	unsigned char * FEptr = 0;
-
-	if (Sess->InputMode == 'Y')			// Yapp
-	{
-		ProcessYAPPMessage(Sess, Buffer, len);
-		return;
-	}
-
-	// See if Teletext data
-
-			// We need to identify a viewdata frame. Seems to start
-
-		//1e 0a 0a 0a 0a 0a 0a 0a  0a 0a 0a 0a 0a 0a 0a 0a   ........ ........
-			//00000170  0a 0a 0a 0a 0a 0a 0a 0a  11 0c 1b
-
-		// Page seems to start 1c
-
-		// After page get 
-
-		//1e 0a 0a 0a 0a 0a 0a 0a  0a 0a 0a 0a 0a 0a 0a 0a   ........ ........
-		//	0000049D  0a 0a 0a 0a 0a 0a 0a 0a  11 14 1b 44 1b 5d 1b 43   ........ ...D.].C
-		//	000004AD  53 65 6c 65                                        Sele
-		//	000004B1  63 74 20 69 74 65 6d 20  6f 72 1b 47 2a 70 61 67   ct item or .G*pag
-		//	000004C1  65 5f 20 3a 20 20 20 20  20 20 20 20 20 20 20 20   e_ :
-		//	000004D1  20 0d 09 09 09 09 09 09  09 09 09 09 09 09 09 09    ....... ........
-		//	000004E1  09 09 09 09 09 09 09 09  09 09 09 09 09 11
-
-	Buffer[len] = 0;
-
-	if (AutoTeletext && (Buffer[0] == 0x1e || Buffer[0] == 0x0c))
-	{
-		if (Sess->TTActive == 0)
-		{
-			Sess->TTActive = 1;
-			DoTermResize(Sess);
-		}
-	}
-
-	if (Sess->TTActive)
-	{
-		// Feed to Teletext code
-
-		// We need to decode a whole page. There is no obvious delimiter so process till data stops.
-		// Buffer is cleared when next input is sent
-
-		if (strlen(&Sess->pageBuffer[0] + len) > 4090)
-			Sess->pageBuffer[0] = 0;							// Protect buffer
-
-		strcat(Sess->pageBuffer, (char *)Buffer);
-
-		DecodeTeleText(Sess, (char *)Sess->pageBuffer);			// Re-decode same data until we get the end
-		return;
-	}
-
-
-
-	//	mbstowcs(Buffer, BufferB, len);
-
-	// Look for MON delimiters (FF/FE)
-
-
-	Buffptr = Buffer;
-
-	if (Sess->MonData)
-	{
-		// Already in MON State
-
-		FEptr = (UCHAR *)memchr(Buffptr, 0xfe, len);
-
-		if (!FEptr)
-		{
-			// no FE - so send all to monitor
-
-			WritetoMonWindow(Sess, Buffer, len);
-			return;
-		}
-
-		Sess->MonData = FALSE;
-
-		MonLen = FEptr - Buffptr;		// Mon Data, Excluding the FE
-
-		WritetoMonWindow(Sess, Buffptr, MonLen);
-
-		Buffptr = ++FEptr;				// Char following FE
-
-		if (++MonLen < len)
-		{
-			len -= MonLen;
-			goto MonLoop;				// See if next in MON or Data
-		}
-
-		// Nothing Left
-
-		return;
-	}
-
-MonLoop:
-
-	ptr = (UCHAR *)memchr(Buffptr, 0xff, len);
-
-	if (ptr)
-	{
-		unsigned char telcmd[] = "\xff\xfb\x03\xff\xfb\x01";
-
-		// Try to trap connect to normal Telnet Port
-
-		if (memcmp(ptr, telcmd, 6) == 0)
-			return;
-
-		// Buffer contains Mon Data
-
-		if (ptr > Buffptr)
-		{
-			// Some Normal Data before the FF
-
-			int NormLen = ptr - Buffptr;				// Before the FF
-
-			if (NormLen == 1 && Buffptr[0] == 0)
-			{
-				// Keepalive
-			}
-
-			else
-			{
-				CheckKeyWords(Buffptr, NormLen);
-				WritetoOutputWindow(Sess, Buffptr, NormLen);
-			}
-
-			len -= NormLen;
-			Buffptr = ptr;
-			goto MonLoop;
-		}
-
-		if (ptr[1] == 0xff)
-		{
-			// Port Definition String
-
-			int NumberofPorts = atoi((char *)&ptr[2]);
-			char *p, *Context;
-			int i = 1;
-			TCHAR msg[80];
-			int portnum;
-			char delim[] = "|";
-			int m;
-
-			// Save for changes of Window
-
-			if (len < 2048)
-				memcpy(Sess->PortMonString, ptr, len);
-
-			
-			// Remove old menu
-			
-			for (i = 0; i < 65; i++)
-			{
-				SetPortMonLine(i, (char *)"", 0, 0);
-			}
-
-			p = strtok_s((char *)&ptr[2], delim, &Context);
-
-			while (NumberofPorts--)
-			{
-				p = strtok_s(NULL, delim, &Context);
-				if (p == NULL)
-					break;
-
-				m = portnum = atoi(p);
-				sprintf(msg, "Port %s", p);
-
-				if (m == 0)
-					m = 64;
-
-				if (Sess->portmask & (1ll << (m - 1)))
-					SetPortMonLine(portnum, msg, 1, 1);
-				else
-					SetPortMonLine(portnum, msg, 1, 0);
-			}
-			return;
-		}
-
-		MonLen = len;				// in case no fe
-
-		Sess->MonData = 1;
-
-		FEptr = (UCHAR *)memchr(Buffptr, 0xfe, len);
-
-		if (FEptr)
-		{
-			Sess->MonData = 0;
-
-			MonLen = FEptr + 1 - Buffptr;				// MonLen includes FF and FE
-
-			WritetoMonWindow(Sess, Buffptr + 1, MonLen - 2);
-
-			len -= MonLen;
-			Buffptr += MonLen;							// Char Following FE
-
-			if (len <= 0)
-			{
-				return;
-			}
-			goto MonLoop;
-		}
-		else
-		{
-			// No FE, so rest of buffer is MON Data
-
-			if (MonLen)
-				WritetoMonWindow(Sess, Buffptr + 1, MonLen - 1);
-			return;
-		}
-	}
-
-	// No FF, so must be session data
-
-	if (Sess->InputMode == 'Y')			// Yapp
-	{
-		ProcessYAPPMessage(Sess, Buffer, len);
-		return;
-	}
-
-
-	if (len == 1 && Buffptr[0] == 0)
-		return;							// Keepalive
-
-	// Could be a YAPP Header
-
-	if (len == 2 && Buffptr[0] == ENQ && Buffptr[1] == 1)		// YAPP Send_Init
-	{
-		char YAPPRR[2];
-
-		// Turn off monitoring
-
-		setTraceOff(Sess);
-		
-		Sess->InputMode = 'Y';
-
-		YAPPRR[0] = ACK;
-		YAPPRR[1] = 1;
-
-		SocketFlush(Sess);			// To give Monitor Msg time to be sent
-		mySleep(1000);
-		QueueMsg(Sess, YAPPRR, 2);
-
-		return;
-	}
-	// Check UTF8
-	{
-		CheckKeyWords(Buffptr, len);
-		WritetoOutputWindow(Sess, Buffptr, len);
-	}
-	Sess->SlowTimer = 0;
-	return;
-}
-
-extern myTcpSocket * VARASock;
-extern myTcpSocket * VARADataSock;
-extern "C" void SendtoAX25(void * conn, unsigned char * Msg, int Len);
-
-int SendMsg(Ui_ListenSession * Sess, TCHAR * Buffer, int len)
-{
-	if (Sess->KISSSession)
-	{
-		// Send to ax.25 code
-
-		SendtoAX25(Sess->KISSSession, (unsigned char *)Buffer, len);
-		return len;
-	}
-	else if (Sess->AGWSession)
-	{
-		// Terminal is in AGWPE mode - send as AGW frame
-
-		AGW_AX25_data_in(Sess->AGWSession, (unsigned char *)Buffer, len);
-		return len;
-	}
-	else if (VARASock && VARASock->Sess == Sess)
-	{
-		VARADataSock->write(Buffer, len);
-		return len;
-	}
-
-	return SocketSend(Sess, Buffer, len);
-}
-
-
-
-void QueueMsg(Ui_ListenSession * Sess, char * Msg, int len)
-{
-	int Sent = SendMsg(Sess, Msg, len);
-
-	if (Sent != len)
-		Sent = 0;
-}
-
-int InnerProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len);
-
-int ProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len)
-{
-	// may have saved data
-
-	memcpy(&SavedData[SaveLen], Msg, Len);
-
-	SaveLen += Len;
-
-	while (SaveLen && Sess->InputMode == 'Y')
-	{
-		int Used = InnerProcessYAPPMessage(Sess, SavedData, SaveLen);
-
-		if (Used == 0)
-			return 0;			// Waiting for more
-
-		SaveLen -= Used;
-
-		if (SaveLen)
-			memmove(SavedData, &SavedData[Used], SaveLen);
-	}
-	return 0;
-}
-
-extern int VARAEnable;
-
-int InnerProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len)
-{
-	int pktLen = Msg[1];
-	char Reply[2] = { ACK };
-	size_t NameLen, SizeLen, OptLen;
-	char * ptr;
-	int FileSize;
-	WCHAR MsgFile[MAX_PATH];
-	FILE * hFile;
-	char Mess[255];
-	int len;
-	UCHAR Buffer[2000];
-	struct stat STAT;
-
-	switch (Msg[0])
-	{
-	case ENQ: // YAPP Send_Init
-
-		// Shouldn't occur in session. Reset state and process
-
-		if (MailBuffer)
-		{
-			free(MailBuffer);
-			MailBufferSize = 0;
-			MailBuffer = 0;
-		}
-
-		Mess[0] = ACK;
-		Mess[1] = 1;
-
-		Sess->InputMode = 'Y';
-		QueueMsg(Sess, Mess, 2);
-
-		// Turn off monitoring
-
-		mySleep(1000);				// To give YAPP Msg time to be sent
-
-		setTraceOff(Sess);
-
-		return Len;
-
-	case SOH:
-
-		// HD Send_Hdr     SOH  len  (Filename)  NUL  (File Size in ASCII)  NUL (Opt) 
-
-		// YAPPC has date/time in dos format
-
-		if (Len < Msg[1] + 1)
-			return 0;				// Wait till we have it all
-
-		NameLen = strlen((char *)&Msg[2]);
-		strcpy(ARQFilename, (char *)&Msg[2]);
-
-		ptr = (char *)&Msg[3 + NameLen];
-		SizeLen = strlen(ptr);
-		FileSize = atoi(ptr);
-
-		OptLen = pktLen - (NameLen + SizeLen + 2);
-
-		YAPPDate = 0;
-
-		if (OptLen >= 8)		// We have a Date/Time for YAPPC
-		{
-			ptr = ptr + SizeLen + 1;
-			YAPPDate = strtol(ptr, NULL, 16);
-		}
-
-		// Check Size
-
-		if (FileSize > MaxRXSize && VARAEnable == 0)
-		{
-			Mess[0] = NAK;
-			Mess[1] = sprintf(&Mess[2], "File %s size %d larger than limit %d\r", ARQFilename, FileSize, MaxRXSize);
-			mySleep(1000);				// To give YAPP Msg time to be sent
-			QueueMsg(Sess, Mess, Mess[1] + 2);
-
-			len = sprintf((char *)Buffer, "YAPP File %s size %d larger than limit %d\r", ARQFilename, FileSize, MaxRXSize);
-			WritetoOutputWindow(Sess, Buffer, len);
-
-			Sess->InputMode = 0;
-			SendTraceOptions(Sess);
-
-			return Len;
-		}
-
-		// Check that Path is set
-
-		if (YAPPPath[0] == 0)
-		{
-			Mess[0] = NAK;
-			Mess[1] = sprintf(&Mess[2], "%s", "YAPP Receive directory not set");
-			mySleep(1000);				// To give YAPP Msg time to be sent
-			QueueMsg(Sess, Mess, Mess[1] + 2);
-			len = sprintf((char *)Buffer, "YAPP File Receive Failed - YAPP Receive directory not set\r");
-			WritetoOutputWindow(Sess, Buffer, len);
-
-			Sess->InputMode = 0;
-			SendTraceOptions(Sess);
-
-			return Len;
-		}
-
-		// Make sure file does not exist
-
-		sprintf(MsgFile, "%s/%s", YAPPPath, ARQFilename);
-
-		if (stat(MsgFile, &STAT) == 0)
-		{
-			FileSize = STAT.st_size;
-
-			Mess[0] = NAK;
-			Mess[1] = sprintf(&Mess[2], "%s", "File Already Exists");
-			mySleep(1000);				// To give YAPP Msg time to be sent
-			QueueMsg(Sess, Mess, Mess[1] + 2);
-			len = sprintf((char *)Buffer, "YAPP File Receive Failed - %s already exists\r", MsgFile);
-			WritetoOutputWindow(Sess, Buffer, len);
-
-			Sess->InputMode = 0;
-			SendTraceOptions(Sess);
-
-			return Len;
-		}
-
-
-		MailBufferSize = FileSize;
-		MailBuffer = (UCHAR *)malloc(FileSize);
-		YAPPLen = 0;
-
-		if (YAPPDate)			// If present use YAPPC
-			Reply[1] = ACK;			//Receive_TPK
-		else
-			Reply[1] = 2;			//Rcv_File
-
-		QueueMsg(Sess, Reply, 2);
-
-		len = sprintf((char *)Buffer, "YAPP Receving File %s size %d\r", ARQFilename, FileSize);
-		WritetoOutputWindow(Sess, Buffer, len);
-
-		return Len;
-
-	case STX:
-
-		// Data Packet
-
-		// Check we have it all
-
-		if (YAPPDate)			// If present use YAPPC so have checksum
-		{
-			if (pktLen > (Len - 3))		// -2 for header and checksum
-				return 0;				// Wait for rest
-		}
-		else
-		{
-			if (pktLen > (Len - 2))		// -2 for header
-				return 0;				// Wait for rest
-		}
-
-		// Save data and remove from buffer
-
-		// if YAPPC check checksum
-
-		if (YAPPDate)
-		{
-			UCHAR Sum = 0;
-			int i;
-			UCHAR * uptr = &Msg[2];
-
-			i = pktLen;
-
-			while (i--)
-				Sum += *(uptr++);
-
-			if (Sum != *uptr)
-			{
-				// Checksum Error
-
-				Mess[0] = CAN;
-				Mess[1] = sprintf(&Mess[2], "YAPPC Checksum Error");
-				QueueMsg(Sess, Mess, Mess[1] + 2);
-
-				len = sprintf((char *)Buffer, "YAPPC Checksum Error on file %s\r", MsgFile);
-				WritetoOutputWindow(Sess, Buffer, len);
-
-				Sess->InputMode = 0;
-				SendTraceOptions(Sess);
-				return Len;
-			}
-		}
-
-		if ((YAPPLen) + pktLen > MailBufferSize)
-		{
-			// Too Big ??
-
-			Mess[0] = CAN;
-			Mess[1] = sprintf(&Mess[2], "YAPP Too much data received");
-			QueueMsg(Sess, Mess, Mess[1] + 2);
-
-			len = sprintf((char *)Buffer, "YAPP Too much data received on file %s\r", MsgFile);
-			WritetoOutputWindow(Sess, Buffer, len);
-
-			Sess->InputMode = 0;
-			SendTraceOptions(Sess);
-			return Len;
-		}
-
-
-		memcpy(&MailBuffer[YAPPLen], &Msg[2], pktLen);
-		YAPPLen += pktLen;
-
-		if (YAPPDate)
-			++pktLen;				// Add Checksum
-
-//		if (YAPPLen == MailBufferSize)
-//			pktLen = pktLen;
-
-		return pktLen + 2;
-
-	case ETX:
-
-		// End Data
-
-		if (YAPPLen == MailBufferSize)
-		{
-			// All received
-
-			int Written = 0;
-
-			sprintf(MsgFile, "%s/%s", YAPPPath, ARQFilename);
-
-			hFile = fopen(MsgFile, "wb");
-
-			if (hFile)
-			{
-				Written = (int)fwrite(MailBuffer, 1, YAPPLen, hFile);
-				fclose(hFile);
-
-				if (YAPPDate)
-				{
-//					struct tm TM;
-//					struct timeval times[2];
-					/*
-										The MS-DOS date. The date is a packed value with the following format.
-
-										cant use DosDateTimeToFileTime on Linux
-
-										Bits	Description
-										0-4	Day of the month (131)
-										5-8	Month (1 = January, 2 = February, and so on)
-										9-15	Year offset from 1980 (add 1980 to get actual year)
-										wFatTime
-										The MS-DOS time. The time is a packed value with the following format.
-										Bits	Description
-										0-4	Second divided by 2
-										5-10	Minute (059)
-										11-15	Hour (023 on a 24-hour clock)
-					*/
-					/*
-				
-					memset(&TM, 0, sizeof(TM));
-
-					TM.tm_sec = (YAPPDate & 0x1f) << 1;
-					TM.tm_min = ((YAPPDate >> 5) & 0x3f);
-					TM.tm_hour = ((YAPPDate >> 11) & 0x1f);
-
-					TM.tm_mday = ((YAPPDate >> 16) & 0x1f);
-					TM.tm_mon = ((YAPPDate >> 21) & 0xf) - 1;
-					TM.tm_year = ((YAPPDate >> 25) & 0x7f) + 80;
-
-					Debugprintf("%d %d %d %d %d %d", TM.tm_year, TM.tm_mon, TM.tm_mday, TM.tm_hour, TM.tm_min, TM.tm_sec);
-
-					times[0].tv_sec = times[1].tv_sec = mktime(&TM);
-					times[0].tv_usec = times[1].tv_usec = 0;
-						*/
-				}
-			}
-
-
-			free(MailBuffer);
-			MailBufferSize = 0;
-			MailBuffer = 0;
-
-			if (Written != YAPPLen)
-			{
-				Mess[0] = CAN;
-				Mess[1] = sprintf(&Mess[2], "Failed to save YAPP File");
-				QueueMsg(Sess, Mess, Mess[1] + 2);
-
-				len = sprintf((char *)Buffer, "Failed to save YAPP File %s\r", MsgFile);
-				WritetoOutputWindow(Sess, Buffer, len);
-
-				Sess->InputMode = 0;
-				SendTraceOptions(Sess);
-			}
-		}
-
-		Reply[1] = 3;		//Ack_EOF
-		QueueMsg(Sess, Reply, 2);
-
-		len = sprintf((char *)Buffer, "Reception of file %s complete\r", MsgFile);
-		WritetoOutputWindow(Sess, Buffer, len);
-
-		return Len;
-
-	case EOT:
-
-		// End Session
-
-		Reply[1] = 4;		// Ack_EOT
-		QueueMsg(Sess, Reply, 2);
-		SocketFlush(Sess);
-		Sess->InputMode = 0;
-
-		SendTraceOptions(Sess);
-		return Len;
-
-	case CAN:
-
-		// Abort
-
-		Mess[0] = ACK;
-		Mess[1] = 5;			// CAN Ack
-		QueueMsg(Sess, Mess, 2);
-
-		if (MailBuffer)
-		{
-			free(MailBuffer);
-			MailBufferSize = 0;
-			MailBuffer = 0;
-		}
-
-		// May have an error message
-
-		len = Msg[1];
-
-		if (len)
-		{
-			len = sprintf((char *)Buffer, "YAPP Transfer cancelled - %s\r", &Msg[2]);
-		}
-		else
-			len = sprintf(Mess, "YAPP Transfer cancelled\r");
-
-		Sess->InputMode = 0;
-		SendTraceOptions(Sess);
-
-		return Len;
-
-	case ACK:
-
-		switch (Msg[1])
-		{
-			char * ptr;
-
-		case 1:					// Rcv_Rdy
-
-			// HD Send_Hdr     SOH  len  (Filename)  NUL  (File Size in ASCII)  NUL (Opt)
-
-			// Remote only needs filename so remove path
-
-			ptr = ARQFilename;
-
-			while (strchr(ptr, '/'))
-				ptr = strchr(ptr, '/') + 1;
-
-			len = (int)strlen(ptr) + 3;
-
-			strcpy(&Mess[2], ptr);
-			len += sprintf(&Mess[len], "%d", MailBufferSize);
-			len++;					// include null
-//			len += sprintf(&Mess[len], "%8X", YAPPDate);
-//			len++;					// include null
-			Mess[0] = SOH;
-			Mess[1] = len - 2;
-
-			QueueMsg(Sess, Mess, len);
-
-			return Len;
-
-		case 2:
-
-			YAPPDate = 0;				// Switch to Normal (No Checksum) Mode
-
-			// Drop through
-
-		case 6:							// Send using YAPPC
-
-			//	Start sending message
-
-			YAPPSendData(Sess);
-			return Len;
-
-		case 3:
-
-			// ACK EOF - Send EOT
-
-			Mess[0] = EOT;
-			Mess[1] = 1;
-			QueueMsg(Sess, Mess, 2);
-
-			return Len;
-
-		case 4:
-
-			// ACK EOT
-
-			Sess->InputMode = 0;
-			SendTraceOptions(Sess);
-
-			len = sprintf((char *)Buffer, "File transfer complete\r");
-			WritetoOutputWindow(Sess, Buffer, len);
-	
-
-			return Len;
-
-		default:
-			return Len;
-
-		}
-
-	case NAK:
-
-		// Either Reject or Restart
-
-		// RE Resume       NAK  len  R  NULL  (File size in ASCII)  NULL
-
-		if (Len > 2 && Msg[2] == 'R' && Msg[3] == 0)
-		{
-			int posn = atoi((char *)&Msg[4]);
-
-			YAPPLen += posn;
-			MailBufferSize -= posn;
-
-			YAPPSendData(Sess);
-			return Len;
-
-		}
-
-		// May have an error message
-
-		len = Msg[1];
-
-		if (len)
-		{
-			char ws[256];
-
-			Msg[len + 2] = 0;
-
-			strcpy(ws, (char *)&Msg[2]);
-
-			len = sprintf((char *)Buffer, "File rejected - %s\r", ws);
-		}
-		else
-			len = sprintf((char *)Buffer, "File rejected\r");
-
-		WritetoOutputWindow(Sess, Buffer, len);
-	
-
-		Sess->InputMode = 0;
-		SendTraceOptions(Sess);
-
-		return Len;
-
-	}
-
-	len = sprintf((char *)Buffer, "Unexpected message during YAPP Transfer. Transfer cancelled\r");
-	WritetoOutputWindow(Sess, Buffer, len);
-	
-	Sess->InputMode = 0;
-	SendTraceOptions(Sess);
-
-	return Len;
-
-}
-
-void YAPPSendFile(Ui_ListenSession * Sess, WCHAR * FN)
-{
-	int FileSize = 0;
-	char MsgFile[MAX_PATH];
-	FILE * hFile;
-	struct stat STAT;
-	UCHAR Buffer[2000];
-	int Len;
-
-	strcpy(MsgFile, FN);
-
-	if (MsgFile[0] == 0)
-	{
-		Len = sprintf((char *)Buffer, "Filename missing\r");
-		WritetoOutputWindow(Sess, Buffer, Len);
-	
-		SendTraceOptions(Sess);
-
-		return;
-	}
-
-	if (stat(MsgFile, &STAT) != -1)
-	{
-		FileSize = STAT.st_size;
-
-		hFile = fopen(MsgFile, "rb");
-
-		if (hFile)
-		{
-			char Mess[255];
-//			time_t UnixTime = STAT.st_mtime;
-
-//			FILETIME ft;
-//			long long ll;
-//			SYSTEMTIME st;
-//			WORD FatDate;
-//			WORD FatTime;
-//			struct tm TM;
-
-			strcpy(ARQFilename, MsgFile);
-
-			if (MailBuffer)
-			{
-				free(MailBuffer);
-				MailBufferSize = 0;
-				MailBuffer = 0;
-			}
-
-			MailBuffer = (UCHAR *)malloc(FileSize);
-			MailBufferSize = FileSize;
-			YAPPLen = 0;
-			fread(MailBuffer, 1, FileSize, hFile);
-
-			// Get Date and Time for YAPPC Mode
-
-/*					The MS-DOS date. The date is a packed value with the following format.
-
-					cant use DosDateTimeToFileTime on Linux
-
-					Bits	Description
-					0-4	Day of the month (131)
-					5-8	Month (1 = January, 2 = February, and so on)
-					9-15	Year offset from 1980 (add 1980 to get actual year)
-					wFatTime
-					The MS-DOS time. The time is a packed value with the following format.
-					Bits	Description
-					0-4	Second divided by 2
-					5-10	Minute (059)
-					11-15	Hour (023 on a 24-hour clock)
-
-					memset(&TM, 0, sizeof(TM));
-
-					TM.tm_sec = (YAPPDate & 0x1f) << 1;
-					TM.tm_min = ((YAPPDate >> 5) & 0x3f);
-					TM.tm_hour =  ((YAPPDate >> 11) & 0x1f);
-
-					TM.tm_mday =  ((YAPPDate >> 16) & 0x1f);
-					TM.tm_mon =  ((YAPPDate >> 21) & 0xf) - 1;
-					TM.tm_year = ((YAPPDate >> 25) & 0x7f) + 80;
-
-
-// Note that LONGLONG is a 64-bit value
-
-			ll = Int32x32To64(UnixTime, 10000000) + 116444736000000000;
-			ft.dwLowDateTime = (DWORD)ll;
-			ll >>= 32;
-			ft.dwHighDateTime = (DWORD)ll;
-
-			FileTimeToSystemTime(&ft, &st);
-			FileTimeToDosDateTime(&ft, &FatDate, &FatTime);
-
-			YAPPDate = (FatDate << 16) + FatTime;
-
-			memset(&TM, 0, sizeof(TM));
-
-			TM.tm_sec = (YAPPDate & 0x1f) << 1;
-			TM.tm_min = ((YAPPDate >> 5) & 0x3f);
-			TM.tm_hour = ((YAPPDate >> 11) & 0x1f);
-
-			TM.tm_mday = ((YAPPDate >> 16) & 0x1f);
-			TM.tm_mon = ((YAPPDate >> 21) & 0xf) - 1;
-			TM.tm_year = ((YAPPDate >> 25) & 0x7f) + 80;
-*/
-			fclose(hFile);
-
-			Mess[0] = ENQ;
-			Mess[1] = 1;
-
-			QueueMsg(Sess, Mess, 2);
-			Sess->InputMode = 'Y';
-
-			Len = sprintf((char *)Buffer, "Sending File %s ...\r", FN);
-			WritetoOutputWindow(Sess, Buffer, Len);
-
-			return;
-		}
-	}
-
-	Len = sprintf((char *)Buffer, "File %s not found\r", FN);
-	WritetoOutputWindow(Sess, Buffer, Len);
-
-}
-
-void YAPPSendData(Ui_ListenSession * Sess)
-{
-	char Mess[258];
-
-	while (1)
-	{
-		int Left = MailBufferSize;
-
-		if (Left == 0)
-		{
-			// Finished - send End Data
-
-			Mess[0] = ETX;
-			Mess[1] = 1;
-
-			QueueMsg(Sess, Mess, 2);
-
-			break;
-		}
-
-		if (Left > paclen - 3)		// two bytes header and possible checksum
-			Left = paclen - 3;
-
-		memcpy(&Mess[2], &MailBuffer[YAPPLen], Left);
-
-		YAPPLen += Left;
-		MailBufferSize -= Left;
-
-		// if YAPPC add checksum
-
-		if (YAPPDate)
-		{
-			UCHAR Sum = 0;
-			int i;
-			UCHAR * uptr = (UCHAR *)&Mess[2];
-
-			i = Left;
-
-			while (i--)
-				Sum += *(uptr++);
-
-			*(uptr) = Sum;
-
-			Mess[0] = STX;
-			Mess[1] = Left;
-
-			QueueMsg(Sess, Mess, Left + 3);
-		}
-		else
-		{
-			Mess[0] = STX;
-			Mess[1] = Left;
-
-			QueueMsg(Sess, Mess, Left + 2);
-		}
-	}
-}
-
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include "QtTermTCP.h"
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#define TRUE 1
+#define FALSE 0
+#define UCHAR unsigned char
+#define MAX_PATH 256
+#define WCHAR char
+
+#ifndef WIN32
+#define strtok_s strtok_r
+#endif
+
+
+typedef unsigned long       DWORD;
+typedef int                 BOOL;
+typedef unsigned char       BYTE;
+typedef unsigned short      WORD;
+
+#define MAXHOSTS 16
+
+#define TCHAR char
+
+void QueueMsg(Ui_ListenSession * Sess, char * Msg, int Len);
+int ProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len);
+void SetPortMonLine(int i, char * Text, int visible, int enabled);
+void AGW_AX25_data_in(void  * Sess, UCHAR * data, int Len);
+int checkUTF8(unsigned char * Msg, int Len, unsigned char * out);
+void DoTermResize(Ui_ListenSession * Sess);
+void DecodeTeleText(Ui_ListenSession * Sess, char * page);
+
+int Bells = TRUE;
+int StripLF = FALSE;
+int LogOutput = FALSE;
+int SendDisconnected = TRUE;
+int ChatMode = TRUE;
+int AutoTeletext = 1;
+
+int MonPorts = 1;
+int ListenOn = FALSE;
+
+time_t LastWrite = 0xffffffff;
+int AlertInterval = 300;
+int AlertBeep = TRUE;
+int AlertFreq = 600;
+int AlertDuration = 250;
+TCHAR AlertFileName[256] = { 0 };
+int ConnectBeep = TRUE;
+int UseKeywords = TRUE;
+
+QString KeyWordsFile = "Keywords.sys";
+
+char ** KeyWords = NULL;
+int NumberofKeyWords = 0;
+
+
+// YAPP stuff
+
+#define SOH 1
+#define STX 2
+#define ETX 3
+#define EOT 4
+#define ENQ 5
+#define ACK 6
+#define DLE	0x10
+#define NAK 0x15
+#define CAN 0x18
+
+#define YAPPTX	32768					// Sending YAPP file
+
+int MaxRXSize = 100000;
+char BaseDir[256] = "";
+
+unsigned char InputBuffer[1024];
+
+char  YAPPPath[MAX_PATH] = "";	// Path for saving YAPP Files
+
+int paclen = 128;
+
+int InputLen;				// Data we have already = Offset of end of an incomplete packet;
+
+unsigned char * MailBuffer;			// Yapp Message being received
+int MailBufferSize;
+int YAPPLen;				// Bytes sent/received of YAPP Message
+long YAPPDate;				// Date for received file - if set enables YAPPC
+char ARQFilename[200];		// Filename from YAPP Header
+
+unsigned char SavedData[8192];		// Max receive is 4096 is should never get more that 8k
+int SaveLen = 0;
+
+void YAPPSendData(Ui_ListenSession * Sess);
+
+
+char * strlop(char * buf, char delim)
+{
+	// Terminate buf at delim, and return rest of string
+
+	char * ptr = strchr(buf, delim);
+
+	if (ptr == NULL) return NULL;
+
+	*(ptr)++ = 0;
+
+	return ptr;
+}
+
+#ifdef WIN32
+
+char * strcasestr(char *ch1, char *ch2)
+{
+	char	*chN1, *chN2;
+	char	*chNdx;
+	char	*chRet = NULL;
+
+	chN1 = _strdup(ch1);
+	chN2 = _strdup(ch2);
+
+	if (chN1 && chN2)
+	{
+		chNdx = chN1;
+		while (*chNdx)
+		{
+			*chNdx = (char)tolower(*chNdx);
+			chNdx++;
+		}
+		chNdx = chN2;
+
+		while (*chNdx)
+		{
+			*chNdx = (char)tolower(*chNdx);
+			chNdx++;
+		}
+
+		chNdx = strstr(chN1, chN2);
+
+		if (chNdx)
+			chRet = ch1 + (chNdx - chN1);
+	}
+
+	free(chN1);
+	free(chN2);
+	return chRet;
+}
+
+#endif
+
+void GetKeyWordFile()
+{
+	DWORD FileSize;
+	char * ptr1, *ptr2;
+	char * KeyWordFile;
+
+	QFile file(KeyWordsFile);
+	
+	if (!file.open(QIODevice::ReadOnly))
+	{
+		if (UseKeywords)				// Don't need to alert if not being used
+		{
+			QMessageBox msgBox;
+			msgBox.setText("Keyword File " + KeyWordsFile + " not found");
+			msgBox.exec();
+		}
+		return;
+	}
+
+	FileSize = file.size();
+
+	KeyWordFile = (char *)malloc(FileSize + 1);
+
+	file.read(KeyWordFile, FileSize);
+
+	file.close();
+
+	KeyWordFile[FileSize] = 0;
+ 
+	ptr1 = KeyWordFile;
+
+	while (ptr1)
+	{
+		if (*ptr1 == '\n') ptr1++;
+
+		ptr2 = strtok_s(NULL, "\r\n", &ptr1);
+		if (ptr2)
+		{
+			if (*ptr2 != '#')
+			{
+				KeyWords = (char **)realloc(KeyWords, (++NumberofKeyWords + 1) * 4);
+				KeyWords[NumberofKeyWords] = ptr2;
+			}
+		}
+		else
+			break;
+	}
+}
+
+
+int CheckKeyWord(char * Word, char * Msg)
+{
+	char * ptr1 = Msg, *ptr2;
+	int len = (int)strlen(Word);
+
+	while (*ptr1)					// Stop at end
+	{
+		ptr2 = strcasestr(ptr1, Word);
+
+		if (ptr2 == NULL)
+			return FALSE;				// OK
+
+		// Only bad if it ia not part of a longer word
+
+		if ((ptr2 == Msg) || !(isalpha(*(ptr2 - 1))))	// No alpha before
+			if (!(isalpha(*(ptr2 + len))))			// No alpha after
+				return TRUE;					// Bad word
+
+		// Keep searching
+
+		ptr1 = ptr2 + len;
+	}
+
+	return FALSE;					// OK
+}
+
+int CheckKeyWords(UCHAR * Msg, int len)
+{
+	int i;
+
+	if (UseKeywords == 0 || NumberofKeyWords == 0)
+		return FALSE;
+
+	// we need to null terminate Msg, so create a copy
+
+	unsigned char * copy = (unsigned char *)malloc(len + 1);
+
+	memcpy(copy, Msg, len);
+	copy[len] = 0;
+
+	for (i = 1; i <= NumberofKeyWords; i++)
+	{
+		if (CheckKeyWord(KeyWords[i], (char *)copy))
+		{
+			myBeep(&AlertWAV);
+			free (copy);
+			return TRUE;			// Alert
+		}
+	}
+
+	free(copy);
+	return FALSE;					// OK
+
+}
+
+
+void ProcessReceivedData(Ui_ListenSession * Sess, unsigned char * Buffer, int len)
+{
+	int MonLen = 0;
+	unsigned char * ptr;
+	unsigned char * Buffptr;
+	unsigned char * FEptr = 0;
+
+	if (Sess->InputMode == 'Y')			// Yapp
+	{
+		ProcessYAPPMessage(Sess, Buffer, len);
+		return;
+	}
+
+	// See if Teletext data
+
+			// We need to identify a viewdata frame. Seems to start
+
+		//1e 0a 0a 0a 0a 0a 0a 0a  0a 0a 0a 0a 0a 0a 0a 0a   ........ ........
+			//00000170  0a 0a 0a 0a 0a 0a 0a 0a  11 0c 1b
+
+		// Page seems to start 1c
+
+		// After page get 
+
+		//1e 0a 0a 0a 0a 0a 0a 0a  0a 0a 0a 0a 0a 0a 0a 0a   ........ ........
+		//	0000049D  0a 0a 0a 0a 0a 0a 0a 0a  11 14 1b 44 1b 5d 1b 43   ........ ...D.].C
+		//	000004AD  53 65 6c 65                                        Sele
+		//	000004B1  63 74 20 69 74 65 6d 20  6f 72 1b 47 2a 70 61 67   ct item or .G*pag
+		//	000004C1  65 5f 20 3a 20 20 20 20  20 20 20 20 20 20 20 20   e_ :
+		//	000004D1  20 0d 09 09 09 09 09 09  09 09 09 09 09 09 09 09    ....... ........
+		//	000004E1  09 09 09 09 09 09 09 09  09 09 09 09 09 11
+
+	Buffer[len] = 0;
+
+	if (AutoTeletext && (Buffer[0] == 0x1e || Buffer[0] == 0x0c))
+	{
+		if (Sess->TTActive == 0)
+		{
+			Sess->TTActive = 1;
+			DoTermResize(Sess);
+		}
+	}
+
+	if (Sess->TTActive)
+	{
+		// Feed to Teletext code
+
+		// We need to decode a whole page. There is no obvious delimiter so process till data stops.
+		// Buffer is cleared when next input is sent
+
+		if (strlen(&Sess->pageBuffer[0] + len) > 4090)
+			Sess->pageBuffer[0] = 0;							// Protect buffer
+
+		strcat(Sess->pageBuffer, (char *)Buffer);
+
+		DecodeTeleText(Sess, (char *)Sess->pageBuffer);			// Re-decode same data until we get the end
+		return;
+	}
+
+
+
+	//	mbstowcs(Buffer, BufferB, len);
+
+	// Look for MON delimiters (FF/FE)
+
+
+	Buffptr = Buffer;
+
+	if (Sess->MonData)
+	{
+		// Already in MON State
+
+		FEptr = (UCHAR *)memchr(Buffptr, 0xfe, len);
+
+		if (!FEptr)
+		{
+			// no FE - so send all to monitor
+
+			WritetoMonWindow(Sess, Buffer, len);
+			return;
+		}
+
+		Sess->MonData = FALSE;
+
+		MonLen = FEptr - Buffptr;		// Mon Data, Excluding the FE
+
+		WritetoMonWindow(Sess, Buffptr, MonLen);
+
+		Buffptr = ++FEptr;				// Char following FE
+
+		if (++MonLen < len)
+		{
+			len -= MonLen;
+			goto MonLoop;				// See if next in MON or Data
+		}
+
+		// Nothing Left
+
+		return;
+	}
+
+MonLoop:
+
+	ptr = (UCHAR *)memchr(Buffptr, 0xff, len);
+
+	if (ptr)
+	{
+		unsigned char telcmd[] = "\xff\xfb\x03\xff\xfb\x01";
+
+		// Try to trap connect to normal Telnet Port
+
+		if (memcmp(ptr, telcmd, 6) == 0)
+			return;
+
+		// Buffer contains Mon Data
+
+		if (ptr > Buffptr)
+		{
+			// Some Normal Data before the FF
+
+			int NormLen = ptr - Buffptr;				// Before the FF
+
+			if (NormLen == 1 && Buffptr[0] == 0)
+			{
+				// Keepalive
+			}
+
+			else
+			{
+				CheckKeyWords(Buffptr, NormLen);
+				WritetoOutputWindow(Sess, Buffptr, NormLen);
+			}
+
+			len -= NormLen;
+			Buffptr = ptr;
+			goto MonLoop;
+		}
+
+		if (ptr[1] == 0xff)
+		{
+			// Port Definition String
+
+			int NumberofPorts = atoi((char *)&ptr[2]);
+			char *p, *Context;
+			int i = 1;
+			TCHAR msg[80];
+			int portnum;
+			char delim[] = "|";
+			int m;
+
+			// Save for changes of Window
+
+			if (len < 2048)
+				memcpy(Sess->PortMonString, ptr, len);
+
+			
+			// Remove old menu
+			
+			for (i = 0; i < 65; i++)
+			{
+				SetPortMonLine(i, (char *)"", 0, 0);
+			}
+
+			p = strtok_s((char *)&ptr[2], delim, &Context);
+
+			while (NumberofPorts--)
+			{
+				p = strtok_s(NULL, delim, &Context);
+				if (p == NULL)
+					break;
+
+				m = portnum = atoi(p);
+				sprintf(msg, "Port %s", p);
+
+				if (m == 0)
+					m = 64;
+
+				if (Sess->portmask & (1ll << (m - 1)))
+					SetPortMonLine(portnum, msg, 1, 1);
+				else
+					SetPortMonLine(portnum, msg, 1, 0);
+			}
+			return;
+		}
+
+		MonLen = len;				// in case no fe
+
+		Sess->MonData = 1;
+
+		FEptr = (UCHAR *)memchr(Buffptr, 0xfe, len);
+
+		if (FEptr)
+		{
+			Sess->MonData = 0;
+
+			MonLen = FEptr + 1 - Buffptr;				// MonLen includes FF and FE
+
+			WritetoMonWindow(Sess, Buffptr + 1, MonLen - 2);
+
+			len -= MonLen;
+			Buffptr += MonLen;							// Char Following FE
+
+			if (len <= 0)
+			{
+				return;
+			}
+			goto MonLoop;
+		}
+		else
+		{
+			// No FE, so rest of buffer is MON Data
+
+			if (MonLen)
+				WritetoMonWindow(Sess, Buffptr + 1, MonLen - 1);
+			return;
+		}
+	}
+
+	// No FF, so must be session data
+
+	if (Sess->InputMode == 'Y')			// Yapp
+	{
+		ProcessYAPPMessage(Sess, Buffer, len);
+		return;
+	}
+
+
+	if (len == 1 && Buffptr[0] == 0)
+		return;							// Keepalive
+
+	// Could be a YAPP Header
+
+	if (len == 2 && Buffptr[0] == ENQ && Buffptr[1] == 1)		// YAPP Send_Init
+	{
+		char YAPPRR[2];
+
+		// Turn off monitoring
+
+		setTraceOff(Sess);
+		
+		Sess->InputMode = 'Y';
+
+		YAPPRR[0] = ACK;
+		YAPPRR[1] = 1;
+
+		SocketFlush(Sess);			// To give Monitor Msg time to be sent
+		mySleep(1000);
+		QueueMsg(Sess, YAPPRR, 2);
+
+		return;
+	}
+	// Check UTF8
+	{
+		CheckKeyWords(Buffptr, len);
+		WritetoOutputWindow(Sess, Buffptr, len);
+	}
+	Sess->SlowTimer = 0;
+	return;
+}
+
+extern myTcpSocket * VARASock;
+extern myTcpSocket * VARADataSock;
+extern "C" void SendtoAX25(void * conn, unsigned char * Msg, int Len);
+
+int SendMsg(Ui_ListenSession * Sess, TCHAR * Buffer, int len)
+{
+	if (Sess->KISSSession)
+	{
+		// Send to ax.25 code
+
+		SendtoAX25(Sess->KISSSession, (unsigned char *)Buffer, len);
+		return len;
+	}
+	else if (Sess->AGWSession)
+	{
+		// Terminal is in AGWPE mode - send as AGW frame
+
+		AGW_AX25_data_in(Sess->AGWSession, (unsigned char *)Buffer, len);
+		return len;
+	}
+	else if (VARASock && VARASock->Sess == Sess)
+	{
+		VARADataSock->write(Buffer, len);
+		return len;
+	}
+
+	return SocketSend(Sess, Buffer, len);
+}
+
+
+
+void QueueMsg(Ui_ListenSession * Sess, char * Msg, int len)
+{
+	int Sent = SendMsg(Sess, Msg, len);
+
+	if (Sent != len)
+		Sent = 0;
+}
+
+int InnerProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len);
+
+int ProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len)
+{
+	// may have saved data
+
+	memcpy(&SavedData[SaveLen], Msg, Len);
+
+	SaveLen += Len;
+
+	while (SaveLen && Sess->InputMode == 'Y')
+	{
+		int Used = InnerProcessYAPPMessage(Sess, SavedData, SaveLen);
+
+		if (Used == 0)
+			return 0;			// Waiting for more
+
+		SaveLen -= Used;
+
+		if (SaveLen)
+			memmove(SavedData, &SavedData[Used], SaveLen);
+	}
+	return 0;
+}
+
+extern int VARAEnable;
+
+int InnerProcessYAPPMessage(Ui_ListenSession * Sess, UCHAR * Msg, int Len)
+{
+	int pktLen = Msg[1];
+	char Reply[2] = { ACK };
+	size_t NameLen, SizeLen, OptLen;
+	char * ptr;
+	int FileSize;
+	WCHAR MsgFile[MAX_PATH];
+	FILE * hFile;
+	char Mess[255];
+	int len;
+	UCHAR Buffer[2000];
+	struct stat STAT;
+
+	switch (Msg[0])
+	{
+	case ENQ: // YAPP Send_Init
+
+		// Shouldn't occur in session. Reset state and process
+
+		if (MailBuffer)
+		{
+			free(MailBuffer);
+			MailBufferSize = 0;
+			MailBuffer = 0;
+		}
+
+		Mess[0] = ACK;
+		Mess[1] = 1;
+
+		Sess->InputMode = 'Y';
+		QueueMsg(Sess, Mess, 2);
+
+		// Turn off monitoring
+
+		mySleep(1000);				// To give YAPP Msg time to be sent
+
+		setTraceOff(Sess);
+
+		return Len;
+
+	case SOH:
+
+		// HD Send_Hdr     SOH  len  (Filename)  NUL  (File Size in ASCII)  NUL (Opt) 
+
+		// YAPPC has date/time in dos format
+
+		if (Len < Msg[1] + 1)
+			return 0;				// Wait till we have it all
+
+		NameLen = strlen((char *)&Msg[2]);
+		strcpy(ARQFilename, (char *)&Msg[2]);
+
+		ptr = (char *)&Msg[3 + NameLen];
+		SizeLen = strlen(ptr);
+		FileSize = atoi(ptr);
+
+		OptLen = pktLen - (NameLen + SizeLen + 2);
+
+		YAPPDate = 0;
+
+		if (OptLen >= 8)		// We have a Date/Time for YAPPC
+		{
+			ptr = ptr + SizeLen + 1;
+			YAPPDate = strtol(ptr, NULL, 16);
+		}
+
+		// Check Size
+
+		if (FileSize > MaxRXSize && VARAEnable == 0)
+		{
+			Mess[0] = NAK;
+			Mess[1] = sprintf(&Mess[2], "File %s size %d larger than limit %d\r", ARQFilename, FileSize, MaxRXSize);
+			mySleep(1000);				// To give YAPP Msg time to be sent
+			QueueMsg(Sess, Mess, Mess[1] + 2);
+
+			len = sprintf((char *)Buffer, "YAPP File %s size %d larger than limit %d\r", ARQFilename, FileSize, MaxRXSize);
+			WritetoOutputWindow(Sess, Buffer, len);
+
+			Sess->InputMode = 0;
+			SendTraceOptions(Sess);
+
+			return Len;
+		}
+
+		// Check that Path is set
+
+		if (YAPPPath[0] == 0)
+		{
+			Mess[0] = NAK;
+			Mess[1] = sprintf(&Mess[2], "%s", "YAPP Receive directory not set");
+			mySleep(1000);				// To give YAPP Msg time to be sent
+			QueueMsg(Sess, Mess, Mess[1] + 2);
+			len = sprintf((char *)Buffer, "YAPP File Receive Failed - YAPP Receive directory not set\r");
+			WritetoOutputWindow(Sess, Buffer, len);
+
+			Sess->InputMode = 0;
+			SendTraceOptions(Sess);
+
+			return Len;
+		}
+
+		// Make sure file does not exist
+
+		sprintf(MsgFile, "%s/%s", YAPPPath, ARQFilename);
+
+		if (stat(MsgFile, &STAT) == 0)
+		{
+			FileSize = STAT.st_size;
+
+			Mess[0] = NAK;
+			Mess[1] = sprintf(&Mess[2], "%s", "File Already Exists");
+			mySleep(1000);				// To give YAPP Msg time to be sent
+			QueueMsg(Sess, Mess, Mess[1] + 2);
+			len = sprintf((char *)Buffer, "YAPP File Receive Failed - %s already exists\r", MsgFile);
+			WritetoOutputWindow(Sess, Buffer, len);
+
+			Sess->InputMode = 0;
+			SendTraceOptions(Sess);
+
+			return Len;
+		}
+
+
+		MailBufferSize = FileSize;
+		MailBuffer = (UCHAR *)malloc(FileSize);
+		YAPPLen = 0;
+
+		if (YAPPDate)			// If present use YAPPC
+			Reply[1] = ACK;			//Receive_TPK
+		else
+			Reply[1] = 2;			//Rcv_File
+
+		QueueMsg(Sess, Reply, 2);
+
+		len = sprintf((char *)Buffer, "YAPP Receving File %s size %d\r", ARQFilename, FileSize);
+		WritetoOutputWindow(Sess, Buffer, len);
+
+		return Len;
+
+	case STX:
+
+		// Data Packet
+
+		// Check we have it all
+
+		if (YAPPDate)			// If present use YAPPC so have checksum
+		{
+			if (pktLen > (Len - 3))		// -2 for header and checksum
+				return 0;				// Wait for rest
+		}
+		else
+		{
+			if (pktLen > (Len - 2))		// -2 for header
+				return 0;				// Wait for rest
+		}
+
+		// Save data and remove from buffer
+
+		// if YAPPC check checksum
+
+		if (YAPPDate)
+		{
+			UCHAR Sum = 0;
+			int i;
+			UCHAR * uptr = &Msg[2];
+
+			i = pktLen;
+
+			while (i--)
+				Sum += *(uptr++);
+
+			if (Sum != *uptr)
+			{
+				// Checksum Error
+
+				Mess[0] = CAN;
+				Mess[1] = sprintf(&Mess[2], "YAPPC Checksum Error");
+				QueueMsg(Sess, Mess, Mess[1] + 2);
+
+				len = sprintf((char *)Buffer, "YAPPC Checksum Error on file %s\r", MsgFile);
+				WritetoOutputWindow(Sess, Buffer, len);
+
+				Sess->InputMode = 0;
+				SendTraceOptions(Sess);
+				return Len;
+			}
+		}
+
+		if ((YAPPLen) + pktLen > MailBufferSize)
+		{
+			// Too Big ??
+
+			Mess[0] = CAN;
+			Mess[1] = sprintf(&Mess[2], "YAPP Too much data received");
+			QueueMsg(Sess, Mess, Mess[1] + 2);
+
+			len = sprintf((char *)Buffer, "YAPP Too much data received on file %s\r", MsgFile);
+			WritetoOutputWindow(Sess, Buffer, len);
+
+			Sess->InputMode = 0;
+			SendTraceOptions(Sess);
+			return Len;
+		}
+
+
+		memcpy(&MailBuffer[YAPPLen], &Msg[2], pktLen);
+		YAPPLen += pktLen;
+
+		if (YAPPDate)
+			++pktLen;				// Add Checksum
+
+//		if (YAPPLen == MailBufferSize)
+//			pktLen = pktLen;
+
+		return pktLen + 2;
+
+	case ETX:
+
+		// End Data
+
+		if (YAPPLen == MailBufferSize)
+		{
+			// All received
+
+			int Written = 0;
+
+			sprintf(MsgFile, "%s/%s", YAPPPath, ARQFilename);
+
+			hFile = fopen(MsgFile, "wb");
+
+			if (hFile)
+			{
+				Written = (int)fwrite(MailBuffer, 1, YAPPLen, hFile);
+				fclose(hFile);
+
+				if (YAPPDate)
+				{
+//					struct tm TM;
+//					struct timeval times[2];
+					/*
+										The MS-DOS date. The date is a packed value with the following format.
+
+										cant use DosDateTimeToFileTime on Linux
+
+										Bits	Description
+										0-4	Day of the month (131)
+										5-8	Month (1 = January, 2 = February, and so on)
+										9-15	Year offset from 1980 (add 1980 to get actual year)
+										wFatTime
+										The MS-DOS time. The time is a packed value with the following format.
+										Bits	Description
+										0-4	Second divided by 2
+										5-10	Minute (059)
+										11-15	Hour (023 on a 24-hour clock)
+					*/
+					/*
+				
+					memset(&TM, 0, sizeof(TM));
+
+					TM.tm_sec = (YAPPDate & 0x1f) << 1;
+					TM.tm_min = ((YAPPDate >> 5) & 0x3f);
+					TM.tm_hour = ((YAPPDate >> 11) & 0x1f);
+
+					TM.tm_mday = ((YAPPDate >> 16) & 0x1f);
+					TM.tm_mon = ((YAPPDate >> 21) & 0xf) - 1;
+					TM.tm_year = ((YAPPDate >> 25) & 0x7f) + 80;
+
+					Debugprintf("%d %d %d %d %d %d", TM.tm_year, TM.tm_mon, TM.tm_mday, TM.tm_hour, TM.tm_min, TM.tm_sec);
+
+					times[0].tv_sec = times[1].tv_sec = mktime(&TM);
+					times[0].tv_usec = times[1].tv_usec = 0;
+						*/
+				}
+			}
+
+
+			free(MailBuffer);
+			MailBufferSize = 0;
+			MailBuffer = 0;
+
+			if (Written != YAPPLen)
+			{
+				Mess[0] = CAN;
+				Mess[1] = sprintf(&Mess[2], "Failed to save YAPP File");
+				QueueMsg(Sess, Mess, Mess[1] + 2);
+
+				len = sprintf((char *)Buffer, "Failed to save YAPP File %s\r", MsgFile);
+				WritetoOutputWindow(Sess, Buffer, len);
+
+				Sess->InputMode = 0;
+				SendTraceOptions(Sess);
+			}
+		}
+
+		Reply[1] = 3;		//Ack_EOF
+		QueueMsg(Sess, Reply, 2);
+
+		len = sprintf((char *)Buffer, "Reception of file %s complete\r", MsgFile);
+		WritetoOutputWindow(Sess, Buffer, len);
+
+		return Len;
+
+	case EOT:
+
+		// End Session
+
+		Reply[1] = 4;		// Ack_EOT
+		QueueMsg(Sess, Reply, 2);
+		SocketFlush(Sess);
+		Sess->InputMode = 0;
+
+		SendTraceOptions(Sess);
+		return Len;
+
+	case CAN:
+
+		// Abort
+
+		Mess[0] = ACK;
+		Mess[1] = 5;			// CAN Ack
+		QueueMsg(Sess, Mess, 2);
+
+		if (MailBuffer)
+		{
+			free(MailBuffer);
+			MailBufferSize = 0;
+			MailBuffer = 0;
+		}
+
+		// May have an error message
+
+		len = Msg[1];
+
+		if (len)
+		{
+			len = sprintf((char *)Buffer, "YAPP Transfer cancelled - %s\r", &Msg[2]);
+		}
+		else
+			len = sprintf(Mess, "YAPP Transfer cancelled\r");
+
+		Sess->InputMode = 0;
+		SendTraceOptions(Sess);
+
+		return Len;
+
+	case ACK:
+
+		switch (Msg[1])
+		{
+			char * ptr;
+
+		case 1:					// Rcv_Rdy
+
+			// HD Send_Hdr     SOH  len  (Filename)  NUL  (File Size in ASCII)  NUL (Opt)
+
+			// Remote only needs filename so remove path
+
+			ptr = ARQFilename;
+
+			while (strchr(ptr, '/'))
+				ptr = strchr(ptr, '/') + 1;
+
+			len = (int)strlen(ptr) + 3;
+
+			strcpy(&Mess[2], ptr);
+			len += sprintf(&Mess[len], "%d", MailBufferSize);
+			len++;					// include null
+//			len += sprintf(&Mess[len], "%8X", YAPPDate);
+//			len++;					// include null
+			Mess[0] = SOH;
+			Mess[1] = len - 2;
+
+			QueueMsg(Sess, Mess, len);
+
+			return Len;
+
+		case 2:
+
+			YAPPDate = 0;				// Switch to Normal (No Checksum) Mode
+
+			// Drop through
+
+		case 6:							// Send using YAPPC
+
+			//	Start sending message
+
+			YAPPSendData(Sess);
+			return Len;
+
+		case 3:
+
+			// ACK EOF - Send EOT
+
+			Mess[0] = EOT;
+			Mess[1] = 1;
+			QueueMsg(Sess, Mess, 2);
+
+			return Len;
+
+		case 4:
+
+			// ACK EOT
+
+			Sess->InputMode = 0;
+			SendTraceOptions(Sess);
+
+			len = sprintf((char *)Buffer, "File transfer complete\r");
+			WritetoOutputWindow(Sess, Buffer, len);
+	
+
+			return Len;
+
+		default:
+			return Len;
+
+		}
+
+	case NAK:
+
+		// Either Reject or Restart
+
+		// RE Resume       NAK  len  R  NULL  (File size in ASCII)  NULL
+
+		if (Len > 2 && Msg[2] == 'R' && Msg[3] == 0)
+		{
+			int posn = atoi((char *)&Msg[4]);
+
+			YAPPLen += posn;
+			MailBufferSize -= posn;
+
+			YAPPSendData(Sess);
+			return Len;
+
+		}
+
+		// May have an error message
+
+		len = Msg[1];
+
+		if (len)
+		{
+			char ws[256];
+
+			Msg[len + 2] = 0;
+
+			strcpy(ws, (char *)&Msg[2]);
+
+			len = sprintf((char *)Buffer, "File rejected - %s\r", ws);
+		}
+		else
+			len = sprintf((char *)Buffer, "File rejected\r");
+
+		WritetoOutputWindow(Sess, Buffer, len);
+	
+
+		Sess->InputMode = 0;
+		SendTraceOptions(Sess);
+
+		return Len;
+
+	}
+
+	len = sprintf((char *)Buffer, "Unexpected message during YAPP Transfer. Transfer cancelled\r");
+	WritetoOutputWindow(Sess, Buffer, len);
+	
+	Sess->InputMode = 0;
+	SendTraceOptions(Sess);
+
+	return Len;
+
+}
+
+void YAPPSendFile(Ui_ListenSession * Sess, WCHAR * FN)
+{
+	int FileSize = 0;
+	char MsgFile[MAX_PATH];
+	FILE * hFile;
+	struct stat STAT;
+	UCHAR Buffer[2000];
+	int Len;
+
+	strcpy(MsgFile, FN);
+
+	if (MsgFile[0] == 0)
+	{
+		Len = sprintf((char *)Buffer, "Filename missing\r");
+		WritetoOutputWindow(Sess, Buffer, Len);
+	
+		SendTraceOptions(Sess);
+
+		return;
+	}
+
+	if (stat(MsgFile, &STAT) != -1)
+	{
+		FileSize = STAT.st_size;
+
+		hFile = fopen(MsgFile, "rb");
+
+		if (hFile)
+		{
+			char Mess[255];
+//			time_t UnixTime = STAT.st_mtime;
+
+//			FILETIME ft;
+//			long long ll;
+//			SYSTEMTIME st;
+//			WORD FatDate;
+//			WORD FatTime;
+//			struct tm TM;
+
+			strcpy(ARQFilename, MsgFile);
+
+			if (MailBuffer)
+			{
+				free(MailBuffer);
+				MailBufferSize = 0;
+				MailBuffer = 0;
+			}
+
+			MailBuffer = (UCHAR *)malloc(FileSize);
+			MailBufferSize = FileSize;
+			YAPPLen = 0;
+			fread(MailBuffer, 1, FileSize, hFile);
+
+			// Get Date and Time for YAPPC Mode
+
+/*					The MS-DOS date. The date is a packed value with the following format.
+
+					cant use DosDateTimeToFileTime on Linux
+
+					Bits	Description
+					0-4	Day of the month (131)
+					5-8	Month (1 = January, 2 = February, and so on)
+					9-15	Year offset from 1980 (add 1980 to get actual year)
+					wFatTime
+					The MS-DOS time. The time is a packed value with the following format.
+					Bits	Description
+					0-4	Second divided by 2
+					5-10	Minute (059)
+					11-15	Hour (023 on a 24-hour clock)
+
+					memset(&TM, 0, sizeof(TM));
+
+					TM.tm_sec = (YAPPDate & 0x1f) << 1;
+					TM.tm_min = ((YAPPDate >> 5) & 0x3f);
+					TM.tm_hour =  ((YAPPDate >> 11) & 0x1f);
+
+					TM.tm_mday =  ((YAPPDate >> 16) & 0x1f);
+					TM.tm_mon =  ((YAPPDate >> 21) & 0xf) - 1;
+					TM.tm_year = ((YAPPDate >> 25) & 0x7f) + 80;
+
+
+// Note that LONGLONG is a 64-bit value
+
+			ll = Int32x32To64(UnixTime, 10000000) + 116444736000000000;
+			ft.dwLowDateTime = (DWORD)ll;
+			ll >>= 32;
+			ft.dwHighDateTime = (DWORD)ll;
+
+			FileTimeToSystemTime(&ft, &st);
+			FileTimeToDosDateTime(&ft, &FatDate, &FatTime);
+
+			YAPPDate = (FatDate << 16) + FatTime;
+
+			memset(&TM, 0, sizeof(TM));
+
+			TM.tm_sec = (YAPPDate & 0x1f) << 1;
+			TM.tm_min = ((YAPPDate >> 5) & 0x3f);
+			TM.tm_hour = ((YAPPDate >> 11) & 0x1f);
+
+			TM.tm_mday = ((YAPPDate >> 16) & 0x1f);
+			TM.tm_mon = ((YAPPDate >> 21) & 0xf) - 1;
+			TM.tm_year = ((YAPPDate >> 25) & 0x7f) + 80;
+*/
+			fclose(hFile);
+
+			Mess[0] = ENQ;
+			Mess[1] = 1;
+
+			QueueMsg(Sess, Mess, 2);
+			Sess->InputMode = 'Y';
+
+			Len = sprintf((char *)Buffer, "Sending File %s ...\r", FN);
+			WritetoOutputWindow(Sess, Buffer, Len);
+
+			return;
+		}
+	}
+
+	Len = sprintf((char *)Buffer, "File %s not found\r", FN);
+	WritetoOutputWindow(Sess, Buffer, Len);
+
+}
+
+void YAPPSendData(Ui_ListenSession * Sess)
+{
+	char Mess[258];
+
+	while (1)
+	{
+		int Left = MailBufferSize;
+
+		if (Left == 0)
+		{
+			// Finished - send End Data
+
+			Mess[0] = ETX;
+			Mess[1] = 1;
+
+			QueueMsg(Sess, Mess, 2);
+
+			break;
+		}
+
+		if (Left > paclen - 3)		// two bytes header and possible checksum
+			Left = paclen - 3;
+
+		memcpy(&Mess[2], &MailBuffer[YAPPLen], Left);
+
+		YAPPLen += Left;
+		MailBufferSize -= Left;
+
+		// if YAPPC add checksum
+
+		if (YAPPDate)
+		{
+			UCHAR Sum = 0;
+			int i;
+			UCHAR * uptr = (UCHAR *)&Mess[2];
+
+			i = Left;
+
+			while (i--)
+				Sum += *(uptr++);
+
+			*(uptr) = Sum;
+
+			Mess[0] = STX;
+			Mess[1] = Left;
+
+			QueueMsg(Sess, Mess, Left + 3);
+		}
+		else
+		{
+			Mess[0] = STX;
+			Mess[1] = Left;
+
+			QueueMsg(Sess, Mess, Left + 2);
+		}
+	}
+}
+
--- qttermtcp-0.0.0.79.orig/UZ7HOUtils.c
+++ qttermtcp-0.0.0.79/UZ7HOUtils.c
@@ -1,320 +1,320 @@
-/*
-Copyright (C) 2019-2020 Andrei Kopanchuk UZ7HO
-
-This file is part of QtSoundModem
-
-QtSoundModem is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-QtSoundModem is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with QtSoundModem.  If not, see http://www.gnu.org/licenses
-
-*/
-
-// UZ7HO Soundmodem Port by John Wiseman G8BPQ
-#include "ax25.h"
-
-// TStringlist And String emulation Functions
-
-// Dephi seems to mix starting counts at 0 or 1. I'll try making everything
-// base zero. 
-
-// Initialise a list
-
-void CreateStringList(TStringList * List)
-{
-	List->Count = 0;
-	List->Items = 0;
-}
-
-
-int Count(TStringList * List)
-{
-	return List->Count;
-}
-
-string * newString()
-{
-	// Creates and Initialises a string 
-
-	UCHAR * ptr = malloc(sizeof(string));			// Malloc Data separately so it can be ralloc'ed
-	string * New = (string *)ptr;
-	New->Length = 0;
-	New->AllocatedLength = 256;
-	New->Data = malloc(256);
-
-	return New;
-}
-
-void initString(string * S)
-{
-	S->Length = 0;
-	S->AllocatedLength = 256;
-	S->Data = malloc(256);
-}
-
-void initTStringList(TStringList* T)
-{
-	//string * New = newString();
-
-	T->Count = 0;
-	T->Items = NULL;
-
-	//Add(T, New);
-}
-
-
-
-TStringList * newTStringList()
-{
-	TStringList * T = (TStringList *) malloc(sizeof(TStringList));
-	string * New = newString();
-
-	T->Count = 0;
-	T->Items = NULL;
-
-	Add(T, New);
-
-	return T;
-}
-
-
-void freeString(string * Msg)
-{
-	if (Msg->Data)
-		free(Msg->Data);
-
-	free(Msg);
-}
-
-string * Strings(TStringList * Q, int Index)
-{
-	if (Index >= Q->Count)
-		return NULL;
-
-	return Q->Items[Index];
-}
-
-int Add(TStringList * Q, string * Entry)
-{
-	Q->Items = realloc(Q->Items,(Q->Count + 1) * sizeof(void *));
-	Q->Items[Q->Count++] = Entry;
-
-	return (Q->Count);
-}
-
-
-void mydelete(string * Source, int StartChar, int Count)
-{
-	 //Description
-	//The Delete procedure deletes up to Count characters from the passed parameter Source string starting
-	//from position StartChar.
-
-	if (StartChar > Source->Length)
-		return;
-
-	int left = Source->Length - StartChar;
-
-	if (Count > left)
-		Count = left;
-
-	memmove(&Source->Data[StartChar], &Source->Data[StartChar + Count], left - Count);
-
-	Source->Length -= Count;
-}
- 
-
-void Delete(TStringList * Q, int Index)
-{
-	// Remove item at Index and move rest up list
-	// Index starts at zero
-	
-	if (Index >= Q->Count)
-		return;
-
-	// We should free it, so user must duplicate msg if needed after delete
-
-	freeString(Q->Items[Index]);
-
-	Q->Count--;
-
-	while (Index < Q->Count)
-	{
-		Q->Items[Index] = Q->Items[Index + 1];
-		Index++;
-	}
-}
-
-void setlength(string * Msg, int Count)
-{
-	// Set length, allocating more space if needed
-
-	if (Count > Msg->AllocatedLength)
-	{
-		Msg->AllocatedLength = Count + 256;
-		Msg->Data = realloc(Msg->Data, Msg->AllocatedLength);
-	}
-
-	Msg->Length = Count;
-}
-
-string * stringAdd(string * Msg, UCHAR * Chars, int Count)
-{
-	// Add Chars to string 
-
-	if (Msg->Length + Count > Msg->AllocatedLength)
-	{
-		Msg->AllocatedLength += Count + 256;
-		Msg->Data = realloc(Msg->Data, Msg->AllocatedLength);
-	}
-
-	memcpy(&Msg->Data[Msg->Length], Chars, Count);
-	Msg->Length += Count;
-	
-	return Msg;
-}
-
-void Clear(TStringList * Q)
-{
-	int i = 0;
-
-	if (Q->Items == NULL)
-		return;
-
-	while (Q->Count)
-	{
-		freeString(Q->Items[i++]);
-		Q->Count--;
-	}
-
-	free(Q->Items);
-
-	Q->Items = NULL;
-}
-
-// procedure move ( const SourcePointer; var DestinationPointer; CopyCount : Integer ) ;
-// Description
-// The move procedure is a badly named method of copying a section of memory from one place to another.
- 
-// CopyCount bytes are copied from storage referenced by SourcePointer and written to DestinationPointer
- 
-void move(UCHAR * SourcePointer, UCHAR * DestinationPointer, int CopyCount)
-{
-	memmove(DestinationPointer, SourcePointer, CopyCount);
-}
-
-void fmove(float * SourcePointer, float * DestinationPointer, int CopyCount)
-{
-	memmove(DestinationPointer, SourcePointer, CopyCount);
-}
-
-
-
-//Description
-//The copy function has 2 forms. In the first, it creates a new string from part of an existing string. In the second, it creates a new array from part of an existing array.
- 
-//1.String copy
- 
-//The first character of a string has index = 1.
-
-//Up to Count characters are copied from the StartChar of the Source string to the returned string.
-//Less than Count characters if the end of the Source string is encountered before Count characters have been copied.
-
-
-string * copy(string * Source, int StartChar, int Count)
-{
-	string * NewString = newString();
-	int end = StartChar + Count;
-
-	if (end > Source->Length)
-		Count = Source->Length - StartChar;
-
-	memcpy(NewString->Data, &Source->Data[StartChar], Count);
-
-	NewString->Length = Count;
-
-	return NewString;
-}
-
-// Duplicate from > to
-
-void Assign(TStringList * to, TStringList * from)
-{
-	int i;
-
-	Clear(to);
-
-	if (from->Count == 0)
-		return;
-
-	// Duplicate each item
-
-	for (i = 0; i < from->Count; i++)
-	{
-		string * new = newString();
-
-		stringAdd(new, from->Items[i]->Data, from->Items[i]->Length);
-		Add(to, new);
-	}
-}
-
-string * duplicateString(string * in)
-{
-	string * new = newString();
-
-	stringAdd(new, in->Data, in->Length);
-
-	return new;
-}
-
-
-double pila(double x)
-{
-	//x : = frac(x); The frac function returns the fractional part of a floating point number.
-
-	double whole;
-	double rem;
-
-	rem = modf(x, &whole);  // returns fraction, writes whole to whole
-
-	if (rem != rem)
-		rem = 0;
-
-	if (rem > 0.5)
-		rem = 1 - rem;
-
-	return 2 * rem;
-}
-
-boolean compareStrings(string * a, string * b)
-{
-	if (a->Length == b->Length && memcmp(a->Data, b->Data, a->Length) == 0)
-		return TRUE;
-
-	return FALSE;
-}
-
-// This looks for a string in a stringlist. Returns index if found, otherwise -1
-
-int  my_indexof(TStringList * l, string * s)
-{
-	int i;
-
-	for (i = 0; i < l->Count; i++)
-	{
-		// Need to compare count and data - C doesn't allow struct compare
-
-		if (l->Items[i]->Length == s->Length && memcmp(l->Items[i]->Data, s->Data, s->Length) == 0)
-			return i;
-	}
-	return -1;
-}
-
+/*
+Copyright (C) 2019-2020 Andrei Kopanchuk UZ7HO
+
+This file is part of QtSoundModem
+
+QtSoundModem is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+QtSoundModem is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with QtSoundModem.  If not, see http://www.gnu.org/licenses
+
+*/
+
+// UZ7HO Soundmodem Port by John Wiseman G8BPQ
+#include "ax25.h"
+
+// TStringlist And String emulation Functions
+
+// Dephi seems to mix starting counts at 0 or 1. I'll try making everything
+// base zero. 
+
+// Initialise a list
+
+void CreateStringList(TStringList * List)
+{
+	List->Count = 0;
+	List->Items = 0;
+}
+
+
+int Count(TStringList * List)
+{
+	return List->Count;
+}
+
+string * newString()
+{
+	// Creates and Initialises a string 
+
+	UCHAR * ptr = malloc(sizeof(string));			// Malloc Data separately so it can be ralloc'ed
+	string * New = (string *)ptr;
+	New->Length = 0;
+	New->AllocatedLength = 256;
+	New->Data = malloc(256);
+
+	return New;
+}
+
+void initString(string * S)
+{
+	S->Length = 0;
+	S->AllocatedLength = 256;
+	S->Data = malloc(256);
+}
+
+void initTStringList(TStringList* T)
+{
+	//string * New = newString();
+
+	T->Count = 0;
+	T->Items = NULL;
+
+	//Add(T, New);
+}
+
+
+
+TStringList * newTStringList()
+{
+	TStringList * T = (TStringList *) malloc(sizeof(TStringList));
+	string * New = newString();
+
+	T->Count = 0;
+	T->Items = NULL;
+
+	Add(T, New);
+
+	return T;
+}
+
+
+void freeString(string * Msg)
+{
+	if (Msg->Data)
+		free(Msg->Data);
+
+	free(Msg);
+}
+
+string * Strings(TStringList * Q, int Index)
+{
+	if (Index >= Q->Count)
+		return NULL;
+
+	return Q->Items[Index];
+}
+
+int Add(TStringList * Q, string * Entry)
+{
+	Q->Items = realloc(Q->Items,(Q->Count + 1) * sizeof(void *));
+	Q->Items[Q->Count++] = Entry;
+
+	return (Q->Count);
+}
+
+
+void mydelete(string * Source, int StartChar, int Count)
+{
+	 //Description
+	//The Delete procedure deletes up to Count characters from the passed parameter Source string starting
+	//from position StartChar.
+
+	if (StartChar > Source->Length)
+		return;
+
+	int left = Source->Length - StartChar;
+
+	if (Count > left)
+		Count = left;
+
+	memmove(&Source->Data[StartChar], &Source->Data[StartChar + Count], left - Count);
+
+	Source->Length -= Count;
+}
+ 
+
+void Delete(TStringList * Q, int Index)
+{
+	// Remove item at Index and move rest up list
+	// Index starts at zero
+	
+	if (Index >= Q->Count)
+		return;
+
+	// We should free it, so user must duplicate msg if needed after delete
+
+	freeString(Q->Items[Index]);
+
+	Q->Count--;
+
+	while (Index < Q->Count)
+	{
+		Q->Items[Index] = Q->Items[Index + 1];
+		Index++;
+	}
+}
+
+void setlength(string * Msg, int Count)
+{
+	// Set length, allocating more space if needed
+
+	if (Count > Msg->AllocatedLength)
+	{
+		Msg->AllocatedLength = Count + 256;
+		Msg->Data = realloc(Msg->Data, Msg->AllocatedLength);
+	}
+
+	Msg->Length = Count;
+}
+
+string * stringAdd(string * Msg, UCHAR * Chars, int Count)
+{
+	// Add Chars to string 
+
+	if (Msg->Length + Count > Msg->AllocatedLength)
+	{
+		Msg->AllocatedLength += Count + 256;
+		Msg->Data = realloc(Msg->Data, Msg->AllocatedLength);
+	}
+
+	memcpy(&Msg->Data[Msg->Length], Chars, Count);
+	Msg->Length += Count;
+	
+	return Msg;
+}
+
+void Clear(TStringList * Q)
+{
+	int i = 0;
+
+	if (Q->Items == NULL)
+		return;
+
+	while (Q->Count)
+	{
+		freeString(Q->Items[i++]);
+		Q->Count--;
+	}
+
+	free(Q->Items);
+
+	Q->Items = NULL;
+}
+
+// procedure move ( const SourcePointer; var DestinationPointer; CopyCount : Integer ) ;
+// Description
+// The move procedure is a badly named method of copying a section of memory from one place to another.
+ 
+// CopyCount bytes are copied from storage referenced by SourcePointer and written to DestinationPointer
+ 
+void move(UCHAR * SourcePointer, UCHAR * DestinationPointer, int CopyCount)
+{
+	memmove(DestinationPointer, SourcePointer, CopyCount);
+}
+
+void fmove(float * SourcePointer, float * DestinationPointer, int CopyCount)
+{
+	memmove(DestinationPointer, SourcePointer, CopyCount);
+}
+
+
+
+//Description
+//The copy function has 2 forms. In the first, it creates a new string from part of an existing string. In the second, it creates a new array from part of an existing array.
+ 
+//1.String copy
+ 
+//The first character of a string has index = 1.
+
+//Up to Count characters are copied from the StartChar of the Source string to the returned string.
+//Less than Count characters if the end of the Source string is encountered before Count characters have been copied.
+
+
+string * copy(string * Source, int StartChar, int Count)
+{
+	string * NewString = newString();
+	int end = StartChar + Count;
+
+	if (end > Source->Length)
+		Count = Source->Length - StartChar;
+
+	memcpy(NewString->Data, &Source->Data[StartChar], Count);
+
+	NewString->Length = Count;
+
+	return NewString;
+}
+
+// Duplicate from > to
+
+void Assign(TStringList * to, TStringList * from)
+{
+	int i;
+
+	Clear(to);
+
+	if (from->Count == 0)
+		return;
+
+	// Duplicate each item
+
+	for (i = 0; i < from->Count; i++)
+	{
+		string * new = newString();
+
+		stringAdd(new, from->Items[i]->Data, from->Items[i]->Length);
+		Add(to, new);
+	}
+}
+
+string * duplicateString(string * in)
+{
+	string * new = newString();
+
+	stringAdd(new, in->Data, in->Length);
+
+	return new;
+}
+
+
+double pila(double x)
+{
+	//x : = frac(x); The frac function returns the fractional part of a floating point number.
+
+	double whole;
+	double rem;
+
+	rem = modf(x, &whole);  // returns fraction, writes whole to whole
+
+	if (rem != rem)
+		rem = 0;
+
+	if (rem > 0.5)
+		rem = 1 - rem;
+
+	return 2 * rem;
+}
+
+boolean compareStrings(string * a, string * b)
+{
+	if (a->Length == b->Length && memcmp(a->Data, b->Data, a->Length) == 0)
+		return TRUE;
+
+	return FALSE;
+}
+
+// This looks for a string in a stringlist. Returns index if found, otherwise -1
+
+int  my_indexof(TStringList * l, string * s)
+{
+	int i;
+
+	for (i = 0; i < l->Count; i++)
+	{
+		// Need to compare count and data - C doesn't allow struct compare
+
+		if (l->Items[i]->Length == s->Length && memcmp(l->Items[i]->Data, s->Data, s->Length) == 0)
+			return i;
+	}
+	return -1;
+}
+
  
\ No newline at end of file
--- qttermtcp-0.0.0.79.orig/VARA.ui
+++ qttermtcp-0.0.0.79/VARA.ui
@@ -1,148 +1,148 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>AGWConnectDkg</class>
- <widget class="QDialog" name="AGWConnectDkg">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>500</width>
-    <height>400</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Dialog</string>
-  </property>
-  <widget class="QWidget" name="verticalLayoutWidget">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>10</y>
-     <width>480</width>
-     <height>380</height>
-    </rect>
-   </property>
-   <layout class="QVBoxLayout" name="verticalLayout">
-    <item>
-     <layout class="QFormLayout" name="formLayout_2">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label">
-        <property name="text">
-         <string>Call From </string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLineEdit" name="CallFrom"/>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string>Call To </string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QComboBox" name="CallTo">
-        <property name="editable">
-         <bool>true</bool>
-        </property>
-        <property name="insertPolicy">
-         <enum>QComboBox::NoInsert</enum>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QLabel" name="label_3">
-        <property name="text">
-         <string>Digis</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="QLineEdit" name="Digis"/>
-      </item>
-     </layout>
-    </item>
-    <item>
-     <widget class="QLabel" name="label_4">
-      <property name="text">
-       <string>Radio Ports</string>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QListWidget" name="RadioPorts"/>
-    </item>
-    <item>
-     <layout class="QHBoxLayout">
-      <property name="spacing">
-       <number>6</number>
-      </property>
-      <property name="leftMargin">
-       <number>0</number>
-      </property>
-      <property name="topMargin">
-       <number>0</number>
-      </property>
-      <property name="rightMargin">
-       <number>0</number>
-      </property>
-      <property name="bottomMargin">
-       <number>0</number>
-      </property>
-      <item>
-       <widget class="QPushButton" name="okButton">
-        <property name="text">
-         <string>OK</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QPushButton" name="cancelButton">
-        <property name="text">
-         <string>Cancel</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </item>
-   </layout>
-  </widget>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>okButton</sender>
-   <signal>clicked()</signal>
-   <receiver>AGWConnectDkg</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>278</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>96</x>
-     <y>254</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>cancelButton</sender>
-   <signal>clicked()</signal>
-   <receiver>AGWConnectDkg</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>369</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>179</x>
-     <y>282</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AGWConnectDkg</class>
+ <widget class="QDialog" name="AGWConnectDkg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>500</width>
+    <height>400</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QWidget" name="verticalLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>480</width>
+     <height>380</height>
+    </rect>
+   </property>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QFormLayout" name="formLayout_2">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Call From </string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="CallFrom"/>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Call To </string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QComboBox" name="CallTo">
+        <property name="editable">
+         <bool>true</bool>
+        </property>
+        <property name="insertPolicy">
+         <enum>QComboBox::NoInsert</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_3">
+        <property name="text">
+         <string>Digis</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="Digis"/>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <widget class="QLabel" name="label_4">
+      <property name="text">
+       <string>Radio Ports</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QListWidget" name="RadioPorts"/>
+    </item>
+    <item>
+     <layout class="QHBoxLayout">
+      <property name="spacing">
+       <number>6</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QPushButton" name="okButton">
+        <property name="text">
+         <string>OK</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="cancelButton">
+        <property name="text">
+         <string>Cancel</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>AGWConnectDkg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>278</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>96</x>
+     <y>254</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cancelButton</sender>
+   <signal>clicked()</signal>
+   <receiver>AGWConnectDkg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>369</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>179</x>
+     <y>282</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- qttermtcp-0.0.0.79.orig/VARAConfig.ui
+++ qttermtcp-0.0.0.79/VARAConfig.ui
@@ -1,608 +1,608 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Dialog</class>
- <widget class="QDialog" name="Dialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>571</width>
-    <height>589</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>VARA Configuration</string>
-  </property>
-  <widget class="QWidget" name="layoutWidget">
-   <property name="geometry">
-    <rect>
-     <x>170</x>
-     <y>490</y>
-     <width>211</width>
-     <height>33</height>
-    </rect>
-   </property>
-   <layout class="QHBoxLayout">
-    <property name="spacing">
-     <number>6</number>
-    </property>
-    <property name="leftMargin">
-     <number>0</number>
-    </property>
-    <property name="topMargin">
-     <number>0</number>
-    </property>
-    <property name="rightMargin">
-     <number>0</number>
-    </property>
-    <property name="bottomMargin">
-     <number>0</number>
-    </property>
-    <item>
-     <widget class="QPushButton" name="okButton">
-      <property name="text">
-       <string>OK</string>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QPushButton" name="cancelButton">
-      <property name="text">
-       <string>Cancel</string>
-      </property>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QGroupBox" name="TNCInfo">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>120</y>
-     <width>551</width>
-     <height>161</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>TNC Setup</string>
-   </property>
-   <widget class="QLineEdit" name="Host">
-    <property name="geometry">
-     <rect>
-      <x>130</x>
-      <y>22</y>
-      <width>101</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="Port">
-    <property name="geometry">
-     <rect>
-      <x>400</x>
-      <y>20</y>
-      <width>47</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="Path">
-    <property name="geometry">
-     <rect>
-      <x>130</x>
-      <y>57</y>
-      <width>391</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_11">
-    <property name="geometry">
-     <rect>
-      <x>16</x>
-      <y>24</y>
-      <width>47</width>
-      <height>13</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Host</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_12">
-    <property name="geometry">
-     <rect>
-      <x>286</x>
-      <y>19</y>
-      <width>47</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Port</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_13">
-    <property name="geometry">
-     <rect>
-      <x>16</x>
-      <y>56</y>
-      <width>47</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Path</string>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="InitCommands">
-    <property name="geometry">
-     <rect>
-      <x>130</x>
-      <y>91</y>
-      <width>391</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_15">
-    <property name="geometry">
-     <rect>
-      <x>16</x>
-      <y>90</y>
-      <width>101</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Init Commands</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_16">
-    <property name="geometry">
-     <rect>
-      <x>80</x>
-      <y>120</y>
-      <width>371</width>
-      <height>31</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>You can specify more than one command, but the separator must be just a comma with no spaces</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-    <property name="wordWrap">
-     <bool>true</bool>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QGroupBox" name="groupBox_3">
-   <property name="geometry">
-    <rect>
-     <x>8</x>
-     <y>300</y>
-     <width>541</width>
-     <height>181</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>PTT Port</string>
-   </property>
-   <widget class="QComboBox" name="PTTPort">
-    <property name="geometry">
-     <rect>
-      <x>150</x>
-      <y>20</y>
-      <width>111</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="label_6">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>23</y>
-      <width>131</width>
-      <height>16</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Select PTT Port</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="PTTOnLab">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>80</y>
-      <width>121</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>PTT On String</string>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="PTTOn">
-    <property name="geometry">
-     <rect>
-      <x>150</x>
-      <y>83</y>
-      <width>247</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="PTTOff">
-    <property name="geometry">
-     <rect>
-      <x>150</x>
-      <y>114</y>
-      <width>247</width>
-      <height>22</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="PTTOffLab">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>112</y>
-      <width>121</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>PTT Off String</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="GPIOLab">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>52</y>
-      <width>111</width>
-      <height>16</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>GPIO Pin Left</string>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="GPIOLeft">
-    <property name="geometry">
-     <rect>
-      <x>150</x>
-      <y>50</y>
-      <width>25</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="GPIORight">
-    <property name="geometry">
-     <rect>
-      <x>310</x>
-      <y>50</y>
-      <width>25</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="GPIOLab2">
-    <property name="geometry">
-     <rect>
-      <x>165</x>
-      <y>50</y>
-      <width>83</width>
-      <height>18</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>GPIO Pin Right</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="CATLabel">
-    <property name="geometry">
-     <rect>
-      <x>18</x>
-      <y>50</y>
-      <width>121</width>
-      <height>18</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>CAT Port Speed</string>
-    </property>
-   </widget>
-   <widget class="QLineEdit" name="CATSpeed">
-    <property name="geometry">
-     <rect>
-      <x>150</x>
-      <y>50</y>
-      <width>47</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QRadioButton" name="RTSDTR">
-    <property name="geometry">
-     <rect>
-      <x>290</x>
-      <y>22</y>
-      <width>131</width>
-      <height>18</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>RTS/DTR</string>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup_2</string>
-    </attribute>
-   </widget>
-   <widget class="QRadioButton" name="CAT">
-    <property name="geometry">
-     <rect>
-      <x>420</x>
-      <y>22</y>
-      <width>121</width>
-      <height>18</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>CAT</string>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup_2</string>
-    </attribute>
-   </widget>
-   <widget class="QLineEdit" name="VIDPID">
-    <property name="geometry">
-     <rect>
-      <x>150</x>
-      <y>50</y>
-      <width>121</width>
-      <height>20</height>
-     </rect>
-    </property>
-   </widget>
-   <widget class="QLabel" name="CM108Label">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>50</y>
-      <width>111</width>
-      <height>18</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>CM108 VID/PID</string>
-    </property>
-   </widget>
-   <widget class="QRadioButton" name="CATHex">
-    <property name="geometry">
-     <rect>
-      <x>290</x>
-      <y>50</y>
-      <width>131</width>
-      <height>18</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Hex Strings</string>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup</string>
-    </attribute>
-   </widget>
-   <widget class="QRadioButton" name="CATText">
-    <property name="geometry">
-     <rect>
-      <x>420</x>
-      <y>50</y>
-      <width>131</width>
-      <height>18</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Text Strings</string>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup</string>
-    </attribute>
-   </widget>
-  </widget>
-  <widget class="QLineEdit" name="TermCall">
-   <property name="geometry">
-    <rect>
-     <x>140</x>
-     <y>44</y>
-     <width>113</width>
-     <height>22</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label">
-   <property name="geometry">
-    <rect>
-     <x>16</x>
-     <y>42</y>
-     <width>131</width>
-     <height>22</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Terminal Callsign</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_14">
-   <property name="geometry">
-    <rect>
-     <x>18</x>
-     <y>12</y>
-     <width>161</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Enable VARA Interface</string>
-   </property>
-  </widget>
-  <widget class="QCheckBox" name="VARAEnable">
-   <property name="geometry">
-    <rect>
-     <x>180</x>
-     <y>10</y>
-     <width>23</width>
-     <height>25</height>
-    </rect>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QGroupBox" name="VARAMode">
-   <property name="geometry">
-    <rect>
-     <x>270</x>
-     <y>10</y>
-     <width>131</width>
-     <height>101</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>VARA Mode</string>
-   </property>
-   <widget class="QRadioButton" name="VARAHF">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>20</y>
-      <width>121</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>VARA HF</string>
-    </property>
-    <property name="checked">
-     <bool>true</bool>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup_4</string>
-    </attribute>
-   </widget>
-   <widget class="QRadioButton" name="VARAFM">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>43</y>
-      <width>121</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>VARA FM</string>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup_4</string>
-    </attribute>
-   </widget>
-   <widget class="QRadioButton" name="VARASAT">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>66</y>
-      <width>121</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>VARA SAT</string>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup_4</string>
-    </attribute>
-   </widget>
-  </widget>
-  <widget class="QGroupBox" name="HFMode">
-   <property name="geometry">
-    <rect>
-     <x>410</x>
-     <y>10</y>
-     <width>131</width>
-     <height>101</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>VARA HF BW</string>
-   </property>
-   <widget class="QRadioButton" name="VARA500">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>20</y>
-      <width>101</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>500 Hz</string>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup_3</string>
-    </attribute>
-   </widget>
-   <widget class="QRadioButton" name="VARA2300">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>43</y>
-      <width>101</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>2300 Hz</string>
-    </property>
-    <property name="checked">
-     <bool>true</bool>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup_3</string>
-    </attribute>
-   </widget>
-   <widget class="QRadioButton" name="VARA2750">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>66</y>
-      <width>101</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>2750 Hz</string>
-    </property>
-    <attribute name="buttonGroup">
-     <string notr="true">buttonGroup_3</string>
-    </attribute>
-   </widget>
-  </widget>
- </widget>
- <resources/>
- <connections/>
- <buttongroups>
-  <buttongroup name="buttonGroup_3"/>
-  <buttongroup name="buttonGroup"/>
-  <buttongroup name="buttonGroup_4"/>
-  <buttongroup name="buttonGroup_2"/>
- </buttongroups>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>571</width>
+    <height>589</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>VARA Configuration</string>
+  </property>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>170</x>
+     <y>490</y>
+     <width>211</width>
+     <height>33</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout">
+    <property name="spacing">
+     <number>6</number>
+    </property>
+    <property name="leftMargin">
+     <number>0</number>
+    </property>
+    <property name="topMargin">
+     <number>0</number>
+    </property>
+    <property name="rightMargin">
+     <number>0</number>
+    </property>
+    <property name="bottomMargin">
+     <number>0</number>
+    </property>
+    <item>
+     <widget class="QPushButton" name="okButton">
+      <property name="text">
+       <string>OK</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="cancelButton">
+      <property name="text">
+       <string>Cancel</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QGroupBox" name="TNCInfo">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>120</y>
+     <width>551</width>
+     <height>161</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>TNC Setup</string>
+   </property>
+   <widget class="QLineEdit" name="Host">
+    <property name="geometry">
+     <rect>
+      <x>130</x>
+      <y>22</y>
+      <width>101</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="Port">
+    <property name="geometry">
+     <rect>
+      <x>400</x>
+      <y>20</y>
+      <width>47</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="Path">
+    <property name="geometry">
+     <rect>
+      <x>130</x>
+      <y>57</y>
+      <width>391</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_11">
+    <property name="geometry">
+     <rect>
+      <x>16</x>
+      <y>24</y>
+      <width>47</width>
+      <height>13</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Host</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_12">
+    <property name="geometry">
+     <rect>
+      <x>286</x>
+      <y>19</y>
+      <width>47</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Port</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_13">
+    <property name="geometry">
+     <rect>
+      <x>16</x>
+      <y>56</y>
+      <width>47</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Path</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="InitCommands">
+    <property name="geometry">
+     <rect>
+      <x>130</x>
+      <y>91</y>
+      <width>391</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_15">
+    <property name="geometry">
+     <rect>
+      <x>16</x>
+      <y>90</y>
+      <width>101</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Init Commands</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_16">
+    <property name="geometry">
+     <rect>
+      <x>80</x>
+      <y>120</y>
+      <width>371</width>
+      <height>31</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>You can specify more than one command, but the separator must be just a comma with no spaces</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+    <property name="wordWrap">
+     <bool>true</bool>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="groupBox_3">
+   <property name="geometry">
+    <rect>
+     <x>8</x>
+     <y>300</y>
+     <width>541</width>
+     <height>181</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>PTT Port</string>
+   </property>
+   <widget class="QComboBox" name="PTTPort">
+    <property name="geometry">
+     <rect>
+      <x>150</x>
+      <y>20</y>
+      <width>111</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_6">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>23</y>
+      <width>131</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Select PTT Port</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="PTTOnLab">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>80</y>
+      <width>121</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>PTT On String</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="PTTOn">
+    <property name="geometry">
+     <rect>
+      <x>150</x>
+      <y>83</y>
+      <width>247</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="PTTOff">
+    <property name="geometry">
+     <rect>
+      <x>150</x>
+      <y>114</y>
+      <width>247</width>
+      <height>22</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="PTTOffLab">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>112</y>
+      <width>121</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>PTT Off String</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="GPIOLab">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>52</y>
+      <width>111</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>GPIO Pin Left</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="GPIOLeft">
+    <property name="geometry">
+     <rect>
+      <x>150</x>
+      <y>50</y>
+      <width>25</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="GPIORight">
+    <property name="geometry">
+     <rect>
+      <x>310</x>
+      <y>50</y>
+      <width>25</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="GPIOLab2">
+    <property name="geometry">
+     <rect>
+      <x>165</x>
+      <y>50</y>
+      <width>83</width>
+      <height>18</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>GPIO Pin Right</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="CATLabel">
+    <property name="geometry">
+     <rect>
+      <x>18</x>
+      <y>50</y>
+      <width>121</width>
+      <height>18</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>CAT Port Speed</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="CATSpeed">
+    <property name="geometry">
+     <rect>
+      <x>150</x>
+      <y>50</y>
+      <width>47</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QRadioButton" name="RTSDTR">
+    <property name="geometry">
+     <rect>
+      <x>290</x>
+      <y>22</y>
+      <width>131</width>
+      <height>18</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>RTS/DTR</string>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup_2</string>
+    </attribute>
+   </widget>
+   <widget class="QRadioButton" name="CAT">
+    <property name="geometry">
+     <rect>
+      <x>420</x>
+      <y>22</y>
+      <width>121</width>
+      <height>18</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>CAT</string>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup_2</string>
+    </attribute>
+   </widget>
+   <widget class="QLineEdit" name="VIDPID">
+    <property name="geometry">
+     <rect>
+      <x>150</x>
+      <y>50</y>
+      <width>121</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="CM108Label">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>50</y>
+      <width>111</width>
+      <height>18</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>CM108 VID/PID</string>
+    </property>
+   </widget>
+   <widget class="QRadioButton" name="CATHex">
+    <property name="geometry">
+     <rect>
+      <x>290</x>
+      <y>50</y>
+      <width>131</width>
+      <height>18</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Hex Strings</string>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup</string>
+    </attribute>
+   </widget>
+   <widget class="QRadioButton" name="CATText">
+    <property name="geometry">
+     <rect>
+      <x>420</x>
+      <y>50</y>
+      <width>131</width>
+      <height>18</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Text Strings</string>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup</string>
+    </attribute>
+   </widget>
+  </widget>
+  <widget class="QLineEdit" name="TermCall">
+   <property name="geometry">
+    <rect>
+     <x>140</x>
+     <y>44</y>
+     <width>113</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>16</x>
+     <y>42</y>
+     <width>131</width>
+     <height>22</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Terminal Callsign</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_14">
+   <property name="geometry">
+    <rect>
+     <x>18</x>
+     <y>12</y>
+     <width>161</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Enable VARA Interface</string>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="VARAEnable">
+   <property name="geometry">
+    <rect>
+     <x>180</x>
+     <y>10</y>
+     <width>23</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QGroupBox" name="VARAMode">
+   <property name="geometry">
+    <rect>
+     <x>270</x>
+     <y>10</y>
+     <width>131</width>
+     <height>101</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>VARA Mode</string>
+   </property>
+   <widget class="QRadioButton" name="VARAHF">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>20</y>
+      <width>121</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>VARA HF</string>
+    </property>
+    <property name="checked">
+     <bool>true</bool>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup_4</string>
+    </attribute>
+   </widget>
+   <widget class="QRadioButton" name="VARAFM">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>43</y>
+      <width>121</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>VARA FM</string>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup_4</string>
+    </attribute>
+   </widget>
+   <widget class="QRadioButton" name="VARASAT">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>66</y>
+      <width>121</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>VARA SAT</string>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup_4</string>
+    </attribute>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="HFMode">
+   <property name="geometry">
+    <rect>
+     <x>410</x>
+     <y>10</y>
+     <width>131</width>
+     <height>101</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>VARA HF BW</string>
+   </property>
+   <widget class="QRadioButton" name="VARA500">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>20</y>
+      <width>101</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>500 Hz</string>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup_3</string>
+    </attribute>
+   </widget>
+   <widget class="QRadioButton" name="VARA2300">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>43</y>
+      <width>101</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>2300 Hz</string>
+    </property>
+    <property name="checked">
+     <bool>true</bool>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup_3</string>
+    </attribute>
+   </widget>
+   <widget class="QRadioButton" name="VARA2750">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>66</y>
+      <width>101</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>2750 Hz</string>
+    </property>
+    <attribute name="buttonGroup">
+     <string notr="true">buttonGroup_3</string>
+    </attribute>
+   </widget>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+ <buttongroups>
+  <buttongroup name="buttonGroup_3"/>
+  <buttongroup name="buttonGroup"/>
+  <buttongroup name="buttonGroup_4"/>
+  <buttongroup name="buttonGroup_2"/>
+ </buttongroups>
+</ui>
--- qttermtcp-0.0.0.79.orig/YAPPRxSize.ui
+++ qttermtcp-0.0.0.79/YAPPRxSize.ui
@@ -1,116 +1,116 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>SizeDialog</class>
- <widget class="QDialog" name="SizeDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>243</width>
-    <height>157</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Dialog</string>
-  </property>
-  <widget class="QWidget" name="layoutWidget">
-   <property name="geometry">
-    <rect>
-     <x>20</x>
-     <y>80</y>
-     <width>181</width>
-     <height>33</height>
-    </rect>
-   </property>
-   <layout class="QHBoxLayout">
-    <property name="spacing">
-     <number>6</number>
-    </property>
-    <property name="leftMargin">
-     <number>0</number>
-    </property>
-    <property name="topMargin">
-     <number>0</number>
-    </property>
-    <property name="rightMargin">
-     <number>0</number>
-    </property>
-    <property name="bottomMargin">
-     <number>0</number>
-    </property>
-    <item>
-     <widget class="QPushButton" name="okButton">
-      <property name="text">
-       <string>OK</string>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QPushButton" name="cancelButton">
-      <property name="text">
-       <string>Cancel</string>
-      </property>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QLabel" name="label">
-   <property name="geometry">
-    <rect>
-     <x>20</x>
-     <y>30</y>
-     <width>81</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Max RX Size</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="maxSize">
-   <property name="geometry">
-    <rect>
-     <x>120</x>
-     <y>30</y>
-     <width>61</width>
-     <height>20</height>
-    </rect>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>okButton</sender>
-   <signal>clicked()</signal>
-   <receiver>SizeDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>278</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>96</x>
-     <y>254</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>cancelButton</sender>
-   <signal>clicked()</signal>
-   <receiver>SizeDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>369</x>
-     <y>253</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>179</x>
-     <y>282</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SizeDialog</class>
+ <widget class="QDialog" name="SizeDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>243</width>
+    <height>157</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>80</y>
+     <width>181</width>
+     <height>33</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout">
+    <property name="spacing">
+     <number>6</number>
+    </property>
+    <property name="leftMargin">
+     <number>0</number>
+    </property>
+    <property name="topMargin">
+     <number>0</number>
+    </property>
+    <property name="rightMargin">
+     <number>0</number>
+    </property>
+    <property name="bottomMargin">
+     <number>0</number>
+    </property>
+    <item>
+     <widget class="QPushButton" name="okButton">
+      <property name="text">
+       <string>OK</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="cancelButton">
+      <property name="text">
+       <string>Cancel</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>30</y>
+     <width>81</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Max RX Size</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="maxSize">
+   <property name="geometry">
+    <rect>
+     <x>120</x>
+     <y>30</y>
+     <width>61</width>
+     <height>20</height>
+    </rect>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>SizeDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>278</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>96</x>
+     <y>254</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cancelButton</sender>
+   <signal>clicked()</signal>
+   <receiver>SizeDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>369</x>
+     <y>253</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>179</x>
+     <y>282</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- qttermtcp-0.0.0.79.orig/ax25.c
+++ qttermtcp-0.0.0.79/ax25.c
@@ -1,3245 +1,3245 @@
-/*
-Copyright (C) 2019-2020 Andrei Kopanchuk UZ7HO
-
-This file is part of QtSoundModem
-
-QtSoundModem is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-QtSoundModem is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with QtSoundModem.  If not, see http://www.gnu.org/licenses
-
-*/
-
-// UZ7HO Soundmodem Port by John Wiseman G8BPQ
-
-// This is a simplified version for QtTermTCP
-
-#include "ax25.h"
-#include <stdarg.h>
-
-extern int KISSChecksum;
-
-#ifdef WIN32
-
-__declspec(dllimport) unsigned short __stdcall htons(__in unsigned short hostshort);
-__declspec(dllimport) unsigned short __stdcall ntohs(__in unsigned short hostshort);
-
-#else
-
-#define strtok_s strtok_r
-#include <stddef.h>
-#endif 
-
-void decode_frame(Byte * frame, int len, Byte * path, string * data,
-	Byte * pid, Byte * nr, Byte * ns, Byte * f_type, Byte * f_id,
-	Byte *  rpt, Byte * pf, Byte * cr);
-
-void SetSessLabel(void * Sess, char * label);
-void setMenus(int State);
-void MHPROC(unsigned char * Packet, int Len);
-/*
-
-unit ax25;
-
-interface
-
-uses classes,sysutils,windows;
-
-  procedure get_exclude_list(line: string; var list: TStringList);
-  procedure get_exclude_frm(line: string; var list: TStringList);
-  procedure get_monitor_path(path: string; var mycall,corrcall,digi: string);
-  procedure get_call(src_call: string; var call: string);
-  procedure get_call_fm_path(path: string; var callto,callfrom: string);
-  procedure set_corrcall(snd_ch,port: byte; path: string);
-  procedure set_mycall(snd_ch,port: byte; path: string);
-  procedure set_digi(snd_ch,port: byte; path: string);
-  procedure decode_frame(frame: string; var path,data: string; var pid,nr,ns,f_type,f_id: byte; var rpt,pf,cr: boolean);
-  procedure del_incoming_mycalls(src_call: string);
-  procedure del_incoming_mycalls_by_sock(socket: integer);
-  procedure ax25_info_init(snd_ch,port: byte);
-  procedure write_ax25_info(snd_ch,port: byte);
-  procedure clr_frm_win(snd_ch,port: byte);
-  procedure ax25_init;
-  procedure ax25_free;
-  function dec2hex(value: byte): string;
-  function get_corrcall(path: string): string;
-  function get_mycall(path: string): string;
-  function get_digi(path: string): string;
-  function is_excluded_call(snd_ch: byte; path: string): boolean;
-  function is_excluded_frm(snd_ch,f_id: byte; data: string): boolean;
-  function is_last_digi(path: string): boolean;
-  function is_digi(snd_ch,port: byte; path: string): boolean;
-  function is_corrcall(snd_ch,port: byte; path: string): boolean;
-  function is_mycall(snd_ch,port: byte; path: string): boolean;
-  function is_correct_path(path: string; pid: byte): boolean;
-  function direct_addr(path: string): string;
-  function reverse_addr(path: string): string;
-  function reverse_digi(path: string): string;
-  function number_digi(path: string): byte;
-  function info_pid(pid: byte): string;
-  function get_fcs(var data: string; len: word): word;
-  function set_addr(path: string; rpt,cr: boolean): string;
-  function set_ctrl(nr,ns,f_type,f_id: byte; pf: boolean): byte;
-  function make_frame(data,path: string; pid,nr,ns,f_type,f_id: byte; rpt,pf,cr: boolean): string;
-  function get_incoming_socket_by_call(src_call: string): integer;
-  function add_incoming_mycalls(socket: integer; src_call: string): boolean;
-  function in_list_incoming_mycall(path: string): boolean;
-  function get_UTC_time: string;
-  function parse_NETROM(data: string; f_id: byte): string;
-  function parse_IP(data: string): string;
-  function parse_ARP(data: string): string;
-  function add_raw_frames(snd_ch: byte; frame: string; var buf: TStringList): boolean;
-  function scrambler(in_buf: string): string;
-  function my_indexof(var l: TStringList; s: string): integer;
-
-
-const
-  port_num=32;
-  PKT_ERR=17; //Minimum packet size, bytes
-  I_MAX=7; //Maximum number of packets
-  B_IDX_MAX=256;
-  ADDR_MAX_LEN=10;
-  FRAME_FLAG=126;
-  // Status flags
-  STAT_NO_LINK=0;
-  STAT_LINK=1;
-  STAT_CHK_LINK=2;
-  STAT_WAIT_ANS=3;
-  STAT_TRY_LINK=4;
-  STAT_TRY_UNLINK=5;
-  // md,Resp,Poll,Final,Digipeater flags
-  SET_P=TRUE;
-  SET_F=FALSE;
-  SET_C=TRUE;
-  SET_R=FALSE;
-  SET_NO_RPT=FALSE;
-  SET_RPT=TRUE;
-  // Frame ID flags
-  I_FRM=0;
-  S_FRM=1;
-  U_FRM=2;
-  I_I=0;
-  S_RR=1;
-  S_RNR=5;
-  S_REJ=9;
-  U_SABM=47;
-  U_DISC=67;
-  U_DM=15;
-  U_UA=99;
-  U_FRMR=135;
-  U_UI=3;
-  // PID flags
-  PID_X25=$01;       // 00000001-CCIT X25 PLP
-  PID_SEGMENT=$08;   // 00001000-Segmentation fragment
-  PID_TEXNET=$C3;    // 11000011-TEXNET Datagram Protocol
-  PID_LQ=$C4;        // 11001000-Link Quality Protocol
-  PID_APPLETALK=$CA; // 11001010-Appletalk
-  PID_APPLEARP=$CB;  // 11001011-Appletalk ARP
-  PID_IP=$CC;        // 11001100-ARPA Internet Protocol
-  PID_ARP=$CD;       // 11001101-ARPA Address Resolution Protocol
-  PID_NET_ROM=$CF;   // 11001111-NET/ROM
-*/
-
-#define ADDR_MAX_LEN 10
-#define PID_NO_L3 0xF0;     // 11110000-No Level 3 Protocol
-
-
-unsigned short CRCTable[256] = {
-	  0,  4489,  8978, 12955, 17956, 22445, 25910, 29887,
-  35912, 40385, 44890, 48851, 51820, 56293, 59774, 63735,
-   4225,   264, 13203,  8730, 22181, 18220, 30135, 25662,
-  40137, 36160, 49115, 44626, 56045, 52068, 63999, 59510,
-   8450, 12427,   528,  5017, 26406, 30383, 17460, 21949,
-  44362, 48323, 36440, 40913, 60270, 64231, 51324, 55797,
-  12675,  8202,  4753,   792, 30631, 26158, 21685, 17724,
-  48587, 44098, 40665, 36688, 64495, 60006, 55549, 51572,
-  16900, 21389, 24854, 28831,  1056,  5545, 10034, 14011,
-  52812, 57285, 60766, 64727, 34920, 39393, 43898, 47859,
-  21125, 17164, 29079, 24606,  5281,  1320, 14259,  9786,
-  57037, 53060, 64991, 60502, 39145, 35168, 48123, 43634,
-  25350, 29327, 16404, 20893,  9506, 13483,  1584,  6073,
-  61262, 65223, 52316, 56789, 43370, 47331, 35448, 39921,
-  29575, 25102, 20629, 16668, 13731,  9258,  5809,  1848,
-  65487, 60998, 56541, 52564, 47595, 43106, 39673, 35696,
-  33800, 38273, 42778, 46739, 49708, 54181, 57662, 61623,
-   2112,  6601, 11090, 15067, 20068, 24557, 28022, 31999,
-  38025, 34048, 47003, 42514, 53933, 49956, 61887, 57398,
-   6337,  2376, 15315, 10842, 24293, 20332, 32247, 27774,
-  42250, 46211, 34328, 38801, 58158, 62119, 49212, 53685,
-  10562, 14539,  2640,  7129, 28518, 32495, 19572, 24061,
-  46475, 41986, 38553, 34576, 62383, 57894, 53437, 49460,
-  14787, 10314,  6865,  2904, 32743, 28270, 23797, 19836,
-  50700, 55173, 58654, 62615, 32808, 37281, 41786, 45747,
-  19012, 23501, 26966, 30943,  3168,  7657, 12146, 16123,
-  54925, 50948, 62879, 58390, 37033, 33056, 46011, 41522,
-  23237, 19276, 31191, 26718,  7393,  3432, 16371, 11898,
-  59150, 63111, 50204, 54677, 41258, 45219, 33336, 37809,
-  27462, 31439, 18516, 23005, 11618, 15595,  3696,  8185,
-  63375, 58886, 54429, 50452, 45483, 40994, 37561, 33584,
-  31687, 27214, 22741, 18780, 15843, 11370,  7921,  3960 };
-
-
-unsigned short pkt_raw_min_len = 8;
-int stat_r_mem = 0;
-
-struct TKISSMode_t KISS;
-
-
-TAX25Port AX25Port[4][port_num];
-
-TStringList KISS_acked[4];
-TStringList KISS_iacked[4];
-
-typedef struct registeredCalls_t
-{
-	UCHAR myCall[7];		// call in ax.25
-	void * socket;
-
-} registeredCalls;
-
-
-TStringList list_incoming_mycalls;	// list strings containing a registered call
-
-
-boolean busy = 0;
-boolean dcd[5] = { 0 ,0 ,0, 0 };
-
-boolean  tx = 0;
-
-int stdtones = 0;
-int fullduplex = 0;
-
-UCHAR diddles = 0;
-
-word MEMRecovery[5] = { 200,200,200,200 };
-int NonAX25[5] = { 0 };
-
-boolean dyn_frack[4] = { FALSE,FALSE,FALSE,FALSE };
-Byte recovery[4] = { 0,0,0,0 };
-Byte users[4] = { 0,0,0,0 };
-
-short txtail[5] = { 50, 50, 50, 50, 50 };
-short txdelay[5] = { 400, 400, 400, 400, 400 };
-int sendTXDelay[4] = { 0, 0, 0, 0 };
-
-
-short modem_def[5] = { 1, 1, 1, 1, 1 };
-
-int emph_db[5] = { 0, 0, 0, 0, 0 };
-UCHAR emph_all[5] = { 0, 0, 0, 0, 0 };
-
-boolean  KISS_opt[4] = { FALSE, FALSE, FALSE, FALSE };
-int resptime[4] = { 1500,1500,1500,1500 };
-int slottime[4] = { 100,100,100,100 };
-int persist[4] = { 100,100,100,100 };
-int kisspaclen[4] = { 128,128,128,128 };
-int fracks[4] = { 10,10,10,10 };
-int frack_time[4] = { 5,5,5,5 };
-int idletime[4] = { 180,180,180,180 };
-int redtime[4] = { 0,0,0,0 };
-int IPOLL[4] = { 30,30,30,30 };
-int maxframe[4] = { 4,4,4,4 };
-int TXFrmMode[4] = { 1,1,1,1 };
-int max_frame_collector[4] = { 6,6,6,6 };
-
-
-char MyDigiCall[4][512] = { "","","","" };
-char exclude_callsigns[4][512] = { "","","","" };
-char exclude_APRS_frm[4][512] = { "","","","" };
-
-TStringList  list_exclude_callsigns[4];
-TStringList list_exclude_APRS_frm[4];
-TStringList list_digi_callsigns[4];
-
-Byte xData[256];
-Byte xEncoded[256];
-Byte xDecoded[256];
-
-int frame_count = 0;
-int single_frame_count = 0;
-
-/*
-  mydigi: string;
-  //// end of user params
-  addr: string[70];
-  ctrl: byte;
-  pid: byte=PID_NO_L3;
-  fcs: word;
-  data: string;
-  frame: string;
-
-implementation
-
-uses ax25_l2,sm_main;
-
-*/
-
-char * strlop(char * buf, char delim)
-{
-	// Terminate buf at delim, and return rest of string
-
-	char * ptr = strchr(buf, delim);
-
-	if (ptr == NULL) return NULL;
-
-	*(ptr)++ = 0;
-	return ptr;
-}
-
-void Debugprintf(const char * format, ...)
-{
-	char Mess[10000];
-	va_list(arglist);
-
-	va_start(arglist, format);
-	vsprintf(Mess, format, arglist);
-	WriteDebugLog(Mess);
-
-	return;
-}
-
-
-	
-void AX25_conn(TAX25Port * AX25Sess, int snd_ch, Byte mode)
-{
-	UNUSED(snd_ch);
-	char Msg[128];
-	int Len = 0;
-
-	switch (mode)
-	{
-	case MODE_OTHER:
-
-		Len = sprintf(Msg, "Incoming KISS Connection from %s\r", AX25Sess->corrcall);
-		break;
-
-	case MODE_OUR:
-
-		Len = sprintf(Msg, "Connected To %s\r", AX25Sess->corrcall);
-		break;
-
-	};
-
-	SendtoTerm(AX25Sess->Sess, Msg, Len);
-	SetSessLabel(AX25Sess->Sess, AX25Sess->corrcall);
-	setMenus(1);
-}
-
-void send_data_buf(TAX25Port * AX25Sess, int  nr);
-
-void SendtoAX25(void * conn, Byte * Msg, int Len)
-{
-	TAX25Port * AX25Sess;
-	AX25Sess = (TAX25Port * )conn;
-
-	// Need to enforce PacLen
-
-	if (AX25Sess)
-	{
-		int n;
-
-		while (Len)
-		{
-			string * data = newString();
-
-			if (Len > kisspaclen[0])
-				n = kisspaclen[0];
-			else
-				n = Len;
-
-			stringAdd(data, Msg, n);
-			Add(&AX25Sess->in_data_buf, data);
-
-			Len -= n;
-			Msg += n;
-		}
-		send_data_buf(AX25Sess, AX25Sess->vs);
-	}
-}
-
-
-
-
-
-void scrambler(UCHAR * in_buf, int Len)
-{
-	integer i;
-	word  sreg;
-	Byte  a = 0, k;
-
-	sreg = 0x1ff;
-
-	for (i = 0; i < Len; i++)
-	{
-		for (k = 0; k < 8; k++)
-		{
-
-			//	a: = (a shr 1) or (sreg and 1 shl 7);
-
-			a = (a >> 1) | ((sreg & 1) << 7);
-
-			//	sreg: = (sreg shl 4 and $200) xor (sreg shl 8 and $200) or (sreg shr 1);
-
-
-			sreg = (((sreg << 4) & 0x200) ^ ((sreg << 8) & 0x200)) | (sreg >> 1);
-		}
-		in_buf[i] = in_buf[i] ^ a;
-	}
-}
-
-
-/*
-function parse_ARP(data: string): string;
-
-function get_callsign(data: string): string;
-var
-  i: integer;
-  s: string;
-  a: byte;
-begin
-  s:='';
-  if length(data)=7 then
-  begin
-	for i:=1 to 6 do
-	begin
-	  a:=ord(data[i]) shr 1;
-	  if (a in [$30..$39,$41..$5A]) then s:=s+chr(a);
-	end;
-	a:=ord(data[7]) shr 1 and 15;
-	if a>0 then s:=s+'-'+inttostr(a);
-  end
-  else
-  begin
-	if length(data)>0 then
-	begin
-	  for i:=1 to length(data) do
-		if i=1 then s:=dec2hex(ord(data[i])) else s:=s+':'+dec2hex(ord(data[i]));
-	end;
-  end;
-  if s<>'' then s:=s+' ';
-  result:=s;
-end;
-
-function get_IP(data: string): string;
-var
-  i: integer;
-  s: string;
-begin
-  s:='';
-  if length(data)>0 then
-  begin
-	for i:=1 to length(data) do
-	  if i=1 then s:=inttostr(ord(data[i])) else s:=s+'.'+inttostr(ord(data[i]));
-  end;
-  if s<>'' then s:=s+' ';
-  result:=s;
-end;
-
-const
-  opcode: array [0..3] of string = ('ARP Request','ARP Response','RARP Request','RARP Response');
-var
-  oper: word;
-  hlen,plen: byte;
-  sha,spa,tha,tpa: string;
-  s: string;
-  i: word;
-begin
-  s:=data;
-  if length(data)>7 then
-  begin
-	hlen:=ord(data[5]);
-	plen:=ord(data[6]);
-	oper:=(ord(data[7]) shl 8 or ord(data[8])) and 2;
-	i:=9;      sha:=get_callsign(copy(data,i,hlen));
-	i:=i+hlen; spa:=get_ip(copy(data,i,plen));
-	i:=i+plen; tha:=get_callsign(copy(data,i,hlen));
-	i:=i+hlen; tpa:=get_ip(copy(data,i,plen));
-	s:='  [ARP] '+opcode[oper]+' from '+sha+spa+'to '+tha+tpa;
-  end;
-  result:=s;
-end;
-
-function parse_NETROM(data: string; f_id: byte): string;
-
-  function deshift_AX25(data: string): string;
-  var
-	i: byte;
-	call: string[6];
-	ssid: string[2];
-  begin
-	result:='';
-	if length(data)<7 then exit;
-	for i:=1 to 7 do data[i]:=chr(ord(data[i]) shr 1);
-	call:=trim(copy(data,1,6));
-	ssid:=trim(inttostr(ord(data[7]) and 15));
-	if ssid='0' then result:=call else result:=call+'-'+ssid;
-  end;
-
-  function con_req_info(data: string): string;
-  var
-	s_call: string;
-	d_call: string;
-	w: byte;
-	t_o: byte;
-  begin
-	result:='';
-	if length(data)>14 then
-	begin
-	  w:=ord(data[1]);
-	  s_call:=deshift_AX25(copy(data,2,7));
-	  d_call:=deshift_AX25(copy(data,9,7));
-	  result:=' w='+inttostr(w)+' '+s_call+' at '+d_call;
-	end;
-	if length(data)>15 then
-	begin
-	  t_o:=ord(data[16]);
-	  result:=result+' t/o '+inttostr(t_o);
-	end;
-  end;
-
-  function con_ack_info(data: string): string;
-  var
-	w: byte;
-  begin
-	result:='';
-	if length(data)>0 then
-	begin
-	  w:=ord(data[1]);
-	  result:=' w='+inttostr(w);
-	end;
-  end;
-
-const
-  opcode_arr: array[0..7] of string = ('PE','CON REQ','CON ACK','DISC REQ','DISQ ACK','INFO','INFO ACK','RST');
-var
-  s: string;
-  netrom_header: string;
-  c_idx:  byte;
-  c_ID:   byte;
-  TX_nr:  byte;
-  RX_nr:  byte;
-  opcode: byte;
-  s_call: string;
-  s_node: string;
-  d_call: string;
-  d_node: string;
-  b_call: string;
-  r_s_nr: string;
-  opc_flags: string;
-  quality: byte;
-  ttl: byte;
-  hops: byte;
-  rtt: word;
-  inp3_nr_field: byte;
-  inp3_field_len: byte;
-  inp3_ext_fields: boolean;
-begin
-  s:=data;
-  if length(data)>0 then
-  begin
-	if data[1]=#$FF then
-	begin
-	  delete(data,1,1);
-	  //Nodes broadcasting
-	  if (f_id=U_UI) and (length(data)>5) then
-	  begin
-		s_node:=copy(data,1,6);
-		delete(data,1,6);
-		s:='NODES broadcast from '+s_node+#13#10;
-		while length(data)>20 do
-		begin
-		  d_call:=deshift_AX25(copy(data,1,7));
-		  d_node:=copy(data,8,6);
-		  b_call:=deshift_AX25(copy(data,14,7));
-		  quality:=ord(data[21]);
-		  delete(data,1,21);
-		  s:=s+'  '+d_node+':'+d_call+' via '+b_call+' Q='+inttostr(quality)+#13#10;
-		end;
-	  end;
-	  // INP3 RIF
-	  if (f_id=I_I) and (length(data)>10) then
-	  begin
-		s:='[INP3 RIF]'+#13#10;
-		while length(data)>10 do
-		begin
-		  d_call:=deshift_AX25(copy(data,1,7));
-		  hops:=ord(data[8]);
-		  rtt:=(ord(data[9]) shl 8) or ord(data[10]);
-		  delete(data,1,10);
-		  inp3_ext_fields:=TRUE;
-		  inp3_nr_field:=0;
-		  while (length(data)>0) and inp3_ext_fields do
-		  begin
-			inp3_field_len:=ord(data[1]);
-			if inp3_field_len>0 then
-			begin
-			  if (inp3_nr_field=0) and (length(data)>1) then
-			  begin
-				if data[2]=#0 then d_call:=copy(data,3,inp3_field_len-2)+':'+d_call; // Copy alias
-			  end;
-			  delete(data,1,inp3_field_len);
-			  inc(inp3_nr_field);
-			end
-			else inp3_ext_fields:=FALSE;
-		  end;
-		  delete(data,1,1);
-		  s:=s+d_call+' hops='+inttostr(hops)+' rtt='+inttostr(rtt)+#13#10;
-		end;
-	  end;
-	end
-	else
-	begin
-	  // NETROM frames
-	  if length(data)>19 then
-	  begin
-		s_call:=deshift_AX25(copy(data,1,7));
-		d_call:=deshift_AX25(copy(data,8,7));
-		ttl:=ord(data[15]);
-		netrom_header:=copy(data,16,5);
-		delete(data,1,20);
-		c_idx:=ord(netrom_header[1]);
-		c_ID:=ord(netrom_header[2]);
-		TX_nr:=ord(netrom_header[3]);
-		RX_nr:=ord(netrom_header[4]);
-		opcode:=ord(netrom_header[5]);
-		// Opcode flags
-		opc_flags:='';
-		if opcode and 128 = 128 then opc_flags:=opc_flags+' C';
-		if opcode and 64  = 64  then opc_flags:=opc_flags+' N';
-		//
-		s:='  [NETROM] '+s_call+' to '+d_call+' ttl='+inttostr(ttl)+' cct='+dec2hex(c_idx)+dec2hex(c_ID);
-		r_s_nr:=' S'+inttostr(TX_nr)+' R'+inttostr(RX_nr);
-		case (opcode and 7) of
-		  0 : s:=s+' <'+opcode_arr[opcode and 7]+r_s_nr+'>'+#13#10+data;
-		  1 : s:=s+' <'+opcode_arr[opcode and 7]+'>'+con_req_info(data);
-		  2 : s:=s+' <'+opcode_arr[opcode and 7]+'>'+con_ack_info(data)+' my cct='+dec2hex(TX_nr)+dec2hex(RX_nr);
-		  3 : s:=s+' <'+opcode_arr[opcode and 7]+'>';
-		  4 : s:=s+' <'+opcode_arr[opcode and 7]+'>';
-		  5 : s:=s+' <'+opcode_arr[opcode and 7]+r_s_nr+'>:'+#13#10+data;
-		  6 : s:=s+' <'+opcode_arr[opcode and 7]+' R'+inttostr(RX_nr)+'>'+opc_flags;
-		  7 : s:=s+' <'+opcode_arr[opcode and 7]+r_s_nr+'>'+#13#10+data;
-		end;
-	  end;
-	end;
-  end;
-  result:=s;
-end;
-
-function parse_IP(data: string): string;
-
-  function parse_ICMP(var data: string): string;
-  var
-	ICMP_type: byte;
-	ICMP_code: byte;
-	s: string;
-  begin
-	result:='';
-	if length(data)>3 then
-	begin
-	  ICMP_type:=ord(data[1]);
-	  ICMP_code:=ord(data[2]);
-	  delete(data,1,4);
-	  s:='  [ICMP] Type='+inttostr(ICMP_type)+' Code='+inttostr(ICMP_code)+#13#10;
-	  result:=s;
-	end;
-  end;
-
-  function parse_TCP(var data: string): string;
-  var
-	s: string;
-	src_port: string;
-	dest_port: string;
-	wnd: string;
-	ihl: word;
-	idl: word;
-	flags: byte;
-	seq: string;
-	ack: string;
-	s_flags: string;
-	s_idl: string;
-  begin
-	result:='';
-	if length(data)>19 then
-	begin
-	  src_port:=' src_port:'+inttostr((ord(data[1]) shl 8)+ord(data[2]));
-	  dest_port:=' dest_port:'+inttostr((ord(data[3]) shl 8)+ord(data[4]));
-	  seq:=' seq='+dec2hex(ord(data[5]))+dec2hex(ord(data[6]))+dec2hex(ord(data[7]))+dec2hex(ord(data[8]));
-	  ack:=' ack='+dec2hex(ord(data[9]))+dec2hex(ord(data[10]))+dec2hex(ord(data[11]))+dec2hex(ord(data[12]));
-	  ihl:=(ord(data[13]) shr 4)*4;
-	  idl:=length(data)-ihl;
-	  flags:=ord(data[14]);
-	  wnd:=' wnd='+inttostr((ord(data[15]) shl 8)+ord(data[16]));
-	  delete(data,1,ihl);
-	  //
-	  s_flags:=' ';
-	  if (flags and 32)=32 then s_flags:=s_flags+'URG ';
-	  if (flags and 16)=16 then s_flags:=s_flags+'ACK ';
-	  if (flags and 8)=8   then s_flags:=s_flags+'PSH ';
-	  if (flags and 4)=4   then s_flags:=s_flags+'RST ';
-	  if (flags and 2)=2   then s_flags:=s_flags+'SYN ';
-	  if (flags and 1)=1   then s_flags:=s_flags+'FIN ';
-	  //
-	  if idl>0 then s_idl:=' data='+inttostr(idl) else s_idl:='';
-	  if (flags and 16)<>16 then ack:='';
-	  //
-	  s:='  [TCP]'+src_port+dest_port+seq+ack+wnd+s_idl+s_flags+#13#10;
-	  result:=s;
-	end;
-  end;
-
-  function parse_UDP(var data: string): string;
-  var
-	s: string;
-	src_port: string;
-	dest_port: string;
-	idl: word;
-	len: word;
-	s_idl: string;
-  begin
-	result:='';
-	if length(data)>7 then
-	begin
-	  src_port:=' src_port:'+inttostr((ord(data[1]) shl 8)+ord(data[2]));
-	  dest_port:=' dest_port:'+inttostr((ord(data[3]) shl 8)+ord(data[4]));
-	  len:=(ord(data[5]) shl 8)+ord(data[6]);
-	  idl:=len-8;
-	  delete(data,1,8);
-	  //
-	  if idl>0 then s_idl:=' data='+inttostr(idl) else s_idl:='';
-	  //
-	  s:='  [UDP]'+src_port+dest_port+' len='+inttostr(len)+s_idl+#13#10;
-	  result:=s;
-	end;
-  end;
-
-const
-  prot_idx=#1#6#17;
-  prot_name: array [1..3] of string = ('ICMP','TCP','UDP');
-var
-  s: string;
-  src_ip: string;
-  dest_ip: string;
-  s_prot: string;
-  len: string;
-  c_prot: char;
-  ttl: string;
-  offset: string;
-  ihl: byte;
-  p: byte;
-  fragment_offset: word;
-begin
-  s:=data;
-  if length(data)>19 then
-  begin
-	ihl:=(ord(data[1]) and 15)*4;
-	len:=' len='+inttostr((ord(data[3]) shl 8)+ord(data[4]));
-	fragment_offset:=((ord(data[7]) shl 8)+ord(data[8])) shl 3;
-	ttl:=' ttl='+inttostr(ord(data[9]));
-	c_prot:=data[10];
-	src_ip:=' Fm '+inttostr(ord(data[13]))+'.'+inttostr(ord(data[14]))+'.'+inttostr(ord(data[15]))+'.'+inttostr(ord(data[16]));
-	dest_ip:=' To '+inttostr(ord(data[17]))+'.'+inttostr(ord(data[18]))+'.'+inttostr(ord(data[19]))+'.'+inttostr(ord(data[20]));
-	delete(data,1,ihl);
-	//
-	p:=pos(c_prot,prot_idx);
-	if p>0 then s_prot:=' prot='+prot_name[p] else s_prot:=' prot=Type'+inttostr(ord(c_prot));
-	if fragment_offset>0 then offset:=' offset='+inttostr(fragment_offset) else offset:='';
-	s:='  [IP]'+src_ip+dest_ip+s_prot+ttl+len+offset+#13#10;
-	if fragment_offset=0 then
-	case p of
-	  1 : s:=s+parse_ICMP(data);
-	  2 : s:=s+parse_TCP(data);
-	  3 : s:=s+parse_UDP(data);
-	end;
-	s:=s+data;
-  end;
-  result:=s;
-end;
-
-function get_UTC_time: string;
-var
-  st: TSYSTEMTIME;
-  sec,hour,minute: string;
-begin
-  GetSystemTime(st);
-  if st.wSecond<10 then sec:='0'+inttostr(st.wSecond) else sec:=inttostr(st.wSecond);
-  if st.wMinute<10 then minute:='0'+inttostr(st.wMinute) else minute:=inttostr(st.wMinute);
-  if st.wHour<10 then Hour:='0'+inttostr(st.wHour) else Hour:=inttostr(st.wHour);
-  result:=hour+':'+minute+':'+sec;
-end;
-
-function dec2hex(value: byte): string;
-const
-  hex='0123456789ABCDEF';
-var
-  lo,hi: byte;
-begin
-  lo:=value and 15;
-  hi:=value shr 4;
-  result:=hex[hi+1]+hex[lo+1];
-end;
-
-*/
-
-unsigned short get_fcs(UCHAR * Data, unsigned short len)
-{
-	unsigned short i;
-	unsigned short result;
-
-	result = 0xFFFF;
-
-	if (len == 0)
-		return result;
-
-	for (i = 0; i < len; i++)
-		result = (result >> 8) ^ CRCTable[(result ^ Data[i]) & 0xff];
-
-
-	result ^= 0xffff;
-
-	return result;
-}
-
-
-unsigned short CRCTAB[256] = {
-	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-unsigned short int compute_crc(unsigned char *buf, int len)
-{
-	unsigned short fcs = 0xffff;
-	int i;
-
-	for (i = 0; i < len; i++)
-		fcs = (fcs >> 8) ^ CRCTAB[(fcs ^ buf[i]) & 0xff];
-
-	fcs ^= 0xffff;
-
-	return fcs;
-}
-
-
-
-int get_addr(char * Calls, UCHAR * AXCalls)
-{
-	//	CONVERT CALL + OPTIONAL DIGI STRING (Comma separated) TO AX25, RETURN 
-	//	CONVERTED STRING IN AXCALLS. Return FALSE if invalied
-
-	Byte * axptr = AXCalls;
-	char * ptr, *Context;
-	int n = 8;						// Max digis
-
-	memset(AXCalls, 0, 72);
-
-	ptr = strtok_s(Calls, " ,", &Context);
-
-	if (ptr == NULL)
-		return FALSE;
-
-	// First field is Call
-
-	if (ConvToAX25(ptr, axptr) == 0)
-		return FALSE;
-
-	axptr += 7;
-
-	ptr = strtok_s(NULL, " ,", &Context);
-
-	if (ptr == 0 || ConvToAX25(ptr, axptr) == 0)
-		return FALSE;
-
-	axptr += 7;
-
-	ptr = strtok_s(NULL, " ,", &Context);
-
-	while (ptr && n--)
-	{
-		// NEXT FIELD = COULD BE CALLSIGN, VIA, 
-
-		if (memcmp(ptr, "VIA", (int)strlen(ptr)) == 0)
-		{
-		}	//skip via
-		else
-		{
-			// Convert next digi
-
-			if (ConvToAX25(ptr, axptr) == 0)
-				return FALSE;
-
-			axptr += 7;
-		}
-
-		ptr = strtok_s(NULL, " ,", &Context);
-	}
-
-	axptr[-1] |= 1;			// Set end of address
-
-	return axptr - AXCalls;
-}
-
-Byte set_ctrl(Byte nr, Byte ns, Byte f_type, Byte f_id, boolean pf)
-{
-	Byte  pf_bit, ctrl;
-
-	ctrl = 0;
-	pf_bit = 0;
-
-	if (pf)
-		pf_bit = 16;
-
-	switch (f_type)
-	{
-	case I_FRM:
-
-		ctrl = (nr << 5) + pf_bit + (ns << 1);
-		break;
-
-	case S_FRM:
-
-		ctrl = (nr << 5) + pf_bit + f_id;
-		break;
-
-	case U_FRM:
-
-		ctrl = f_id + pf_bit;
-	}
-
-	return ctrl;
-}
-
-string * make_frame(string * data, Byte * axaddr,  Byte pid, Byte nr, Byte ns, Byte f_type, Byte f_id, boolean rpr, boolean pf, boolean cr)
-{
-	UNUSED(rpr);
-
-	Byte ctrl;
-
-	string * frame = newString();
-	int addrlen;
-	Byte addr[80];
-
-	frame->Data[0] = 0;					// Lower software expects a kiss control byte here
-	frame->Length = 1;
-
-	ctrl = set_ctrl(nr, ns, f_type, f_id, pf);
-
-	addrlen = strlen((char *)axaddr);
-
-	memcpy(addr, axaddr, addrlen);
-
-	if (cr)
-		addr[6] |= 0x80;		// Set Command Bit
-	else
-		addr[13] |= 0x80;	// Set Response Bit
-
-
-	switch (f_type)
-	{
-	case I_FRM:
-
-		stringAdd(frame, addr, addrlen);
-		stringAdd(frame, (Byte *)&ctrl, 1);
-		stringAdd(frame, (Byte *)&pid, 1);
-		stringAdd(frame, data->Data, data->Length);
-
-		break;
-
-
-	case S_FRM:
-
-		stringAdd(frame, addr, addrlen);
-		stringAdd(frame, (Byte *)&ctrl, 1);
-
-		break;
-
-	case U_FRM:
-
-		if (f_id == U_UI)
-		{
-			stringAdd(frame, addr, addrlen);
-			stringAdd(frame, (Byte *)&ctrl, 1);
-			stringAdd(frame, (Byte *)&pid, 1);
-			stringAdd(frame, data->Data, data->Length);
-		}
-		else if (f_id == U_FRMR)
-		{
-			stringAdd(frame, addr, addrlen);
-			stringAdd(frame, (Byte *)&ctrl, 1);
-			stringAdd(frame, data->Data, data->Length);
-		}
-		else
-		{
-			stringAdd(frame, addr, addrlen);
-			stringAdd(frame, (Byte *)&ctrl, 1);
-		}
-	}
-
-	return frame;
-}
-
-
-int add_raw_frames(int snd_ch, string * frame, TStringList * buf)
-{
-	UNUSED(snd_ch);
-
-	string  *s_data = newString();
-	Byte  s_pid, s_nr, s_ns, s_f_type, s_f_id;
-	Byte  s_rpt, s_cr, s_pf;
-	string  *d_data = newString();
-	Byte  d_pid, d_nr, d_ns, d_f_type, d_f_id;
-	Byte  d_rpt, d_cr, d_pf;
-
-	Byte d_path[80];
-	Byte s_path[80];
-
-	boolean  found_I;
-	int  i;
-
-	unsigned char * framecontents;
-	int Length;
-
-	boolean result = TRUE;
-
-	// Have to be careful as at this point frames have KISS Header and maybe trailer
-
-	if (buf->Count > 0)
-	{
-		// Check for duplicate. Ok to just compare as copy will have same header
-
-		if (my_indexof(buf, frame) >= 0)
-		{
-//			Debugprintf("KISSOptimise discarding duplicate frame");
-			return FALSE;
-		}
-
-		// Need to adjust for KISS bytes
-
-		// Normally one, but ackmode has 3 on front and sizeof(void *) on end
-
-		framecontents = frame->Data;
-		Length = frame->Length;
-
-		if ((framecontents[0] & 15) == 12)		// Ackmode
-		{
-			framecontents += 3;
-			Length -= (3 + sizeof(void *));
-		}
-		else
-		{
-			framecontents++;
-			Length--;
-		}
-
-		decode_frame(framecontents, Length, s_path, s_data, &s_pid, &s_nr, &s_ns, &s_f_type, &s_f_id, &s_rpt, &s_pf, &s_cr);
-
-		found_I = FALSE;
-
-		// check for multiple RR (r)
-
-		if (s_f_id == S_FRM && s_cr == SET_R)
-		{
-			for (i = 0; i < buf->Count; i++)
-			{
-				framecontents = buf->Items[i]->Data;
-				Length = buf->Items[i]->Length;
-
-				if ((framecontents[0] & 15) == 12)		// Ackmode
-				{
-					framecontents += 3;
-					Length -= (3 + sizeof(void *));
-				}
-				else
-				{
-					framecontents++;
-					Length--;
-				}
-
-				decode_frame(framecontents, Length, d_path, d_data, &d_pid, &d_nr, &d_ns, &d_f_type, &d_f_id, &d_rpt, &d_pf, &d_cr);
-
-				if (d_f_id == S_FRM && d_cr == SET_R && strcmp((char *)s_path, (char *)d_path) == 0)
-				{
-					Delete(buf, i);
-					Debugprintf("KISSOptimise discarding unneeded RR(R%d)", d_nr);
-
-					break;
-				}
-			}
-		}
-
-	
-		// check for RR after I Frame
-	
-		if (s_f_id == S_FRM && s_cr == SET_C)
-		{
-			for (i = 0; i < buf->Count; i++)
-			{
-				framecontents = buf->Items[i]->Data;
-				Length = buf->Items[i]->Length;
-
-				if ((framecontents[0] & 15) == 12)		// Ackmode
-				{
-					framecontents += 3;
-					Length -= (3 + sizeof(void *));
-				}
-				else
-				{
-					framecontents++;
-					Length--;
-				}
-
-				decode_frame(framecontents, Length, d_path, d_data, &d_pid, &d_nr, &d_ns, &d_f_type, &d_f_id, &d_rpt, &d_pf, &d_cr);
-
-				if (d_f_id == I_FRM && strcmp((char *)s_path, (char *)d_path) == 0)
-				{
-					found_I = TRUE;
-					break;
-				}
-			}
-
-			if (found_I)
-			{
-				Debugprintf("KISSOptimise discarding unneeded RR(C %d) after I frame", s_nr);
-				result = FALSE;
-			}
-		}
-			
-		// check on I
-
-		if (s_f_id == I_FRM)
-		{
-			for (i = 0; i < buf->Count; i++)
-			{
-				framecontents = buf->Items[i]->Data;
-				Length = buf->Items[i]->Length;
-
-				if ((framecontents[0] & 15) == 12)		// Ackmode
-				{
-					framecontents += 3;
-					Length -= (3 + sizeof(void *));
-				}
-				else
-				{
-					framecontents++;
-					Length--;
-				}
-
-				decode_frame(framecontents, Length, d_path, d_data, &d_pid, &d_nr, &d_ns, &d_f_type, &d_f_id, &d_rpt, &d_pf, &d_cr);
-
-				if (strcmp((char *)s_path, (char *)d_path) == 0 && d_f_id == S_FRM && d_cr == SET_C)
-				{
-					Delete(buf, i);
-					Debugprintf("KISSOptimise discarding unneeded RR(C %d)", d_nr);
-					i--;				// i was removed
-				}
-			}
-		}
-	}
-
-	freeString(d_data);
-	freeString(s_data);
-
-	return result;
-}
-
-//////////////////////// Register incoming callsign ////////////////////////////
-
-// I think a call should only be registered on one socket (or we won't know where to send
-// incoming calls
-
-boolean add_incoming_mycalls(void * socket, char * src_call)
-{
-	registeredCalls * reg = malloc(sizeof(struct registeredCalls_t));
-	int i = 0;
-
-	// Build a string containing Call and Socket
-
-	ConvToAX25(src_call, reg->myCall);
-	reg->socket = socket;
-
-	if (list_incoming_mycalls.Count > 0)
-	{
-		for (i = 0; i < list_incoming_mycalls.Count; i++)
-		{
-			registeredCalls * check = (registeredCalls *)list_incoming_mycalls.Items[i];
-
-			if (memcmp(check->myCall, reg->myCall, 7) == 0)
-			{
-				// Update socket
-
-				check->socket = socket;
-				return FALSE;
-			}
-		}
-	}
-
-	Add(&list_incoming_mycalls, (string *)reg);
-	return TRUE;
-}
-
-
-
-void del_incoming_mycalls(char * src_call)
-{
-	int i = 0;
-	Byte axcall[7];
-	registeredCalls * reg;
-
-	ConvToAX25(src_call, axcall);
-
-	while (i < list_incoming_mycalls.Count)
-	{
-		reg = (registeredCalls *)list_incoming_mycalls.Items[i];
-		{
-			if (memcmp(reg->myCall, axcall, 7) == 0)
-			{
-				// cant use Delete as stringlist doesn't contain strings
-
-				TStringList * Q = &list_incoming_mycalls;
-				int Index = i;
-
-				free(Q->Items[Index]);
-
-				Q->Count--;
-
-				while (Index < Q->Count)
-				{
-					Q->Items[Index] = Q->Items[Index + 1];
-					Index++;
-				}
-
-				return;
-			}
-		}
-		i++;
-	}
-}
-
-
-void del_incoming_mycalls_by_sock(void * socket)
-{
-	int i = 0, snd_ch, port;
-	registeredCalls * reg;
-
-	while (i < list_incoming_mycalls.Count)
-	{
-		reg = (registeredCalls *)list_incoming_mycalls.Items[i];
-		{
-			if (reg->socket == socket)
-			{
-				// cant use Delete as stringlist doesn't contain strings
-
-				TStringList * Q = &list_incoming_mycalls;
-				int Index = i; 
-		
-				free(Q->Items[Index]);
-
-				Q->Count--;
-
-				while (Index < Q->Count)
-				{
-					Q->Items[Index] = Q->Items[Index + 1];
-					Index++;
-				}
-				
-				//Delete(&list_incoming_mycalls, i);
-			}
-			else
-				i++;
-		}
-	}
-
-	// Should clear all connections on socket
-
-	for (snd_ch = 0; snd_ch < 4; snd_ch++)
-	{
-		for (port = 0; port < port_num; port++)
-		{
-			TAX25Port * AX25Sess = &AX25Port[snd_ch][port];
-
-			if (AX25Sess->socket == socket)
-			{
-				if (AX25Sess->status != STAT_NO_LINK)
-				{
-					// Shouldn't we send DM? -0 try it
-
-					set_DM(snd_ch, AX25Sess->ReversePath);
-
-					rst_timer(AX25Sess);
-					rst_values(AX25Sess);
-
-					AX25Sess->status = STAT_NO_LINK;
-				}
-				AX25Sess->socket = 0;
-			}
-		}
-	}
-}
-
-
-/*
-function get_incoming_socket_by_call(src_call: string): integer;
-var
-  i: integer;
-  found: boolean;
-  socket: integer;
-  call,ssid: string;
-  a_call: array[0..1] of string;
-begin
-  socket:=-1;
-  i:=0;
-  found:=FALSE;
-  try explode(a_call,'-',src_call,2); except end;
-  call:=trim(a_call[0]);
-  if a_call[1]<>'' then ssid:=a_call[1] else ssid:='0';
-  if list_incoming_mycalls.Count>0 then
-  repeat
-	if (call+'-'+ssid)=list_incoming_mycalls.Strings[i] then
-	begin socket:=strtoint(list_incoming_mycalls_sock.Strings[i]); found:=TRUE; end;
-	inc(i);
-  until found or (i=list_incoming_mycalls.Count);
-  result:=socket;
-end;
-*/
-
-
-
-void * in_list_incoming_mycall(Byte * path)
-{
-	// See if to call is in registered calls list
-
-	int i = 0;
-	registeredCalls * check;		// list_incoming_mycalls contains registeredCalls, not Strings
-	
-	while (i < list_incoming_mycalls.Count)
-	{
-		check = (registeredCalls *)list_incoming_mycalls.Items[i];
-
-		if (memcmp(check->myCall, path, 7) == 0)
-			return check->socket;
-
-		i++;
-	}
-
-	return NULL;
-}
-
-/*
-////////////////////////////////////////////////////////////////////////////////
-
-function is_corrcall(snd_ch,port: byte; path: string): boolean;
-var
-  call,ssid: string;
-begin
-  call:=trim(copy(path,8,6));
-  ssid:=copy(path,14,1);
-  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15)) else ssid:='0';
-  call:=call+'-'+ssid;
-  if call=AX25Sess->corrcall then result:=TRUE else result:=FALSE;
-end;
-
-function is_mycall(snd_ch,port: byte; path: string): boolean;
-var
-  call,ssid: string;
-begin
-  call:=trim(copy(path,1,6));
-  ssid:=copy(path,7,1);
-  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15)) else ssid:='0';
-  call:=call+'-'+ssid;
-  if call=AX25Sess->mycall then result:=TRUE else result:=FALSE;
-end;
-
-function is_digi(snd_ch,port: byte; path: string): boolean;
-var
-  digi,call,ssid: string;
-begin
-  digi:='';
-  if length(path)>14 then
-  begin
-	delete(path,1,14);
-	repeat
-	  call:=trim(copy(path,1,6));
-	  ssid:=copy(path,7,1);
-	  delete(path,1,7);
-	  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
-	  else ssid:='0';
-	  if path<>'' then digi:=digi+call+'-'+ssid+','
-	  else digi:=digi+call+'-'+ssid;
-	until path='';
-  end;
-  if digi=AX25Sess->digi then result:=TRUE else result:=FALSE;
-end;
-*/
-
-// Check if laast digi used
-
-boolean is_last_digi(Byte *path)
-{
-	int len = strlen((char *)path);
-
-	if (len == 14)
-		return TRUE;
-
-	if ((path[len - 1] & 128) == 128)
-		return TRUE;
-
-	return FALSE;
-}
-
-
-
-/*
-function get_corrcall(path: string): string;
-var
-  call,ssid: string;
-begin
-  call:=trim(copy(path,8,6));
-  ssid:=copy(path,14,1);
-  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15)) else ssid:='0';
-  call:=call+'-'+ssid;
-  result:=call;
-end;
-
-function get_mycall(path: string): string;
-var
-  call,ssid: string;
-begin
-  call:=trim(copy(path,1,6));
-  ssid:=copy(path,7,1);
-  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15)) else ssid:='0';
-  call:=call+'-'+ssid;
-  result:=call;
-end;
-
-function get_digi(path: string): string;
-var
-  digi,call,ssid: string;
-begin
-  digi:='';
-  if length(path)>14 then
-  begin
-	delete(path,1,14);
-	repeat
-	  call:=trim(copy(path,1,6));
-	  ssid:=copy(path,7,1);
-	  delete(path,1,7);
-	  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
-	  else ssid:='0';
-	  if path<>'' then digi:=digi+call+'-'+ssid+','
-	  else digi:=digi+call+'-'+ssid;
-	until path='';
-  end;
-  result:=digi;
-end;
-*/
-
-boolean is_correct_path(Byte * path, Byte pid)
-{
-	Byte networks[] = { 6, 7, 8, 0xc4, 0xcc, 0xcd, 0xce, 0xcf, 0xf0 , 0 };
-	int i;
-
-
-	if (pid == 0 || strchr((char *)networks, pid))
-	{
-		// Validate calls
-
-		// I think checking bottom  bit of first 13 bytes is enough
-
-		for (i = 0; i < 13; i++)
-		{
-			if ((*(path) & 1))
-				return FALSE;
-
-			path++;
-		}
-		return TRUE;
-	}
-	return FALSE;
-}
-
-
-void get_exclude_list(char * line, TStringList * list)
-{
-	// Convert comma separated list of calls to ax25 format in list
-
-	string axcall;
-
-	char copy[512];
-
-	char * ptr, *Context;
-
-	if (line[0] == 0)
-		return;
-
-	strcpy(copy, line);						// copy as strtok messes with it
-	strcat(copy, ",");
-
-	axcall.Length = 8;
-	axcall.AllocatedLength = 8;
-	axcall.Data = malloc(8);
-
-	memset(axcall.Data, 0, 8);
-
-	ptr = strtok_s(copy, " ,", &Context);
-
-	while (ptr)
-	{
-		if (ConvToAX25(ptr, axcall.Data) == 0)
-			return;
-
-		Add(list, duplicateString(&axcall));
-
-		ptr = strtok_s(NULL, " ,", &Context);
-	}
-}
-
-
-
-void get_exclude_frm(char * line, TStringList * list)
-{
-	UNUSED(line);
-	UNUSED(list);
-	/*
-
-  s: string;
-  p: integer;
-  n: integer;
-begin
-  list.Clear;
-  if line='' then exit;
-  repeat
-	p:=pos(',',line);
-	if p>0 then
-	  begin
-		s:=trim(copy(line,1,p-1));
-		if s<>'' then
-		begin
-		  try n:=strtoint(s); except n:=-1; end;
-		  if n in [0..255] then list.Add(chr(n));
-		end;
-		delete(line,1,p);
-	  end
-	else
-	  begin
-		s:=trim(line);
-		if s<>'' then
-		begin
-		  try n:=strtoint(s); except n:=-1; end;
-		  if n in [0..255] then list.Add(chr(n));
-		end;
-	  end;
-  until p=0;
-end;
-*/
-}
-
-/*
-
-function is_excluded_call(snd_ch: byte; path: string): boolean;
-var
-  excluded: boolean;
-  call: string;
-  ssid: string;
-begin
-  excluded:=FALSE;
-  if (list_exclude_callsigns[snd_ch].Count>0) and (length(path)>13) then
-  begin
-	// Copy sender
-	call:=trim(copy(path,8,6));
-	ssid:=copy(path,14,1);
-	if ssid<>'' then call:=call+'-'+inttostr((ord(ssid[1]) and 15));
-	if list_exclude_callsigns[snd_ch].IndexOf(call)>-1 then excluded:=TRUE;
-  end;
-  result:=excluded;
-end;
-
-function is_excluded_frm(snd_ch,f_id: byte; data: string): boolean;
-var
-  excluded: boolean;
-begin
-  excluded:=FALSE;
-  if list_exclude_APRS_frm[snd_ch].Count>0 then
-	if f_id=U_UI then
-	  if length(data)>0 then
-		if list_exclude_APRS_frm[snd_ch].IndexOf(data[1])>=0 then excluded:=TRUE;
-  result:=excluded;
-end;
-
-procedure set_corrcall(snd_ch,port: byte; path: string);
-var
-  call,ssid: string;
-begin
-  call:=trim(copy(path,8,6));
-  ssid:=copy(path,14,1);
-  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
-  else ssid:='0';
-  AX25Sess->corrcall:=call+'-'+ssid;
-end;
-
-procedure set_mycall(snd_ch,port: byte; path: string);
-var
-  call,ssid: string;
-begin
-  call:=trim(copy(path,1,6));
-  ssid:=copy(path,7,1);
-  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
-  else ssid:='0';
-  AX25Sess->mycall:=call+'-'+ssid;
-end;
-
-procedure set_digi(snd_ch,port: byte; path: string);
-var
-  digi,call,ssid: string;
-begin
-  digi:='';
-  if length(path)>14 then
-  begin
-	delete(path,1,14);
-	repeat
-	  call:=trim(copy(path,1,6));
-	  ssid:=copy(path,7,1);
-	  delete(path,1,7);
-	  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
-	  else ssid:='0';
-	  if path<>'' then digi:=digi+call+'-'+ssid+','
-	  else digi:=digi+call+'-'+ssid;
-	until path='';
-  end;
-  AX25Sess->digi:=digi;
-end;
-
-procedure get_call_fm_path(path: string; var callto,callfrom: string);
-var
-  a_path: array [0..ADDR_MAX_LEN-1] of string;
-  i: byte;
-begin
-  for i:=0 to ADDR_MAX_LEN-1 do a_path[i]:='';
-  try explode(a_path,',',path,ADDR_MAX_LEN); except end;
-  callto:=a_path[0];
-  callfrom:=a_path[1];
-end;
-
-procedure get_call(src_call: string; var call: string);
-var
-  a_call: array[0..1] of string;
-  ssid: string;
-begin
-  try explode(a_call,'-',src_call,2); except end;
-  call:=trim(a_call[0]);
-  if a_call[1]<>'' then ssid:=trim(a_call[1]) else ssid:='0';
-  call:=call+'-'+ssid;
-end;
-*/
-
-int number_digi(unsigned char * path)
-{
-	UNUSED(path);
-	int n = 0;
-
-	//  a_path: array [0..ADDR_MAX_LEN-3] of string;
-	// for i:=0 to ADDR_MAX_LEN-3 do a_path[i]:='';
-	// try explode(a_path,',',path,ADDR_MAX_LEN-2); except end;
-	// for i:=0 to ADDR_MAX_LEN-3 do if a_path[i]<>'' then inc(n);
-
-	return n;
-}
-
-
-
-void get_monitor_path(Byte * path, char * mycall, char * corrcall, char * digi)
-{
-	char * digiptr = digi;
-
-	digi[0] = 0;
-
-	mycall[ConvFromAX25(path, mycall)] = 0;
-	path += 7;
-	corrcall[ConvFromAX25(path, corrcall)] = 0;
-
-	while ((path[6] & 1) == 0)				// End of call bit
-	{
-		if (digi != digiptr)
-			*(digi++) = ',';
-
-		path += 7;
-		digi += ConvFromAX25(path, digi);
-
-		if (((path[6] & 128) == 128))		// Digi'd
-			*(digi++) = '*';
-	}
-	*digi = 0;
-}
-
-
-/*
-
-function reverse_digi(path: string): string;
-var
-  digi: string;
-  a_path: array [0..ADDR_MAX_LEN-3] of string;
-  i: word;
-begin
-  digi:='';
-  for i:=0 to ADDR_MAX_LEN-3 do a_path[i]:='';
-  try explode(a_path,',',path,ADDR_MAX_LEN-2); except end;
-  for i:=0 to ADDR_MAX_LEN-3 do
-  if a_path[i]<>'' then
-  begin
-	if digi='' then digi:=a_path[i]+digi
-	else digi:=a_path[i]+','+digi;
-  end;
-  result:=digi;
-end;
-
-function direct_addr(path: string): string;
-var
-  s,call,ssid: string;
-begin
-  s:='';
-  repeat
-	call:=copy(path,1,6);
-	delete(path,1,6);
-	ssid:=copy(path,1,1);
-	delete(path,1,1);
-	if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15));
-	if s='' then s:=call+'-'+ssid else s:=s+','+call+'-'+ssid;
-  until path='';
-  result:=s;
-end;
-*/
-
-void reverse_addr(Byte * path, Byte * revpath, int Len)
-{
-	Byte * ptr = path;
-	Byte * copy = revpath;
-	int endbit = Len - 1;
-	int numdigis = (Len - 14) / 7;
-	int i;
-
-	if (Len < 14)
-		return;
-
-	Byte digis[57];						// 8 * 7 + null terminator
-	memset(digis, 0, 57);
-	Byte * digiptr = digis + 49;			// Last Digi
-
-	// remove end of address bit
-
-	path[endbit] &= 0xFE;
-
-	// first reverse dest and origin
-
-	memcpy(copy + 7, ptr, 7);
-	memcpy(copy, ptr + 7, 7);
-
-	Len -= 14;
-	ptr += 14;
-
-	for (i = 0; i < numdigis; i++)
-	{
-		memcpy(digiptr, ptr, 7);
-		ptr += 7;
-		digiptr -= 7;
-	}
-
-	// Digiptr now points to new first digi 
-
-	memcpy(&copy[14], &digiptr[7], 7 * numdigis);
-
-	path[endbit] |= 1;			// restore original end bit
-
-	copy[endbit++] |= 1;
-	copy[endbit] = 0;			//  Null terminate
-
-	return;
-}
-
-
-
-void decode_frame(Byte * frame, int len, Byte * path, string * data,
-	Byte * pid, Byte * nr, Byte * ns, Byte * f_type, Byte * f_id,
-	Byte *  rpt, Byte * pf, Byte * cr)
-{
-	int i;
-	int addr_end;
-	Byte ctrl;
-	Byte * savepath = path;
-
-	i = 0;
-	addr_end = FALSE;
-
-	*cr = SET_R;
-	*pf = SET_F;
-	data->Length = 0;
-	ctrl = 0;
-	*pid = 0;
-	*nr = 0;
-	*ns = 0;
-	*f_type = 0;
-	*f_id = 0;
-	*rpt = FALSE;
-
-	if ((frame[6] & 128) == 128 && (frame[13] & 128) == 0)
-		*cr = SET_C;
-
-	while (len > i && i < ADDR_MAX_LEN * 7)
-	{
-		*path++ = frame[i];
-		if ((frame[i] & 1) == 1)
-		{
-			addr_end = TRUE;
-			break;
-		}
-		i++;
-	}
-
-	if (addr_end == 0)
-		return;
-
-	// clear the c and r bits from address
-
-	savepath[6] &= 0x7f;		// Mask 
-	savepath[13] &= 0x7f;		// Mask 
-
-	*path = 0;		// add null terminate		
-
-	i++;			// Points to ctrl byte
-
-	ctrl = frame[i];
-
-	if ((ctrl & 16) == 16)
-		*pf = SET_P;
-
-	if ((ctrl & 1) == 0)		// I frame
-	{
-		*f_type = I_FRM;
-		*f_id = I_I;
-		*nr = (ctrl >> 5);
-		*ns = (ctrl >> 1) & 7;
-	}
-	else
-	{
-		// Not I
-
-		*f_type = U_FRM;
-
-		*f_id = ctrl & 239;
-
-		switch (ctrl & 15)
-		{
-		case  S_RR:
-		case  S_RNR:
-		case  S_REJ:
-		case  S_SREJ:
-
-			*f_type = S_FRM;
-		}
-
-		if (*f_type == S_FRM)
-		{
-			*f_id = ctrl & 15;
-			*nr = ctrl >> 5;
-		}
-	}
-
-
-	if (*f_id == I_I || *f_id == U_UI)
-	{
-		i++;
-		*pid = frame[i];
-		i++;
-		if (len > i)
-			stringAdd(data, &frame[i], len - i);
-	}
-	else if (*f_id == U_FRMR)
-	{
-		*pid = 0;
-		i++;
-		if (len > i)
-			stringAdd(data, &frame[i], len - i);
-	}
-}
-
-void ax25_info_init(TAX25Port * AX25Sess)
-{
-	AX25Sess->info.stat_s_pkt = 0;
-	AX25Sess->info.stat_s_byte = 0;
-	AX25Sess->info.stat_r_pkt = 0;
-	AX25Sess->info.stat_r_byte = 0;
-	AX25Sess->info.stat_r_fc = 0;
-	AX25Sess->info.stat_fec_count = 0;
-	AX25Sess->info.stat_l_r_byte = 0;
-	AX25Sess->info.stat_l_s_byte = 0;
-	AX25Sess->info.stat_begin_ses = 0;
-	AX25Sess->info.stat_end_ses = 0;
-}
-
-
-void  clr_frm_win(TAX25Port * AX25Sess)
-{
-	int  i;
-
-	for (i = 0; i < 8; i++)
-		initString(&AX25Sess->frm_win[i]);
-}
-
-void ax25_init()
-{
-	int snd_ch, port, i;
-
-	for (i = 0; i < 4; i++)
-	{
-		initTStringList(&list_exclude_callsigns[i]);
-		initTStringList(&list_exclude_APRS_frm[i]);
-		initTStringList(&list_digi_callsigns[i]);
-		initTStringList(&KISS_acked[i]);
-
-		get_exclude_list(MyDigiCall[i], &list_digi_callsigns[i]);
-		get_exclude_list(exclude_callsigns[i], &list_exclude_callsigns[i]);
-		get_exclude_frm(exclude_APRS_frm[i], &list_exclude_APRS_frm[i]);
-
-	}
-
-	initTStringList(&list_incoming_mycalls);
-//	initTStringList(&list_incoming_mycalls_sock);
-
-	for (snd_ch = 0; snd_ch < 4; snd_ch++)
-	{
-		for (port = 0; port < port_num; port++)
-		{
-			TAX25Port * AX25Sess = &AX25Port[snd_ch][port];
-
-			AX25Sess->hi_vs = 0;
-			AX25Sess->vs = 0;
-			AX25Sess->vr = 0;
-			AX25Sess->PID = PID_NO_L3;
-			initTStringList(&AX25Sess->in_data_buf);
-			initString(&AX25Sess->out_data_buf);
-			AX25Sess->t1 = 0;
-			AX25Sess->t2 = 0;
-			AX25Sess->t3 = 0;
-			AX25Sess->i_lo = 0;
-			AX25Sess->i_hi = 0;
-			AX25Sess->n1 = 0;
-			AX25Sess->n2 = 0;
-			AX25Sess->status = 0;
-			AX25Sess->clk_frack = 0;
-			initTStringList(&AX25Sess->frame_buf);
-			initTStringList(&AX25Sess->I_frame_buf);
-			initTStringList(&AX25Sess->frm_collector);
-			AX25Sess->corrcall[0] = 0;
-			AX25Sess->mycall[0] = 0;
-			AX25Sess->digi[0] = 0;
-			AX25Sess->Path[0] = 0;
-			AX25Sess->kind[0] = 0;
-			AX25Sess->socket = NULL;
-			ax25_info_init(AX25Sess);
-			clr_frm_win(AX25Sess);
-		}
-	}
-}
-/*
-
-procedure ax25_free;
-var
-  snd_ch,port,i: byte;
-begin
-  for snd_ch:=1 to 4 do
-  for port:=0 to port_num-1 do
-  begin
-	AX25Sess->in_data_buf.Free;
-	AX25Sess->frame_buf.Free;
-	AX25Sess->I_frame_buf.Free;
-	AX25Sess->frm_collector.Free;
-  end;
-  for i:=1 to 4 do
-  begin
-	all_frame_buf[i].Free;
-	list_exclude_callsigns[i].Free;
-	list_exclude_APRS_frm[i].Free;
-	list_digi_callsigns[i].Free;
-  end;
-  list_incoming_mycalls.Free;
-  list_incoming_mycalls_sock.Free;
-end;
-*/
-void  write_ax25_info(TAX25Port * AX25Sess)
-{
-	UNUSED(AX25Sess);
-}
-
-/*var
-  new: boolean;
-  t: text;
-  s: string;
-  time_ses: tdatetime;
-  time_ses_sec: extended;
-  call,mycall,spkt,sbyte,rpkt,rbyte,rfc,tcps,rcps,acps,startses,timeses: string;
-begin
-  if stat_log then
-  begin
-	time_ses:=AX25Sess->info.stat_end_ses-AX25Sess->info.stat_begin_ses;
-	time_ses_sec:=time_ses*86400; //   
-	if time_ses_sec<1 then exit;
-	mycall:=copy(AX25Sess->mycall+'         ',1,9);
-	call:=copy(AX25Sess->corrcall+'         ',1,9);
-	spkt:=copy(inttostr(AX25Sess->info.stat_s_pkt)+'         ',1,6);
-	sbyte:=copy(inttostr(AX25Sess->info.stat_s_byte)+'         ',1,9);
-	rpkt:=copy(inttostr(AX25Sess->info.stat_r_pkt)+'         ',1,6);
-	rbyte:=copy(inttostr(AX25Sess->info.stat_r_byte)+'         ',1,9);
-	rfc:=copy(inttostr(AX25Sess->info.stat_r_fc)+'         ',1,6);
-	tcps:=copy(inttostr(round(AX25Sess->info.stat_s_byte/time_ses_sec))+'         ',1,5);
-	rcps:=copy(inttostr(round(AX25Sess->info.stat_r_byte/time_ses_sec))+'         ',1,5);
-	acps:=copy(inttostr(round(AX25Sess->info.stat_s_byte/time_ses_sec+AX25Sess->info.stat_r_byte/time_ses_sec))+'         ',1,5);
-	timeses:=FormatDateTime('hh:mm:ss',time_ses);
-	startses:=FormatDateTime('dd-mm-yy hh:mm:ss',AX25Sess->info.stat_begin_ses);
-	s:=mycall+' '+call+' '+spkt+' '+sbyte+' '+rpkt+' '+rbyte+' '+rfc+' '+tcps+' '+rcps+' '+acps+' '+startses+' '+timeses;
-	assignfile(t,'log.txt');
-	if FileSearch('log.txt','')='' then new:=TRUE else new:=FALSE;
-	if new then
-	begin
-	  rewrite(t);
-	  writeln(t,'Mycall    CorrCall  TXPkt  TXByte    RXPkt  RXByte    FCPkt  TXCPS RXCPS T.CPS Begin session     SesTime');
-	  writeln(t,'--------  --------- ------ --------- ------ --------- ------ ----- ----- ----- ----------------- --------');
-	end
-	else append(t);
-	if (AX25Sess->info.stat_s_byte>0) or (AX25Sess->info.stat_r_byte>0) then writeln(t,s);
-	closefile(t);
-  end;
-end;
-
-end.
-*/
-
-
-/*
-Copyright 2001-2018 John Wiseman G8BPQ
-
-This file is part of LinBPQ/BPQ32.
-
-LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-LinBPQ/BPQ32 is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
-*/
-
-
-
-// Monitor Code - from moncode.asm
-
-
-#define	CMDBIT	4		// CURRENT MESSAGE IS A COMMAND
-#define	RESP 2		// CURRENT MSG IS RESPONSE
-#define	VER1 1 		// CURRENT MSG IS VERSION 1
-
-
-#define	UI	3
-#define	SABM 0x2F
-#define	DISC 0x43
-#define	DM	0x0F
-#define	UA	0x63
-#define	FRMR 0x87
-#define	RR	1
-#define	RNR	5
-#define	REJ	9
-
-#define	PFBIT 0x10		// POLL/FINAL BIT IN CONTROL BYTE
-
-#define	NETROM_PID 0xCF
-#define	IP_PID 0xCC
-#define	ARP_PID 0xCD
-
-#define	NODES_SIG	0xFF
-
-/*
-
-DllExport int APIENTRY SetTraceOptions(int mask, int mtxparam, int mcomparam)
-{
-
-	//	Sets the tracing options for DecodeFrame. Mask is a bit
-	//	mask of ports to monitor (ie 101 binary will monitor ports
-	//	1 and 3). MTX enables monitoring on transmitted frames. MCOM
-	//	enables monitoring of protocol control frames (eg SABM, UA, RR),
-	//	as well as info frames.
-
-	MMASK = mask;
-	MTX = mtxparam;
-	MCOM = mcomparam;
-
-	return (0);
-}
-
-DllExport int APIENTRY SetTraceOptionsEx(int mask, int mtxparam, int mcomparam, int monUIOnly)
-{
-
-	//	Sets the tracing options for DecodeFrame. Mask is a bit
-	//	mask of ports to monitor (ie 101 binary will monitor ports
-	//	1 and 3). MTX enables monitoring on transmitted frames. MCOM
-	//	enables monitoring of protocol control frames (eg SABM, UA, RR),
-	//	as well as info frames.
-
-
-	MMASK = mask;
-	MTX = mtxparam;
-	MCOM = mcomparam;
-	MUIONLY = monUIOnly;
-
-	return 0;
-}
-
-*/
-
-#define USHORT unsigned short
-
-UCHAR	MCOM = 1;
-UCHAR	MTX = 1;
-ULONG	MMASK = 0xF;
-UCHAR	MUIONLY = 0;
-
-#define	SREJ 0x0D
-#define SABME 0x6F
-#define XID 0xAF
-#define TEST 0xE3
-
-#define L4BUSY	0x80		// BNA - DONT SEND ANY MORE
-#define L4NAK	0x40		// NEGATIVE RESPONSE FLAG
-#define L4MORE	0x20		// MORE DATA FOLLOWS - FRAGMENTATION FLAG
-
-#define L4CREQ	1		// CONNECT REQUEST
-#define L4CACK	2		// CONNECT ACK
-#define L4DREQ	3		// DISCONNECT REQUEST
-#define L4DACK	4		// DISCONNECT ACK
-#define L4INFO	5		// INFORMATION
-#define L4IACK	6		// INFORMATION ACK
-
-//#pragma pack(1)
-#pragma pack(push, 1) 
-
-struct myin_addr {
-	union {
-		struct { unsigned char s_b1, s_b2, s_b3, s_b4; } S_un_b;
-		struct { unsigned short s_w1, s_w2; } S_un_w;
-		unsigned long addr;
-	};
-};
-
-
-typedef struct _IPMSG
-{
-	//       FORMAT OF IP HEADER
-	//
-	//       NOTE THESE FIELDS ARE STORED HI ORDER BYTE FIRST (NOT NORMAL 8086 FORMAT)
-
-	UCHAR	VERLEN;          // 4 BITS VERSION, 4 BITS LENGTH
-	UCHAR	TOS;             // TYPE OF SERVICE
-	USHORT	IPLENGTH;        // DATAGRAM LENGTH
-	USHORT	IPID;            // IDENTIFICATION
-	USHORT	FRAGWORD;        // 3 BITS FLAGS, 13 BITS OFFSET
-	UCHAR	IPTTL;
-	UCHAR	IPPROTOCOL;      // HIGHER LEVEL PROTOCOL
-	USHORT	IPCHECKSUM;      // HEADER CHECKSUM
-	struct myin_addr IPSOURCE;
-	struct myin_addr IPDEST;
-
-	UCHAR	Data;
-
-} IPMSG, *PIPMSG;
-
-
-typedef struct _TCPMSG
-{
-
-	//	FORMAT OF TCP HEADER WITHIN AN IP DATAGRAM
-
-	//	NOTE THESE FIELDS ARE STORED HI ORDER BYTE FIRST (NOT NORMAL 8086 FORMAT)
-
-	USHORT	SOURCEPORT;
-	USHORT	DESTPORT;
-
-	ULONG	SEQNUM;
-	ULONG	ACKNUM;
-
-	UCHAR	TCPCONTROL;			// 4 BITS DATA OFFSET 4 RESERVED
-	UCHAR	TCPFLAGS;			// (2 RESERVED) URG ACK PSH RST SYN FIN
-
-	USHORT	WINDOW;
-	USHORT	CHECKSUM;
-	USHORT	URGPTR;
-
-
-} TCPMSG, *PTCPMSG;
-
-typedef struct _UDPMSG
-{
-
-	//	FORMAT OF UDP HEADER WITHIN AN IP DATAGRAM
-
-	//	NOTE THESE FIELDS ARE STORED HI ORDER BYTE FIRST (NOT NORMAL 8086 FORMAT)
-
-	USHORT	SOURCEPORT;
-	USHORT	DESTPORT;
-	USHORT	LENGTH;
-	USHORT	CHECKSUM;
-	UCHAR	UDPData[0];
-
-} UDPMSG, *PUDPMSG;
-
-//		ICMP MESSAGE STRUCTURE
-
-typedef struct _ICMPMSG
-{
-	//	FORMAT OF ICMP HEADER WITHIN AN IP DATAGRAM
-
-	//	NOTE THESE FIELDS ARE STORED HI ORDER BYTE FIRST (NOT NORMAL 8086 FORMAT)
-
-	UCHAR	ICMPTYPE;
-	UCHAR	ICMPCODE;
-	USHORT	ICMPCHECKSUM;
-
-	USHORT	ICMPID;
-	USHORT	ICMPSEQUENCE;
-	UCHAR	ICMPData[0];
-
-} ICMPMSG, *PICMPMSG;
-
-
-typedef struct _L3MESSAGE
-{
-	//
-	//	NETROM LEVEL 3 MESSAGE - WITHOUT L2 INFO 
-	//
-	UCHAR	L3SRCE[7];			// ORIGIN NODE
-	UCHAR	L3DEST[7];			// DEST NODE
-	UCHAR	L3TTL;				// TX MONITOR FIELD - TO PREVENT MESSAGE GOING								// ROUND THE NETWORK FOR EVER DUE TO ROUTING LOOP
-//
-//	NETROM LEVEL 4 DATA
-//
-	UCHAR	L4INDEX;			// TRANSPORT SESSION INDEX
-	UCHAR	L4ID;				// TRANSPORT SESSION ID
-	UCHAR	L4TXNO;				// TRANSMIT SEQUENCE NUMBER
-	UCHAR	L4RXNO;				// RECEIVE (ACK) SEQ NUMBER
-	UCHAR	L4FLAGS;			// FRAGMENTATION, ACK/NAK, FLOW CONTROL AND MSG TYPE BITS
-
-	UCHAR	L4DATA[236];		//DATA
-
-} L3MESSAGE, *PL3MESSAGE;
-
-
-typedef struct _MESSAGE
-{
-	//	BASIC LINK LEVEL MESSAGE BUFFER LAYOUT
-
-	struct _MESSAGE * CHAIN;
-
-	UCHAR	PORT;
-	USHORT	LENGTH;
-
-	UCHAR	DEST[7];
-	UCHAR	ORIGIN[7];
-
-	//	 MAY BE UP TO 56 BYTES OF DIGIS
-
-	UCHAR	CTL;
-	UCHAR	PID;
-
-	union
-	{                   /*  array named screen */
-		UCHAR L2DATA[256];
-		struct _L3MESSAGE L3MSG;
-	};
-
-
-}MESSAGE, *PMESSAGE;
-
-//#pragma pack()
-#pragma pack(pop) 
-
-char * strlop(char * buf, char delim);
-UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen);
-char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen);
-UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen);
-char * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output);
-
-int CountBits(unsigned long in)
-{
-	int n = 0;
-	while (in)
-	{
-		if (in & 1) n++;
-		in >>= 1;
-	}
-	return n;
-}
-
-BOOL ConvToAX25(char * callsign, unsigned char * ax25call)
-{
-	int i;
-
-	memset(ax25call, 0x40, 6);		// in case short
-	ax25call[6] = 0x60;				// default SSID
-
-	for (i = 0; i < 7; i++)
-	{
-		if (callsign[i] == '-')
-		{
-			//
-			//	process ssid and return
-			//
-			i = atoi(&callsign[i + 1]);
-
-			if (i < 16)
-			{
-				ax25call[6] |= i << 1;
-				return (TRUE);
-			}
-			return (FALSE);
-		}
-
-		if (callsign[i] == 0 || callsign[i] == 13 || callsign[i] == ' ' || callsign[i] == ',')
-		{
-			//
-			//	End of call - no ssid
-			//
-			return (TRUE);
-		}
-
-		ax25call[i] = callsign[i] << 1;
-	}
-
-	//
-	//	Too many chars
-	//
-
-	return (FALSE);
-}
-
-
-int ConvFromAX25(unsigned char * incall, char * outcall)
-{
-	int in, out = 0;
-	unsigned char chr;
-
-	memset(outcall, 0x20, 10);
-
-	for (in = 0; in < 6; in++)
-	{
-		chr = incall[in];
-		if (chr == 0x40)
-			break;
-		chr >>= 1;
-		outcall[out++] = chr;
-	}
-
-	chr = incall[6];				// ssid
-
-	if (chr == 0x42)
-	{
-		outcall[out++] = '-';
-		outcall[out++] = 'T';
-		return out;
-	}
-
-	if (chr == 0x44)
-	{
-		outcall[out++] = '-';
-		outcall[out++] = 'R';
-		return out;
-	}
-
-	chr >>= 1;
-	chr &= 15;
-
-	if (chr > 0)
-	{
-		outcall[out++] = '-';
-		if (chr > 9)
-		{
-			chr -= 10;
-			outcall[out++] = '1';
-		}
-		chr += 48;
-		outcall[out++] = chr;
-	}
-	return (out);
-}
-
-TKISSMode ** KissConnections = NULL;
-int KISSConCount = 0;
-
-#define FEND 0xc0
-#define FESC 0xDB
-#define TFEND 0xDC
-#define TFESC 0xDD
-#define KISS_ACKMODE 0x0C
-#define KISS_DATA 0
-
-int KISS_encode(UCHAR * KISSBuffer, int port, string * frame, int TXMON);
-
-void KISS_init()
-{
-	int i;
-
-	KISS.data_in = newString();
-
-	//	initTStringList(KISS.socket);
-
-	for (i = 0; i < 4; i++)
-	{
-		initTStringList(&KISS.buffer[i]);
-	}
-}
-
-void ProcessKISSFrame(void * socket, UCHAR * Msg, int Len);
-
-void KISSDataReceived(void * socket, unsigned char * data, int length)
-{
-	int i;
-	unsigned char * ptr1, *ptr2;
-	int Length;
-
-	TKISSMode * KISS = NULL;
-
-	if (KISSConCount == 0)
-		return;
-
-	for (i = 0; i < KISSConCount; i++)
-	{
-		if (KissConnections[i]->Socket == socket)
-		{
-			KISS = KissConnections[i];
-			break;
-		}
-	}
-
-	if (KISS == NULL)
-		return;
-
-	stringAdd(KISS->data_in, data, length);
-
-	if (KISS->data_in->Length > 10000)				// Probably AGW Data on KISS Port
-	{
-		KISS->data_in->Length = 0;
-		return;
-	}
-
-	ptr1 = KISS->data_in->Data;
-	Length = KISS->data_in->Length;
-
-
-	while ((ptr2 = memchr(ptr1, FEND, Length)))
-	{
-		int Len = (ptr2 - ptr1);
-
-		if (Len == 0)
-		{
-			// Start of frame
-
-			mydelete(KISS->data_in, 0, 1);
-
-			ptr1 = KISS->data_in->Data;
-			Length = KISS->data_in->Length;
-
-			continue;
-		}
-
-		// Process Frame
-
-		if (Len < 350)								// Drop obviously corrupt frames
-			ProcessKISSFrame(socket, ptr1, Len);
-
-		mydelete(KISS->data_in, 0, Len + 1);
-
-		ptr1 = KISS->data_in->Data;
-		Length = KISS->data_in->Length;
-
-	}
-}
-
-void analiz_frame(int snd_ch, string * frame, void * socket, boolean fecflag);
-
-void KISSSendtoServer(void * Socket, char * Data, int Length);
-
-void ProcessKISSFrame(void * socket, UCHAR * Msg, int Len)
-{
-	int n = Len;
-	UCHAR c;
-	int ESCFLAG = 0;
-	UCHAR * ptr1, *ptr2;
-	int Chan;
-	int Opcode;
-	string * TXMSG;
-
-	ptr1 = ptr2 = Msg;
-
-	while (n--)
-	{
-		c = *(ptr1++);
-
-		if (ESCFLAG)
-		{
-			//
-			//	FESC received - next should be TFESC or TFEND
-
-			ESCFLAG = 0;
-
-			if (c == TFESC)
-				c = FESC;
-
-			if (c == TFEND)
-				c = FEND;
-
-		}
-		else
-		{
-			switch (c)
-			{
-			case FEND:
-
-				//
-				//	Either start of message or message complete
-				//
-
-				//	npKISSINFO->MSGREADY = TRUE;
-				return;
-
-			case FESC:
-
-				ESCFLAG = 1;
-				continue;
-
-			}
-		}
-
-		//
-		//	Ok, a normal char
-		//
-
-		*(ptr2++) = c;
-
-	}
-	Len = ptr2 - Msg;
-
-	Chan = (Msg[0] >> 4);
-	Opcode = Msg[0] & 0x0f;
-
-	if (Chan > 3)
-		return;
-
-	// This is a lot simpler than QtSM, as frames will always be immediately processed locally, so ack mode isn't needed.
-	//	but if enabled ack can be sent immediately
-	//	checksum if needed
-
-	switch (Opcode)
-	{
-	case KISS_ACKMODE:
-	{
-		// send ack
-
-		unsigned char ACK[16];
-		unsigned char * ackptr = ACK;
-
-		*ackptr++ = FEND;
-		*ackptr++ = Msg[0];			// opcode and channel
-
-		*ackptr++ = Msg[1];
-		*ackptr++ = Msg[2];			// ACK Bytes
-		*ackptr++ = FEND;
-
-		KISSSendtoServer(socket, ACK, 5);
-
-		// remove ack bytes
-
-		memmove(&Msg[1], &Msg[3], Len - 2);
-
-		// drop through to KISS Data
-
-		Len -= 2;
-	}
-	case KISS_DATA:
-
-		if (KISSChecksum)
-		{
-			//	SUM MESSAGE, AND IF DUFF DISCARD. IF OK DECREMENT COUNT TO REMOVE SUM
-
-			int sumlen = Len;
-			char * ptr = &Msg[0];
-			UCHAR sum = 0;
-
-			while (sumlen--)
-			{
-				sum ^= *(ptr++);
-			}
-
-			if (sum)
-			{
-				Debugprintf("KISS Checksum Error");
-				return;
-			}
-
-			Len--;							// Remove Checksum
-		}
-
-		TXMSG = newString();
-		stringAdd(TXMSG, &Msg[1], Len - 1);		// include Control
-
-		MHPROC(TXMSG->Data, TXMSG->Length);
-		
-		analiz_frame(Chan, TXMSG, socket, 0);
-
-		free(TXMSG);
-		return;
-	}
-
-	// Still need to process kiss control frames
-}
-
-
-void KISS_add_stream(void * Socket)
-{
-	// Add a new connection. Called when QT accepts an incoming call}
-
-	TKISSMode * KISS;
-
-	KissConnections = realloc(KissConnections, (KISSConCount + 1) * sizeof(void *));
-
-	KISS = KissConnections[KISSConCount++] = malloc(sizeof(TKISSMode));
-
-	KISS->Socket = Socket;
-	KISS->data_in = newString();
-
-}
-
-void KISS_del_socket(void * socket)
-{
-	int i;
-
-	TKISSMode * KISS = NULL;
-
-	if (KISSConCount == 0)
-		return;
-
-	for (i = 0; i < KISSConCount; i++)
-	{
-		if (KissConnections[i]->Socket == socket)
-		{
-			KISS = KissConnections[i];
-			break;
-		}
-	}
-
-	if (KISS == NULL)
-		return;
-
-	// Need to remove entry and move others down
-
-	KISSConCount--;
-
-	while (i < KISSConCount)
-	{
-		KissConnections[i] = KissConnections[i + 1];
-		i++;
-	}
-}
-
-TAX25Port * get_free_port(int snd_ch);
-
-TAX25Port * KISSConnectOut(void * Sess, char * CallFrom, char * CallTo, char * Digis, int Chan, void * Socket)
-{
-	TAX25Port * AX25Sess = 0;
-	char path[128];
-	Byte axpath[80];
-
-	AX25Sess = get_free_port(Chan);
-
-	if (AX25Sess)
-	{
-		AX25Sess->snd_ch = Chan;
-		AX25Sess->Sess = Sess;
-		strcpy(AX25Sess->mycall, CallFrom);
-		strcpy(AX25Sess->corrcall, CallTo);
-		AX25Sess->PID = 0xf0;
-
-		sprintf(path, "%s,%s", CallTo, CallFrom);
-
-		if (Digis && Digis[0])
-		{
-			strcat(path, ",");
-			strcat(path, Digis);
-		}
-	
-		AX25Sess->digi[0] = 0;
-
-		//		rst_timer(snd_ch, free_port);
-
-		strcpy(AX25Sess->kind, "Outgoing");
-		AX25Sess->socket = Socket;
-
-		AX25Sess->pathLen = get_addr(path, axpath);
-
-		if (AX25Sess->pathLen == 0)
-			return AX25Sess;						// Invalid Path
-
-		strcpy((char *)AX25Sess->Path, (char *)axpath);
-		reverse_addr(axpath, AX25Sess->ReversePath, AX25Sess->pathLen);
-
-		set_link(AX25Sess, AX25Sess->Path);				// Sends SABM
-		return AX25Sess;
-	}
-	return 0;
-}
-
-
-
-// Monitor Code - from moncode.asm
-
-
-#define	CMDBIT	4		// CURRENT MESSAGE IS A COMMAND
-#define	RESP 2		// CURRENT MSG IS RESPONSE
-#define	VER1 1 		// CURRENT MSG IS VERSION 1
-
-
-#define	UI	3
-#define	SABM 0x2F
-#define	DISC 0x43
-#define	DM	0x0F
-#define	UA	0x63
-#define	FRMR 0x87
-#define	RR	1
-#define	RNR	5
-#define	REJ	9
-
-#define	SREJ 0x0D
-#define SABME 0x6F
-#define XID 0xAF
-#define TEST 0xE3
-
-
-#define	PFBIT 0x10		// POLL/FINAL BIT IN CONTROL BYTE
-
-#define	NETROM_PID 0xCF
-#define	IP_PID 0xCC
-#define	ARP_PID 0xCD
-
-#define	NODES_SIG	0xFF
-
-char ShortDT[] = "HH:MM:SS";
-
-int KISSLocalTime = 0;
-int KISSMonEnable = 0;
-int KISSMonNodes = 0;
-
-char * ShortDateTime()
-{
-	struct tm * tm;
-	time_t NOW = time(NULL);
-
-	if (KISSLocalTime)
-		tm = localtime(&NOW);
-	else
-		tm = gmtime(&NOW);
-
-	sprintf(ShortDT, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
-	return ShortDT;
-}
-
-
-char FrameData[1024] = "";
-
-char * frame_monitor(string * frame, char * code, int tx_stat)
-{
-	char mon_frm[512];
-	char Path[256];
-
-	char * frm = "???";
-	Byte * datap;
-	Byte _data[512] = "";
-	Byte * p_data = _data;
-	int _datalen;
-	char CallFrom[10], CallTo[10], Digi[80];
-
-	char TR = 'R';
-	char codestr[16] = "";
-
-	integer i;
-	int len;
-
-
-	Byte pid, nr, ns, f_type, f_id;
-	Byte  rpt, cr, pf;
-	Byte path[80];
-	char c;
-	const char * p;
-
-	string * data = newString();
-
-	if (code[0] && strlen(code) < 14)
-		sprintf(codestr, "[%s]", code);
-
-	if (tx_stat)
-		TR = 'T';
-
-	if (tx_stat)	// TX frame has control byte
-
-		decode_frame(frame->Data + 1, frame->Length - 1, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
-	else
-		decode_frame(frame->Data, frame->Length, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
-
-
-	datap = data->Data;
-
-	len = data->Length;
-
-	if (pid == 0xCF) 
-	{
-		if (datap[0] == 255)	 //Nodes broadcast
-		{
-			if (KISSMonNodes == 0)
-			{
-				freeString(data);
-				return 0;
-			}
-		}
-	}
-	
-		
-		
-	//		data = parse_NETROM(data, f_id);
-	// IP parsing
-	//	else if (pid == 0xCC)
-	//		data = parse_IP(data);
-		// ARP parsing
-	//	else if (pid == 0xCD)
-	//		data = parse_ARP(data);
-		//
-
-	if (len > 0)
-	{
-		for (i = 0; i < len; i++)
-		{
-			if (datap[i] > 31 || datap[i] == 13 || datap[i] == 9)
-				*(p_data++) = datap[i];
-		}
-	}
-
-	_datalen = p_data - _data;
-
-	if (_datalen)
-	{
-		Byte * ptr = _data;
-		i = 0;
-
-		// remove successive cr or cr on end		while (i < _datalen)
-
-		while (i < _datalen)
-		{
-			if ((_data[i] == 13) && (_data[i + 1] == 13))
-				i++;
-			else
-				*(ptr++) = _data[i++];
-		}
-
-		if (*(ptr - 1) == 13)
-			ptr--;
-
-		*ptr = 0;
-
-		_datalen = ptr - _data;
-	}
-
-	get_monitor_path(path, CallTo, CallFrom, Digi);
-
-	if (cr)
-	{
-		c = 'C';
-		if (pf)
-			p = " P";
-		else p = "";
-	}
-	else
-	{
-		c = 'R';
-		if (pf)
-			p = " F";
-		else
-			p = "";
-	}
-
-	switch (f_id)
-	{
-	case I_I:
-
-		frm = "I";
-		break;
-
-	case S_RR:
-
-		frm = "RR";
-		break;
-
-	case S_RNR:
-
-		frm = "RNR";
-		break;
-
-	case S_REJ:
-
-		frm = "REJ";
-		break;
-
-	case S_SREJ:
-
-		frm = "SREJ";
-		break;
-
-	case U_SABM:
-
-		frm = "SABM";
-		break;
-
-	case SABME:
-
-		frm = "SABME";
-		break;
-
-	case U_DISC:
-
-		frm = "DISC";
-		break;
-
-	case U_DM:
-
-		frm = "DM";
-		break;
-
-	case U_UA:
-
-		frm = "UA";
-		break;
-
-	case U_FRMR:
-
-		frm = "FRMR";
-		break;
-
-	case U_UI:
-
-		frm = "UI";
-	}
-
-//	07:29:42T G8BPQ - 2 > TEST Port = 20 < UI > :
-//	helllo
-//	07:30: 8T G8BPQ - 2 > ID Port = 20 < UI C > :
-//	Network node(BPQ)
-
-	if (Digi[0])
-//		sprintf(Path, "Fm %s To %s Via %s <%s %c%s", CallFrom, CallTo, Digi, frm, c, p);
-		sprintf(Path, "%s%c %s>%s,%s <%s %c%s", ShortDateTime(), TR, CallFrom, CallTo, Digi, frm, c, p);
-	else
-//		sprintf(Path, "Fm %s To %s <%s %c %s", CallFrom, CallTo, frm, c, p);
-	sprintf(Path, "%s%c %s>%s <%s %c%s", ShortDateTime(), TR, CallFrom, CallTo, frm, c, p);
-
-
-	switch (f_type)
-	{
-	case I_FRM:
-
-		//mon_frm = Path + ctrl + ' R' + inttostr(nr) + ' S' + inttostr(ns) + ' pid=' + dec2hex(pid) + ' Len=' + inttostr(len) + ' >' + time_now + #13 + _data + #13#13;
-		sprintf(mon_frm, "%s R%d S%d>%s\r%s\r", Path, nr, ns, codestr, _data);
-
-		break;
-
-	case U_FRM:
-
-		if (f_id == U_UI)
-		{
-			sprintf(mon_frm, "%s>:\r%s\r", Path, _data); // "= Path + ctrl + '>' + time_now + #13;
-		}
-		else if (f_id == U_FRMR)
-		{
-			sprintf(mon_frm, "%s>%02x %02x %02x\r", Path, datap[0], datap[1], datap[2]); // "= Path + ctrl + '>' + time_now + #13;
-		}
-		else
-			sprintf(mon_frm, "%s>%s\r", Path, codestr); // "= Path + ctrl + '>' + time_now + #13;
-
-		break;
-
-	case S_FRM:
-
-		//		mon_frm = Path + ctrl + ' R' + inttostr(nr) + ' >' + time_now + #13;
-		sprintf(mon_frm, "%s R%d>%s\r", Path, nr, codestr); // "= Path + ctrl + '>' + time_now + #13;
-
-		break;
-
-	}
-	sprintf(FrameData, "%s", mon_frm);
-
-	freeString(data);
-	return FrameData;
-}
-
-typedef struct _MHSTRUC
-{
-	UCHAR MHCALL[7];
-	UCHAR MHDIGIS[7][8];
-	time_t MHTIME;
-	int MHCOUNT;
-	unsigned char MHDIGI;
-	char MHFreq[12];
-	char MHLocator[6];
-} MHSTRUC, *PMHSTRUC;
-
-
-#define MHENTRIES 30
-
-MHSTRUC MHEARD[(MHENTRIES + 1) * sizeof(MHSTRUC)] = { 0 };
-
-int CompareCalls(UCHAR * c1, UCHAR * c2)
-{
-	//	COMPARE AX25 CALLSIGNS IGNORING EXTRA BITS IN SSID
-
-	if (memcmp(c1, c2, 6))
-		return FALSE;			// No Match
-
-	if ((c1[6] & 0x1e) == (c2[6] & 0x1e))
-		return TRUE;
-
-	return FALSE;
-}
-
-static char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-void * MHWindow = 0;
-void WritetoMHWindow(char * Buffer);
-int KISSMH = 0;
-
-char * FormatMH(PMHSTRUC MH)
-{
-	struct tm * TM;
-	static char MHTime[50];
-	time_t szClock;
-	char LOC[7];
-
-	memcpy(LOC, MH->MHLocator, 6);
-	LOC[6] = 0;
-
-		szClock = MH->MHTIME;
-//	else
-//		szClock = time(NULL) - MH->MHTIME;
-
-	TM = gmtime(&szClock);
-
-		sprintf(MHTime, "%s %02d %.2d:%.2d:%.2d  %s %s",
-			month[TM->tm_mon], TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec, MH->MHFreq, LOC);
-
-	return MHTime;
-}
-
-
-
-
-void  MHPROC(unsigned char * Packet, int Len)
-{
-	PMHSTRUC MH = &MHEARD[0];
-	PMHSTRUC MHBASE = MH;
-	int i;
-	int OldCount = 0;
-	char Freq[64] = "";
-	char DIGI = '*';
-
-	MESSAGE Frame;
-	MESSAGE * Buffer = &Frame;
-
-	memcpy(Buffer->DEST, Packet, Len);
-
-
-	// if port has a freq associated with it use it
-
-
-	//	if (Buffer->ORIGIN[6] & 1)
-	DIGI = 0;					// Don't think we want to do this
-
-// See if in list
-
-	for (i = 0; i < MHENTRIES; i++)
-	{
-		if ((MH->MHCALL[0] == 0) || (CompareCalls(Buffer->ORIGIN, MH->MHCALL) && MH->MHDIGI == DIGI)) // Spare or our entry
-		{
-			OldCount = MH->MHCOUNT;
-			goto DoMove;
-		}
-		MH++;
-	}
-
-	//	TABLE FULL AND ENTRY NOT FOUND - MOVE DOWN ONE, AND ADD TO TOP
-
-	i = MHENTRIES - 1;
-
-	// Move others down and add at front
-DoMove:
-	if (i != 0)				// First
-		memmove(MHBASE + 1, MHBASE, i * sizeof(MHSTRUC));
-
-	memcpy(MHBASE->MHCALL, Buffer->ORIGIN, 7 * 9);		// Save Digis
-	MHBASE->MHDIGI = DIGI;
-	MHBASE->MHTIME = time(NULL);
-	MHBASE->MHCOUNT = ++OldCount;
-	strcpy(MHBASE->MHFreq, Freq);
-	MHBASE->MHLocator[0] = 0;
-
-	if (MHWindow)
-	{
-		int count = MHENTRIES;
-		int n;
-		char Normcall[20];
-		char From[10];
-		char DigiList[100];
-		char * Output;
-		int len;
-		char Digi = 0;
-		char MHPage[MHENTRIES * 100];
-		char * Bufferptr = MHPage;
-		unsigned char * ptr;
-
-		MH = &MHEARD[0];
-
-		// Note that the MHDIGIS field may contain rubbish. You have to check End of Address bit to find
-		// how many digis there are
-
-		Bufferptr += sprintf(Bufferptr, "Callsign   Last heard     Pkts RX    via Digi\r");
-		Bufferptr += sprintf(Bufferptr, "\r");
-
-		while (count--)
-		{
-			if (MH->MHCALL[0] == 0)
-				break;
-
-			Digi = 0;
-
-			len = ConvFromAX25(MH->MHCALL, Normcall);
-
-			Normcall[len++] = MH->MHDIGI;
-			Normcall[len++] = 0;
-
-			n = 8;					// Max number of digi-peaters
-
-			ptr = &MH->MHCALL[6];	// End of Address bit
-
-			Output = &DigiList[0];
-
-			if ((*ptr & 1) == 0)
-			{
-				// at least one digi
-
-				strcpy(Output, "via ");
-				Output += 4;
-
-				while ((*ptr & 1) == 0)
-				{
-					//	MORE TO COME
-
-					From[ConvFromAX25(ptr + 1, From)] = 0;
-					Output += sprintf((char *)Output, "%s", From);
-
-					ptr += 7;
-					n--;
-
-					if (n == 0)
-						break;
-
-					// See if digi actioned - put a * on last actioned
-
-					if (*ptr & 0x80)
-					{
-						if (*ptr & 1)						// if last address, must need *
-						{
-							*(Output++) = '*';
-							Digi = '*';
-						}
-
-						else
-							if ((ptr[7] & 0x80) == 0)		// Repeased by next?
-							{
-								*(Output++) = '*';			// No, so need *
-								Digi = '*';
-							}
-
-					}
-					*(Output++) = ',';
-				}
-				*(--Output) = 0;							// remove last comma
-			}
-			else
-				*(Output) = 0;
-
-			// if we used a digi set * on call and display via string
-
-
-			if (Digi)
-				Normcall[len++] = Digi;
-			else
-				DigiList[0] = 0;	// Dont show list if not used
-
-			Normcall[len++] = 0;
-
-			ptr = FormatMH(MH);
-
-			Bufferptr += sprintf(Bufferptr, "%-10s %-10s %-10d %-30s\r", Normcall, ptr, MH->MHCOUNT, DigiList);
-
-			MH++;
-		}
-
-		WritetoMHWindow(MHPage);
-	}
-	return;
-}
-
-
-
-
-
-
-
+/*
+Copyright (C) 2019-2020 Andrei Kopanchuk UZ7HO
+
+This file is part of QtSoundModem
+
+QtSoundModem is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+QtSoundModem is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with QtSoundModem.  If not, see http://www.gnu.org/licenses
+
+*/
+
+// UZ7HO Soundmodem Port by John Wiseman G8BPQ
+
+// This is a simplified version for QtTermTCP
+
+#include "ax25.h"
+#include <stdarg.h>
+
+extern int KISSChecksum;
+
+#ifdef WIN32
+
+__declspec(dllimport) unsigned short __stdcall htons(__in unsigned short hostshort);
+__declspec(dllimport) unsigned short __stdcall ntohs(__in unsigned short hostshort);
+
+#else
+
+#define strtok_s strtok_r
+#include <stddef.h>
+#endif 
+
+void decode_frame(Byte * frame, int len, Byte * path, string * data,
+	Byte * pid, Byte * nr, Byte * ns, Byte * f_type, Byte * f_id,
+	Byte *  rpt, Byte * pf, Byte * cr);
+
+void SetSessLabel(void * Sess, char * label);
+void setMenus(int State);
+void MHPROC(unsigned char * Packet, int Len);
+/*
+
+unit ax25;
+
+interface
+
+uses classes,sysutils,windows;
+
+  procedure get_exclude_list(line: string; var list: TStringList);
+  procedure get_exclude_frm(line: string; var list: TStringList);
+  procedure get_monitor_path(path: string; var mycall,corrcall,digi: string);
+  procedure get_call(src_call: string; var call: string);
+  procedure get_call_fm_path(path: string; var callto,callfrom: string);
+  procedure set_corrcall(snd_ch,port: byte; path: string);
+  procedure set_mycall(snd_ch,port: byte; path: string);
+  procedure set_digi(snd_ch,port: byte; path: string);
+  procedure decode_frame(frame: string; var path,data: string; var pid,nr,ns,f_type,f_id: byte; var rpt,pf,cr: boolean);
+  procedure del_incoming_mycalls(src_call: string);
+  procedure del_incoming_mycalls_by_sock(socket: integer);
+  procedure ax25_info_init(snd_ch,port: byte);
+  procedure write_ax25_info(snd_ch,port: byte);
+  procedure clr_frm_win(snd_ch,port: byte);
+  procedure ax25_init;
+  procedure ax25_free;
+  function dec2hex(value: byte): string;
+  function get_corrcall(path: string): string;
+  function get_mycall(path: string): string;
+  function get_digi(path: string): string;
+  function is_excluded_call(snd_ch: byte; path: string): boolean;
+  function is_excluded_frm(snd_ch,f_id: byte; data: string): boolean;
+  function is_last_digi(path: string): boolean;
+  function is_digi(snd_ch,port: byte; path: string): boolean;
+  function is_corrcall(snd_ch,port: byte; path: string): boolean;
+  function is_mycall(snd_ch,port: byte; path: string): boolean;
+  function is_correct_path(path: string; pid: byte): boolean;
+  function direct_addr(path: string): string;
+  function reverse_addr(path: string): string;
+  function reverse_digi(path: string): string;
+  function number_digi(path: string): byte;
+  function info_pid(pid: byte): string;
+  function get_fcs(var data: string; len: word): word;
+  function set_addr(path: string; rpt,cr: boolean): string;
+  function set_ctrl(nr,ns,f_type,f_id: byte; pf: boolean): byte;
+  function make_frame(data,path: string; pid,nr,ns,f_type,f_id: byte; rpt,pf,cr: boolean): string;
+  function get_incoming_socket_by_call(src_call: string): integer;
+  function add_incoming_mycalls(socket: integer; src_call: string): boolean;
+  function in_list_incoming_mycall(path: string): boolean;
+  function get_UTC_time: string;
+  function parse_NETROM(data: string; f_id: byte): string;
+  function parse_IP(data: string): string;
+  function parse_ARP(data: string): string;
+  function add_raw_frames(snd_ch: byte; frame: string; var buf: TStringList): boolean;
+  function scrambler(in_buf: string): string;
+  function my_indexof(var l: TStringList; s: string): integer;
+
+
+const
+  port_num=32;
+  PKT_ERR=17; //Minimum packet size, bytes
+  I_MAX=7; //Maximum number of packets
+  B_IDX_MAX=256;
+  ADDR_MAX_LEN=10;
+  FRAME_FLAG=126;
+  // Status flags
+  STAT_NO_LINK=0;
+  STAT_LINK=1;
+  STAT_CHK_LINK=2;
+  STAT_WAIT_ANS=3;
+  STAT_TRY_LINK=4;
+  STAT_TRY_UNLINK=5;
+  // md,Resp,Poll,Final,Digipeater flags
+  SET_P=TRUE;
+  SET_F=FALSE;
+  SET_C=TRUE;
+  SET_R=FALSE;
+  SET_NO_RPT=FALSE;
+  SET_RPT=TRUE;
+  // Frame ID flags
+  I_FRM=0;
+  S_FRM=1;
+  U_FRM=2;
+  I_I=0;
+  S_RR=1;
+  S_RNR=5;
+  S_REJ=9;
+  U_SABM=47;
+  U_DISC=67;
+  U_DM=15;
+  U_UA=99;
+  U_FRMR=135;
+  U_UI=3;
+  // PID flags
+  PID_X25=$01;       // 00000001-CCIT X25 PLP
+  PID_SEGMENT=$08;   // 00001000-Segmentation fragment
+  PID_TEXNET=$C3;    // 11000011-TEXNET Datagram Protocol
+  PID_LQ=$C4;        // 11001000-Link Quality Protocol
+  PID_APPLETALK=$CA; // 11001010-Appletalk
+  PID_APPLEARP=$CB;  // 11001011-Appletalk ARP
+  PID_IP=$CC;        // 11001100-ARPA Internet Protocol
+  PID_ARP=$CD;       // 11001101-ARPA Address Resolution Protocol
+  PID_NET_ROM=$CF;   // 11001111-NET/ROM
+*/
+
+#define ADDR_MAX_LEN 10
+#define PID_NO_L3 0xF0;     // 11110000-No Level 3 Protocol
+
+
+unsigned short CRCTable[256] = {
+	  0,  4489,  8978, 12955, 17956, 22445, 25910, 29887,
+  35912, 40385, 44890, 48851, 51820, 56293, 59774, 63735,
+   4225,   264, 13203,  8730, 22181, 18220, 30135, 25662,
+  40137, 36160, 49115, 44626, 56045, 52068, 63999, 59510,
+   8450, 12427,   528,  5017, 26406, 30383, 17460, 21949,
+  44362, 48323, 36440, 40913, 60270, 64231, 51324, 55797,
+  12675,  8202,  4753,   792, 30631, 26158, 21685, 17724,
+  48587, 44098, 40665, 36688, 64495, 60006, 55549, 51572,
+  16900, 21389, 24854, 28831,  1056,  5545, 10034, 14011,
+  52812, 57285, 60766, 64727, 34920, 39393, 43898, 47859,
+  21125, 17164, 29079, 24606,  5281,  1320, 14259,  9786,
+  57037, 53060, 64991, 60502, 39145, 35168, 48123, 43634,
+  25350, 29327, 16404, 20893,  9506, 13483,  1584,  6073,
+  61262, 65223, 52316, 56789, 43370, 47331, 35448, 39921,
+  29575, 25102, 20629, 16668, 13731,  9258,  5809,  1848,
+  65487, 60998, 56541, 52564, 47595, 43106, 39673, 35696,
+  33800, 38273, 42778, 46739, 49708, 54181, 57662, 61623,
+   2112,  6601, 11090, 15067, 20068, 24557, 28022, 31999,
+  38025, 34048, 47003, 42514, 53933, 49956, 61887, 57398,
+   6337,  2376, 15315, 10842, 24293, 20332, 32247, 27774,
+  42250, 46211, 34328, 38801, 58158, 62119, 49212, 53685,
+  10562, 14539,  2640,  7129, 28518, 32495, 19572, 24061,
+  46475, 41986, 38553, 34576, 62383, 57894, 53437, 49460,
+  14787, 10314,  6865,  2904, 32743, 28270, 23797, 19836,
+  50700, 55173, 58654, 62615, 32808, 37281, 41786, 45747,
+  19012, 23501, 26966, 30943,  3168,  7657, 12146, 16123,
+  54925, 50948, 62879, 58390, 37033, 33056, 46011, 41522,
+  23237, 19276, 31191, 26718,  7393,  3432, 16371, 11898,
+  59150, 63111, 50204, 54677, 41258, 45219, 33336, 37809,
+  27462, 31439, 18516, 23005, 11618, 15595,  3696,  8185,
+  63375, 58886, 54429, 50452, 45483, 40994, 37561, 33584,
+  31687, 27214, 22741, 18780, 15843, 11370,  7921,  3960 };
+
+
+unsigned short pkt_raw_min_len = 8;
+int stat_r_mem = 0;
+
+struct TKISSMode_t KISS;
+
+
+TAX25Port AX25Port[4][port_num];
+
+TStringList KISS_acked[4];
+TStringList KISS_iacked[4];
+
+typedef struct registeredCalls_t
+{
+	UCHAR myCall[7];		// call in ax.25
+	void * socket;
+
+} registeredCalls;
+
+
+TStringList list_incoming_mycalls;	// list strings containing a registered call
+
+
+boolean busy = 0;
+boolean dcd[5] = { 0 ,0 ,0, 0 };
+
+boolean  tx = 0;
+
+int stdtones = 0;
+int fullduplex = 0;
+
+UCHAR diddles = 0;
+
+word MEMRecovery[5] = { 200,200,200,200 };
+int NonAX25[5] = { 0 };
+
+boolean dyn_frack[4] = { FALSE,FALSE,FALSE,FALSE };
+Byte recovery[4] = { 0,0,0,0 };
+Byte users[4] = { 0,0,0,0 };
+
+short txtail[5] = { 50, 50, 50, 50, 50 };
+short txdelay[5] = { 400, 400, 400, 400, 400 };
+int sendTXDelay[4] = { 0, 0, 0, 0 };
+
+
+short modem_def[5] = { 1, 1, 1, 1, 1 };
+
+int emph_db[5] = { 0, 0, 0, 0, 0 };
+UCHAR emph_all[5] = { 0, 0, 0, 0, 0 };
+
+boolean  KISS_opt[4] = { FALSE, FALSE, FALSE, FALSE };
+int resptime[4] = { 1500,1500,1500,1500 };
+int slottime[4] = { 100,100,100,100 };
+int persist[4] = { 100,100,100,100 };
+int kisspaclen[4] = { 128,128,128,128 };
+int fracks[4] = { 10,10,10,10 };
+int frack_time[4] = { 5,5,5,5 };
+int idletime[4] = { 180,180,180,180 };
+int redtime[4] = { 0,0,0,0 };
+int IPOLL[4] = { 30,30,30,30 };
+int maxframe[4] = { 4,4,4,4 };
+int TXFrmMode[4] = { 1,1,1,1 };
+int max_frame_collector[4] = { 6,6,6,6 };
+
+
+char MyDigiCall[4][512] = { "","","","" };
+char exclude_callsigns[4][512] = { "","","","" };
+char exclude_APRS_frm[4][512] = { "","","","" };
+
+TStringList  list_exclude_callsigns[4];
+TStringList list_exclude_APRS_frm[4];
+TStringList list_digi_callsigns[4];
+
+Byte xData[256];
+Byte xEncoded[256];
+Byte xDecoded[256];
+
+int frame_count = 0;
+int single_frame_count = 0;
+
+/*
+  mydigi: string;
+  //// end of user params
+  addr: string[70];
+  ctrl: byte;
+  pid: byte=PID_NO_L3;
+  fcs: word;
+  data: string;
+  frame: string;
+
+implementation
+
+uses ax25_l2,sm_main;
+
+*/
+
+char * strlop(char * buf, char delim)
+{
+	// Terminate buf at delim, and return rest of string
+
+	char * ptr = strchr(buf, delim);
+
+	if (ptr == NULL) return NULL;
+
+	*(ptr)++ = 0;
+	return ptr;
+}
+
+void Debugprintf(const char * format, ...)
+{
+	char Mess[10000];
+	va_list(arglist);
+
+	va_start(arglist, format);
+	vsprintf(Mess, format, arglist);
+	WriteDebugLog(Mess);
+
+	return;
+}
+
+
+	
+void AX25_conn(TAX25Port * AX25Sess, int snd_ch, Byte mode)
+{
+	UNUSED(snd_ch);
+	char Msg[128];
+	int Len = 0;
+
+	switch (mode)
+	{
+	case MODE_OTHER:
+
+		Len = sprintf(Msg, "Incoming KISS Connection from %s\r", AX25Sess->corrcall);
+		break;
+
+	case MODE_OUR:
+
+		Len = sprintf(Msg, "Connected To %s\r", AX25Sess->corrcall);
+		break;
+
+	};
+
+	SendtoTerm(AX25Sess->Sess, Msg, Len);
+	SetSessLabel(AX25Sess->Sess, AX25Sess->corrcall);
+	setMenus(1);
+}
+
+void send_data_buf(TAX25Port * AX25Sess, int  nr);
+
+void SendtoAX25(void * conn, Byte * Msg, int Len)
+{
+	TAX25Port * AX25Sess;
+	AX25Sess = (TAX25Port * )conn;
+
+	// Need to enforce PacLen
+
+	if (AX25Sess)
+	{
+		int n;
+
+		while (Len)
+		{
+			string * data = newString();
+
+			if (Len > kisspaclen[0])
+				n = kisspaclen[0];
+			else
+				n = Len;
+
+			stringAdd(data, Msg, n);
+			Add(&AX25Sess->in_data_buf, data);
+
+			Len -= n;
+			Msg += n;
+		}
+		send_data_buf(AX25Sess, AX25Sess->vs);
+	}
+}
+
+
+
+
+
+void scrambler(UCHAR * in_buf, int Len)
+{
+	integer i;
+	word  sreg;
+	Byte  a = 0, k;
+
+	sreg = 0x1ff;
+
+	for (i = 0; i < Len; i++)
+	{
+		for (k = 0; k < 8; k++)
+		{
+
+			//	a: = (a shr 1) or (sreg and 1 shl 7);
+
+			a = (a >> 1) | ((sreg & 1) << 7);
+
+			//	sreg: = (sreg shl 4 and $200) xor (sreg shl 8 and $200) or (sreg shr 1);
+
+
+			sreg = (((sreg << 4) & 0x200) ^ ((sreg << 8) & 0x200)) | (sreg >> 1);
+		}
+		in_buf[i] = in_buf[i] ^ a;
+	}
+}
+
+
+/*
+function parse_ARP(data: string): string;
+
+function get_callsign(data: string): string;
+var
+  i: integer;
+  s: string;
+  a: byte;
+begin
+  s:='';
+  if length(data)=7 then
+  begin
+	for i:=1 to 6 do
+	begin
+	  a:=ord(data[i]) shr 1;
+	  if (a in [$30..$39,$41..$5A]) then s:=s+chr(a);
+	end;
+	a:=ord(data[7]) shr 1 and 15;
+	if a>0 then s:=s+'-'+inttostr(a);
+  end
+  else
+  begin
+	if length(data)>0 then
+	begin
+	  for i:=1 to length(data) do
+		if i=1 then s:=dec2hex(ord(data[i])) else s:=s+':'+dec2hex(ord(data[i]));
+	end;
+  end;
+  if s<>'' then s:=s+' ';
+  result:=s;
+end;
+
+function get_IP(data: string): string;
+var
+  i: integer;
+  s: string;
+begin
+  s:='';
+  if length(data)>0 then
+  begin
+	for i:=1 to length(data) do
+	  if i=1 then s:=inttostr(ord(data[i])) else s:=s+'.'+inttostr(ord(data[i]));
+  end;
+  if s<>'' then s:=s+' ';
+  result:=s;
+end;
+
+const
+  opcode: array [0..3] of string = ('ARP Request','ARP Response','RARP Request','RARP Response');
+var
+  oper: word;
+  hlen,plen: byte;
+  sha,spa,tha,tpa: string;
+  s: string;
+  i: word;
+begin
+  s:=data;
+  if length(data)>7 then
+  begin
+	hlen:=ord(data[5]);
+	plen:=ord(data[6]);
+	oper:=(ord(data[7]) shl 8 or ord(data[8])) and 2;
+	i:=9;      sha:=get_callsign(copy(data,i,hlen));
+	i:=i+hlen; spa:=get_ip(copy(data,i,plen));
+	i:=i+plen; tha:=get_callsign(copy(data,i,hlen));
+	i:=i+hlen; tpa:=get_ip(copy(data,i,plen));
+	s:='  [ARP] '+opcode[oper]+' from '+sha+spa+'to '+tha+tpa;
+  end;
+  result:=s;
+end;
+
+function parse_NETROM(data: string; f_id: byte): string;
+
+  function deshift_AX25(data: string): string;
+  var
+	i: byte;
+	call: string[6];
+	ssid: string[2];
+  begin
+	result:='';
+	if length(data)<7 then exit;
+	for i:=1 to 7 do data[i]:=chr(ord(data[i]) shr 1);
+	call:=trim(copy(data,1,6));
+	ssid:=trim(inttostr(ord(data[7]) and 15));
+	if ssid='0' then result:=call else result:=call+'-'+ssid;
+  end;
+
+  function con_req_info(data: string): string;
+  var
+	s_call: string;
+	d_call: string;
+	w: byte;
+	t_o: byte;
+  begin
+	result:='';
+	if length(data)>14 then
+	begin
+	  w:=ord(data[1]);
+	  s_call:=deshift_AX25(copy(data,2,7));
+	  d_call:=deshift_AX25(copy(data,9,7));
+	  result:=' w='+inttostr(w)+' '+s_call+' at '+d_call;
+	end;
+	if length(data)>15 then
+	begin
+	  t_o:=ord(data[16]);
+	  result:=result+' t/o '+inttostr(t_o);
+	end;
+  end;
+
+  function con_ack_info(data: string): string;
+  var
+	w: byte;
+  begin
+	result:='';
+	if length(data)>0 then
+	begin
+	  w:=ord(data[1]);
+	  result:=' w='+inttostr(w);
+	end;
+  end;
+
+const
+  opcode_arr: array[0..7] of string = ('PE','CON REQ','CON ACK','DISC REQ','DISQ ACK','INFO','INFO ACK','RST');
+var
+  s: string;
+  netrom_header: string;
+  c_idx:  byte;
+  c_ID:   byte;
+  TX_nr:  byte;
+  RX_nr:  byte;
+  opcode: byte;
+  s_call: string;
+  s_node: string;
+  d_call: string;
+  d_node: string;
+  b_call: string;
+  r_s_nr: string;
+  opc_flags: string;
+  quality: byte;
+  ttl: byte;
+  hops: byte;
+  rtt: word;
+  inp3_nr_field: byte;
+  inp3_field_len: byte;
+  inp3_ext_fields: boolean;
+begin
+  s:=data;
+  if length(data)>0 then
+  begin
+	if data[1]=#$FF then
+	begin
+	  delete(data,1,1);
+	  //Nodes broadcasting
+	  if (f_id=U_UI) and (length(data)>5) then
+	  begin
+		s_node:=copy(data,1,6);
+		delete(data,1,6);
+		s:='NODES broadcast from '+s_node+#13#10;
+		while length(data)>20 do
+		begin
+		  d_call:=deshift_AX25(copy(data,1,7));
+		  d_node:=copy(data,8,6);
+		  b_call:=deshift_AX25(copy(data,14,7));
+		  quality:=ord(data[21]);
+		  delete(data,1,21);
+		  s:=s+'  '+d_node+':'+d_call+' via '+b_call+' Q='+inttostr(quality)+#13#10;
+		end;
+	  end;
+	  // INP3 RIF
+	  if (f_id=I_I) and (length(data)>10) then
+	  begin
+		s:='[INP3 RIF]'+#13#10;
+		while length(data)>10 do
+		begin
+		  d_call:=deshift_AX25(copy(data,1,7));
+		  hops:=ord(data[8]);
+		  rtt:=(ord(data[9]) shl 8) or ord(data[10]);
+		  delete(data,1,10);
+		  inp3_ext_fields:=TRUE;
+		  inp3_nr_field:=0;
+		  while (length(data)>0) and inp3_ext_fields do
+		  begin
+			inp3_field_len:=ord(data[1]);
+			if inp3_field_len>0 then
+			begin
+			  if (inp3_nr_field=0) and (length(data)>1) then
+			  begin
+				if data[2]=#0 then d_call:=copy(data,3,inp3_field_len-2)+':'+d_call; // Copy alias
+			  end;
+			  delete(data,1,inp3_field_len);
+			  inc(inp3_nr_field);
+			end
+			else inp3_ext_fields:=FALSE;
+		  end;
+		  delete(data,1,1);
+		  s:=s+d_call+' hops='+inttostr(hops)+' rtt='+inttostr(rtt)+#13#10;
+		end;
+	  end;
+	end
+	else
+	begin
+	  // NETROM frames
+	  if length(data)>19 then
+	  begin
+		s_call:=deshift_AX25(copy(data,1,7));
+		d_call:=deshift_AX25(copy(data,8,7));
+		ttl:=ord(data[15]);
+		netrom_header:=copy(data,16,5);
+		delete(data,1,20);
+		c_idx:=ord(netrom_header[1]);
+		c_ID:=ord(netrom_header[2]);
+		TX_nr:=ord(netrom_header[3]);
+		RX_nr:=ord(netrom_header[4]);
+		opcode:=ord(netrom_header[5]);
+		// Opcode flags
+		opc_flags:='';
+		if opcode and 128 = 128 then opc_flags:=opc_flags+' C';
+		if opcode and 64  = 64  then opc_flags:=opc_flags+' N';
+		//
+		s:='  [NETROM] '+s_call+' to '+d_call+' ttl='+inttostr(ttl)+' cct='+dec2hex(c_idx)+dec2hex(c_ID);
+		r_s_nr:=' S'+inttostr(TX_nr)+' R'+inttostr(RX_nr);
+		case (opcode and 7) of
+		  0 : s:=s+' <'+opcode_arr[opcode and 7]+r_s_nr+'>'+#13#10+data;
+		  1 : s:=s+' <'+opcode_arr[opcode and 7]+'>'+con_req_info(data);
+		  2 : s:=s+' <'+opcode_arr[opcode and 7]+'>'+con_ack_info(data)+' my cct='+dec2hex(TX_nr)+dec2hex(RX_nr);
+		  3 : s:=s+' <'+opcode_arr[opcode and 7]+'>';
+		  4 : s:=s+' <'+opcode_arr[opcode and 7]+'>';
+		  5 : s:=s+' <'+opcode_arr[opcode and 7]+r_s_nr+'>:'+#13#10+data;
+		  6 : s:=s+' <'+opcode_arr[opcode and 7]+' R'+inttostr(RX_nr)+'>'+opc_flags;
+		  7 : s:=s+' <'+opcode_arr[opcode and 7]+r_s_nr+'>'+#13#10+data;
+		end;
+	  end;
+	end;
+  end;
+  result:=s;
+end;
+
+function parse_IP(data: string): string;
+
+  function parse_ICMP(var data: string): string;
+  var
+	ICMP_type: byte;
+	ICMP_code: byte;
+	s: string;
+  begin
+	result:='';
+	if length(data)>3 then
+	begin
+	  ICMP_type:=ord(data[1]);
+	  ICMP_code:=ord(data[2]);
+	  delete(data,1,4);
+	  s:='  [ICMP] Type='+inttostr(ICMP_type)+' Code='+inttostr(ICMP_code)+#13#10;
+	  result:=s;
+	end;
+  end;
+
+  function parse_TCP(var data: string): string;
+  var
+	s: string;
+	src_port: string;
+	dest_port: string;
+	wnd: string;
+	ihl: word;
+	idl: word;
+	flags: byte;
+	seq: string;
+	ack: string;
+	s_flags: string;
+	s_idl: string;
+  begin
+	result:='';
+	if length(data)>19 then
+	begin
+	  src_port:=' src_port:'+inttostr((ord(data[1]) shl 8)+ord(data[2]));
+	  dest_port:=' dest_port:'+inttostr((ord(data[3]) shl 8)+ord(data[4]));
+	  seq:=' seq='+dec2hex(ord(data[5]))+dec2hex(ord(data[6]))+dec2hex(ord(data[7]))+dec2hex(ord(data[8]));
+	  ack:=' ack='+dec2hex(ord(data[9]))+dec2hex(ord(data[10]))+dec2hex(ord(data[11]))+dec2hex(ord(data[12]));
+	  ihl:=(ord(data[13]) shr 4)*4;
+	  idl:=length(data)-ihl;
+	  flags:=ord(data[14]);
+	  wnd:=' wnd='+inttostr((ord(data[15]) shl 8)+ord(data[16]));
+	  delete(data,1,ihl);
+	  //
+	  s_flags:=' ';
+	  if (flags and 32)=32 then s_flags:=s_flags+'URG ';
+	  if (flags and 16)=16 then s_flags:=s_flags+'ACK ';
+	  if (flags and 8)=8   then s_flags:=s_flags+'PSH ';
+	  if (flags and 4)=4   then s_flags:=s_flags+'RST ';
+	  if (flags and 2)=2   then s_flags:=s_flags+'SYN ';
+	  if (flags and 1)=1   then s_flags:=s_flags+'FIN ';
+	  //
+	  if idl>0 then s_idl:=' data='+inttostr(idl) else s_idl:='';
+	  if (flags and 16)<>16 then ack:='';
+	  //
+	  s:='  [TCP]'+src_port+dest_port+seq+ack+wnd+s_idl+s_flags+#13#10;
+	  result:=s;
+	end;
+  end;
+
+  function parse_UDP(var data: string): string;
+  var
+	s: string;
+	src_port: string;
+	dest_port: string;
+	idl: word;
+	len: word;
+	s_idl: string;
+  begin
+	result:='';
+	if length(data)>7 then
+	begin
+	  src_port:=' src_port:'+inttostr((ord(data[1]) shl 8)+ord(data[2]));
+	  dest_port:=' dest_port:'+inttostr((ord(data[3]) shl 8)+ord(data[4]));
+	  len:=(ord(data[5]) shl 8)+ord(data[6]);
+	  idl:=len-8;
+	  delete(data,1,8);
+	  //
+	  if idl>0 then s_idl:=' data='+inttostr(idl) else s_idl:='';
+	  //
+	  s:='  [UDP]'+src_port+dest_port+' len='+inttostr(len)+s_idl+#13#10;
+	  result:=s;
+	end;
+  end;
+
+const
+  prot_idx=#1#6#17;
+  prot_name: array [1..3] of string = ('ICMP','TCP','UDP');
+var
+  s: string;
+  src_ip: string;
+  dest_ip: string;
+  s_prot: string;
+  len: string;
+  c_prot: char;
+  ttl: string;
+  offset: string;
+  ihl: byte;
+  p: byte;
+  fragment_offset: word;
+begin
+  s:=data;
+  if length(data)>19 then
+  begin
+	ihl:=(ord(data[1]) and 15)*4;
+	len:=' len='+inttostr((ord(data[3]) shl 8)+ord(data[4]));
+	fragment_offset:=((ord(data[7]) shl 8)+ord(data[8])) shl 3;
+	ttl:=' ttl='+inttostr(ord(data[9]));
+	c_prot:=data[10];
+	src_ip:=' Fm '+inttostr(ord(data[13]))+'.'+inttostr(ord(data[14]))+'.'+inttostr(ord(data[15]))+'.'+inttostr(ord(data[16]));
+	dest_ip:=' To '+inttostr(ord(data[17]))+'.'+inttostr(ord(data[18]))+'.'+inttostr(ord(data[19]))+'.'+inttostr(ord(data[20]));
+	delete(data,1,ihl);
+	//
+	p:=pos(c_prot,prot_idx);
+	if p>0 then s_prot:=' prot='+prot_name[p] else s_prot:=' prot=Type'+inttostr(ord(c_prot));
+	if fragment_offset>0 then offset:=' offset='+inttostr(fragment_offset) else offset:='';
+	s:='  [IP]'+src_ip+dest_ip+s_prot+ttl+len+offset+#13#10;
+	if fragment_offset=0 then
+	case p of
+	  1 : s:=s+parse_ICMP(data);
+	  2 : s:=s+parse_TCP(data);
+	  3 : s:=s+parse_UDP(data);
+	end;
+	s:=s+data;
+  end;
+  result:=s;
+end;
+
+function get_UTC_time: string;
+var
+  st: TSYSTEMTIME;
+  sec,hour,minute: string;
+begin
+  GetSystemTime(st);
+  if st.wSecond<10 then sec:='0'+inttostr(st.wSecond) else sec:=inttostr(st.wSecond);
+  if st.wMinute<10 then minute:='0'+inttostr(st.wMinute) else minute:=inttostr(st.wMinute);
+  if st.wHour<10 then Hour:='0'+inttostr(st.wHour) else Hour:=inttostr(st.wHour);
+  result:=hour+':'+minute+':'+sec;
+end;
+
+function dec2hex(value: byte): string;
+const
+  hex='0123456789ABCDEF';
+var
+  lo,hi: byte;
+begin
+  lo:=value and 15;
+  hi:=value shr 4;
+  result:=hex[hi+1]+hex[lo+1];
+end;
+
+*/
+
+unsigned short get_fcs(UCHAR * Data, unsigned short len)
+{
+	unsigned short i;
+	unsigned short result;
+
+	result = 0xFFFF;
+
+	if (len == 0)
+		return result;
+
+	for (i = 0; i < len; i++)
+		result = (result >> 8) ^ CRCTable[(result ^ Data[i]) & 0xff];
+
+
+	result ^= 0xffff;
+
+	return result;
+}
+
+
+unsigned short CRCTAB[256] = {
+	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+unsigned short int compute_crc(unsigned char *buf, int len)
+{
+	unsigned short fcs = 0xffff;
+	int i;
+
+	for (i = 0; i < len; i++)
+		fcs = (fcs >> 8) ^ CRCTAB[(fcs ^ buf[i]) & 0xff];
+
+	fcs ^= 0xffff;
+
+	return fcs;
+}
+
+
+
+int get_addr(char * Calls, UCHAR * AXCalls)
+{
+	//	CONVERT CALL + OPTIONAL DIGI STRING (Comma separated) TO AX25, RETURN 
+	//	CONVERTED STRING IN AXCALLS. Return FALSE if invalied
+
+	Byte * axptr = AXCalls;
+	char * ptr, *Context;
+	int n = 8;						// Max digis
+
+	memset(AXCalls, 0, 72);
+
+	ptr = strtok_s(Calls, " ,", &Context);
+
+	if (ptr == NULL)
+		return FALSE;
+
+	// First field is Call
+
+	if (ConvToAX25(ptr, axptr) == 0)
+		return FALSE;
+
+	axptr += 7;
+
+	ptr = strtok_s(NULL, " ,", &Context);
+
+	if (ptr == 0 || ConvToAX25(ptr, axptr) == 0)
+		return FALSE;
+
+	axptr += 7;
+
+	ptr = strtok_s(NULL, " ,", &Context);
+
+	while (ptr && n--)
+	{
+		// NEXT FIELD = COULD BE CALLSIGN, VIA, 
+
+		if (memcmp(ptr, "VIA", (int)strlen(ptr)) == 0)
+		{
+		}	//skip via
+		else
+		{
+			// Convert next digi
+
+			if (ConvToAX25(ptr, axptr) == 0)
+				return FALSE;
+
+			axptr += 7;
+		}
+
+		ptr = strtok_s(NULL, " ,", &Context);
+	}
+
+	axptr[-1] |= 1;			// Set end of address
+
+	return axptr - AXCalls;
+}
+
+Byte set_ctrl(Byte nr, Byte ns, Byte f_type, Byte f_id, boolean pf)
+{
+	Byte  pf_bit, ctrl;
+
+	ctrl = 0;
+	pf_bit = 0;
+
+	if (pf)
+		pf_bit = 16;
+
+	switch (f_type)
+	{
+	case I_FRM:
+
+		ctrl = (nr << 5) + pf_bit + (ns << 1);
+		break;
+
+	case S_FRM:
+
+		ctrl = (nr << 5) + pf_bit + f_id;
+		break;
+
+	case U_FRM:
+
+		ctrl = f_id + pf_bit;
+	}
+
+	return ctrl;
+}
+
+string * make_frame(string * data, Byte * axaddr,  Byte pid, Byte nr, Byte ns, Byte f_type, Byte f_id, boolean rpr, boolean pf, boolean cr)
+{
+	UNUSED(rpr);
+
+	Byte ctrl;
+
+	string * frame = newString();
+	int addrlen;
+	Byte addr[80];
+
+	frame->Data[0] = 0;					// Lower software expects a kiss control byte here
+	frame->Length = 1;
+
+	ctrl = set_ctrl(nr, ns, f_type, f_id, pf);
+
+	addrlen = strlen((char *)axaddr);
+
+	memcpy(addr, axaddr, addrlen);
+
+	if (cr)
+		addr[6] |= 0x80;		// Set Command Bit
+	else
+		addr[13] |= 0x80;	// Set Response Bit
+
+
+	switch (f_type)
+	{
+	case I_FRM:
+
+		stringAdd(frame, addr, addrlen);
+		stringAdd(frame, (Byte *)&ctrl, 1);
+		stringAdd(frame, (Byte *)&pid, 1);
+		stringAdd(frame, data->Data, data->Length);
+
+		break;
+
+
+	case S_FRM:
+
+		stringAdd(frame, addr, addrlen);
+		stringAdd(frame, (Byte *)&ctrl, 1);
+
+		break;
+
+	case U_FRM:
+
+		if (f_id == U_UI)
+		{
+			stringAdd(frame, addr, addrlen);
+			stringAdd(frame, (Byte *)&ctrl, 1);
+			stringAdd(frame, (Byte *)&pid, 1);
+			stringAdd(frame, data->Data, data->Length);
+		}
+		else if (f_id == U_FRMR)
+		{
+			stringAdd(frame, addr, addrlen);
+			stringAdd(frame, (Byte *)&ctrl, 1);
+			stringAdd(frame, data->Data, data->Length);
+		}
+		else
+		{
+			stringAdd(frame, addr, addrlen);
+			stringAdd(frame, (Byte *)&ctrl, 1);
+		}
+	}
+
+	return frame;
+}
+
+
+int add_raw_frames(int snd_ch, string * frame, TStringList * buf)
+{
+	UNUSED(snd_ch);
+
+	string  *s_data = newString();
+	Byte  s_pid, s_nr, s_ns, s_f_type, s_f_id;
+	Byte  s_rpt, s_cr, s_pf;
+	string  *d_data = newString();
+	Byte  d_pid, d_nr, d_ns, d_f_type, d_f_id;
+	Byte  d_rpt, d_cr, d_pf;
+
+	Byte d_path[80];
+	Byte s_path[80];
+
+	boolean  found_I;
+	int  i;
+
+	unsigned char * framecontents;
+	int Length;
+
+	boolean result = TRUE;
+
+	// Have to be careful as at this point frames have KISS Header and maybe trailer
+
+	if (buf->Count > 0)
+	{
+		// Check for duplicate. Ok to just compare as copy will have same header
+
+		if (my_indexof(buf, frame) >= 0)
+		{
+//			Debugprintf("KISSOptimise discarding duplicate frame");
+			return FALSE;
+		}
+
+		// Need to adjust for KISS bytes
+
+		// Normally one, but ackmode has 3 on front and sizeof(void *) on end
+
+		framecontents = frame->Data;
+		Length = frame->Length;
+
+		if ((framecontents[0] & 15) == 12)		// Ackmode
+		{
+			framecontents += 3;
+			Length -= (3 + sizeof(void *));
+		}
+		else
+		{
+			framecontents++;
+			Length--;
+		}
+
+		decode_frame(framecontents, Length, s_path, s_data, &s_pid, &s_nr, &s_ns, &s_f_type, &s_f_id, &s_rpt, &s_pf, &s_cr);
+
+		found_I = FALSE;
+
+		// check for multiple RR (r)
+
+		if (s_f_id == S_FRM && s_cr == SET_R)
+		{
+			for (i = 0; i < buf->Count; i++)
+			{
+				framecontents = buf->Items[i]->Data;
+				Length = buf->Items[i]->Length;
+
+				if ((framecontents[0] & 15) == 12)		// Ackmode
+				{
+					framecontents += 3;
+					Length -= (3 + sizeof(void *));
+				}
+				else
+				{
+					framecontents++;
+					Length--;
+				}
+
+				decode_frame(framecontents, Length, d_path, d_data, &d_pid, &d_nr, &d_ns, &d_f_type, &d_f_id, &d_rpt, &d_pf, &d_cr);
+
+				if (d_f_id == S_FRM && d_cr == SET_R && strcmp((char *)s_path, (char *)d_path) == 0)
+				{
+					Delete(buf, i);
+					Debugprintf("KISSOptimise discarding unneeded RR(R%d)", d_nr);
+
+					break;
+				}
+			}
+		}
+
+	
+		// check for RR after I Frame
+	
+		if (s_f_id == S_FRM && s_cr == SET_C)
+		{
+			for (i = 0; i < buf->Count; i++)
+			{
+				framecontents = buf->Items[i]->Data;
+				Length = buf->Items[i]->Length;
+
+				if ((framecontents[0] & 15) == 12)		// Ackmode
+				{
+					framecontents += 3;
+					Length -= (3 + sizeof(void *));
+				}
+				else
+				{
+					framecontents++;
+					Length--;
+				}
+
+				decode_frame(framecontents, Length, d_path, d_data, &d_pid, &d_nr, &d_ns, &d_f_type, &d_f_id, &d_rpt, &d_pf, &d_cr);
+
+				if (d_f_id == I_FRM && strcmp((char *)s_path, (char *)d_path) == 0)
+				{
+					found_I = TRUE;
+					break;
+				}
+			}
+
+			if (found_I)
+			{
+				Debugprintf("KISSOptimise discarding unneeded RR(C %d) after I frame", s_nr);
+				result = FALSE;
+			}
+		}
+			
+		// check on I
+
+		if (s_f_id == I_FRM)
+		{
+			for (i = 0; i < buf->Count; i++)
+			{
+				framecontents = buf->Items[i]->Data;
+				Length = buf->Items[i]->Length;
+
+				if ((framecontents[0] & 15) == 12)		// Ackmode
+				{
+					framecontents += 3;
+					Length -= (3 + sizeof(void *));
+				}
+				else
+				{
+					framecontents++;
+					Length--;
+				}
+
+				decode_frame(framecontents, Length, d_path, d_data, &d_pid, &d_nr, &d_ns, &d_f_type, &d_f_id, &d_rpt, &d_pf, &d_cr);
+
+				if (strcmp((char *)s_path, (char *)d_path) == 0 && d_f_id == S_FRM && d_cr == SET_C)
+				{
+					Delete(buf, i);
+					Debugprintf("KISSOptimise discarding unneeded RR(C %d)", d_nr);
+					i--;				// i was removed
+				}
+			}
+		}
+	}
+
+	freeString(d_data);
+	freeString(s_data);
+
+	return result;
+}
+
+//////////////////////// Register incoming callsign ////////////////////////////
+
+// I think a call should only be registered on one socket (or we won't know where to send
+// incoming calls
+
+boolean add_incoming_mycalls(void * socket, char * src_call)
+{
+	registeredCalls * reg = malloc(sizeof(struct registeredCalls_t));
+	int i = 0;
+
+	// Build a string containing Call and Socket
+
+	ConvToAX25(src_call, reg->myCall);
+	reg->socket = socket;
+
+	if (list_incoming_mycalls.Count > 0)
+	{
+		for (i = 0; i < list_incoming_mycalls.Count; i++)
+		{
+			registeredCalls * check = (registeredCalls *)list_incoming_mycalls.Items[i];
+
+			if (memcmp(check->myCall, reg->myCall, 7) == 0)
+			{
+				// Update socket
+
+				check->socket = socket;
+				return FALSE;
+			}
+		}
+	}
+
+	Add(&list_incoming_mycalls, (string *)reg);
+	return TRUE;
+}
+
+
+
+void del_incoming_mycalls(char * src_call)
+{
+	int i = 0;
+	Byte axcall[7];
+	registeredCalls * reg;
+
+	ConvToAX25(src_call, axcall);
+
+	while (i < list_incoming_mycalls.Count)
+	{
+		reg = (registeredCalls *)list_incoming_mycalls.Items[i];
+		{
+			if (memcmp(reg->myCall, axcall, 7) == 0)
+			{
+				// cant use Delete as stringlist doesn't contain strings
+
+				TStringList * Q = &list_incoming_mycalls;
+				int Index = i;
+
+				free(Q->Items[Index]);
+
+				Q->Count--;
+
+				while (Index < Q->Count)
+				{
+					Q->Items[Index] = Q->Items[Index + 1];
+					Index++;
+				}
+
+				return;
+			}
+		}
+		i++;
+	}
+}
+
+
+void del_incoming_mycalls_by_sock(void * socket)
+{
+	int i = 0, snd_ch, port;
+	registeredCalls * reg;
+
+	while (i < list_incoming_mycalls.Count)
+	{
+		reg = (registeredCalls *)list_incoming_mycalls.Items[i];
+		{
+			if (reg->socket == socket)
+			{
+				// cant use Delete as stringlist doesn't contain strings
+
+				TStringList * Q = &list_incoming_mycalls;
+				int Index = i; 
+		
+				free(Q->Items[Index]);
+
+				Q->Count--;
+
+				while (Index < Q->Count)
+				{
+					Q->Items[Index] = Q->Items[Index + 1];
+					Index++;
+				}
+				
+				//Delete(&list_incoming_mycalls, i);
+			}
+			else
+				i++;
+		}
+	}
+
+	// Should clear all connections on socket
+
+	for (snd_ch = 0; snd_ch < 4; snd_ch++)
+	{
+		for (port = 0; port < port_num; port++)
+		{
+			TAX25Port * AX25Sess = &AX25Port[snd_ch][port];
+
+			if (AX25Sess->socket == socket)
+			{
+				if (AX25Sess->status != STAT_NO_LINK)
+				{
+					// Shouldn't we send DM? -0 try it
+
+					set_DM(snd_ch, AX25Sess->ReversePath);
+
+					rst_timer(AX25Sess);
+					rst_values(AX25Sess);
+
+					AX25Sess->status = STAT_NO_LINK;
+				}
+				AX25Sess->socket = 0;
+			}
+		}
+	}
+}
+
+
+/*
+function get_incoming_socket_by_call(src_call: string): integer;
+var
+  i: integer;
+  found: boolean;
+  socket: integer;
+  call,ssid: string;
+  a_call: array[0..1] of string;
+begin
+  socket:=-1;
+  i:=0;
+  found:=FALSE;
+  try explode(a_call,'-',src_call,2); except end;
+  call:=trim(a_call[0]);
+  if a_call[1]<>'' then ssid:=a_call[1] else ssid:='0';
+  if list_incoming_mycalls.Count>0 then
+  repeat
+	if (call+'-'+ssid)=list_incoming_mycalls.Strings[i] then
+	begin socket:=strtoint(list_incoming_mycalls_sock.Strings[i]); found:=TRUE; end;
+	inc(i);
+  until found or (i=list_incoming_mycalls.Count);
+  result:=socket;
+end;
+*/
+
+
+
+void * in_list_incoming_mycall(Byte * path)
+{
+	// See if to call is in registered calls list
+
+	int i = 0;
+	registeredCalls * check;		// list_incoming_mycalls contains registeredCalls, not Strings
+	
+	while (i < list_incoming_mycalls.Count)
+	{
+		check = (registeredCalls *)list_incoming_mycalls.Items[i];
+
+		if (memcmp(check->myCall, path, 7) == 0)
+			return check->socket;
+
+		i++;
+	}
+
+	return NULL;
+}
+
+/*
+////////////////////////////////////////////////////////////////////////////////
+
+function is_corrcall(snd_ch,port: byte; path: string): boolean;
+var
+  call,ssid: string;
+begin
+  call:=trim(copy(path,8,6));
+  ssid:=copy(path,14,1);
+  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15)) else ssid:='0';
+  call:=call+'-'+ssid;
+  if call=AX25Sess->corrcall then result:=TRUE else result:=FALSE;
+end;
+
+function is_mycall(snd_ch,port: byte; path: string): boolean;
+var
+  call,ssid: string;
+begin
+  call:=trim(copy(path,1,6));
+  ssid:=copy(path,7,1);
+  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15)) else ssid:='0';
+  call:=call+'-'+ssid;
+  if call=AX25Sess->mycall then result:=TRUE else result:=FALSE;
+end;
+
+function is_digi(snd_ch,port: byte; path: string): boolean;
+var
+  digi,call,ssid: string;
+begin
+  digi:='';
+  if length(path)>14 then
+  begin
+	delete(path,1,14);
+	repeat
+	  call:=trim(copy(path,1,6));
+	  ssid:=copy(path,7,1);
+	  delete(path,1,7);
+	  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
+	  else ssid:='0';
+	  if path<>'' then digi:=digi+call+'-'+ssid+','
+	  else digi:=digi+call+'-'+ssid;
+	until path='';
+  end;
+  if digi=AX25Sess->digi then result:=TRUE else result:=FALSE;
+end;
+*/
+
+// Check if laast digi used
+
+boolean is_last_digi(Byte *path)
+{
+	int len = strlen((char *)path);
+
+	if (len == 14)
+		return TRUE;
+
+	if ((path[len - 1] & 128) == 128)
+		return TRUE;
+
+	return FALSE;
+}
+
+
+
+/*
+function get_corrcall(path: string): string;
+var
+  call,ssid: string;
+begin
+  call:=trim(copy(path,8,6));
+  ssid:=copy(path,14,1);
+  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15)) else ssid:='0';
+  call:=call+'-'+ssid;
+  result:=call;
+end;
+
+function get_mycall(path: string): string;
+var
+  call,ssid: string;
+begin
+  call:=trim(copy(path,1,6));
+  ssid:=copy(path,7,1);
+  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15)) else ssid:='0';
+  call:=call+'-'+ssid;
+  result:=call;
+end;
+
+function get_digi(path: string): string;
+var
+  digi,call,ssid: string;
+begin
+  digi:='';
+  if length(path)>14 then
+  begin
+	delete(path,1,14);
+	repeat
+	  call:=trim(copy(path,1,6));
+	  ssid:=copy(path,7,1);
+	  delete(path,1,7);
+	  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
+	  else ssid:='0';
+	  if path<>'' then digi:=digi+call+'-'+ssid+','
+	  else digi:=digi+call+'-'+ssid;
+	until path='';
+  end;
+  result:=digi;
+end;
+*/
+
+boolean is_correct_path(Byte * path, Byte pid)
+{
+	Byte networks[] = { 6, 7, 8, 0xc4, 0xcc, 0xcd, 0xce, 0xcf, 0xf0 , 0 };
+	int i;
+
+
+	if (pid == 0 || strchr((char *)networks, pid))
+	{
+		// Validate calls
+
+		// I think checking bottom  bit of first 13 bytes is enough
+
+		for (i = 0; i < 13; i++)
+		{
+			if ((*(path) & 1))
+				return FALSE;
+
+			path++;
+		}
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+void get_exclude_list(char * line, TStringList * list)
+{
+	// Convert comma separated list of calls to ax25 format in list
+
+	string axcall;
+
+	char copy[512];
+
+	char * ptr, *Context;
+
+	if (line[0] == 0)
+		return;
+
+	strcpy(copy, line);						// copy as strtok messes with it
+	strcat(copy, ",");
+
+	axcall.Length = 8;
+	axcall.AllocatedLength = 8;
+	axcall.Data = malloc(8);
+
+	memset(axcall.Data, 0, 8);
+
+	ptr = strtok_s(copy, " ,", &Context);
+
+	while (ptr)
+	{
+		if (ConvToAX25(ptr, axcall.Data) == 0)
+			return;
+
+		Add(list, duplicateString(&axcall));
+
+		ptr = strtok_s(NULL, " ,", &Context);
+	}
+}
+
+
+
+void get_exclude_frm(char * line, TStringList * list)
+{
+	UNUSED(line);
+	UNUSED(list);
+	/*
+
+  s: string;
+  p: integer;
+  n: integer;
+begin
+  list.Clear;
+  if line='' then exit;
+  repeat
+	p:=pos(',',line);
+	if p>0 then
+	  begin
+		s:=trim(copy(line,1,p-1));
+		if s<>'' then
+		begin
+		  try n:=strtoint(s); except n:=-1; end;
+		  if n in [0..255] then list.Add(chr(n));
+		end;
+		delete(line,1,p);
+	  end
+	else
+	  begin
+		s:=trim(line);
+		if s<>'' then
+		begin
+		  try n:=strtoint(s); except n:=-1; end;
+		  if n in [0..255] then list.Add(chr(n));
+		end;
+	  end;
+  until p=0;
+end;
+*/
+}
+
+/*
+
+function is_excluded_call(snd_ch: byte; path: string): boolean;
+var
+  excluded: boolean;
+  call: string;
+  ssid: string;
+begin
+  excluded:=FALSE;
+  if (list_exclude_callsigns[snd_ch].Count>0) and (length(path)>13) then
+  begin
+	// Copy sender
+	call:=trim(copy(path,8,6));
+	ssid:=copy(path,14,1);
+	if ssid<>'' then call:=call+'-'+inttostr((ord(ssid[1]) and 15));
+	if list_exclude_callsigns[snd_ch].IndexOf(call)>-1 then excluded:=TRUE;
+  end;
+  result:=excluded;
+end;
+
+function is_excluded_frm(snd_ch,f_id: byte; data: string): boolean;
+var
+  excluded: boolean;
+begin
+  excluded:=FALSE;
+  if list_exclude_APRS_frm[snd_ch].Count>0 then
+	if f_id=U_UI then
+	  if length(data)>0 then
+		if list_exclude_APRS_frm[snd_ch].IndexOf(data[1])>=0 then excluded:=TRUE;
+  result:=excluded;
+end;
+
+procedure set_corrcall(snd_ch,port: byte; path: string);
+var
+  call,ssid: string;
+begin
+  call:=trim(copy(path,8,6));
+  ssid:=copy(path,14,1);
+  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
+  else ssid:='0';
+  AX25Sess->corrcall:=call+'-'+ssid;
+end;
+
+procedure set_mycall(snd_ch,port: byte; path: string);
+var
+  call,ssid: string;
+begin
+  call:=trim(copy(path,1,6));
+  ssid:=copy(path,7,1);
+  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
+  else ssid:='0';
+  AX25Sess->mycall:=call+'-'+ssid;
+end;
+
+procedure set_digi(snd_ch,port: byte; path: string);
+var
+  digi,call,ssid: string;
+begin
+  digi:='';
+  if length(path)>14 then
+  begin
+	delete(path,1,14);
+	repeat
+	  call:=trim(copy(path,1,6));
+	  ssid:=copy(path,7,1);
+	  delete(path,1,7);
+	  if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15))
+	  else ssid:='0';
+	  if path<>'' then digi:=digi+call+'-'+ssid+','
+	  else digi:=digi+call+'-'+ssid;
+	until path='';
+  end;
+  AX25Sess->digi:=digi;
+end;
+
+procedure get_call_fm_path(path: string; var callto,callfrom: string);
+var
+  a_path: array [0..ADDR_MAX_LEN-1] of string;
+  i: byte;
+begin
+  for i:=0 to ADDR_MAX_LEN-1 do a_path[i]:='';
+  try explode(a_path,',',path,ADDR_MAX_LEN); except end;
+  callto:=a_path[0];
+  callfrom:=a_path[1];
+end;
+
+procedure get_call(src_call: string; var call: string);
+var
+  a_call: array[0..1] of string;
+  ssid: string;
+begin
+  try explode(a_call,'-',src_call,2); except end;
+  call:=trim(a_call[0]);
+  if a_call[1]<>'' then ssid:=trim(a_call[1]) else ssid:='0';
+  call:=call+'-'+ssid;
+end;
+*/
+
+int number_digi(unsigned char * path)
+{
+	UNUSED(path);
+	int n = 0;
+
+	//  a_path: array [0..ADDR_MAX_LEN-3] of string;
+	// for i:=0 to ADDR_MAX_LEN-3 do a_path[i]:='';
+	// try explode(a_path,',',path,ADDR_MAX_LEN-2); except end;
+	// for i:=0 to ADDR_MAX_LEN-3 do if a_path[i]<>'' then inc(n);
+
+	return n;
+}
+
+
+
+void get_monitor_path(Byte * path, char * mycall, char * corrcall, char * digi)
+{
+	char * digiptr = digi;
+
+	digi[0] = 0;
+
+	mycall[ConvFromAX25(path, mycall)] = 0;
+	path += 7;
+	corrcall[ConvFromAX25(path, corrcall)] = 0;
+
+	while ((path[6] & 1) == 0)				// End of call bit
+	{
+		if (digi != digiptr)
+			*(digi++) = ',';
+
+		path += 7;
+		digi += ConvFromAX25(path, digi);
+
+		if (((path[6] & 128) == 128))		// Digi'd
+			*(digi++) = '*';
+	}
+	*digi = 0;
+}
+
+
+/*
+
+function reverse_digi(path: string): string;
+var
+  digi: string;
+  a_path: array [0..ADDR_MAX_LEN-3] of string;
+  i: word;
+begin
+  digi:='';
+  for i:=0 to ADDR_MAX_LEN-3 do a_path[i]:='';
+  try explode(a_path,',',path,ADDR_MAX_LEN-2); except end;
+  for i:=0 to ADDR_MAX_LEN-3 do
+  if a_path[i]<>'' then
+  begin
+	if digi='' then digi:=a_path[i]+digi
+	else digi:=a_path[i]+','+digi;
+  end;
+  result:=digi;
+end;
+
+function direct_addr(path: string): string;
+var
+  s,call,ssid: string;
+begin
+  s:='';
+  repeat
+	call:=copy(path,1,6);
+	delete(path,1,6);
+	ssid:=copy(path,1,1);
+	delete(path,1,1);
+	if ssid<>'' then ssid:=inttostr((ord(ssid[1]) and 15));
+	if s='' then s:=call+'-'+ssid else s:=s+','+call+'-'+ssid;
+  until path='';
+  result:=s;
+end;
+*/
+
+void reverse_addr(Byte * path, Byte * revpath, int Len)
+{
+	Byte * ptr = path;
+	Byte * copy = revpath;
+	int endbit = Len - 1;
+	int numdigis = (Len - 14) / 7;
+	int i;
+
+	if (Len < 14)
+		return;
+
+	Byte digis[57];						// 8 * 7 + null terminator
+	memset(digis, 0, 57);
+	Byte * digiptr = digis + 49;			// Last Digi
+
+	// remove end of address bit
+
+	path[endbit] &= 0xFE;
+
+	// first reverse dest and origin
+
+	memcpy(copy + 7, ptr, 7);
+	memcpy(copy, ptr + 7, 7);
+
+	Len -= 14;
+	ptr += 14;
+
+	for (i = 0; i < numdigis; i++)
+	{
+		memcpy(digiptr, ptr, 7);
+		ptr += 7;
+		digiptr -= 7;
+	}
+
+	// Digiptr now points to new first digi 
+
+	memcpy(&copy[14], &digiptr[7], 7 * numdigis);
+
+	path[endbit] |= 1;			// restore original end bit
+
+	copy[endbit++] |= 1;
+	copy[endbit] = 0;			//  Null terminate
+
+	return;
+}
+
+
+
+void decode_frame(Byte * frame, int len, Byte * path, string * data,
+	Byte * pid, Byte * nr, Byte * ns, Byte * f_type, Byte * f_id,
+	Byte *  rpt, Byte * pf, Byte * cr)
+{
+	int i;
+	int addr_end;
+	Byte ctrl;
+	Byte * savepath = path;
+
+	i = 0;
+	addr_end = FALSE;
+
+	*cr = SET_R;
+	*pf = SET_F;
+	data->Length = 0;
+	ctrl = 0;
+	*pid = 0;
+	*nr = 0;
+	*ns = 0;
+	*f_type = 0;
+	*f_id = 0;
+	*rpt = FALSE;
+
+	if ((frame[6] & 128) == 128 && (frame[13] & 128) == 0)
+		*cr = SET_C;
+
+	while (len > i && i < ADDR_MAX_LEN * 7)
+	{
+		*path++ = frame[i];
+		if ((frame[i] & 1) == 1)
+		{
+			addr_end = TRUE;
+			break;
+		}
+		i++;
+	}
+
+	if (addr_end == 0)
+		return;
+
+	// clear the c and r bits from address
+
+	savepath[6] &= 0x7f;		// Mask 
+	savepath[13] &= 0x7f;		// Mask 
+
+	*path = 0;		// add null terminate		
+
+	i++;			// Points to ctrl byte
+
+	ctrl = frame[i];
+
+	if ((ctrl & 16) == 16)
+		*pf = SET_P;
+
+	if ((ctrl & 1) == 0)		// I frame
+	{
+		*f_type = I_FRM;
+		*f_id = I_I;
+		*nr = (ctrl >> 5);
+		*ns = (ctrl >> 1) & 7;
+	}
+	else
+	{
+		// Not I
+
+		*f_type = U_FRM;
+
+		*f_id = ctrl & 239;
+
+		switch (ctrl & 15)
+		{
+		case  S_RR:
+		case  S_RNR:
+		case  S_REJ:
+		case  S_SREJ:
+
+			*f_type = S_FRM;
+		}
+
+		if (*f_type == S_FRM)
+		{
+			*f_id = ctrl & 15;
+			*nr = ctrl >> 5;
+		}
+	}
+
+
+	if (*f_id == I_I || *f_id == U_UI)
+	{
+		i++;
+		*pid = frame[i];
+		i++;
+		if (len > i)
+			stringAdd(data, &frame[i], len - i);
+	}
+	else if (*f_id == U_FRMR)
+	{
+		*pid = 0;
+		i++;
+		if (len > i)
+			stringAdd(data, &frame[i], len - i);
+	}
+}
+
+void ax25_info_init(TAX25Port * AX25Sess)
+{
+	AX25Sess->info.stat_s_pkt = 0;
+	AX25Sess->info.stat_s_byte = 0;
+	AX25Sess->info.stat_r_pkt = 0;
+	AX25Sess->info.stat_r_byte = 0;
+	AX25Sess->info.stat_r_fc = 0;
+	AX25Sess->info.stat_fec_count = 0;
+	AX25Sess->info.stat_l_r_byte = 0;
+	AX25Sess->info.stat_l_s_byte = 0;
+	AX25Sess->info.stat_begin_ses = 0;
+	AX25Sess->info.stat_end_ses = 0;
+}
+
+
+void  clr_frm_win(TAX25Port * AX25Sess)
+{
+	int  i;
+
+	for (i = 0; i < 8; i++)
+		initString(&AX25Sess->frm_win[i]);
+}
+
+void ax25_init()
+{
+	int snd_ch, port, i;
+
+	for (i = 0; i < 4; i++)
+	{
+		initTStringList(&list_exclude_callsigns[i]);
+		initTStringList(&list_exclude_APRS_frm[i]);
+		initTStringList(&list_digi_callsigns[i]);
+		initTStringList(&KISS_acked[i]);
+
+		get_exclude_list(MyDigiCall[i], &list_digi_callsigns[i]);
+		get_exclude_list(exclude_callsigns[i], &list_exclude_callsigns[i]);
+		get_exclude_frm(exclude_APRS_frm[i], &list_exclude_APRS_frm[i]);
+
+	}
+
+	initTStringList(&list_incoming_mycalls);
+//	initTStringList(&list_incoming_mycalls_sock);
+
+	for (snd_ch = 0; snd_ch < 4; snd_ch++)
+	{
+		for (port = 0; port < port_num; port++)
+		{
+			TAX25Port * AX25Sess = &AX25Port[snd_ch][port];
+
+			AX25Sess->hi_vs = 0;
+			AX25Sess->vs = 0;
+			AX25Sess->vr = 0;
+			AX25Sess->PID = PID_NO_L3;
+			initTStringList(&AX25Sess->in_data_buf);
+			initString(&AX25Sess->out_data_buf);
+			AX25Sess->t1 = 0;
+			AX25Sess->t2 = 0;
+			AX25Sess->t3 = 0;
+			AX25Sess->i_lo = 0;
+			AX25Sess->i_hi = 0;
+			AX25Sess->n1 = 0;
+			AX25Sess->n2 = 0;
+			AX25Sess->status = 0;
+			AX25Sess->clk_frack = 0;
+			initTStringList(&AX25Sess->frame_buf);
+			initTStringList(&AX25Sess->I_frame_buf);
+			initTStringList(&AX25Sess->frm_collector);
+			AX25Sess->corrcall[0] = 0;
+			AX25Sess->mycall[0] = 0;
+			AX25Sess->digi[0] = 0;
+			AX25Sess->Path[0] = 0;
+			AX25Sess->kind[0] = 0;
+			AX25Sess->socket = NULL;
+			ax25_info_init(AX25Sess);
+			clr_frm_win(AX25Sess);
+		}
+	}
+}
+/*
+
+procedure ax25_free;
+var
+  snd_ch,port,i: byte;
+begin
+  for snd_ch:=1 to 4 do
+  for port:=0 to port_num-1 do
+  begin
+	AX25Sess->in_data_buf.Free;
+	AX25Sess->frame_buf.Free;
+	AX25Sess->I_frame_buf.Free;
+	AX25Sess->frm_collector.Free;
+  end;
+  for i:=1 to 4 do
+  begin
+	all_frame_buf[i].Free;
+	list_exclude_callsigns[i].Free;
+	list_exclude_APRS_frm[i].Free;
+	list_digi_callsigns[i].Free;
+  end;
+  list_incoming_mycalls.Free;
+  list_incoming_mycalls_sock.Free;
+end;
+*/
+void  write_ax25_info(TAX25Port * AX25Sess)
+{
+	UNUSED(AX25Sess);
+}
+
+/*var
+  new: boolean;
+  t: text;
+  s: string;
+  time_ses: tdatetime;
+  time_ses_sec: extended;
+  call,mycall,spkt,sbyte,rpkt,rbyte,rfc,tcps,rcps,acps,startses,timeses: string;
+begin
+  if stat_log then
+  begin
+	time_ses:=AX25Sess->info.stat_end_ses-AX25Sess->info.stat_begin_ses;
+	time_ses_sec:=time_ses*86400; //   
+	if time_ses_sec<1 then exit;
+	mycall:=copy(AX25Sess->mycall+'         ',1,9);
+	call:=copy(AX25Sess->corrcall+'         ',1,9);
+	spkt:=copy(inttostr(AX25Sess->info.stat_s_pkt)+'         ',1,6);
+	sbyte:=copy(inttostr(AX25Sess->info.stat_s_byte)+'         ',1,9);
+	rpkt:=copy(inttostr(AX25Sess->info.stat_r_pkt)+'         ',1,6);
+	rbyte:=copy(inttostr(AX25Sess->info.stat_r_byte)+'         ',1,9);
+	rfc:=copy(inttostr(AX25Sess->info.stat_r_fc)+'         ',1,6);
+	tcps:=copy(inttostr(round(AX25Sess->info.stat_s_byte/time_ses_sec))+'         ',1,5);
+	rcps:=copy(inttostr(round(AX25Sess->info.stat_r_byte/time_ses_sec))+'         ',1,5);
+	acps:=copy(inttostr(round(AX25Sess->info.stat_s_byte/time_ses_sec+AX25Sess->info.stat_r_byte/time_ses_sec))+'         ',1,5);
+	timeses:=FormatDateTime('hh:mm:ss',time_ses);
+	startses:=FormatDateTime('dd-mm-yy hh:mm:ss',AX25Sess->info.stat_begin_ses);
+	s:=mycall+' '+call+' '+spkt+' '+sbyte+' '+rpkt+' '+rbyte+' '+rfc+' '+tcps+' '+rcps+' '+acps+' '+startses+' '+timeses;
+	assignfile(t,'log.txt');
+	if FileSearch('log.txt','')='' then new:=TRUE else new:=FALSE;
+	if new then
+	begin
+	  rewrite(t);
+	  writeln(t,'Mycall    CorrCall  TXPkt  TXByte    RXPkt  RXByte    FCPkt  TXCPS RXCPS T.CPS Begin session     SesTime');
+	  writeln(t,'--------  --------- ------ --------- ------ --------- ------ ----- ----- ----- ----------------- --------');
+	end
+	else append(t);
+	if (AX25Sess->info.stat_s_byte>0) or (AX25Sess->info.stat_r_byte>0) then writeln(t,s);
+	closefile(t);
+  end;
+end;
+
+end.
+*/
+
+
+/*
+Copyright 2001-2018 John Wiseman G8BPQ
+
+This file is part of LinBPQ/BPQ32.
+
+LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+LinBPQ/BPQ32 is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
+*/
+
+
+
+// Monitor Code - from moncode.asm
+
+
+#define	CMDBIT	4		// CURRENT MESSAGE IS A COMMAND
+#define	RESP 2		// CURRENT MSG IS RESPONSE
+#define	VER1 1 		// CURRENT MSG IS VERSION 1
+
+
+#define	UI	3
+#define	SABM 0x2F
+#define	DISC 0x43
+#define	DM	0x0F
+#define	UA	0x63
+#define	FRMR 0x87
+#define	RR	1
+#define	RNR	5
+#define	REJ	9
+
+#define	PFBIT 0x10		// POLL/FINAL BIT IN CONTROL BYTE
+
+#define	NETROM_PID 0xCF
+#define	IP_PID 0xCC
+#define	ARP_PID 0xCD
+
+#define	NODES_SIG	0xFF
+
+/*
+
+DllExport int APIENTRY SetTraceOptions(int mask, int mtxparam, int mcomparam)
+{
+
+	//	Sets the tracing options for DecodeFrame. Mask is a bit
+	//	mask of ports to monitor (ie 101 binary will monitor ports
+	//	1 and 3). MTX enables monitoring on transmitted frames. MCOM
+	//	enables monitoring of protocol control frames (eg SABM, UA, RR),
+	//	as well as info frames.
+
+	MMASK = mask;
+	MTX = mtxparam;
+	MCOM = mcomparam;
+
+	return (0);
+}
+
+DllExport int APIENTRY SetTraceOptionsEx(int mask, int mtxparam, int mcomparam, int monUIOnly)
+{
+
+	//	Sets the tracing options for DecodeFrame. Mask is a bit
+	//	mask of ports to monitor (ie 101 binary will monitor ports
+	//	1 and 3). MTX enables monitoring on transmitted frames. MCOM
+	//	enables monitoring of protocol control frames (eg SABM, UA, RR),
+	//	as well as info frames.
+
+
+	MMASK = mask;
+	MTX = mtxparam;
+	MCOM = mcomparam;
+	MUIONLY = monUIOnly;
+
+	return 0;
+}
+
+*/
+
+#define USHORT unsigned short
+
+UCHAR	MCOM = 1;
+UCHAR	MTX = 1;
+ULONG	MMASK = 0xF;
+UCHAR	MUIONLY = 0;
+
+#define	SREJ 0x0D
+#define SABME 0x6F
+#define XID 0xAF
+#define TEST 0xE3
+
+#define L4BUSY	0x80		// BNA - DONT SEND ANY MORE
+#define L4NAK	0x40		// NEGATIVE RESPONSE FLAG
+#define L4MORE	0x20		// MORE DATA FOLLOWS - FRAGMENTATION FLAG
+
+#define L4CREQ	1		// CONNECT REQUEST
+#define L4CACK	2		// CONNECT ACK
+#define L4DREQ	3		// DISCONNECT REQUEST
+#define L4DACK	4		// DISCONNECT ACK
+#define L4INFO	5		// INFORMATION
+#define L4IACK	6		// INFORMATION ACK
+
+//#pragma pack(1)
+#pragma pack(push, 1) 
+
+struct myin_addr {
+	union {
+		struct { unsigned char s_b1, s_b2, s_b3, s_b4; } S_un_b;
+		struct { unsigned short s_w1, s_w2; } S_un_w;
+		unsigned long addr;
+	};
+};
+
+
+typedef struct _IPMSG
+{
+	//       FORMAT OF IP HEADER
+	//
+	//       NOTE THESE FIELDS ARE STORED HI ORDER BYTE FIRST (NOT NORMAL 8086 FORMAT)
+
+	UCHAR	VERLEN;          // 4 BITS VERSION, 4 BITS LENGTH
+	UCHAR	TOS;             // TYPE OF SERVICE
+	USHORT	IPLENGTH;        // DATAGRAM LENGTH
+	USHORT	IPID;            // IDENTIFICATION
+	USHORT	FRAGWORD;        // 3 BITS FLAGS, 13 BITS OFFSET
+	UCHAR	IPTTL;
+	UCHAR	IPPROTOCOL;      // HIGHER LEVEL PROTOCOL
+	USHORT	IPCHECKSUM;      // HEADER CHECKSUM
+	struct myin_addr IPSOURCE;
+	struct myin_addr IPDEST;
+
+	UCHAR	Data;
+
+} IPMSG, *PIPMSG;
+
+
+typedef struct _TCPMSG
+{
+
+	//	FORMAT OF TCP HEADER WITHIN AN IP DATAGRAM
+
+	//	NOTE THESE FIELDS ARE STORED HI ORDER BYTE FIRST (NOT NORMAL 8086 FORMAT)
+
+	USHORT	SOURCEPORT;
+	USHORT	DESTPORT;
+
+	ULONG	SEQNUM;
+	ULONG	ACKNUM;
+
+	UCHAR	TCPCONTROL;			// 4 BITS DATA OFFSET 4 RESERVED
+	UCHAR	TCPFLAGS;			// (2 RESERVED) URG ACK PSH RST SYN FIN
+
+	USHORT	WINDOW;
+	USHORT	CHECKSUM;
+	USHORT	URGPTR;
+
+
+} TCPMSG, *PTCPMSG;
+
+typedef struct _UDPMSG
+{
+
+	//	FORMAT OF UDP HEADER WITHIN AN IP DATAGRAM
+
+	//	NOTE THESE FIELDS ARE STORED HI ORDER BYTE FIRST (NOT NORMAL 8086 FORMAT)
+
+	USHORT	SOURCEPORT;
+	USHORT	DESTPORT;
+	USHORT	LENGTH;
+	USHORT	CHECKSUM;
+	UCHAR	UDPData[0];
+
+} UDPMSG, *PUDPMSG;
+
+//		ICMP MESSAGE STRUCTURE
+
+typedef struct _ICMPMSG
+{
+	//	FORMAT OF ICMP HEADER WITHIN AN IP DATAGRAM
+
+	//	NOTE THESE FIELDS ARE STORED HI ORDER BYTE FIRST (NOT NORMAL 8086 FORMAT)
+
+	UCHAR	ICMPTYPE;
+	UCHAR	ICMPCODE;
+	USHORT	ICMPCHECKSUM;
+
+	USHORT	ICMPID;
+	USHORT	ICMPSEQUENCE;
+	UCHAR	ICMPData[0];
+
+} ICMPMSG, *PICMPMSG;
+
+
+typedef struct _L3MESSAGE
+{
+	//
+	//	NETROM LEVEL 3 MESSAGE - WITHOUT L2 INFO 
+	//
+	UCHAR	L3SRCE[7];			// ORIGIN NODE
+	UCHAR	L3DEST[7];			// DEST NODE
+	UCHAR	L3TTL;				// TX MONITOR FIELD - TO PREVENT MESSAGE GOING								// ROUND THE NETWORK FOR EVER DUE TO ROUTING LOOP
+//
+//	NETROM LEVEL 4 DATA
+//
+	UCHAR	L4INDEX;			// TRANSPORT SESSION INDEX
+	UCHAR	L4ID;				// TRANSPORT SESSION ID
+	UCHAR	L4TXNO;				// TRANSMIT SEQUENCE NUMBER
+	UCHAR	L4RXNO;				// RECEIVE (ACK) SEQ NUMBER
+	UCHAR	L4FLAGS;			// FRAGMENTATION, ACK/NAK, FLOW CONTROL AND MSG TYPE BITS
+
+	UCHAR	L4DATA[236];		//DATA
+
+} L3MESSAGE, *PL3MESSAGE;
+
+
+typedef struct _MESSAGE
+{
+	//	BASIC LINK LEVEL MESSAGE BUFFER LAYOUT
+
+	struct _MESSAGE * CHAIN;
+
+	UCHAR	PORT;
+	USHORT	LENGTH;
+
+	UCHAR	DEST[7];
+	UCHAR	ORIGIN[7];
+
+	//	 MAY BE UP TO 56 BYTES OF DIGIS
+
+	UCHAR	CTL;
+	UCHAR	PID;
+
+	union
+	{                   /*  array named screen */
+		UCHAR L2DATA[256];
+		struct _L3MESSAGE L3MSG;
+	};
+
+
+}MESSAGE, *PMESSAGE;
+
+//#pragma pack()
+#pragma pack(pop) 
+
+char * strlop(char * buf, char delim);
+UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen);
+char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen);
+UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen);
+char * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output);
+
+int CountBits(unsigned long in)
+{
+	int n = 0;
+	while (in)
+	{
+		if (in & 1) n++;
+		in >>= 1;
+	}
+	return n;
+}
+
+BOOL ConvToAX25(char * callsign, unsigned char * ax25call)
+{
+	int i;
+
+	memset(ax25call, 0x40, 6);		// in case short
+	ax25call[6] = 0x60;				// default SSID
+
+	for (i = 0; i < 7; i++)
+	{
+		if (callsign[i] == '-')
+		{
+			//
+			//	process ssid and return
+			//
+			i = atoi(&callsign[i + 1]);
+
+			if (i < 16)
+			{
+				ax25call[6] |= i << 1;
+				return (TRUE);
+			}
+			return (FALSE);
+		}
+
+		if (callsign[i] == 0 || callsign[i] == 13 || callsign[i] == ' ' || callsign[i] == ',')
+		{
+			//
+			//	End of call - no ssid
+			//
+			return (TRUE);
+		}
+
+		ax25call[i] = callsign[i] << 1;
+	}
+
+	//
+	//	Too many chars
+	//
+
+	return (FALSE);
+}
+
+
+int ConvFromAX25(unsigned char * incall, char * outcall)
+{
+	int in, out = 0;
+	unsigned char chr;
+
+	memset(outcall, 0x20, 10);
+
+	for (in = 0; in < 6; in++)
+	{
+		chr = incall[in];
+		if (chr == 0x40)
+			break;
+		chr >>= 1;
+		outcall[out++] = chr;
+	}
+
+	chr = incall[6];				// ssid
+
+	if (chr == 0x42)
+	{
+		outcall[out++] = '-';
+		outcall[out++] = 'T';
+		return out;
+	}
+
+	if (chr == 0x44)
+	{
+		outcall[out++] = '-';
+		outcall[out++] = 'R';
+		return out;
+	}
+
+	chr >>= 1;
+	chr &= 15;
+
+	if (chr > 0)
+	{
+		outcall[out++] = '-';
+		if (chr > 9)
+		{
+			chr -= 10;
+			outcall[out++] = '1';
+		}
+		chr += 48;
+		outcall[out++] = chr;
+	}
+	return (out);
+}
+
+TKISSMode ** KissConnections = NULL;
+int KISSConCount = 0;
+
+#define FEND 0xc0
+#define FESC 0xDB
+#define TFEND 0xDC
+#define TFESC 0xDD
+#define KISS_ACKMODE 0x0C
+#define KISS_DATA 0
+
+int KISS_encode(UCHAR * KISSBuffer, int port, string * frame, int TXMON);
+
+void KISS_init()
+{
+	int i;
+
+	KISS.data_in = newString();
+
+	//	initTStringList(KISS.socket);
+
+	for (i = 0; i < 4; i++)
+	{
+		initTStringList(&KISS.buffer[i]);
+	}
+}
+
+void ProcessKISSFrame(void * socket, UCHAR * Msg, int Len);
+
+void KISSDataReceived(void * socket, unsigned char * data, int length)
+{
+	int i;
+	unsigned char * ptr1, *ptr2;
+	int Length;
+
+	TKISSMode * KISS = NULL;
+
+	if (KISSConCount == 0)
+		return;
+
+	for (i = 0; i < KISSConCount; i++)
+	{
+		if (KissConnections[i]->Socket == socket)
+		{
+			KISS = KissConnections[i];
+			break;
+		}
+	}
+
+	if (KISS == NULL)
+		return;
+
+	stringAdd(KISS->data_in, data, length);
+
+	if (KISS->data_in->Length > 10000)				// Probably AGW Data on KISS Port
+	{
+		KISS->data_in->Length = 0;
+		return;
+	}
+
+	ptr1 = KISS->data_in->Data;
+	Length = KISS->data_in->Length;
+
+
+	while ((ptr2 = memchr(ptr1, FEND, Length)))
+	{
+		int Len = (ptr2 - ptr1);
+
+		if (Len == 0)
+		{
+			// Start of frame
+
+			mydelete(KISS->data_in, 0, 1);
+
+			ptr1 = KISS->data_in->Data;
+			Length = KISS->data_in->Length;
+
+			continue;
+		}
+
+		// Process Frame
+
+		if (Len < 350)								// Drop obviously corrupt frames
+			ProcessKISSFrame(socket, ptr1, Len);
+
+		mydelete(KISS->data_in, 0, Len + 1);
+
+		ptr1 = KISS->data_in->Data;
+		Length = KISS->data_in->Length;
+
+	}
+}
+
+void analiz_frame(int snd_ch, string * frame, void * socket, boolean fecflag);
+
+void KISSSendtoServer(void * Socket, char * Data, int Length);
+
+void ProcessKISSFrame(void * socket, UCHAR * Msg, int Len)
+{
+	int n = Len;
+	UCHAR c;
+	int ESCFLAG = 0;
+	UCHAR * ptr1, *ptr2;
+	int Chan;
+	int Opcode;
+	string * TXMSG;
+
+	ptr1 = ptr2 = Msg;
+
+	while (n--)
+	{
+		c = *(ptr1++);
+
+		if (ESCFLAG)
+		{
+			//
+			//	FESC received - next should be TFESC or TFEND
+
+			ESCFLAG = 0;
+
+			if (c == TFESC)
+				c = FESC;
+
+			if (c == TFEND)
+				c = FEND;
+
+		}
+		else
+		{
+			switch (c)
+			{
+			case FEND:
+
+				//
+				//	Either start of message or message complete
+				//
+
+				//	npKISSINFO->MSGREADY = TRUE;
+				return;
+
+			case FESC:
+
+				ESCFLAG = 1;
+				continue;
+
+			}
+		}
+
+		//
+		//	Ok, a normal char
+		//
+
+		*(ptr2++) = c;
+
+	}
+	Len = ptr2 - Msg;
+
+	Chan = (Msg[0] >> 4);
+	Opcode = Msg[0] & 0x0f;
+
+	if (Chan > 3)
+		return;
+
+	// This is a lot simpler than QtSM, as frames will always be immediately processed locally, so ack mode isn't needed.
+	//	but if enabled ack can be sent immediately
+	//	checksum if needed
+
+	switch (Opcode)
+	{
+	case KISS_ACKMODE:
+	{
+		// send ack
+
+		unsigned char ACK[16];
+		unsigned char * ackptr = ACK;
+
+		*ackptr++ = FEND;
+		*ackptr++ = Msg[0];			// opcode and channel
+
+		*ackptr++ = Msg[1];
+		*ackptr++ = Msg[2];			// ACK Bytes
+		*ackptr++ = FEND;
+
+		KISSSendtoServer(socket, ACK, 5);
+
+		// remove ack bytes
+
+		memmove(&Msg[1], &Msg[3], Len - 2);
+
+		// drop through to KISS Data
+
+		Len -= 2;
+	}
+	case KISS_DATA:
+
+		if (KISSChecksum)
+		{
+			//	SUM MESSAGE, AND IF DUFF DISCARD. IF OK DECREMENT COUNT TO REMOVE SUM
+
+			int sumlen = Len;
+			char * ptr = &Msg[0];
+			UCHAR sum = 0;
+
+			while (sumlen--)
+			{
+				sum ^= *(ptr++);
+			}
+
+			if (sum)
+			{
+				Debugprintf("KISS Checksum Error");
+				return;
+			}
+
+			Len--;							// Remove Checksum
+		}
+
+		TXMSG = newString();
+		stringAdd(TXMSG, &Msg[1], Len - 1);		// include Control
+
+		MHPROC(TXMSG->Data, TXMSG->Length);
+		
+		analiz_frame(Chan, TXMSG, socket, 0);
+
+		free(TXMSG);
+		return;
+	}
+
+	// Still need to process kiss control frames
+}
+
+
+void KISS_add_stream(void * Socket)
+{
+	// Add a new connection. Called when QT accepts an incoming call}
+
+	TKISSMode * KISS;
+
+	KissConnections = realloc(KissConnections, (KISSConCount + 1) * sizeof(void *));
+
+	KISS = KissConnections[KISSConCount++] = malloc(sizeof(TKISSMode));
+
+	KISS->Socket = Socket;
+	KISS->data_in = newString();
+
+}
+
+void KISS_del_socket(void * socket)
+{
+	int i;
+
+	TKISSMode * KISS = NULL;
+
+	if (KISSConCount == 0)
+		return;
+
+	for (i = 0; i < KISSConCount; i++)
+	{
+		if (KissConnections[i]->Socket == socket)
+		{
+			KISS = KissConnections[i];
+			break;
+		}
+	}
+
+	if (KISS == NULL)
+		return;
+
+	// Need to remove entry and move others down
+
+	KISSConCount--;
+
+	while (i < KISSConCount)
+	{
+		KissConnections[i] = KissConnections[i + 1];
+		i++;
+	}
+}
+
+TAX25Port * get_free_port(int snd_ch);
+
+TAX25Port * KISSConnectOut(void * Sess, char * CallFrom, char * CallTo, char * Digis, int Chan, void * Socket)
+{
+	TAX25Port * AX25Sess = 0;
+	char path[128];
+	Byte axpath[80];
+
+	AX25Sess = get_free_port(Chan);
+
+	if (AX25Sess)
+	{
+		AX25Sess->snd_ch = Chan;
+		AX25Sess->Sess = Sess;
+		strcpy(AX25Sess->mycall, CallFrom);
+		strcpy(AX25Sess->corrcall, CallTo);
+		AX25Sess->PID = 0xf0;
+
+		sprintf(path, "%s,%s", CallTo, CallFrom);
+
+		if (Digis && Digis[0])
+		{
+			strcat(path, ",");
+			strcat(path, Digis);
+		}
+	
+		AX25Sess->digi[0] = 0;
+
+		//		rst_timer(snd_ch, free_port);
+
+		strcpy(AX25Sess->kind, "Outgoing");
+		AX25Sess->socket = Socket;
+
+		AX25Sess->pathLen = get_addr(path, axpath);
+
+		if (AX25Sess->pathLen == 0)
+			return AX25Sess;						// Invalid Path
+
+		strcpy((char *)AX25Sess->Path, (char *)axpath);
+		reverse_addr(axpath, AX25Sess->ReversePath, AX25Sess->pathLen);
+
+		set_link(AX25Sess, AX25Sess->Path);				// Sends SABM
+		return AX25Sess;
+	}
+	return 0;
+}
+
+
+
+// Monitor Code - from moncode.asm
+
+
+#define	CMDBIT	4		// CURRENT MESSAGE IS A COMMAND
+#define	RESP 2		// CURRENT MSG IS RESPONSE
+#define	VER1 1 		// CURRENT MSG IS VERSION 1
+
+
+#define	UI	3
+#define	SABM 0x2F
+#define	DISC 0x43
+#define	DM	0x0F
+#define	UA	0x63
+#define	FRMR 0x87
+#define	RR	1
+#define	RNR	5
+#define	REJ	9
+
+#define	SREJ 0x0D
+#define SABME 0x6F
+#define XID 0xAF
+#define TEST 0xE3
+
+
+#define	PFBIT 0x10		// POLL/FINAL BIT IN CONTROL BYTE
+
+#define	NETROM_PID 0xCF
+#define	IP_PID 0xCC
+#define	ARP_PID 0xCD
+
+#define	NODES_SIG	0xFF
+
+char ShortDT[] = "HH:MM:SS";
+
+int KISSLocalTime = 0;
+int KISSMonEnable = 0;
+int KISSMonNodes = 0;
+
+char * ShortDateTime()
+{
+	struct tm * tm;
+	time_t NOW = time(NULL);
+
+	if (KISSLocalTime)
+		tm = localtime(&NOW);
+	else
+		tm = gmtime(&NOW);
+
+	sprintf(ShortDT, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
+	return ShortDT;
+}
+
+
+char FrameData[1024] = "";
+
+char * frame_monitor(string * frame, char * code, int tx_stat)
+{
+	char mon_frm[512];
+	char Path[256];
+
+	char * frm = "???";
+	Byte * datap;
+	Byte _data[512] = "";
+	Byte * p_data = _data;
+	int _datalen;
+	char CallFrom[10], CallTo[10], Digi[80];
+
+	char TR = 'R';
+	char codestr[16] = "";
+
+	integer i;
+	int len;
+
+
+	Byte pid, nr, ns, f_type, f_id;
+	Byte  rpt, cr, pf;
+	Byte path[80];
+	char c;
+	const char * p;
+
+	string * data = newString();
+
+	if (code[0] && strlen(code) < 14)
+		sprintf(codestr, "[%s]", code);
+
+	if (tx_stat)
+		TR = 'T';
+
+	if (tx_stat)	// TX frame has control byte
+
+		decode_frame(frame->Data + 1, frame->Length - 1, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
+	else
+		decode_frame(frame->Data, frame->Length, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
+
+
+	datap = data->Data;
+
+	len = data->Length;
+
+	if (pid == 0xCF) 
+	{
+		if (datap[0] == 255)	 //Nodes broadcast
+		{
+			if (KISSMonNodes == 0)
+			{
+				freeString(data);
+				return 0;
+			}
+		}
+	}
+	
+		
+		
+	//		data = parse_NETROM(data, f_id);
+	// IP parsing
+	//	else if (pid == 0xCC)
+	//		data = parse_IP(data);
+		// ARP parsing
+	//	else if (pid == 0xCD)
+	//		data = parse_ARP(data);
+		//
+
+	if (len > 0)
+	{
+		for (i = 0; i < len; i++)
+		{
+			if (datap[i] > 31 || datap[i] == 13 || datap[i] == 9)
+				*(p_data++) = datap[i];
+		}
+	}
+
+	_datalen = p_data - _data;
+
+	if (_datalen)
+	{
+		Byte * ptr = _data;
+		i = 0;
+
+		// remove successive cr or cr on end		while (i < _datalen)
+
+		while (i < _datalen)
+		{
+			if ((_data[i] == 13) && (_data[i + 1] == 13))
+				i++;
+			else
+				*(ptr++) = _data[i++];
+		}
+
+		if (*(ptr - 1) == 13)
+			ptr--;
+
+		*ptr = 0;
+
+		_datalen = ptr - _data;
+	}
+
+	get_monitor_path(path, CallTo, CallFrom, Digi);
+
+	if (cr)
+	{
+		c = 'C';
+		if (pf)
+			p = " P";
+		else p = "";
+	}
+	else
+	{
+		c = 'R';
+		if (pf)
+			p = " F";
+		else
+			p = "";
+	}
+
+	switch (f_id)
+	{
+	case I_I:
+
+		frm = "I";
+		break;
+
+	case S_RR:
+
+		frm = "RR";
+		break;
+
+	case S_RNR:
+
+		frm = "RNR";
+		break;
+
+	case S_REJ:
+
+		frm = "REJ";
+		break;
+
+	case S_SREJ:
+
+		frm = "SREJ";
+		break;
+
+	case U_SABM:
+
+		frm = "SABM";
+		break;
+
+	case SABME:
+
+		frm = "SABME";
+		break;
+
+	case U_DISC:
+
+		frm = "DISC";
+		break;
+
+	case U_DM:
+
+		frm = "DM";
+		break;
+
+	case U_UA:
+
+		frm = "UA";
+		break;
+
+	case U_FRMR:
+
+		frm = "FRMR";
+		break;
+
+	case U_UI:
+
+		frm = "UI";
+	}
+
+//	07:29:42T G8BPQ - 2 > TEST Port = 20 < UI > :
+//	helllo
+//	07:30: 8T G8BPQ - 2 > ID Port = 20 < UI C > :
+//	Network node(BPQ)
+
+	if (Digi[0])
+//		sprintf(Path, "Fm %s To %s Via %s <%s %c%s", CallFrom, CallTo, Digi, frm, c, p);
+		sprintf(Path, "%s%c %s>%s,%s <%s %c%s", ShortDateTime(), TR, CallFrom, CallTo, Digi, frm, c, p);
+	else
+//		sprintf(Path, "Fm %s To %s <%s %c %s", CallFrom, CallTo, frm, c, p);
+	sprintf(Path, "%s%c %s>%s <%s %c%s", ShortDateTime(), TR, CallFrom, CallTo, frm, c, p);
+
+
+	switch (f_type)
+	{
+	case I_FRM:
+
+		//mon_frm = Path + ctrl + ' R' + inttostr(nr) + ' S' + inttostr(ns) + ' pid=' + dec2hex(pid) + ' Len=' + inttostr(len) + ' >' + time_now + #13 + _data + #13#13;
+		sprintf(mon_frm, "%s R%d S%d>%s\r%s\r", Path, nr, ns, codestr, _data);
+
+		break;
+
+	case U_FRM:
+
+		if (f_id == U_UI)
+		{
+			sprintf(mon_frm, "%s>:\r%s\r", Path, _data); // "= Path + ctrl + '>' + time_now + #13;
+		}
+		else if (f_id == U_FRMR)
+		{
+			sprintf(mon_frm, "%s>%02x %02x %02x\r", Path, datap[0], datap[1], datap[2]); // "= Path + ctrl + '>' + time_now + #13;
+		}
+		else
+			sprintf(mon_frm, "%s>%s\r", Path, codestr); // "= Path + ctrl + '>' + time_now + #13;
+
+		break;
+
+	case S_FRM:
+
+		//		mon_frm = Path + ctrl + ' R' + inttostr(nr) + ' >' + time_now + #13;
+		sprintf(mon_frm, "%s R%d>%s\r", Path, nr, codestr); // "= Path + ctrl + '>' + time_now + #13;
+
+		break;
+
+	}
+	sprintf(FrameData, "%s", mon_frm);
+
+	freeString(data);
+	return FrameData;
+}
+
+typedef struct _MHSTRUC
+{
+	UCHAR MHCALL[7];
+	UCHAR MHDIGIS[7][8];
+	time_t MHTIME;
+	int MHCOUNT;
+	unsigned char MHDIGI;
+	char MHFreq[12];
+	char MHLocator[6];
+} MHSTRUC, *PMHSTRUC;
+
+
+#define MHENTRIES 30
+
+MHSTRUC MHEARD[(MHENTRIES + 1) * sizeof(MHSTRUC)] = { 0 };
+
+int CompareCalls(UCHAR * c1, UCHAR * c2)
+{
+	//	COMPARE AX25 CALLSIGNS IGNORING EXTRA BITS IN SSID
+
+	if (memcmp(c1, c2, 6))
+		return FALSE;			// No Match
+
+	if ((c1[6] & 0x1e) == (c2[6] & 0x1e))
+		return TRUE;
+
+	return FALSE;
+}
+
+static char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+void * MHWindow = 0;
+void WritetoMHWindow(char * Buffer);
+int KISSMH = 0;
+
+char * FormatMH(PMHSTRUC MH)
+{
+	struct tm * TM;
+	static char MHTime[50];
+	time_t szClock;
+	char LOC[7];
+
+	memcpy(LOC, MH->MHLocator, 6);
+	LOC[6] = 0;
+
+		szClock = MH->MHTIME;
+//	else
+//		szClock = time(NULL) - MH->MHTIME;
+
+	TM = gmtime(&szClock);
+
+		sprintf(MHTime, "%s %02d %.2d:%.2d:%.2d  %s %s",
+			month[TM->tm_mon], TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec, MH->MHFreq, LOC);
+
+	return MHTime;
+}
+
+
+
+
+void  MHPROC(unsigned char * Packet, int Len)
+{
+	PMHSTRUC MH = &MHEARD[0];
+	PMHSTRUC MHBASE = MH;
+	int i;
+	int OldCount = 0;
+	char Freq[64] = "";
+	char DIGI = '*';
+
+	MESSAGE Frame;
+	MESSAGE * Buffer = &Frame;
+
+	memcpy(Buffer->DEST, Packet, Len);
+
+
+	// if port has a freq associated with it use it
+
+
+	//	if (Buffer->ORIGIN[6] & 1)
+	DIGI = 0;					// Don't think we want to do this
+
+// See if in list
+
+	for (i = 0; i < MHENTRIES; i++)
+	{
+		if ((MH->MHCALL[0] == 0) || (CompareCalls(Buffer->ORIGIN, MH->MHCALL) && MH->MHDIGI == DIGI)) // Spare or our entry
+		{
+			OldCount = MH->MHCOUNT;
+			goto DoMove;
+		}
+		MH++;
+	}
+
+	//	TABLE FULL AND ENTRY NOT FOUND - MOVE DOWN ONE, AND ADD TO TOP
+
+	i = MHENTRIES - 1;
+
+	// Move others down and add at front
+DoMove:
+	if (i != 0)				// First
+		memmove(MHBASE + 1, MHBASE, i * sizeof(MHSTRUC));
+
+	memcpy(MHBASE->MHCALL, Buffer->ORIGIN, 7 * 9);		// Save Digis
+	MHBASE->MHDIGI = DIGI;
+	MHBASE->MHTIME = time(NULL);
+	MHBASE->MHCOUNT = ++OldCount;
+	strcpy(MHBASE->MHFreq, Freq);
+	MHBASE->MHLocator[0] = 0;
+
+	if (MHWindow)
+	{
+		int count = MHENTRIES;
+		int n;
+		char Normcall[20];
+		char From[10];
+		char DigiList[100];
+		char * Output;
+		int len;
+		char Digi = 0;
+		char MHPage[MHENTRIES * 100];
+		char * Bufferptr = MHPage;
+		unsigned char * ptr;
+
+		MH = &MHEARD[0];
+
+		// Note that the MHDIGIS field may contain rubbish. You have to check End of Address bit to find
+		// how many digis there are
+
+		Bufferptr += sprintf(Bufferptr, "Callsign   Last heard     Pkts RX    via Digi\r");
+		Bufferptr += sprintf(Bufferptr, "\r");
+
+		while (count--)
+		{
+			if (MH->MHCALL[0] == 0)
+				break;
+
+			Digi = 0;
+
+			len = ConvFromAX25(MH->MHCALL, Normcall);
+
+			Normcall[len++] = MH->MHDIGI;
+			Normcall[len++] = 0;
+
+			n = 8;					// Max number of digi-peaters
+
+			ptr = &MH->MHCALL[6];	// End of Address bit
+
+			Output = &DigiList[0];
+
+			if ((*ptr & 1) == 0)
+			{
+				// at least one digi
+
+				strcpy(Output, "via ");
+				Output += 4;
+
+				while ((*ptr & 1) == 0)
+				{
+					//	MORE TO COME
+
+					From[ConvFromAX25(ptr + 1, From)] = 0;
+					Output += sprintf((char *)Output, "%s", From);
+
+					ptr += 7;
+					n--;
+
+					if (n == 0)
+						break;
+
+					// See if digi actioned - put a * on last actioned
+
+					if (*ptr & 0x80)
+					{
+						if (*ptr & 1)						// if last address, must need *
+						{
+							*(Output++) = '*';
+							Digi = '*';
+						}
+
+						else
+							if ((ptr[7] & 0x80) == 0)		// Repeased by next?
+							{
+								*(Output++) = '*';			// No, so need *
+								Digi = '*';
+							}
+
+					}
+					*(Output++) = ',';
+				}
+				*(--Output) = 0;							// remove last comma
+			}
+			else
+				*(Output) = 0;
+
+			// if we used a digi set * on call and display via string
+
+
+			if (Digi)
+				Normcall[len++] = Digi;
+			else
+				DigiList[0] = 0;	// Dont show list if not used
+
+			Normcall[len++] = 0;
+
+			ptr = FormatMH(MH);
+
+			Bufferptr += sprintf(Bufferptr, "%-10s %-10s %-10d %-30s\r", Normcall, ptr, MH->MHCOUNT, DigiList);
+
+			MH++;
+		}
+
+		WritetoMHWindow(MHPage);
+	}
+	return;
+}
+
+
+
+
+
+
+
--- qttermtcp-0.0.0.79.orig/ax25.h
+++ qttermtcp-0.0.0.79/ax25.h
@@ -1,293 +1,293 @@
-// ax.25 code for QtTERMTCP KISS Mode
-
-// based on SoundModem/QtSoundModem ax.25 code
-
-// The underlying code allows for up to four KISS ports, but at the moment
-// the config and user interface only supports 1
-
-// The code supports KISS over a Serial port or TCP connection
-
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <time.h>
-
-#define UNUSED(x) (void)(x)
-
-#define single float
-#define boolean int
-#define Byte unsigned char		//                  0 to 255
-#define Word unsigned short	//                        0 to 65,535
-#define SmallInt short 		//                  -32,768 to 32,767
-#define LongWord unsigned int	//                        0 to 4,294,967,295
-//  Int6 : Cardinal; //                        0 to 4,294,967,295
-#define LongInt int			//           -2,147,483,648 to 2,147,483,647
-#define Integer int  //           -2,147,483,648 to 2,147,483,647
-//#define Int64 long long		 // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
-
-//#define Byte unsigned char		//                  0 to 255
-#define word unsigned short	//                        0 to 65,535
-#define smallint short 		//                  -32,768 to 32,767
-#define longword unsigned int	//                        0 to 4,294,967,295
- //  Int6 : Cardinal; //                        0 to 4,294,967,295
-#define longint int			//           -2,147,483,648 to 2,147,483,647
-#define integer int  //           -2,147,483,648 to 2,147,483,647
-
-typedef unsigned long ULONG;
-
-#define UCHAR unsigned char
-#define UINT unsigned int
-#define BOOL int
-#define TRUE 1
-#define FALSE 0
-
-#define FEND 0xc0
-#define FESC 0xDB
-#define TFEND 0xDC
-#define TFESC 0xDD
-
-#define port_num 32		// ?? Max AGW sessions
-#define PKT_ERR 15		// Minimum packet size, bytes
-#define I_MAX 7			// Maximum number of packets
-
-
-// Status flags
-
-#define STAT_NO_LINK  0
-#define STAT_LINK 1
-#define STAT_CHK_LINK 2
-#define STAT_WAIT_ANS 3
-#define STAT_TRY_LINK 4
-#define STAT_TRY_UNLINK 5
-
-
-	// md,Resp,Poll,Final,Digipeater flags
-#define 	SET_P 1
-#define 	SET_F 0
-#define 	SET_C 1
-#define 	SET_R 0
-#define 	SET_NO_RPT 0
-#define 	SET_RPT 1
-	// Frame ID flags
-#define 	I_FRM 0
-#define 	S_FRM 1
-#define 	U_FRM 2
-#define 	I_I 0
-#define 	S_RR 1
-#define 	S_RNR 5
-#define 	S_REJ 9
-#define		S_SREJ 0x0D
-#define 	U_SABM 47
-#define 	U_DISC 67
-#define 	U_DM 15
-#define 	U_UA 99
-#define 	U_FRMR 135
-#define 	U_UI 3
-	// PID flags
-#define 	PID_X25 0x01       // 00000001-CCIT X25 PLP
-#define 	PID_SEGMENT 0x08   // 00001000-Segmentation fragment
-#define 	PID_TEXNET 0xC3    // 11000011-TEXNET Datagram Protocol
-#define 	PID_LQ 0xC4        // 11001000-Link Quality Protocol
-#define 	PID_APPLETALK 0xCA // 11001010-Appletalk
-#define 	PID_APPLEARP 0xCB  // 11001011-Appletalk ARP
-#define 	PID_IP 0xCC        // 11001100-ARPA Internet Protocol
-#define 	PID_ARP 0xCD       // 11001101-ARPA Address Resolution Protocol
-#define 	PID_NET_ROM 0xCF   // 11001111-NET/ROM
-
-#define FX25_LOAD 1
-
-#define    MODE_OUR 0
-#define    MODE_OTHER 1
-#define    MODE_RETRY 2
-
-#define TIMER_FREE 0
-#define TIMER_BUSY 1
-#define TIMER_OFF 2
-#define TIMER_EVENT_ON 3
-#define TIMER_EVENT_OFF 4
-
-
-typedef struct string_T
-{
-	unsigned char * Data;
-	int Length;
-	int AllocatedLength;				// A reasonable sized block is allocated at the start to speed up adding chars
-
-}string;
-
-typedef struct TStringList_T
-{
-	int Count;
-	string ** Items;
-
-} TStringList;
-
-
-typedef struct  TAX25Info_t
-{
-	longint	stat_s_pkt;
-	longint stat_s_byte;
-	longint stat_r_pkt;
-	longint stat_r_byte;
-	longint stat_r_fc;
-	longint stat_fec_count;
-	time_t stat_begin_ses;
-	time_t stat_end_ses;
-	longint stat_l_r_byte;
-	longint stat_l_s_byte;
-
-} TAX25Info;
-
-typedef struct TAX25Port_t
-{
-	Byte hi_vs;
-	Byte vs;
-	Byte vr;
-	Byte PID;
-	TStringList in_data_buf;
-	TStringList frm_collector;
-	string frm_win[8];
-	string out_data_buf;
-	word t1;
-	word t2;
-	word t3;
-	Byte i_lo;
-	Byte i_hi;
-	word n1;
-	word n2;
-	word IPOLL_cnt;
-	TStringList frame_buf; //   
-	TStringList I_frame_buf;
-	Byte status;
-	word clk_frack;
-	char corrcall[10];
-	char mycall[10];
-	UCHAR digi[56];
-	UCHAR Path[80];				// Path in ax25 format - added to save building it each time
-	UCHAR ReversePath[80];
-	int snd_ch;					// Simplifies parameter passing
-	int port;
-	int pathLen;
-	void * socket;
-	void * Sess;
-	char kind[16];
-	TAX25Info info;
-} TAX25Port;
-
-typedef struct TKISSMode_t
-{
-	string * data_in;
-	void * Socket;				// Used as a key
-
-	// Not sure what rest are used for. Seems to be one per channel
-
-	TStringList buffer[4];			// Outgoing Frames
-
-} TKISSMode;
-
-// Dephi emulation functions
-
-string * Strings(TStringList * Q, int Index);
-void Clear(TStringList * Q);
-int Count(TStringList * List);
-
-string * newString();
-string * copy(string * Source, int StartChar, int Count);
-TStringList * newTStringList();
-
-void freeString(string * Msg);
-void initString(string * S);
-void initTStringList(TStringList* T);
-
-// Two delete() This is confusing!!
-// Not really - one acts on String, other TStringList
-
-void Delete(TStringList * Q, int Index);
-void mydelete(string * Source, int StartChar, int Count);
-void move(UCHAR * SourcePointer, UCHAR * DestinationPointer, int CopyCount);
-void fmove(float * SourcePointer, float * DestinationPointer, int CopyCount);
-void setlength(string * Msg, int Count);		// Set string length
-string * stringAdd(string * Msg, UCHAR * Chars, int Count);		// Extend string 
-void Assign(TStringList * to, TStringList * from);	// Duplicate from to to
-string * duplicateString(string * in);
-int  my_indexof(TStringList * l, string * s);
-boolean compareStrings(string * a, string * b);
-int Add(TStringList * Q, string * Entry);
-void Debugprintf(const char * format, ...);
-void ax25_info_init(TAX25Port * AX25Sess);
-void  clr_frm_win(TAX25Port * AX25Sess);
-void decode_frame(Byte * frame, int len, Byte * path, string * data,
-	Byte * pid, Byte * nr, Byte * ns, Byte * f_type, Byte * f_id,
-	Byte *  rpt, Byte * pf, Byte * cr);
-#ifdef __cplusplus
-extern "C" void KISSSendtoServer(myTcpSocket* Socket, char * Data, int Length);
-extern "C" void monitor_frame(int snd_ch, string * frame, char * code, int  tx, int excluded);
-extern "C" void WriteDebugLog(char * Mess);
-extern "C" void SendtoTerm(Ui_ListenSession * Sess, char * Msg, int Len);
-extern "C" void ClearSessLabel(Ui_ListenSession * Sess);
-extern "C" void rst_timer(TAX25Port * AX25Sess);
-extern "C" void Send_UI(int port, Byte PID, char * CallFrom, char *CallTo, char * Via, Byte *  Msg, int MsgLen);
-#else
-void monitor_frame(int snd_ch, string * frame, char * code, int  tx, int excluded);
-void SendtoTerm(void * Sess, char * Msg, int Len);
-void ClearSessLabel(void * Sess);
-void WriteDebugLog(char * Mess);
-void AX25_disc(TAX25Port * AX25Sess, Byte mode);
-void rst_timer(TAX25Port * AX25Sess);
-void Send_UI(int port, Byte PID, char * CallFrom, char *CallTo, char * via, Byte *  Msg, int MsgLen);
-#endif
-
-BOOL ConvToAX25(char * callsign, unsigned char * ax25call);
-int ConvFromAX25(unsigned char * incall, char * outcall);
-void reverse_addr(Byte * path, Byte * revpath, int Len);
-void set_DM(int snd_ch, Byte * path);
-void set_link(TAX25Port * AX25Sess, UCHAR * axpath);
-boolean is_last_digi(Byte *path);
-boolean is_correct_path(Byte * path, Byte pid);
-int number_digi(unsigned char * path);
-void AX25_conn(TAX25Port * AX25Sess, int snd_ch, Byte mode);
-void  write_ax25_info(TAX25Port * AX25Sess);
-void rst_values(TAX25Port * AX25Sess);
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-extern boolean dyn_frack[4];
-extern Byte recovery[4];
-extern Byte users[4];
-
-extern int resptime[4];
-extern int slottime[4];
-extern int persist[4];
-extern int kisspaclen[4];
-extern int fracks[4];
-extern int frack_time[4];
-extern int idletime[4];
-extern int redtime[4];
-extern int IPOLL[4];
-extern int maxframe[4];
-extern int TXFrmMode[4];
-
-extern char MyDigiCall[4][512];
-extern char exclude_callsigns[4][512];
-extern char exclude_APRS_frm[4][512];
-
-extern TStringList  list_exclude_callsigns[4];
-extern TStringList list_exclude_APRS_frm[4];
-extern TStringList list_digi_callsigns[4];
-
-extern int max_frame_collector[4];
-extern boolean KISS_opt[4];
-
-extern TAX25Port AX25Port[4][port_num];
-
-extern TStringList KISS_acked[];
-extern TStringList KISS_iacked[];
-
-#ifdef __cplusplus
-}
+// ax.25 code for QtTERMTCP KISS Mode
+
+// based on SoundModem/QtSoundModem ax.25 code
+
+// The underlying code allows for up to four KISS ports, but at the moment
+// the config and user interface only supports 1
+
+// The code supports KISS over a Serial port or TCP connection
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+
+#define UNUSED(x) (void)(x)
+
+#define single float
+#define boolean int
+#define Byte unsigned char		//                  0 to 255
+#define Word unsigned short	//                        0 to 65,535
+#define SmallInt short 		//                  -32,768 to 32,767
+#define LongWord unsigned int	//                        0 to 4,294,967,295
+//  Int6 : Cardinal; //                        0 to 4,294,967,295
+#define LongInt int			//           -2,147,483,648 to 2,147,483,647
+#define Integer int  //           -2,147,483,648 to 2,147,483,647
+//#define Int64 long long		 // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
+
+//#define Byte unsigned char		//                  0 to 255
+#define word unsigned short	//                        0 to 65,535
+#define smallint short 		//                  -32,768 to 32,767
+#define longword unsigned int	//                        0 to 4,294,967,295
+ //  Int6 : Cardinal; //                        0 to 4,294,967,295
+#define longint int			//           -2,147,483,648 to 2,147,483,647
+#define integer int  //           -2,147,483,648 to 2,147,483,647
+
+typedef unsigned long ULONG;
+
+#define UCHAR unsigned char
+#define UINT unsigned int
+#define BOOL int
+#define TRUE 1
+#define FALSE 0
+
+#define FEND 0xc0
+#define FESC 0xDB
+#define TFEND 0xDC
+#define TFESC 0xDD
+
+#define port_num 32		// ?? Max AGW sessions
+#define PKT_ERR 15		// Minimum packet size, bytes
+#define I_MAX 7			// Maximum number of packets
+
+
+// Status flags
+
+#define STAT_NO_LINK  0
+#define STAT_LINK 1
+#define STAT_CHK_LINK 2
+#define STAT_WAIT_ANS 3
+#define STAT_TRY_LINK 4
+#define STAT_TRY_UNLINK 5
+
+
+	// md,Resp,Poll,Final,Digipeater flags
+#define 	SET_P 1
+#define 	SET_F 0
+#define 	SET_C 1
+#define 	SET_R 0
+#define 	SET_NO_RPT 0
+#define 	SET_RPT 1
+	// Frame ID flags
+#define 	I_FRM 0
+#define 	S_FRM 1
+#define 	U_FRM 2
+#define 	I_I 0
+#define 	S_RR 1
+#define 	S_RNR 5
+#define 	S_REJ 9
+#define		S_SREJ 0x0D
+#define 	U_SABM 47
+#define 	U_DISC 67
+#define 	U_DM 15
+#define 	U_UA 99
+#define 	U_FRMR 135
+#define 	U_UI 3
+	// PID flags
+#define 	PID_X25 0x01       // 00000001-CCIT X25 PLP
+#define 	PID_SEGMENT 0x08   // 00001000-Segmentation fragment
+#define 	PID_TEXNET 0xC3    // 11000011-TEXNET Datagram Protocol
+#define 	PID_LQ 0xC4        // 11001000-Link Quality Protocol
+#define 	PID_APPLETALK 0xCA // 11001010-Appletalk
+#define 	PID_APPLEARP 0xCB  // 11001011-Appletalk ARP
+#define 	PID_IP 0xCC        // 11001100-ARPA Internet Protocol
+#define 	PID_ARP 0xCD       // 11001101-ARPA Address Resolution Protocol
+#define 	PID_NET_ROM 0xCF   // 11001111-NET/ROM
+
+#define FX25_LOAD 1
+
+#define    MODE_OUR 0
+#define    MODE_OTHER 1
+#define    MODE_RETRY 2
+
+#define TIMER_FREE 0
+#define TIMER_BUSY 1
+#define TIMER_OFF 2
+#define TIMER_EVENT_ON 3
+#define TIMER_EVENT_OFF 4
+
+
+typedef struct string_T
+{
+	unsigned char * Data;
+	int Length;
+	int AllocatedLength;				// A reasonable sized block is allocated at the start to speed up adding chars
+
+}string;
+
+typedef struct TStringList_T
+{
+	int Count;
+	string ** Items;
+
+} TStringList;
+
+
+typedef struct  TAX25Info_t
+{
+	longint	stat_s_pkt;
+	longint stat_s_byte;
+	longint stat_r_pkt;
+	longint stat_r_byte;
+	longint stat_r_fc;
+	longint stat_fec_count;
+	time_t stat_begin_ses;
+	time_t stat_end_ses;
+	longint stat_l_r_byte;
+	longint stat_l_s_byte;
+
+} TAX25Info;
+
+typedef struct TAX25Port_t
+{
+	Byte hi_vs;
+	Byte vs;
+	Byte vr;
+	Byte PID;
+	TStringList in_data_buf;
+	TStringList frm_collector;
+	string frm_win[8];
+	string out_data_buf;
+	word t1;
+	word t2;
+	word t3;
+	Byte i_lo;
+	Byte i_hi;
+	word n1;
+	word n2;
+	word IPOLL_cnt;
+	TStringList frame_buf; //   
+	TStringList I_frame_buf;
+	Byte status;
+	word clk_frack;
+	char corrcall[10];
+	char mycall[10];
+	UCHAR digi[56];
+	UCHAR Path[80];				// Path in ax25 format - added to save building it each time
+	UCHAR ReversePath[80];
+	int snd_ch;					// Simplifies parameter passing
+	int port;
+	int pathLen;
+	void * socket;
+	void * Sess;
+	char kind[16];
+	TAX25Info info;
+} TAX25Port;
+
+typedef struct TKISSMode_t
+{
+	string * data_in;
+	void * Socket;				// Used as a key
+
+	// Not sure what rest are used for. Seems to be one per channel
+
+	TStringList buffer[4];			// Outgoing Frames
+
+} TKISSMode;
+
+// Dephi emulation functions
+
+string * Strings(TStringList * Q, int Index);
+void Clear(TStringList * Q);
+int Count(TStringList * List);
+
+string * newString();
+string * copy(string * Source, int StartChar, int Count);
+TStringList * newTStringList();
+
+void freeString(string * Msg);
+void initString(string * S);
+void initTStringList(TStringList* T);
+
+// Two delete() This is confusing!!
+// Not really - one acts on String, other TStringList
+
+void Delete(TStringList * Q, int Index);
+void mydelete(string * Source, int StartChar, int Count);
+void move(UCHAR * SourcePointer, UCHAR * DestinationPointer, int CopyCount);
+void fmove(float * SourcePointer, float * DestinationPointer, int CopyCount);
+void setlength(string * Msg, int Count);		// Set string length
+string * stringAdd(string * Msg, UCHAR * Chars, int Count);		// Extend string 
+void Assign(TStringList * to, TStringList * from);	// Duplicate from to to
+string * duplicateString(string * in);
+int  my_indexof(TStringList * l, string * s);
+boolean compareStrings(string * a, string * b);
+int Add(TStringList * Q, string * Entry);
+void Debugprintf(const char * format, ...);
+void ax25_info_init(TAX25Port * AX25Sess);
+void  clr_frm_win(TAX25Port * AX25Sess);
+void decode_frame(Byte * frame, int len, Byte * path, string * data,
+	Byte * pid, Byte * nr, Byte * ns, Byte * f_type, Byte * f_id,
+	Byte *  rpt, Byte * pf, Byte * cr);
+#ifdef __cplusplus
+extern "C" void KISSSendtoServer(myTcpSocket* Socket, char * Data, int Length);
+extern "C" void monitor_frame(int snd_ch, string * frame, char * code, int  tx, int excluded);
+extern "C" void WriteDebugLog(char * Mess);
+extern "C" void SendtoTerm(Ui_ListenSession * Sess, char * Msg, int Len);
+extern "C" void ClearSessLabel(Ui_ListenSession * Sess);
+extern "C" void rst_timer(TAX25Port * AX25Sess);
+extern "C" void Send_UI(int port, Byte PID, char * CallFrom, char *CallTo, char * Via, Byte *  Msg, int MsgLen);
+#else
+void monitor_frame(int snd_ch, string * frame, char * code, int  tx, int excluded);
+void SendtoTerm(void * Sess, char * Msg, int Len);
+void ClearSessLabel(void * Sess);
+void WriteDebugLog(char * Mess);
+void AX25_disc(TAX25Port * AX25Sess, Byte mode);
+void rst_timer(TAX25Port * AX25Sess);
+void Send_UI(int port, Byte PID, char * CallFrom, char *CallTo, char * via, Byte *  Msg, int MsgLen);
+#endif
+
+BOOL ConvToAX25(char * callsign, unsigned char * ax25call);
+int ConvFromAX25(unsigned char * incall, char * outcall);
+void reverse_addr(Byte * path, Byte * revpath, int Len);
+void set_DM(int snd_ch, Byte * path);
+void set_link(TAX25Port * AX25Sess, UCHAR * axpath);
+boolean is_last_digi(Byte *path);
+boolean is_correct_path(Byte * path, Byte pid);
+int number_digi(unsigned char * path);
+void AX25_conn(TAX25Port * AX25Sess, int snd_ch, Byte mode);
+void  write_ax25_info(TAX25Port * AX25Sess);
+void rst_values(TAX25Port * AX25Sess);
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern boolean dyn_frack[4];
+extern Byte recovery[4];
+extern Byte users[4];
+
+extern int resptime[4];
+extern int slottime[4];
+extern int persist[4];
+extern int kisspaclen[4];
+extern int fracks[4];
+extern int frack_time[4];
+extern int idletime[4];
+extern int redtime[4];
+extern int IPOLL[4];
+extern int maxframe[4];
+extern int TXFrmMode[4];
+
+extern char MyDigiCall[4][512];
+extern char exclude_callsigns[4][512];
+extern char exclude_APRS_frm[4][512];
+
+extern TStringList  list_exclude_callsigns[4];
+extern TStringList list_exclude_APRS_frm[4];
+extern TStringList list_digi_callsigns[4];
+
+extern int max_frame_collector[4];
+extern boolean KISS_opt[4];
+
+extern TAX25Port AX25Port[4][port_num];
+
+extern TStringList KISS_acked[];
+extern TStringList KISS_iacked[];
+
+#ifdef __cplusplus
+}
 #endif
\ No newline at end of file
--- qttermtcp-0.0.0.79.orig/ax25_l2.c
+++ qttermtcp-0.0.0.79/ax25_l2.c
@@ -1,1752 +1,1752 @@
-/*
-Copyright (C) 2019-2020 Andrei Kopanchuk UZ7HO
-
-This file is part of QtSoundModem
-
-QtSoundModem is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-QtSoundModem is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with QtSoundModem.  If not, see http://www.gnu.org/licenses
-
-*/
-
-// UZ7HO Soundmodem Port by John Wiseman G8BPQ
-
-// This is a simplified version for QtTermTCP
-
-
-
-#include "ax25.h"
-
-UCHAR TimerEvent = TIMER_EVENT_OFF;
-extern int busy;
-int listenEnable;
-int KISSListen = 1;
-int KISSChecksum = 0;
-int KISSAckMode = 0;
-
-void * KISSSockCopy[4];
-extern UCHAR axMYCALL[7] = "";			// Mycall in ax.25
-
-string * make_frame(string * data, Byte * path, Byte  pid, Byte nr, Byte ns, Byte f_type, Byte f_id, boolean rpt, boolean pf, boolean cr);
-void rst_t3(TAX25Port * AX25Sess);
-void CheckUIFrame(unsigned char * path, string * data);
-TAX25Port * get_user_port(int snd_ch, Byte * path);
-
-void  inc_frack(TAX25Port * AX25Sess)
-{
-	AX25Sess->clk_frack++;
-}
-
-
-void  rst_frack(TAX25Port * AX25Sess)
-{
-	AX25Sess->clk_frack = 0;
-}
-
-void inc_t1(TAX25Port * AX25Sess)
-{
-	AX25Sess->t1++;
-}
-
-void rst_t1(TAX25Port * AX25Sess)
-{
-	AX25Sess->t1 = 0;
-}
-
-void inc_t3(TAX25Port * AX25Sess)
-{
-	AX25Sess->t3++;
-}
-
-void rst_t3(TAX25Port * AX25Sess)
-{
-	AX25Sess->t3 = 0;
-}
-
-
-void rst_values(TAX25Port * AX25Sess)
-{
-	AX25Sess->IPOLL_cnt = 0;
-	AX25Sess->hi_vs = 0;
-	AX25Sess->vs = 0;
-	AX25Sess->vr = 0;
-	Clear(&AX25Sess->I_frame_buf);
-	Clear(&AX25Sess->in_data_buf);
-	Clear(&AX25Sess->frm_collector);
-
-	ax25_info_init(AX25Sess);
-	clr_frm_win(AX25Sess);
-}
-
-
-void rst_timer(TAX25Port * AX25Sess)
-{
-	rst_frack(AX25Sess);
-	rst_t1(AX25Sess);
-	rst_t3(AX25Sess);
-}
-
-void upd_i_lo(TAX25Port * AX25Sess, int n) //Update the counter of the first frame in the I-frame buffer
-{
-	AX25Sess->i_lo = n;
-}
-
-void upd_i_hi(TAX25Port * AX25Sess, int n) //Update last frame counter in I-frame buffer
-{
-	AX25Sess->i_hi = n;
-}
-
-void upd_vs(TAX25Port * AX25Sess, int n) //Update the counter of the next frame to transmit
-{
-	AX25Sess->vs = ++n & 7;
-}
-
-void upd_vr(TAX25Port * AX25Sess, int n) //Refresh the counter of the next frame at the reception
-{
-	AX25Sess->vr = ++n & 7;
-}
-
-
-void Frame_Optimize(TAX25Port * AX25Sess, TStringList * buf)
-{
-	// I think this removes redundant frames from the TX Queue (eg repeated RR frames)
-
-	string * frame;
-	Byte path[80];
-	string * data = newString();
-
-	Byte  pid, nr, ns, f_type, f_id, rpt, cr, pf;
-	boolean  curr_req, optimize;
-	int i, k;
-	char need_frm[8] = "";
-	int index = 0;
-	boolean  PollRR;
-	boolean PollREJ;
-
-	PollRR = FALSE;
-	PollREJ = FALSE;
-	curr_req = FALSE;
-
-	// Check Poll RR and REJ frame
-
-	i = 0;
-
-	while (i < buf->Count && !PollREJ)
-	{
-		frame = Strings(buf, i);
-		// TX frame has kiss control on front
-
-		decode_frame(frame->Data + 1, frame->Length - 1, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
-
-		if (cr == SET_R && pf == SET_P)
-		{
-			if (f_id == S_REJ)
-				PollREJ = TRUE;
-			else if (f_id == S_RR && nr == AX25Sess->vr)
-				PollRR = TRUE;
-		}
-		i++;
-	}
-
-	// Performance of the REJ Cards: Optional Rej Cards
-
-	i = 0;
-
-	while (i < buf->Count)
-	{
-		optimize = TRUE;
-		frame = Strings(buf, i);
-		decode_frame(frame->Data + 1, frame->Length - 1, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
-
-		if (f_id == S_REJ && cr == SET_R)
-		{
-			if ((pf == SET_F && PollREJ) || nr != AX25Sess->vr)
-			{
-				Debugprintf("Optimizer dropping REJ nr %d vr %d pf %d PollREJ %d", nr, AX25Sess->vr, pf, PollREJ);
-				Delete(buf, i);
-				optimize = FALSE;
-			}
-			if (nr == AX25Sess->vr)
-				curr_req = TRUE;
-		}
-		if (optimize)
-			i++;
-	}
-
-	// Performance Options
-
-	i = 0;
-
-	while (i < buf->Count)
-	{
-		need_frm[0] = 0;
-		index = 0;
-		k = AX25Sess->i_lo;
-
-		while (k != AX25Sess->vs)
-		{
-			need_frm[index++] = k + 'A';
-			k++;
-			k &= 7;
-		}
-
-		optimize = TRUE;
-
-		frame = Strings(buf, i);
-
-		decode_frame(frame->Data +1 , frame->Length - 1, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
-
-		if (f_id == S_RR)
-		{
-			// RR Cards Methods: Optional RR, F Cards
-			if (cr == SET_R)
-			{
-				if (nr != AX25Sess->vr || ((pf == SET_F) && PollRR) || curr_req)
-				{
-					Debugprintf("Optimizer dropping RR nr %d vr %d pf %d PollRR %d", nr, AX25Sess->vr, pf, PollRR);
-
-					Delete(buf, i);
-					optimize = FALSE;
-				}
-			}
-
-
-			// RR Cards Methods : Optional RR, P Cards
-			if (cr == SET_C)
-			{
-				if (AX25Sess->status == STAT_LINK || AX25Sess->status == STAT_WAIT_ANS)
-				{
-					Debugprintf("Optimizer dropping RR nr %d vr %d pf %d PollRR %d", nr, AX25Sess->vr, pf, PollRR);
-					Delete(buf, i);
-					optimize = FALSE;
-				}
-			}
-		}
-		// 	  I - Cards Methods : Options for I - Cards
-		else if (f_id == I_I)
-		{
-			if (strchr(need_frm, ns + 'A') == 0)
-			{
-				Delete(buf, i);
-				optimize = FALSE;
-			}
-			else
-			{
-				if (nr != AX25Sess->vr)
-					buf->Items[i] = make_frame(data, path, pid, AX25Sess->vr, ns, f_type, f_id, rpt, pf, cr);
-			}
-		}
-
-		// SABM Applications
-		
-		if (f_id == U_SABM)
-		{
-			if (AX25Sess->status != STAT_TRY_LINK)
-			{
-				Delete(buf, i);
-				optimize = FALSE;
-			}
-		}
-				
-		if (optimize)
-			i++;
-	}
-}
-
-int KISS_encode(UCHAR * KISSBuffer, int port, string * frame)
-{
-	//	Encode frame
-
-	UCHAR * ptr1 = frame->Data;
-	UCHAR TXCCC = 0;
-	int Len = frame->Length;
-	UCHAR * ptr2 = &KISSBuffer[2];
-	UCHAR c;
-
-	// TX Frame has control byte on front
-
-	ptr1++;
-	Len--;
-
-	KISSBuffer[0] = FEND;
-	KISSBuffer[1] = port << 4;
-
-	TXCCC ^= KISSBuffer[1];
-
-	while (Len--)
-	{
-		c = *(ptr1++);
-		TXCCC ^= c;
-
-		switch (c)
-		{
-		case FEND:
-			(*ptr2++) = FESC;
-			(*ptr2++) = TFEND;
-			break;
-
-		case FESC:
-
-			(*ptr2++) = FESC;
-			(*ptr2++) = TFESC;
-			break;
-
-			// Drop through
-
-		default:
-
-			(*ptr2++) = c;
-		}
-	}
-
-	// Add checksum if needed
-
-	if (KISSChecksum)
-	{
-		c = TXCCC;
-
-		// We don't support TNCX with Checksum
-
-		switch (c)
-		{
-		case FEND:
-			(*ptr2++) = FESC;
-			(*ptr2++) = TFEND;
-			break;
-
-		case FESC:
-			(*ptr2++) = FESC;
-			(*ptr2++) = TFESC;
-			break;
-
-		default:
-			(*ptr2++) = c;
-		}
-	}
-
-	(*ptr2++) = FEND;
-
-	return (int)(ptr2 - KISSBuffer);
-}
-
-void KISSSendtoServer(void * Socket, char * Data, int Length);
-
-void  add_pkt_buf(TAX25Port * AX25Sess, string * data)
-{
-//	boolean found = 0;
-//	int i = 0;
-	UCHAR KISSBuffer[512];
-	int Length;
-
-	// ? Don't we just send to TNC? 
-
-	Length = KISS_encode(KISSBuffer, AX25Sess->snd_ch, data);
-
-	KISSSendtoServer(AX25Sess->socket, KISSBuffer, Length);
-
-	monitor_frame(0, data, "", 1, 0);				// Monitor
-	freeString(data);
-
-}
-
-void add_I_FRM(TAX25Port * AX25Sess)
-{
-	string * data;
-	int  i;
-
-	upd_i_lo(AX25Sess, AX25Sess->vs);
-
-	while (AX25Sess->in_data_buf.Count > 0 && AX25Sess->I_frame_buf.Count != maxframe[AX25Sess->snd_ch])
-	{
-		data = duplicateString(Strings(&AX25Sess->in_data_buf, 0));
-		Delete(&AX25Sess->in_data_buf, 0);
-		Add(&AX25Sess->I_frame_buf, data);
-	}
-	if (AX25Sess->I_frame_buf.Count > 0)
-	{
-		for (i = 0; i < AX25Sess->I_frame_buf.Count; i++)
-		{
-			upd_i_hi(AX25Sess, AX25Sess->vs);
-			upd_vs(AX25Sess, AX25Sess->vs);
-			AX25Sess->hi_vs = AX25Sess->vs; // Last transmitted frame
-		}
-	}
-}
-
-
-void  delete_I_FRM(TAX25Port * AX25Sess, int  nr)
-{
-	int i;
-
-	i = AX25Sess->i_lo;
-
-	while (i != nr)
-	{
-		if (AX25Sess->I_frame_buf.Count > 0)
-		{
-			AX25Sess->info.stat_s_pkt++;
-			AX25Sess->info.stat_s_byte += Strings(&AX25Sess->I_frame_buf, 0)->Length;
-			Delete(&AX25Sess->I_frame_buf, 0);
-		}
-
-		i++;
-		i &= 7;
-	}
-	upd_i_lo(AX25Sess, nr);
-}
-
-void delete_I_FRM_port(TAX25Port * AX25Sess)
-{
-	string * frame;
-	char path[80] = ""; 
-	string data= { 0 };
-
-	Byte pid, nr, ns, f_type, f_id, rpt, cr, pf;
-	boolean  optimize;
-	int  i = 0;
-
-	while (i < AX25Sess->frame_buf.Count)
-	{
-		optimize = TRUE;
-		frame = Strings(&AX25Sess->frame_buf, i);
-
-		decode_frame(frame->Data, frame->Length, path, &data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
-
-		if (f_id == I_I)
-		{
-			Delete(&AX25Sess->frame_buf, i);
-			optimize = FALSE;
-		}
-		if (optimize)
-			i++;
-	}
-}
- 
-void send_data_buf(TAX25Port * AX25Sess, int  nr)
-{
-	int i;
-	boolean new_frames;
-	boolean PF_bit;
-
-	if (AX25Sess->status != STAT_LINK)
-		return;
-
-	AX25Sess->IPOLL_cnt = 0;
-	AX25Sess->vs = nr;
-	delete_I_FRM(AX25Sess, nr);		// ?? free acked frames
-//	delete_I_FRM_port(AX25Sess);
-
-	if (TXFrmMode[AX25Sess->snd_ch] == 1)
-	{
-		new_frames = FALSE;
-	
-		if (AX25Sess->I_frame_buf.Count < 2)
-		{
-			add_I_FRM(AX25Sess);
-			AX25Sess->status = STAT_LINK;
-			new_frames = TRUE;
-		}
-
-		if (AX25Sess->I_frame_buf.Count > 0)
-		{
-			if (new_frames)
-			{
-				for (i = 0; i < AX25Sess->I_frame_buf.Count; i++)
-				{
-					if (i == AX25Sess->I_frame_buf.Count - 1)
-						PF_bit = SET_P;
-					else
-						PF_bit = SET_F;
-
-					add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, i), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, ((AX25Sess->i_lo + i) & 7), I_FRM, I_I, FALSE, PF_bit, SET_C));
-				}
-			}
-			if (!new_frames)
-			{
-				add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, 0), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, AX25Sess->i_lo, I_FRM, I_I, FALSE, SET_P, SET_C)); //SET_P
-				upd_vs(AX25Sess, AX25Sess->vs);
-			}
-			AX25Sess->status = STAT_WAIT_ANS;
-			rst_timer(AX25Sess);
-		}
-	}
-
-	if (TXFrmMode[AX25Sess->snd_ch] == 0)
-	{
-		add_I_FRM(AX25Sess);
-		AX25Sess->status = STAT_LINK;
-		
-		if (AX25Sess->I_frame_buf.Count > 0)
-		{
-			for (i = 0; i < AX25Sess->I_frame_buf.Count; i++)
-			{
-				if (i == AX25Sess->I_frame_buf.Count - 1)
-					PF_bit = SET_P;
-				else
-					PF_bit = SET_F;
-				add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, i), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, ((AX25Sess->i_lo + i) & 7), I_FRM, I_I, FALSE, PF_bit, SET_C));
-			}
-			AX25Sess->status = STAT_WAIT_ANS;
-			rst_timer(AX25Sess);
-		}
-	}
-}
-
-
-void send_data_buf_srej(TAX25Port * AX25Sess, int  nr)
-{
-	// Similar to send_data_buf but only sends the requested I frame with P set
-
-	int i = 0;
-	boolean new_frames;
-	boolean PF_bit;
-
-	if (AX25Sess->status != STAT_LINK)
-		return;
-
-	AX25Sess->IPOLL_cnt = 0;
-	AX25Sess->vs = nr;
-	delete_I_FRM(AX25Sess, nr);		// ?? free acked frames
-
-	new_frames = FALSE;
-
-	add_I_FRM(AX25Sess);
-	AX25Sess->status = STAT_LINK;
-	new_frames = TRUE;
-
-	if (AX25Sess->I_frame_buf.Count > 0)
-	{
-		if (new_frames)
-		{
-			PF_bit = SET_P;
-
-			add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, i), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, ((AX25Sess->i_lo + i) & 7), I_FRM, I_I, FALSE, PF_bit, SET_C));
-		}
-		else
-		{
-
-			add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, 0), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, AX25Sess->i_lo, I_FRM, I_I, FALSE, SET_P, SET_C)); //SET_P
-			upd_vs(AX25Sess, AX25Sess->vs);
-		}
-	}
-	AX25Sess->status = STAT_WAIT_ANS;
-	rst_timer(AX25Sess);
-}
-
-void  write_frame_collector(TAX25Port * AX25Sess, int ns, string * data)
-{
-	Byte  i;
-	char  frm_ns;
-	string  * frm;
-	boolean  found ;
-	boolean need_frm;
-
-	if (max_frame_collector[AX25Sess->snd_ch] < 1)
-		return;
-
-	need_frm = FALSE;
-	i = 1;
-	do
-	{
-		if (ns == ((AX25Sess->vr + i) & 7))
-			need_frm = TRUE;
-
-		i++;
-
-	} while (i <= max_frame_collector[AX25Sess->snd_ch] && !need_frm);
-
-	if (need_frm)
-	{
-		frm_ns = ns;
-		found = FALSE;
-		i = 0;
-
-		if (AX25Sess->frm_collector.Count > 0)
-		{
-			do
-			{
-				frm = Strings(&AX25Sess->frm_collector, i);
-
-				if (frm_ns == frm->Data[0])
-					found = TRUE;
-				i++;
-			}
-			while (!found &&  i != AX25Sess->frm_collector.Count);
-
-		}
-
-		if (!found)
-		{
-			string * frm = newString();
-
-			stringAdd(frm, (char *)&frm_ns, 1);
-			stringAdd(frm, data->Data, data->Length);
-			Add(&AX25Sess->frm_collector, frm);
-		}
-	}
-}
-
-string * read_frame_collector(TAX25Port * AX25Sess, boolean fecflag)
-{
-	// Look for required frame no in saved frames
-
-	string * frm;
-	string * data = newString();
-
-	int i = 0;
-	Byte frm_ns;
-
-	while (i < AX25Sess->frm_collector.Count)
-	{
-		frm = duplicateString(Strings(&AX25Sess->frm_collector, i));
-
-		frm_ns = frm->Data[0];
-
-		if (frm_ns == AX25Sess->vr)
-		{
-			Delete(&AX25Sess->frm_collector, i);
-
-			upd_vr(AX25Sess, AX25Sess->vr);
-
-			mydelete(frm, 0, 1);				// Remove vr from front
-
-			stringAdd(data, frm->Data, frm->Length);
-
-			AX25Sess->info.stat_r_pkt++;
-			AX25Sess->info.stat_r_fc++;
-		
-			if (fecflag)
-				AX25Sess->info.stat_fec_count++;
-
-			AX25Sess->info.stat_r_byte += frm->Length;
-			AX25Sess->frm_win[frm_ns].Length = frm->Length; //Save the frame to the window buffer
-			AX25Sess->frm_win[frm_ns].Data = frm->Data; //Save the frame to the window buffer
-		}
-
-		i++;
-	}
-	return data;
-}
-
-
-/////////////////////////// SET-FRAMES //////////////////////////////////
-
-void set_chk_link(TAX25Port * AX25Sess, Byte * path)
-{
-	boolean  b_IPOLL;
-	int   len;
-
-	AX25Sess->status = STAT_CHK_LINK;
-
-	//  if AX25Sess->digi<>'' then path:=path+','+reverse_digi(AX25Sess->digi);
-
-	b_IPOLL = FALSE;
-
-	if (AX25Sess->I_frame_buf.Count > 0 && AX25Sess->IPOLL_cnt < 2)
-	{
-		len = Strings(&AX25Sess->I_frame_buf, 0)->Length;
-
-		if (len > 0 && len <= IPOLL[AX25Sess->snd_ch])
-		{
-
-			b_IPOLL = TRUE;
-			AX25Sess->IPOLL_cnt++;
-		}
-	}
-	if (b_IPOLL)
-		add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, 0), path, AX25Sess->PID, AX25Sess->vr, AX25Sess->i_lo, I_FRM, I_I, FALSE, SET_P, SET_C));
-	else
-		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0xF0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, SET_P, SET_C));
-
-	inc_frack(AX25Sess);
-}
-
-
-
-// This seems to start a connection
-
-void set_link(TAX25Port * AX25Sess, UCHAR * axpath)
-{
-	if (AX25Sess->status != STAT_LINK)
-	{
-		string nullstring;
-		nullstring.Length = 0;
-
-		rst_values(AX25Sess);
-
-		AX25Sess->status = STAT_TRY_LINK;
-
-		//		if (AX25Sess->digi[0] != 0)
-		//			path: = path + ',' + reverse_digi(AX25Sess->digi);
-
-		add_pkt_buf(AX25Sess, make_frame(&nullstring, axpath, 0, 0, 0, U_FRM, U_SABM, SET_NO_RPT, SET_P, SET_C));
-
-		inc_frack(AX25Sess);
-	}
-}
-
-#define    MODE_OUR 0
-
-void set_try_unlink(TAX25Port * AX25Sess, Byte * path)
-{
-	string nullstring;
-	nullstring.Length = 0;
-	
-	AX25Sess->status = STAT_TRY_UNLINK;
-	add_pkt_buf(AX25Sess, make_frame(&nullstring, path, 0, 0, 0, U_FRM, U_DISC, SET_NO_RPT, SET_P, SET_C));
-	inc_frack(AX25Sess);
-}
-
-
-void set_unlink(TAX25Port * AX25Sess, Byte * path)
-{
-	if (AX25Sess->status == STAT_TRY_UNLINK 
-		|| AX25Sess->status == STAT_TRY_LINK
-		|| AX25Sess->status == STAT_NO_LINK)
-	{
-		string nullstring;
-		nullstring.Length = 0;
-
-		//		if (AX25Sess->digi[0] != 0)
-		//			path: = path + ',' + reverse_digi(AX25Sess->digi);
-
-		AX25_disc(AX25Sess, MODE_OUR);
-
-		if (AX25Sess->status != STAT_TRY_UNLINK)
-			add_pkt_buf(AX25Sess, make_frame(&nullstring, path, 0, 0, 0, U_FRM, U_DISC, SET_NO_RPT, SET_P, SET_C));
-
-		AX25Sess->info.stat_end_ses = time(NULL);
-
-		write_ax25_info(AX25Sess);
-		rst_values(AX25Sess);
-
-		memset(AX25Sess->corrcall, 0, 10);
-		memset(AX25Sess->mycall, 0, 10);
-		AX25Sess->digi[0] = 0;
-		AX25Sess->status = STAT_NO_LINK;
-
-	}
-	else
-		set_try_unlink(AX25Sess, AX25Sess->Path);
-}
-
-void set_FRMR(int snd_ch, Byte * path, unsigned char frameType)
-{
-	//We may not have a session when sending FRMR so reverse path and send
-
-	Byte revpath[80];
-	string * Data = newString();
-	string * Frame;
-
-	UCHAR KISSBuffer[512];
-	int Length;
-
-	Data->Data[0] = frameType;
-	Data->Data[1] = 0;
-	Data->Data[2] = 1;			// Invalid CTL Byte
-	Data->Length = 3;
-
-	reverse_addr(path, revpath, strlen(path));
-
-	Frame = make_frame(Data, revpath, 0, 0, 0, U_FRM, U_FRMR, FALSE, SET_P, SET_R);
-
-	// ? Don't we just send to TNC? 
-
-	Length = KISS_encode(KISSBuffer, 0, Frame);
-
-	KISSSendtoServer(KISSSockCopy[snd_ch], KISSBuffer, Length);
-
-	monitor_frame(0, Frame, "", 1, 0);				// Monitor
-	freeString(Frame);
-	freeString(Data);
-}
-
-void set_DM(int snd_ch, Byte * path)
-{
-	//We may not have a session when sending DM so reverse path and send
-	
-	Byte revpath[80];
-
-	reverse_addr(path, revpath, strlen(path));
-
-	add_pkt_buf(&AX25Port[snd_ch][0], make_frame(NULL, revpath, 0, 0, 0, U_FRM,U_DM,FALSE,SET_P,SET_R));
-}
-
-/////////////////////////// S-FRAMES ////////////////////////////////////
-
-
-void on_RR(TAX25Port * AX25Sess, Byte * path, int  nr, int  pf, int cr)
-{
-	char need_frame[16] = "";
-	int index = 0;
-
-	int i;
-
-	if (AX25Sess->status == STAT_TRY_LINK)
-		return;
-	
-	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
-	{
-		if (cr == SET_C)
-			set_DM(AX25Sess->snd_ch, path);
-
-		return;
-	}
-
-	if (cr == SET_R)
-	{
-		// Determine which frames could get into the users frame buffer.
-		i = AX25Sess->vs;
-
-		need_frame[index++] = i + '0';
-
-//		Debugprintf("RR Rxed vs = %d hi_vs = %d", AX25Sess->vs, AX25Sess->hi_vs);
-		while (i != AX25Sess->hi_vs)
-		{
-			i++;
-			i &= 7;
-
-			need_frame[index++] = i + '0';
-			if (index > 10)
-			{
-				Debugprintf("Index corrupt %d need_frame = %s", index, need_frame);
-				break;
-			}
-		}
-
-		//Clear the received frames from the transmission buffer.
-
-		if (AX25Sess->status == STAT_WAIT_ANS)
-			delete_I_FRM(AX25Sess, nr);
-
-		// We restore the link if the number is valid
-
-		if (AX25Sess->status == STAT_CHK_LINK || strchr(need_frame, nr + '0') != 0)
-		{
-			rst_timer(AX25Sess);
-			AX25Sess->status = STAT_LINK;
-			send_data_buf(AX25Sess, nr);
-		}
-	}
-
-	if (cr == SET_C)
-		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, pf, SET_R));
-
-	rst_t3(AX25Sess);
-}
-
-
-void on_RNR(TAX25Port * AX25Sess, Byte * path, int  nr, int  pf, int cr)
-{
-	UNUSED(pf);
-	
-	if (AX25Sess->status == STAT_TRY_LINK)
-		return;
-
-	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
-	{
-		if (cr == SET_C)
-			set_DM(AX25Sess->snd_ch, path);
-
-		return;
-	}
-
-	if (cr == SET_R)
-	{
-		rst_timer(AX25Sess);
-
-		if (AX25Sess->status == STAT_WAIT_ANS)
-			delete_I_FRM(AX25Sess, nr);
-
-		AX25Sess->status = STAT_CHK_LINK;
-	}
-
-	if (cr == SET_C)
-		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, SET_P, SET_R));
-
-	rst_t3(AX25Sess);
-}
-
-
-void on_REJ(TAX25Port * AX25Sess, Byte * path, int  nr, int  pf, int cr)
-{
-	UNUSED(pf);
-	if (AX25Sess->status == STAT_TRY_LINK)
-		return;
-
-	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
-	{
-		if (cr == SET_C)
-			set_DM(AX25Sess->snd_ch, path);
-
-		return;
-	}
-
-	if (cr == SET_R)
-	{
-		rst_timer(AX25Sess);
-		AX25Sess->status = STAT_LINK;
-
-		send_data_buf(AX25Sess, nr);
-	}
-
-	if (cr == SET_C)
-		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, SET_P, SET_R));
-}
-
-
-void on_SREJ(TAX25Port * AX25Sess, Byte * path, int  nr, int  pf, int cr)
-{
-	UNUSED(pf); 
-	
-	if (AX25Sess->status == STAT_TRY_LINK)
-		return;
-
-	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
-	{
-		if (cr == SET_C)
-			set_DM(AX25Sess->snd_ch, path);
-
-		return;
-	}
-
-	if (cr == SET_R)
-	{
-		rst_timer(AX25Sess);
-		AX25Sess->status = STAT_LINK;
-
-		send_data_buf_srej(AX25Sess, nr);
-	}
-
-	if (cr == SET_C)
-		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, SET_P, SET_R));
-}
-/////////////////////////// I-FRAMES ////////////////////////////////////
-
-void  on_I(void * socket, TAX25Port * AX25Sess, int PID, Byte * path, string * data, int nr, int ns, int pf, int cr, boolean fecflag)
-{
-	UNUSED(cr);
-	UNUSED(socket);
-	string * collector_data = 0;
-	int i;
-	Byte need_frame[16] = "";
-	int index = 0;
-
-
-	if (AX25Sess->status == STAT_TRY_LINK)
-		return;
-
-	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
-	{
-		set_DM(0, path);
-		return;
-	}
-
-	if (busy)
-	{
-		add_pkt_buf(AX25Sess, make_frame(NULL, path, PID, AX25Sess->vr, 0, S_FRM, S_RNR, FALSE, pf, SET_R));
-		return;
-	}
-
-	// Determine which frames could get into the users frame buffer.
-
-	i = AX25Sess->vs;
-
-	need_frame[index++] = i + '0';
-
-	//		Debugprintf("I Rxed vs = %d hi_vs = %d", AX25Sess->vs, AX25Sess->hi_vs);
-
-	while (i != AX25Sess->hi_vs)
-	{
-		i++;
-		i &= 7;
-
-		need_frame[index++] = i + '0';
-		if (index > 10)
-		{
-			Debugprintf("Index corrupt %d need_frame = %s", index, need_frame);
-			break;
-		}
-	}
-
-	//Clear received frames from the transmission buffer.
-
-	if (AX25Sess->status == STAT_WAIT_ANS)
-		delete_I_FRM(AX25Sess, nr);
-
-	//We restore the link if the number is valid
-
-	if (AX25Sess->status == STAT_CHK_LINK || strchr(need_frame, nr + '0') != 0)
-	{
-		//We restore the link if the number is valid
-
-		rst_timer(AX25Sess);
-		AX25Sess->status = STAT_LINK;
-		send_data_buf(AX25Sess, nr);
-	}
-
-	if (ns == AX25Sess->vr)
-	{
-		//If the expected frame, send RR, F
-
-		AX25Sess->info.stat_r_pkt++;
-		AX25Sess->info.stat_r_byte += data->Length;
-
-		if (fecflag)
-			AX25Sess->info.stat_fec_count++;
-
-		upd_vr(AX25Sess, AX25Sess->vr);
-
-		AX25Sess->frm_win[ns].Length = data->Length; //Save the frame to the window buffer
-		AX25Sess->frm_win[ns].Data = data->Data; //Save the frame to the window buffer
-
-		collector_data = read_frame_collector(AX25Sess, fecflag);
-
-		stringAdd(data, collector_data->Data, collector_data->Length);
-
-		SendtoTerm(AX25Sess->Sess, (char *)data->Data, data->Length);
-
-		// Andy's code queues RR immediately and uses frame optimiser to remove
-		// redundant RR (not P) frames. I can't do that so need a proper resptime
-		// system. Try setting an RRNeeded timer (t2).
-
-		if (pf)
-		{
-			// Poll set, so respond immediately
-
-			add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, pf, SET_R));
-			AX25Sess->t2 = 0;
-		}
-		else
-			AX25Sess->t2 = resptime[0] / 100;	// resptime is in mS
-
-		freeString(collector_data);
-	}
-	else
-	{
-		// If the frame is not expected, send REJ, F
-
-		if ((AX25Sess->frm_win[ns].Length != data->Length) &&
-			memcmp(&AX25Sess->frm_win[ns].Data, data->Data, data->Length) != 0)
-
-			write_frame_collector(AX25Sess, ns, data);
-
-		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_REJ, FALSE, pf, SET_R));
-	}
-	rst_t3(AX25Sess);
-
-}
-/////////////////////////// U-FRAMES ////////////////////////////////////
-
-void * ax25IncomingConnect(TAX25Port * AX25Sess);
-
-void on_SABM(void * socket, TAX25Port * AX25Sess)
-{
-	if (AX25Sess->status == STAT_TRY_UNLINK)
-	{
-		AX25Sess->info.stat_end_ses = time(NULL);
-
-		write_ax25_info(AX25Sess);
-		rst_values(AX25Sess);
-
-		memset(AX25Sess->corrcall, 0, 10);
-		memset(AX25Sess->mycall, 0, 10);
-		AX25Sess->digi[0] = 0;
-
-		AX25_disc(AX25Sess, MODE_OTHER);
-		Clear(&AX25Sess->frame_buf);
-
-		AX25Sess->status = STAT_NO_LINK;
-	}
-
-	if (AX25Sess->status == STAT_TRY_LINK)
-	{
-		AX25_disc(AX25Sess, MODE_OTHER);
-
-		rst_timer(AX25Sess);
-		rst_values(AX25Sess);
-		Clear(&AX25Sess->frame_buf);
-		AX25Sess->status = STAT_NO_LINK;
-	}
-
-	if (AX25Sess->status != STAT_NO_LINK)
-	{
-		if ((strcmp(AX25Sess->kind, "Outgoing") == 0) ||
-			AX25Sess->status == STAT_TRY_UNLINK || AX25Sess->info.stat_s_byte > 0 || 
-			AX25Sess->info.stat_r_byte > 0 || AX25Sess->frm_collector.Count > 0)
-		{
-			AX25Sess->info.stat_end_ses = time(NULL);
-			AX25_disc(AX25Sess, MODE_OTHER);
-			write_ax25_info(AX25Sess);
-			rst_timer(AX25Sess);
-			rst_values(AX25Sess);
-			Clear(&AX25Sess->frame_buf);
-			AX25Sess->status = STAT_NO_LINK;
-		}
-	}
-
-	if (AX25Sess->status == STAT_NO_LINK)
-	{
-		AX25Sess->vr = 0;
-		AX25Sess->vs = 0;
-		AX25Sess->hi_vs = 0;
-
-		Clear(&AX25Sess->frm_collector);
-		clr_frm_win(AX25Sess);
-		AX25Sess->status = STAT_LINK;
-		AX25Sess->info.stat_begin_ses = time(NULL);
-		strcpy(AX25Sess->kind, "Incoming");
-		AX25Sess->socket = socket;
-		
-		// Must send UA before any ctext
-		
-		add_pkt_buf(AX25Sess, make_frame(NULL, AX25Sess->Path, 0, 0, 0, U_FRM, U_UA, FALSE, SET_P, SET_R));
-		
-		if (ax25IncomingConnect(AX25Sess))		// Attach to Terminal
-			AX25_conn(AX25Sess, AX25Sess->snd_ch, MODE_OTHER);
-	
-		return;
-	}
-
-	add_pkt_buf(AX25Sess, make_frame(NULL, AX25Sess->Path, 0, 0, 0, U_FRM, U_UA, FALSE, SET_P, SET_R));
-}
-
-void on_DISC(TAX25Port * AX25Sess)
-{
-	if (AX25Sess->status != STAT_NO_LINK)
-	{
-		AX25Sess->info.stat_end_ses = time(NULL);
-		AX25_disc(AX25Sess, MODE_OTHER);
-		write_ax25_info(AX25Sess);
-	}
-
-	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_LINK)
-		set_DM(AX25Sess->snd_ch, AX25Sess->Path);
-	else
-		add_pkt_buf(AX25Sess, make_frame(NULL, AX25Sess->Path, 0, 0, 0, U_FRM, U_UA, FALSE, SET_P, SET_R));
-
-	rst_values(AX25Sess);
-	memset(AX25Sess->corrcall, 0, 10);
-	memset(AX25Sess->mycall, 0, 10);
-	AX25Sess->digi[0] = 0;
-	AX25Sess->status = STAT_NO_LINK;
-}
-
-void on_DM(TAX25Port * AX25Sess)
-{
-	if (AX25Sess->status == STAT_TRY_LINK)
-	{
-
-		char Msg[128];
-		int Len;
-
-		Len = sprintf(Msg, "*** Busy From %s\r", AX25Sess->corrcall);
-		SendtoTerm(AX25Sess->Sess, Msg, Len);
-	}
-	else if (AX25Sess->status != STAT_NO_LINK)
-	{
-		AX25Sess->info.stat_end_ses = time(NULL);
-		AX25_disc(AX25Sess, MODE_OTHER);
-		write_ax25_info(AX25Sess);
-	}
-
-	rst_timer(AX25Sess);
-	rst_values(AX25Sess);
-	memset(AX25Sess->corrcall, 0, 10);
-	memset(AX25Sess->mycall, 0, 10);
-	AX25Sess->digi[0] = 0;
-	AX25Sess->status = STAT_NO_LINK;
-}
-
-
-void on_UA(TAX25Port * AX25Sess)
-{
-	switch (AX25Sess->status)
-	{
-	case STAT_TRY_LINK:
-
-		AX25Sess->info.stat_begin_ses = time(NULL);
-		AX25Sess->status = STAT_LINK;
-		AX25_conn(AX25Sess, AX25Sess->snd_ch, MODE_OUR);
-		break;
-
-	case STAT_TRY_UNLINK:
-
-		AX25Sess->info.stat_end_ses = time(NULL);
-		AX25_disc(AX25Sess, MODE_OUR);
-		write_ax25_info(AX25Sess);
-
-		rst_values(AX25Sess);
-		AX25Sess->status = STAT_NO_LINK;
-		memset(AX25Sess->corrcall, 0, 10);
-		memset(AX25Sess->mycall, 0, 10);
-		AX25Sess->digi[0] = 0;
-		break;
-	}
-
-	rst_timer(AX25Sess);
-}
-
-void on_UI(TAX25Port * AX25Sess, int pf, int cr)
-{
-	UNUSED(AX25Sess);
-	UNUSED(pf);
-	UNUSED(cr);
-
-}
-
-void on_FRMR(void * socket, TAX25Port * AX25Sess, Byte * path)
-{
-	if (AX25Sess->status != STAT_NO_LINK)
-	{
-		AX25Sess->info.stat_end_ses = time(NULL);
-
-		AX25_disc(socket, MODE_OTHER);
-		write_ax25_info(AX25Sess);
-	}
-
-	set_DM(AX25Sess->snd_ch, path);
-
-	rst_values(AX25Sess);
-	memset(AX25Sess->corrcall, 0, 10);
-	memset(AX25Sess->mycall, 0, 10);
-	AX25Sess->digi[0] = 0;
-	AX25Sess->status = STAT_NO_LINK;
-}
-
-
-
-void UpdateActiveConnects(int snd_ch)
-{
-	int port;
-
-	users[snd_ch] = 0;
-
-	for (port = 0; port < port_num; port++)
-		if (AX25Port[snd_ch][port].status != STAT_NO_LINK)
-			users[snd_ch]++;
-}
-
-
-void timer_event()
-{
-	int  snd_ch, port;
-	single  frack;
-	Byte  active;
-	TAX25Port * AX25Sess;
-
-	TimerEvent = TIMER_EVENT_OFF;
-
-	for (snd_ch = 0; snd_ch < 4; snd_ch++)
-	{
-		//reset the slottime timer
-
-		frack = frack_time[snd_ch];
-
-		for (port = 0; port < port_num; port++)
-		{
-			AX25Sess = &AX25Port[snd_ch][port];
-
-			if (AX25Sess->status == STAT_NO_LINK)
-				continue;
-
-			if (AX25Sess->t2)
-			{
-				AX25Sess->t2--;
-				if (AX25Sess->t2 == 0)
-				{
-					// Expired - send RR (without P)
-
-					add_pkt_buf(AX25Sess, make_frame(NULL, AX25Sess->Path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, 0, SET_R));
-				}
-			}
-
-			if (AX25Sess->frame_buf.Count == 0)  //when the transfer buffer is empty
-				inc_t1(AX25Sess); // we consider time of the timer of repeated requests
-
-			// Wouldn't it make more sense to keep path in ax.25 struct?
-
-			if (AX25Sess->t1 >= frack * 10 + (number_digi(AX25Sess->digi) * frack * 20))
-			{
-				if (AX25Sess->clk_frack >= fracks[snd_ch])
-				{
-					// This disconnects after retries expires
-
-					rst_frack(AX25Sess);
-					set_unlink(AX25Sess, AX25Sess->Path);
-				}
-
-				switch (AX25Sess->status)
-				{
-				case STAT_TRY_LINK:
-
-					set_link(AX25Sess, AX25Sess->Path);
-					break;
-
-				case STAT_TRY_UNLINK:
-					
-					set_try_unlink(AX25Sess, AX25Sess->Path);
-					break;
-				
-				case STAT_WAIT_ANS:
-
-					set_chk_link(AX25Sess, AX25Sess->Path);
-					break;
-
-				case STAT_CHK_LINK:
-
-					set_chk_link(AX25Sess, AX25Sess->Path);
-					break;
-				}
-
-				rst_t1(AX25Sess);
-			}
-
-
-			if (AX25Sess->t3 >= idletime[snd_ch] * 10)
-			{
-				set_chk_link(AX25Sess, AX25Sess->Path);
-				rst_t1(AX25Sess);
-				rst_t3(AX25Sess);
-			}
-
-			if (AX25Sess->status == STAT_LINK)
-				inc_t3(AX25Sess);
-
-		}
-	}
-	// KISS ACKMODE
-	//if (snd_status[snd_ch]<>SND_TX) and KISSServ then KISS_send_ack1(snd_ch);
-}
-
-TAX25Port * get_free_port(int snd_ch)
-{
-	int i = 0;
-		
-	while (i < port_num)
-	{
-		if (AX25Port[snd_ch][i].status == STAT_NO_LINK)
-			return &AX25Port[snd_ch][i];
-
-		i++;
-	} 
-	return FALSE;
-}
-
-
-TAX25Port * get_user_port(int snd_ch, Byte * path)
-                                                                                                                                                                                                                                                                                                                                                                       {
-	TAX25Port * AX25Sess = NULL;
-
-	int i = 0;
-
-
-	while (i < port_num)
-	{
-		AX25Sess = &AX25Port[snd_ch][i];
-
-		if (AX25Sess->status != STAT_NO_LINK && memcmp(AX25Sess->ReversePath, path, AX25Sess->pathLen) == 0)
-			return AX25Sess;
-
-		i++;
-	}
-
-	return FALSE;
-}
-
-boolean get_user_dupe(int snd_ch, Byte * path)
-{
-	int i = 0;
-	TAX25Port * AX25Sess;
-
-	while (i < port_num)
-	{
-		AX25Sess = &AX25Port[snd_ch][i];
-
-		if (AX25Sess->status != STAT_NO_LINK && memcmp(AX25Sess->ReversePath, path, AX25Sess->pathLen) == 0)
-			return TRUE;
-
-		i++;
-	}
-
-	return FALSE;
-}
-
-TAX25Port * get_user_port_by_calls(int snd_ch, char *  CallFrom, char *  CallTo)
-{
-	int  i = 0;
-	TAX25Port * AX25Sess = NULL;
-
-	while (i < port_num)
-	{
-		AX25Sess = &AX25Port[snd_ch][i];
-
-		if (AX25Sess->status != STAT_NO_LINK &&
-			strcmp(CallFrom, AX25Sess->mycall) == 0 && strcmp(CallTo, AX25Sess->corrcall) == 0)
-
-			return AX25Sess;
-
-		i++;
-	}
-
-	return NULL;
-}
-
-void * get_sock_by_port(TAX25Port * AX25Sess)
-{
-	void * socket = (void *)-1;
-
-	if (AX25Sess)
-		socket = AX25Sess->socket;
-
-	return socket;
-}
-
-void Digipeater(int snd_ch, string * frame)
-{
-	char call[16];
-	Byte * addr = &frame->Data[7];					// Origin
-	string * frameCopy;
-
-	int n = 8;										// Max digis
-
-	if (list_digi_callsigns[snd_ch].Count == 0)
-		return;
-
-	// Look for first unused digi
-
-	while ((addr[6] & 1) == 0 && n--)					// until end of address
-	{
-		addr += 7;
-
-		if ((addr[6] & 128) == 0)
-		{
-			// unused digi - is it addressed to us?
-
-			memcpy(call, addr, 7);
-			call[6] &= 0x7E;				// Mask end of call 
-
-			// See if in digi list
-
-			int i;
-
-			for (i = 0; i < list_digi_callsigns->Count; i++)
-			{
-				if (memcmp(list_digi_callsigns->Items[i]->Data, call, 7) == 0)
-				{
-					UCHAR KISSBuffer[512];
-					int Length;
-
-					// for us
-
-					addr[6] |= 128;				// set digi'ed
-
-					// TX Frames need a KISS control on front
-
-					frameCopy = newString();
-
-					frameCopy->Data[0] = 0;
-					frameCopy->Length = 1;
-
-					stringAdd(frameCopy, frame->Data, frame->Length);		// Exclude CRC
-
-					addr[6] &= 0x7f;				// clear digi'ed from original;
-
-					// Send to TNC
-					
-					// ? Don't we just send to TNC? 
-
-					Length = KISS_encode(KISSBuffer, 0, frameCopy);
-
-					KISSSendtoServer(KISSSockCopy[snd_ch], KISSBuffer, Length);
-
-					monitor_frame(0, frameCopy, "", 1, 0);				// Monitor
-					freeString(frameCopy);
-
-					return;
-				}
-			}
-		}
-	}
-}
-
-void analiz_frame(int snd_ch, string * frame, void * socket, boolean fecflag)
-{
-	Byte path[80];
-	string * data = 0;
-	Byte  pid, nr, ns, f_type, f_id, rpt, cr, pf;
-	Byte * ptr;
-
-	int excluded = 0;
-	int len;
-
-	TAX25Port * AX25Sess;
-
-	//	mod_icon_status = mod_rx;
-
-	len = frame->Length;
-
-	if (len < PKT_ERR)
-		return;
-
-	data = newString();
-
-	decode_frame(frame->Data, frame->Length, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
-
-	//  if is_excluded_call(snd_ch,path) then excluded:=TRUE;
-	 // if is_excluded_frm(snd_ch,f_id,data) then excluded:=TRUE;	
-
-	// CRC Collision Check
-
-	if (!is_correct_path(path, pid))
-	{
-		// Duff path - if Non-AX25 filter active log and discard
-	}
-
-	monitor_frame(snd_ch, frame, "", 0, excluded);				// Monitor
-
-	// Digipeat frame
-
-	Digipeater(snd_ch, frame);
-
-	if (!is_last_digi(path))
-	{
-		freeString(data);
-		return;							// Don't process if still unused digis
-	}
-
-	// Clear repeated bits from digi path
-
-	ptr = &path[13];
-
-	while ((*ptr & 1) == 0)				// end of address
-	{
-		ptr += 7;
-		*(ptr) &= 0x7f;					// Clear digi'd bit
-	}
-
-	// search for port of correspondent
-
-	AX25Sess = get_user_port(snd_ch, path);
-
-	// if not an active session, AX25Sess will be NULL
-
-//	if (AX25Sess == NULL)
-//		socket = in_list_incoming_mycall(path);
-//	else
-//		socket = get_sock_by_port(AX25Sess);
-
-	// link analysis
-
-	if (AX25Sess == NULL)
-	{
-		if (f_id == U_UI)
-		{
-			CheckUIFrame(path, data);
-			freeString(data);
-			return;						// Don't precess UI at the moment
-		}
-
-		// No Session. If socket is set (so call is in incoming calls list) and SABM set up session
-
-		// Check addresses to us
-
-		if (memcmp(path, axMYCALL, 7) != 0)
-			return;								// ignore
-
-		if (KISSListen == 0)
-		{
-			set_DM(snd_ch, path);
-			freeString(data);
-			return;
-		}
-
-		if (f_id != U_SABM)				// Not SABM
-		{
-			// send DM if P set
-
-			if (cr == SET_C)
-			{
-				switch (f_id)
-				{
-				case U_DISC:
-				case S_RR:
-				case S_REJ:
-				case S_RNR:
-				case I_I:
-
-					set_DM(snd_ch, path);
-					break;
-
-				case U_UI:
-					break;
-
-				default:
-					set_FRMR(snd_ch, path, f_id);
-				}
-
-
-			}
-			freeString(data);
-			return;
-		}
-
-		// Must be SABM. See if it would duplicate an existing session (but could it - wouldn't that be found earlier ??
-
-		// Make sure it is for us
-
-
-
-		if (get_user_dupe(snd_ch, path))		// Not SABM or a duplicate call pair
-		{
-			freeString(data);
-			return;
-		}
-
-		AX25Sess = get_free_port(snd_ch);
-
-		if (AX25Sess == NULL)
-		{
-			// if there are no free ports for connection - reject
-
-			Byte Rev[80];
-
-			reverse_addr(path, Rev, strlen(path));
-			set_DM(snd_ch, Rev);
-			freeString(data);
-			return;
-		}
-
-		// initialise new session
-
-		AX25Sess->snd_ch = snd_ch;
-
-		AX25Sess->corrcall[ConvFromAX25(&path[7], AX25Sess->corrcall)] = 0;
-		AX25Sess->mycall[ConvFromAX25(path, AX25Sess->mycall)] = 0;
-		AX25Sess->digi[0] = 0;
-
-		//		rst_timer(snd_ch, free_port);
-
-		strcpy(AX25Sess->kind, "Incoming");
-		AX25Sess->socket = socket;
-
-		Debugprintf("incoming call socket = %x", socket);
-
-		// I think we need to reverse the path
-
-		AX25Sess->pathLen = strlen(path);
-		strcpy(AX25Sess->ReversePath, path);
-		reverse_addr(path, AX25Sess->Path, strlen(path));
-	}
-
-	// we process a packet on the necessary port
-
-	memcpy(path, AX25Sess->Path, AX25Sess->pathLen);
-
-	switch (f_id)
-	{
-	case I_I:
-
-		on_I(socket, AX25Sess, pid, path, data, nr, ns, pf, cr, fecflag);
-		break;
-
-	case S_RR:
-
-		on_RR(AX25Sess, path, nr, pf, cr);
-		break;
-
-	case S_RNR:
-
-		on_RNR(AX25Sess, path, nr, pf, cr);
-		break;
-
-	case S_REJ:
-
-		on_REJ(AX25Sess, path, nr, pf, cr);
-		break;
-
-	case S_SREJ:
-
-		on_SREJ(AX25Sess, path, nr, pf, cr);
-		break;
-
-	case U_SABM:
-
-		on_SABM(socket, AX25Sess);
-		break;
-
-	case U_DISC:
-
-		on_DISC(AX25Sess);
-		break;
-
-	case U_UA:
-
-		on_UA(AX25Sess);
-		break;
-
-	case U_DM:
-
-		on_DM(AX25Sess);
-		break;
-
-	case U_UI:
-
-		on_UI(AX25Sess, pf, cr);
-		break;
-
-	case U_FRMR:
-
-		on_FRMR(socket, AX25Sess, path);
-		break;
-	}
-	freeString(data);
-}
-
-int get_addr(char * Calls, UCHAR * AXCalls);
-
-void Send_UI(int port, Byte PID, char * CallFrom, char *CallTo, char * via, Byte *  Msg, int MsgLen)
-{
-	char Addrs[256];
-	Byte path[256];
-	int destlen = 0;
-
-	string * Data = newString();
-	string * Frame;
-
-	UCHAR KISSBuffer[512];
-	int Length;
-
-	stringAdd(Data, Msg, MsgLen);
-
-	// We Need Dest, Source, Digis in path, with end of address bit set appropriately.
-
-	sprintf(Addrs, "%s %s %s", CallTo, CallFrom, via);
-
-	destlen = get_addr(Addrs, path);
-
-	Frame = make_frame(Data, path, PID, 0, 0, U_FRM, U_UI, FALSE, SET_F, SET_C);
-
-	// ? Don't we just send to TNC? 
-
-	Length = KISS_encode(KISSBuffer, port, Frame);
-
-	KISSSendtoServer(KISSSockCopy[0], KISSBuffer, Length);
-
-	monitor_frame(0, Frame, "", 1, 0);				// Monitor
-	freeString(Frame);
-
-}
-
-
-
-
+/*
+Copyright (C) 2019-2020 Andrei Kopanchuk UZ7HO
+
+This file is part of QtSoundModem
+
+QtSoundModem is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+QtSoundModem is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with QtSoundModem.  If not, see http://www.gnu.org/licenses
+
+*/
+
+// UZ7HO Soundmodem Port by John Wiseman G8BPQ
+
+// This is a simplified version for QtTermTCP
+
+
+
+#include "ax25.h"
+
+UCHAR TimerEvent = TIMER_EVENT_OFF;
+extern int busy;
+int listenEnable;
+int KISSListen = 1;
+int KISSChecksum = 0;
+int KISSAckMode = 0;
+
+void * KISSSockCopy[4];
+extern UCHAR axMYCALL[7] = "";			// Mycall in ax.25
+
+string * make_frame(string * data, Byte * path, Byte  pid, Byte nr, Byte ns, Byte f_type, Byte f_id, boolean rpt, boolean pf, boolean cr);
+void rst_t3(TAX25Port * AX25Sess);
+void CheckUIFrame(unsigned char * path, string * data);
+TAX25Port * get_user_port(int snd_ch, Byte * path);
+
+void  inc_frack(TAX25Port * AX25Sess)
+{
+	AX25Sess->clk_frack++;
+}
+
+
+void  rst_frack(TAX25Port * AX25Sess)
+{
+	AX25Sess->clk_frack = 0;
+}
+
+void inc_t1(TAX25Port * AX25Sess)
+{
+	AX25Sess->t1++;
+}
+
+void rst_t1(TAX25Port * AX25Sess)
+{
+	AX25Sess->t1 = 0;
+}
+
+void inc_t3(TAX25Port * AX25Sess)
+{
+	AX25Sess->t3++;
+}
+
+void rst_t3(TAX25Port * AX25Sess)
+{
+	AX25Sess->t3 = 0;
+}
+
+
+void rst_values(TAX25Port * AX25Sess)
+{
+	AX25Sess->IPOLL_cnt = 0;
+	AX25Sess->hi_vs = 0;
+	AX25Sess->vs = 0;
+	AX25Sess->vr = 0;
+	Clear(&AX25Sess->I_frame_buf);
+	Clear(&AX25Sess->in_data_buf);
+	Clear(&AX25Sess->frm_collector);
+
+	ax25_info_init(AX25Sess);
+	clr_frm_win(AX25Sess);
+}
+
+
+void rst_timer(TAX25Port * AX25Sess)
+{
+	rst_frack(AX25Sess);
+	rst_t1(AX25Sess);
+	rst_t3(AX25Sess);
+}
+
+void upd_i_lo(TAX25Port * AX25Sess, int n) //Update the counter of the first frame in the I-frame buffer
+{
+	AX25Sess->i_lo = n;
+}
+
+void upd_i_hi(TAX25Port * AX25Sess, int n) //Update last frame counter in I-frame buffer
+{
+	AX25Sess->i_hi = n;
+}
+
+void upd_vs(TAX25Port * AX25Sess, int n) //Update the counter of the next frame to transmit
+{
+	AX25Sess->vs = ++n & 7;
+}
+
+void upd_vr(TAX25Port * AX25Sess, int n) //Refresh the counter of the next frame at the reception
+{
+	AX25Sess->vr = ++n & 7;
+}
+
+
+void Frame_Optimize(TAX25Port * AX25Sess, TStringList * buf)
+{
+	// I think this removes redundant frames from the TX Queue (eg repeated RR frames)
+
+	string * frame;
+	Byte path[80];
+	string * data = newString();
+
+	Byte  pid, nr, ns, f_type, f_id, rpt, cr, pf;
+	boolean  curr_req, optimize;
+	int i, k;
+	char need_frm[8] = "";
+	int index = 0;
+	boolean  PollRR;
+	boolean PollREJ;
+
+	PollRR = FALSE;
+	PollREJ = FALSE;
+	curr_req = FALSE;
+
+	// Check Poll RR and REJ frame
+
+	i = 0;
+
+	while (i < buf->Count && !PollREJ)
+	{
+		frame = Strings(buf, i);
+		// TX frame has kiss control on front
+
+		decode_frame(frame->Data + 1, frame->Length - 1, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
+
+		if (cr == SET_R && pf == SET_P)
+		{
+			if (f_id == S_REJ)
+				PollREJ = TRUE;
+			else if (f_id == S_RR && nr == AX25Sess->vr)
+				PollRR = TRUE;
+		}
+		i++;
+	}
+
+	// Performance of the REJ Cards: Optional Rej Cards
+
+	i = 0;
+
+	while (i < buf->Count)
+	{
+		optimize = TRUE;
+		frame = Strings(buf, i);
+		decode_frame(frame->Data + 1, frame->Length - 1, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
+
+		if (f_id == S_REJ && cr == SET_R)
+		{
+			if ((pf == SET_F && PollREJ) || nr != AX25Sess->vr)
+			{
+				Debugprintf("Optimizer dropping REJ nr %d vr %d pf %d PollREJ %d", nr, AX25Sess->vr, pf, PollREJ);
+				Delete(buf, i);
+				optimize = FALSE;
+			}
+			if (nr == AX25Sess->vr)
+				curr_req = TRUE;
+		}
+		if (optimize)
+			i++;
+	}
+
+	// Performance Options
+
+	i = 0;
+
+	while (i < buf->Count)
+	{
+		need_frm[0] = 0;
+		index = 0;
+		k = AX25Sess->i_lo;
+
+		while (k != AX25Sess->vs)
+		{
+			need_frm[index++] = k + 'A';
+			k++;
+			k &= 7;
+		}
+
+		optimize = TRUE;
+
+		frame = Strings(buf, i);
+
+		decode_frame(frame->Data +1 , frame->Length - 1, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
+
+		if (f_id == S_RR)
+		{
+			// RR Cards Methods: Optional RR, F Cards
+			if (cr == SET_R)
+			{
+				if (nr != AX25Sess->vr || ((pf == SET_F) && PollRR) || curr_req)
+				{
+					Debugprintf("Optimizer dropping RR nr %d vr %d pf %d PollRR %d", nr, AX25Sess->vr, pf, PollRR);
+
+					Delete(buf, i);
+					optimize = FALSE;
+				}
+			}
+
+
+			// RR Cards Methods : Optional RR, P Cards
+			if (cr == SET_C)
+			{
+				if (AX25Sess->status == STAT_LINK || AX25Sess->status == STAT_WAIT_ANS)
+				{
+					Debugprintf("Optimizer dropping RR nr %d vr %d pf %d PollRR %d", nr, AX25Sess->vr, pf, PollRR);
+					Delete(buf, i);
+					optimize = FALSE;
+				}
+			}
+		}
+		// 	  I - Cards Methods : Options for I - Cards
+		else if (f_id == I_I)
+		{
+			if (strchr(need_frm, ns + 'A') == 0)
+			{
+				Delete(buf, i);
+				optimize = FALSE;
+			}
+			else
+			{
+				if (nr != AX25Sess->vr)
+					buf->Items[i] = make_frame(data, path, pid, AX25Sess->vr, ns, f_type, f_id, rpt, pf, cr);
+			}
+		}
+
+		// SABM Applications
+		
+		if (f_id == U_SABM)
+		{
+			if (AX25Sess->status != STAT_TRY_LINK)
+			{
+				Delete(buf, i);
+				optimize = FALSE;
+			}
+		}
+				
+		if (optimize)
+			i++;
+	}
+}
+
+int KISS_encode(UCHAR * KISSBuffer, int port, string * frame)
+{
+	//	Encode frame
+
+	UCHAR * ptr1 = frame->Data;
+	UCHAR TXCCC = 0;
+	int Len = frame->Length;
+	UCHAR * ptr2 = &KISSBuffer[2];
+	UCHAR c;
+
+	// TX Frame has control byte on front
+
+	ptr1++;
+	Len--;
+
+	KISSBuffer[0] = FEND;
+	KISSBuffer[1] = port << 4;
+
+	TXCCC ^= KISSBuffer[1];
+
+	while (Len--)
+	{
+		c = *(ptr1++);
+		TXCCC ^= c;
+
+		switch (c)
+		{
+		case FEND:
+			(*ptr2++) = FESC;
+			(*ptr2++) = TFEND;
+			break;
+
+		case FESC:
+
+			(*ptr2++) = FESC;
+			(*ptr2++) = TFESC;
+			break;
+
+			// Drop through
+
+		default:
+
+			(*ptr2++) = c;
+		}
+	}
+
+	// Add checksum if needed
+
+	if (KISSChecksum)
+	{
+		c = TXCCC;
+
+		// We don't support TNCX with Checksum
+
+		switch (c)
+		{
+		case FEND:
+			(*ptr2++) = FESC;
+			(*ptr2++) = TFEND;
+			break;
+
+		case FESC:
+			(*ptr2++) = FESC;
+			(*ptr2++) = TFESC;
+			break;
+
+		default:
+			(*ptr2++) = c;
+		}
+	}
+
+	(*ptr2++) = FEND;
+
+	return (int)(ptr2 - KISSBuffer);
+}
+
+void KISSSendtoServer(void * Socket, char * Data, int Length);
+
+void  add_pkt_buf(TAX25Port * AX25Sess, string * data)
+{
+//	boolean found = 0;
+//	int i = 0;
+	UCHAR KISSBuffer[512];
+	int Length;
+
+	// ? Don't we just send to TNC? 
+
+	Length = KISS_encode(KISSBuffer, AX25Sess->snd_ch, data);
+
+	KISSSendtoServer(AX25Sess->socket, KISSBuffer, Length);
+
+	monitor_frame(0, data, "", 1, 0);				// Monitor
+	freeString(data);
+
+}
+
+void add_I_FRM(TAX25Port * AX25Sess)
+{
+	string * data;
+	int  i;
+
+	upd_i_lo(AX25Sess, AX25Sess->vs);
+
+	while (AX25Sess->in_data_buf.Count > 0 && AX25Sess->I_frame_buf.Count != maxframe[AX25Sess->snd_ch])
+	{
+		data = duplicateString(Strings(&AX25Sess->in_data_buf, 0));
+		Delete(&AX25Sess->in_data_buf, 0);
+		Add(&AX25Sess->I_frame_buf, data);
+	}
+	if (AX25Sess->I_frame_buf.Count > 0)
+	{
+		for (i = 0; i < AX25Sess->I_frame_buf.Count; i++)
+		{
+			upd_i_hi(AX25Sess, AX25Sess->vs);
+			upd_vs(AX25Sess, AX25Sess->vs);
+			AX25Sess->hi_vs = AX25Sess->vs; // Last transmitted frame
+		}
+	}
+}
+
+
+void  delete_I_FRM(TAX25Port * AX25Sess, int  nr)
+{
+	int i;
+
+	i = AX25Sess->i_lo;
+
+	while (i != nr)
+	{
+		if (AX25Sess->I_frame_buf.Count > 0)
+		{
+			AX25Sess->info.stat_s_pkt++;
+			AX25Sess->info.stat_s_byte += Strings(&AX25Sess->I_frame_buf, 0)->Length;
+			Delete(&AX25Sess->I_frame_buf, 0);
+		}
+
+		i++;
+		i &= 7;
+	}
+	upd_i_lo(AX25Sess, nr);
+}
+
+void delete_I_FRM_port(TAX25Port * AX25Sess)
+{
+	string * frame;
+	char path[80] = ""; 
+	string data= { 0 };
+
+	Byte pid, nr, ns, f_type, f_id, rpt, cr, pf;
+	boolean  optimize;
+	int  i = 0;
+
+	while (i < AX25Sess->frame_buf.Count)
+	{
+		optimize = TRUE;
+		frame = Strings(&AX25Sess->frame_buf, i);
+
+		decode_frame(frame->Data, frame->Length, path, &data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
+
+		if (f_id == I_I)
+		{
+			Delete(&AX25Sess->frame_buf, i);
+			optimize = FALSE;
+		}
+		if (optimize)
+			i++;
+	}
+}
+ 
+void send_data_buf(TAX25Port * AX25Sess, int  nr)
+{
+	int i;
+	boolean new_frames;
+	boolean PF_bit;
+
+	if (AX25Sess->status != STAT_LINK)
+		return;
+
+	AX25Sess->IPOLL_cnt = 0;
+	AX25Sess->vs = nr;
+	delete_I_FRM(AX25Sess, nr);		// ?? free acked frames
+//	delete_I_FRM_port(AX25Sess);
+
+	if (TXFrmMode[AX25Sess->snd_ch] == 1)
+	{
+		new_frames = FALSE;
+	
+		if (AX25Sess->I_frame_buf.Count < 2)
+		{
+			add_I_FRM(AX25Sess);
+			AX25Sess->status = STAT_LINK;
+			new_frames = TRUE;
+		}
+
+		if (AX25Sess->I_frame_buf.Count > 0)
+		{
+			if (new_frames)
+			{
+				for (i = 0; i < AX25Sess->I_frame_buf.Count; i++)
+				{
+					if (i == AX25Sess->I_frame_buf.Count - 1)
+						PF_bit = SET_P;
+					else
+						PF_bit = SET_F;
+
+					add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, i), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, ((AX25Sess->i_lo + i) & 7), I_FRM, I_I, FALSE, PF_bit, SET_C));
+				}
+			}
+			if (!new_frames)
+			{
+				add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, 0), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, AX25Sess->i_lo, I_FRM, I_I, FALSE, SET_P, SET_C)); //SET_P
+				upd_vs(AX25Sess, AX25Sess->vs);
+			}
+			AX25Sess->status = STAT_WAIT_ANS;
+			rst_timer(AX25Sess);
+		}
+	}
+
+	if (TXFrmMode[AX25Sess->snd_ch] == 0)
+	{
+		add_I_FRM(AX25Sess);
+		AX25Sess->status = STAT_LINK;
+		
+		if (AX25Sess->I_frame_buf.Count > 0)
+		{
+			for (i = 0; i < AX25Sess->I_frame_buf.Count; i++)
+			{
+				if (i == AX25Sess->I_frame_buf.Count - 1)
+					PF_bit = SET_P;
+				else
+					PF_bit = SET_F;
+				add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, i), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, ((AX25Sess->i_lo + i) & 7), I_FRM, I_I, FALSE, PF_bit, SET_C));
+			}
+			AX25Sess->status = STAT_WAIT_ANS;
+			rst_timer(AX25Sess);
+		}
+	}
+}
+
+
+void send_data_buf_srej(TAX25Port * AX25Sess, int  nr)
+{
+	// Similar to send_data_buf but only sends the requested I frame with P set
+
+	int i = 0;
+	boolean new_frames;
+	boolean PF_bit;
+
+	if (AX25Sess->status != STAT_LINK)
+		return;
+
+	AX25Sess->IPOLL_cnt = 0;
+	AX25Sess->vs = nr;
+	delete_I_FRM(AX25Sess, nr);		// ?? free acked frames
+
+	new_frames = FALSE;
+
+	add_I_FRM(AX25Sess);
+	AX25Sess->status = STAT_LINK;
+	new_frames = TRUE;
+
+	if (AX25Sess->I_frame_buf.Count > 0)
+	{
+		if (new_frames)
+		{
+			PF_bit = SET_P;
+
+			add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, i), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, ((AX25Sess->i_lo + i) & 7), I_FRM, I_I, FALSE, PF_bit, SET_C));
+		}
+		else
+		{
+
+			add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, 0), AX25Sess->Path, AX25Sess->PID, AX25Sess->vr, AX25Sess->i_lo, I_FRM, I_I, FALSE, SET_P, SET_C)); //SET_P
+			upd_vs(AX25Sess, AX25Sess->vs);
+		}
+	}
+	AX25Sess->status = STAT_WAIT_ANS;
+	rst_timer(AX25Sess);
+}
+
+void  write_frame_collector(TAX25Port * AX25Sess, int ns, string * data)
+{
+	Byte  i;
+	char  frm_ns;
+	string  * frm;
+	boolean  found ;
+	boolean need_frm;
+
+	if (max_frame_collector[AX25Sess->snd_ch] < 1)
+		return;
+
+	need_frm = FALSE;
+	i = 1;
+	do
+	{
+		if (ns == ((AX25Sess->vr + i) & 7))
+			need_frm = TRUE;
+
+		i++;
+
+	} while (i <= max_frame_collector[AX25Sess->snd_ch] && !need_frm);
+
+	if (need_frm)
+	{
+		frm_ns = ns;
+		found = FALSE;
+		i = 0;
+
+		if (AX25Sess->frm_collector.Count > 0)
+		{
+			do
+			{
+				frm = Strings(&AX25Sess->frm_collector, i);
+
+				if (frm_ns == frm->Data[0])
+					found = TRUE;
+				i++;
+			}
+			while (!found &&  i != AX25Sess->frm_collector.Count);
+
+		}
+
+		if (!found)
+		{
+			string * frm = newString();
+
+			stringAdd(frm, (char *)&frm_ns, 1);
+			stringAdd(frm, data->Data, data->Length);
+			Add(&AX25Sess->frm_collector, frm);
+		}
+	}
+}
+
+string * read_frame_collector(TAX25Port * AX25Sess, boolean fecflag)
+{
+	// Look for required frame no in saved frames
+
+	string * frm;
+	string * data = newString();
+
+	int i = 0;
+	Byte frm_ns;
+
+	while (i < AX25Sess->frm_collector.Count)
+	{
+		frm = duplicateString(Strings(&AX25Sess->frm_collector, i));
+
+		frm_ns = frm->Data[0];
+
+		if (frm_ns == AX25Sess->vr)
+		{
+			Delete(&AX25Sess->frm_collector, i);
+
+			upd_vr(AX25Sess, AX25Sess->vr);
+
+			mydelete(frm, 0, 1);				// Remove vr from front
+
+			stringAdd(data, frm->Data, frm->Length);
+
+			AX25Sess->info.stat_r_pkt++;
+			AX25Sess->info.stat_r_fc++;
+		
+			if (fecflag)
+				AX25Sess->info.stat_fec_count++;
+
+			AX25Sess->info.stat_r_byte += frm->Length;
+			AX25Sess->frm_win[frm_ns].Length = frm->Length; //Save the frame to the window buffer
+			AX25Sess->frm_win[frm_ns].Data = frm->Data; //Save the frame to the window buffer
+		}
+
+		i++;
+	}
+	return data;
+}
+
+
+/////////////////////////// SET-FRAMES //////////////////////////////////
+
+void set_chk_link(TAX25Port * AX25Sess, Byte * path)
+{
+	boolean  b_IPOLL;
+	int   len;
+
+	AX25Sess->status = STAT_CHK_LINK;
+
+	//  if AX25Sess->digi<>'' then path:=path+','+reverse_digi(AX25Sess->digi);
+
+	b_IPOLL = FALSE;
+
+	if (AX25Sess->I_frame_buf.Count > 0 && AX25Sess->IPOLL_cnt < 2)
+	{
+		len = Strings(&AX25Sess->I_frame_buf, 0)->Length;
+
+		if (len > 0 && len <= IPOLL[AX25Sess->snd_ch])
+		{
+
+			b_IPOLL = TRUE;
+			AX25Sess->IPOLL_cnt++;
+		}
+	}
+	if (b_IPOLL)
+		add_pkt_buf(AX25Sess, make_frame(Strings(&AX25Sess->I_frame_buf, 0), path, AX25Sess->PID, AX25Sess->vr, AX25Sess->i_lo, I_FRM, I_I, FALSE, SET_P, SET_C));
+	else
+		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0xF0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, SET_P, SET_C));
+
+	inc_frack(AX25Sess);
+}
+
+
+
+// This seems to start a connection
+
+void set_link(TAX25Port * AX25Sess, UCHAR * axpath)
+{
+	if (AX25Sess->status != STAT_LINK)
+	{
+		string nullstring;
+		nullstring.Length = 0;
+
+		rst_values(AX25Sess);
+
+		AX25Sess->status = STAT_TRY_LINK;
+
+		//		if (AX25Sess->digi[0] != 0)
+		//			path: = path + ',' + reverse_digi(AX25Sess->digi);
+
+		add_pkt_buf(AX25Sess, make_frame(&nullstring, axpath, 0, 0, 0, U_FRM, U_SABM, SET_NO_RPT, SET_P, SET_C));
+
+		inc_frack(AX25Sess);
+	}
+}
+
+#define    MODE_OUR 0
+
+void set_try_unlink(TAX25Port * AX25Sess, Byte * path)
+{
+	string nullstring;
+	nullstring.Length = 0;
+	
+	AX25Sess->status = STAT_TRY_UNLINK;
+	add_pkt_buf(AX25Sess, make_frame(&nullstring, path, 0, 0, 0, U_FRM, U_DISC, SET_NO_RPT, SET_P, SET_C));
+	inc_frack(AX25Sess);
+}
+
+
+void set_unlink(TAX25Port * AX25Sess, Byte * path)
+{
+	if (AX25Sess->status == STAT_TRY_UNLINK 
+		|| AX25Sess->status == STAT_TRY_LINK
+		|| AX25Sess->status == STAT_NO_LINK)
+	{
+		string nullstring;
+		nullstring.Length = 0;
+
+		//		if (AX25Sess->digi[0] != 0)
+		//			path: = path + ',' + reverse_digi(AX25Sess->digi);
+
+		AX25_disc(AX25Sess, MODE_OUR);
+
+		if (AX25Sess->status != STAT_TRY_UNLINK)
+			add_pkt_buf(AX25Sess, make_frame(&nullstring, path, 0, 0, 0, U_FRM, U_DISC, SET_NO_RPT, SET_P, SET_C));
+
+		AX25Sess->info.stat_end_ses = time(NULL);
+
+		write_ax25_info(AX25Sess);
+		rst_values(AX25Sess);
+
+		memset(AX25Sess->corrcall, 0, 10);
+		memset(AX25Sess->mycall, 0, 10);
+		AX25Sess->digi[0] = 0;
+		AX25Sess->status = STAT_NO_LINK;
+
+	}
+	else
+		set_try_unlink(AX25Sess, AX25Sess->Path);
+}
+
+void set_FRMR(int snd_ch, Byte * path, unsigned char frameType)
+{
+	//We may not have a session when sending FRMR so reverse path and send
+
+	Byte revpath[80];
+	string * Data = newString();
+	string * Frame;
+
+	UCHAR KISSBuffer[512];
+	int Length;
+
+	Data->Data[0] = frameType;
+	Data->Data[1] = 0;
+	Data->Data[2] = 1;			// Invalid CTL Byte
+	Data->Length = 3;
+
+	reverse_addr(path, revpath, strlen(path));
+
+	Frame = make_frame(Data, revpath, 0, 0, 0, U_FRM, U_FRMR, FALSE, SET_P, SET_R);
+
+	// ? Don't we just send to TNC? 
+
+	Length = KISS_encode(KISSBuffer, 0, Frame);
+
+	KISSSendtoServer(KISSSockCopy[snd_ch], KISSBuffer, Length);
+
+	monitor_frame(0, Frame, "", 1, 0);				// Monitor
+	freeString(Frame);
+	freeString(Data);
+}
+
+void set_DM(int snd_ch, Byte * path)
+{
+	//We may not have a session when sending DM so reverse path and send
+	
+	Byte revpath[80];
+
+	reverse_addr(path, revpath, strlen(path));
+
+	add_pkt_buf(&AX25Port[snd_ch][0], make_frame(NULL, revpath, 0, 0, 0, U_FRM,U_DM,FALSE,SET_P,SET_R));
+}
+
+/////////////////////////// S-FRAMES ////////////////////////////////////
+
+
+void on_RR(TAX25Port * AX25Sess, Byte * path, int  nr, int  pf, int cr)
+{
+	char need_frame[16] = "";
+	int index = 0;
+
+	int i;
+
+	if (AX25Sess->status == STAT_TRY_LINK)
+		return;
+	
+	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
+	{
+		if (cr == SET_C)
+			set_DM(AX25Sess->snd_ch, path);
+
+		return;
+	}
+
+	if (cr == SET_R)
+	{
+		// Determine which frames could get into the users frame buffer.
+		i = AX25Sess->vs;
+
+		need_frame[index++] = i + '0';
+
+//		Debugprintf("RR Rxed vs = %d hi_vs = %d", AX25Sess->vs, AX25Sess->hi_vs);
+		while (i != AX25Sess->hi_vs)
+		{
+			i++;
+			i &= 7;
+
+			need_frame[index++] = i + '0';
+			if (index > 10)
+			{
+				Debugprintf("Index corrupt %d need_frame = %s", index, need_frame);
+				break;
+			}
+		}
+
+		//Clear the received frames from the transmission buffer.
+
+		if (AX25Sess->status == STAT_WAIT_ANS)
+			delete_I_FRM(AX25Sess, nr);
+
+		// We restore the link if the number is valid
+
+		if (AX25Sess->status == STAT_CHK_LINK || strchr(need_frame, nr + '0') != 0)
+		{
+			rst_timer(AX25Sess);
+			AX25Sess->status = STAT_LINK;
+			send_data_buf(AX25Sess, nr);
+		}
+	}
+
+	if (cr == SET_C)
+		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, pf, SET_R));
+
+	rst_t3(AX25Sess);
+}
+
+
+void on_RNR(TAX25Port * AX25Sess, Byte * path, int  nr, int  pf, int cr)
+{
+	UNUSED(pf);
+	
+	if (AX25Sess->status == STAT_TRY_LINK)
+		return;
+
+	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
+	{
+		if (cr == SET_C)
+			set_DM(AX25Sess->snd_ch, path);
+
+		return;
+	}
+
+	if (cr == SET_R)
+	{
+		rst_timer(AX25Sess);
+
+		if (AX25Sess->status == STAT_WAIT_ANS)
+			delete_I_FRM(AX25Sess, nr);
+
+		AX25Sess->status = STAT_CHK_LINK;
+	}
+
+	if (cr == SET_C)
+		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, SET_P, SET_R));
+
+	rst_t3(AX25Sess);
+}
+
+
+void on_REJ(TAX25Port * AX25Sess, Byte * path, int  nr, int  pf, int cr)
+{
+	UNUSED(pf);
+	if (AX25Sess->status == STAT_TRY_LINK)
+		return;
+
+	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
+	{
+		if (cr == SET_C)
+			set_DM(AX25Sess->snd_ch, path);
+
+		return;
+	}
+
+	if (cr == SET_R)
+	{
+		rst_timer(AX25Sess);
+		AX25Sess->status = STAT_LINK;
+
+		send_data_buf(AX25Sess, nr);
+	}
+
+	if (cr == SET_C)
+		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, SET_P, SET_R));
+}
+
+
+void on_SREJ(TAX25Port * AX25Sess, Byte * path, int  nr, int  pf, int cr)
+{
+	UNUSED(pf); 
+	
+	if (AX25Sess->status == STAT_TRY_LINK)
+		return;
+
+	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
+	{
+		if (cr == SET_C)
+			set_DM(AX25Sess->snd_ch, path);
+
+		return;
+	}
+
+	if (cr == SET_R)
+	{
+		rst_timer(AX25Sess);
+		AX25Sess->status = STAT_LINK;
+
+		send_data_buf_srej(AX25Sess, nr);
+	}
+
+	if (cr == SET_C)
+		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, SET_P, SET_R));
+}
+/////////////////////////// I-FRAMES ////////////////////////////////////
+
+void  on_I(void * socket, TAX25Port * AX25Sess, int PID, Byte * path, string * data, int nr, int ns, int pf, int cr, boolean fecflag)
+{
+	UNUSED(cr);
+	UNUSED(socket);
+	string * collector_data = 0;
+	int i;
+	Byte need_frame[16] = "";
+	int index = 0;
+
+
+	if (AX25Sess->status == STAT_TRY_LINK)
+		return;
+
+	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_UNLINK)
+	{
+		set_DM(0, path);
+		return;
+	}
+
+	if (busy)
+	{
+		add_pkt_buf(AX25Sess, make_frame(NULL, path, PID, AX25Sess->vr, 0, S_FRM, S_RNR, FALSE, pf, SET_R));
+		return;
+	}
+
+	// Determine which frames could get into the users frame buffer.
+
+	i = AX25Sess->vs;
+
+	need_frame[index++] = i + '0';
+
+	//		Debugprintf("I Rxed vs = %d hi_vs = %d", AX25Sess->vs, AX25Sess->hi_vs);
+
+	while (i != AX25Sess->hi_vs)
+	{
+		i++;
+		i &= 7;
+
+		need_frame[index++] = i + '0';
+		if (index > 10)
+		{
+			Debugprintf("Index corrupt %d need_frame = %s", index, need_frame);
+			break;
+		}
+	}
+
+	//Clear received frames from the transmission buffer.
+
+	if (AX25Sess->status == STAT_WAIT_ANS)
+		delete_I_FRM(AX25Sess, nr);
+
+	//We restore the link if the number is valid
+
+	if (AX25Sess->status == STAT_CHK_LINK || strchr(need_frame, nr + '0') != 0)
+	{
+		//We restore the link if the number is valid
+
+		rst_timer(AX25Sess);
+		AX25Sess->status = STAT_LINK;
+		send_data_buf(AX25Sess, nr);
+	}
+
+	if (ns == AX25Sess->vr)
+	{
+		//If the expected frame, send RR, F
+
+		AX25Sess->info.stat_r_pkt++;
+		AX25Sess->info.stat_r_byte += data->Length;
+
+		if (fecflag)
+			AX25Sess->info.stat_fec_count++;
+
+		upd_vr(AX25Sess, AX25Sess->vr);
+
+		AX25Sess->frm_win[ns].Length = data->Length; //Save the frame to the window buffer
+		AX25Sess->frm_win[ns].Data = data->Data; //Save the frame to the window buffer
+
+		collector_data = read_frame_collector(AX25Sess, fecflag);
+
+		stringAdd(data, collector_data->Data, collector_data->Length);
+
+		SendtoTerm(AX25Sess->Sess, (char *)data->Data, data->Length);
+
+		// Andy's code queues RR immediately and uses frame optimiser to remove
+		// redundant RR (not P) frames. I can't do that so need a proper resptime
+		// system. Try setting an RRNeeded timer (t2).
+
+		if (pf)
+		{
+			// Poll set, so respond immediately
+
+			add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, pf, SET_R));
+			AX25Sess->t2 = 0;
+		}
+		else
+			AX25Sess->t2 = resptime[0] / 100;	// resptime is in mS
+
+		freeString(collector_data);
+	}
+	else
+	{
+		// If the frame is not expected, send REJ, F
+
+		if ((AX25Sess->frm_win[ns].Length != data->Length) &&
+			memcmp(&AX25Sess->frm_win[ns].Data, data->Data, data->Length) != 0)
+
+			write_frame_collector(AX25Sess, ns, data);
+
+		add_pkt_buf(AX25Sess, make_frame(NULL, path, 0, AX25Sess->vr, 0, S_FRM, S_REJ, FALSE, pf, SET_R));
+	}
+	rst_t3(AX25Sess);
+
+}
+/////////////////////////// U-FRAMES ////////////////////////////////////
+
+void * ax25IncomingConnect(TAX25Port * AX25Sess);
+
+void on_SABM(void * socket, TAX25Port * AX25Sess)
+{
+	if (AX25Sess->status == STAT_TRY_UNLINK)
+	{
+		AX25Sess->info.stat_end_ses = time(NULL);
+
+		write_ax25_info(AX25Sess);
+		rst_values(AX25Sess);
+
+		memset(AX25Sess->corrcall, 0, 10);
+		memset(AX25Sess->mycall, 0, 10);
+		AX25Sess->digi[0] = 0;
+
+		AX25_disc(AX25Sess, MODE_OTHER);
+		Clear(&AX25Sess->frame_buf);
+
+		AX25Sess->status = STAT_NO_LINK;
+	}
+
+	if (AX25Sess->status == STAT_TRY_LINK)
+	{
+		AX25_disc(AX25Sess, MODE_OTHER);
+
+		rst_timer(AX25Sess);
+		rst_values(AX25Sess);
+		Clear(&AX25Sess->frame_buf);
+		AX25Sess->status = STAT_NO_LINK;
+	}
+
+	if (AX25Sess->status != STAT_NO_LINK)
+	{
+		if ((strcmp(AX25Sess->kind, "Outgoing") == 0) ||
+			AX25Sess->status == STAT_TRY_UNLINK || AX25Sess->info.stat_s_byte > 0 || 
+			AX25Sess->info.stat_r_byte > 0 || AX25Sess->frm_collector.Count > 0)
+		{
+			AX25Sess->info.stat_end_ses = time(NULL);
+			AX25_disc(AX25Sess, MODE_OTHER);
+			write_ax25_info(AX25Sess);
+			rst_timer(AX25Sess);
+			rst_values(AX25Sess);
+			Clear(&AX25Sess->frame_buf);
+			AX25Sess->status = STAT_NO_LINK;
+		}
+	}
+
+	if (AX25Sess->status == STAT_NO_LINK)
+	{
+		AX25Sess->vr = 0;
+		AX25Sess->vs = 0;
+		AX25Sess->hi_vs = 0;
+
+		Clear(&AX25Sess->frm_collector);
+		clr_frm_win(AX25Sess);
+		AX25Sess->status = STAT_LINK;
+		AX25Sess->info.stat_begin_ses = time(NULL);
+		strcpy(AX25Sess->kind, "Incoming");
+		AX25Sess->socket = socket;
+		
+		// Must send UA before any ctext
+		
+		add_pkt_buf(AX25Sess, make_frame(NULL, AX25Sess->Path, 0, 0, 0, U_FRM, U_UA, FALSE, SET_P, SET_R));
+		
+		if (ax25IncomingConnect(AX25Sess))		// Attach to Terminal
+			AX25_conn(AX25Sess, AX25Sess->snd_ch, MODE_OTHER);
+	
+		return;
+	}
+
+	add_pkt_buf(AX25Sess, make_frame(NULL, AX25Sess->Path, 0, 0, 0, U_FRM, U_UA, FALSE, SET_P, SET_R));
+}
+
+void on_DISC(TAX25Port * AX25Sess)
+{
+	if (AX25Sess->status != STAT_NO_LINK)
+	{
+		AX25Sess->info.stat_end_ses = time(NULL);
+		AX25_disc(AX25Sess, MODE_OTHER);
+		write_ax25_info(AX25Sess);
+	}
+
+	if (AX25Sess->status == STAT_NO_LINK || AX25Sess->status == STAT_TRY_LINK)
+		set_DM(AX25Sess->snd_ch, AX25Sess->Path);
+	else
+		add_pkt_buf(AX25Sess, make_frame(NULL, AX25Sess->Path, 0, 0, 0, U_FRM, U_UA, FALSE, SET_P, SET_R));
+
+	rst_values(AX25Sess);
+	memset(AX25Sess->corrcall, 0, 10);
+	memset(AX25Sess->mycall, 0, 10);
+	AX25Sess->digi[0] = 0;
+	AX25Sess->status = STAT_NO_LINK;
+}
+
+void on_DM(TAX25Port * AX25Sess)
+{
+	if (AX25Sess->status == STAT_TRY_LINK)
+	{
+
+		char Msg[128];
+		int Len;
+
+		Len = sprintf(Msg, "*** Busy From %s\r", AX25Sess->corrcall);
+		SendtoTerm(AX25Sess->Sess, Msg, Len);
+	}
+	else if (AX25Sess->status != STAT_NO_LINK)
+	{
+		AX25Sess->info.stat_end_ses = time(NULL);
+		AX25_disc(AX25Sess, MODE_OTHER);
+		write_ax25_info(AX25Sess);
+	}
+
+	rst_timer(AX25Sess);
+	rst_values(AX25Sess);
+	memset(AX25Sess->corrcall, 0, 10);
+	memset(AX25Sess->mycall, 0, 10);
+	AX25Sess->digi[0] = 0;
+	AX25Sess->status = STAT_NO_LINK;
+}
+
+
+void on_UA(TAX25Port * AX25Sess)
+{
+	switch (AX25Sess->status)
+	{
+	case STAT_TRY_LINK:
+
+		AX25Sess->info.stat_begin_ses = time(NULL);
+		AX25Sess->status = STAT_LINK;
+		AX25_conn(AX25Sess, AX25Sess->snd_ch, MODE_OUR);
+		break;
+
+	case STAT_TRY_UNLINK:
+
+		AX25Sess->info.stat_end_ses = time(NULL);
+		AX25_disc(AX25Sess, MODE_OUR);
+		write_ax25_info(AX25Sess);
+
+		rst_values(AX25Sess);
+		AX25Sess->status = STAT_NO_LINK;
+		memset(AX25Sess->corrcall, 0, 10);
+		memset(AX25Sess->mycall, 0, 10);
+		AX25Sess->digi[0] = 0;
+		break;
+	}
+
+	rst_timer(AX25Sess);
+}
+
+void on_UI(TAX25Port * AX25Sess, int pf, int cr)
+{
+	UNUSED(AX25Sess);
+	UNUSED(pf);
+	UNUSED(cr);
+
+}
+
+void on_FRMR(void * socket, TAX25Port * AX25Sess, Byte * path)
+{
+	if (AX25Sess->status != STAT_NO_LINK)
+	{
+		AX25Sess->info.stat_end_ses = time(NULL);
+
+		AX25_disc(socket, MODE_OTHER);
+		write_ax25_info(AX25Sess);
+	}
+
+	set_DM(AX25Sess->snd_ch, path);
+
+	rst_values(AX25Sess);
+	memset(AX25Sess->corrcall, 0, 10);
+	memset(AX25Sess->mycall, 0, 10);
+	AX25Sess->digi[0] = 0;
+	AX25Sess->status = STAT_NO_LINK;
+}
+
+
+
+void UpdateActiveConnects(int snd_ch)
+{
+	int port;
+
+	users[snd_ch] = 0;
+
+	for (port = 0; port < port_num; port++)
+		if (AX25Port[snd_ch][port].status != STAT_NO_LINK)
+			users[snd_ch]++;
+}
+
+
+void timer_event()
+{
+	int  snd_ch, port;
+	single  frack;
+	Byte  active;
+	TAX25Port * AX25Sess;
+
+	TimerEvent = TIMER_EVENT_OFF;
+
+	for (snd_ch = 0; snd_ch < 4; snd_ch++)
+	{
+		//reset the slottime timer
+
+		frack = frack_time[snd_ch];
+
+		for (port = 0; port < port_num; port++)
+		{
+			AX25Sess = &AX25Port[snd_ch][port];
+
+			if (AX25Sess->status == STAT_NO_LINK)
+				continue;
+
+			if (AX25Sess->t2)
+			{
+				AX25Sess->t2--;
+				if (AX25Sess->t2 == 0)
+				{
+					// Expired - send RR (without P)
+
+					add_pkt_buf(AX25Sess, make_frame(NULL, AX25Sess->Path, 0, AX25Sess->vr, 0, S_FRM, S_RR, FALSE, 0, SET_R));
+				}
+			}
+
+			if (AX25Sess->frame_buf.Count == 0)  //when the transfer buffer is empty
+				inc_t1(AX25Sess); // we consider time of the timer of repeated requests
+
+			// Wouldn't it make more sense to keep path in ax.25 struct?
+
+			if (AX25Sess->t1 >= frack * 10 + (number_digi(AX25Sess->digi) * frack * 20))
+			{
+				if (AX25Sess->clk_frack >= fracks[snd_ch])
+				{
+					// This disconnects after retries expires
+
+					rst_frack(AX25Sess);
+					set_unlink(AX25Sess, AX25Sess->Path);
+				}
+
+				switch (AX25Sess->status)
+				{
+				case STAT_TRY_LINK:
+
+					set_link(AX25Sess, AX25Sess->Path);
+					break;
+
+				case STAT_TRY_UNLINK:
+					
+					set_try_unlink(AX25Sess, AX25Sess->Path);
+					break;
+				
+				case STAT_WAIT_ANS:
+
+					set_chk_link(AX25Sess, AX25Sess->Path);
+					break;
+
+				case STAT_CHK_LINK:
+
+					set_chk_link(AX25Sess, AX25Sess->Path);
+					break;
+				}
+
+				rst_t1(AX25Sess);
+			}
+
+
+			if (AX25Sess->t3 >= idletime[snd_ch] * 10)
+			{
+				set_chk_link(AX25Sess, AX25Sess->Path);
+				rst_t1(AX25Sess);
+				rst_t3(AX25Sess);
+			}
+
+			if (AX25Sess->status == STAT_LINK)
+				inc_t3(AX25Sess);
+
+		}
+	}
+	// KISS ACKMODE
+	//if (snd_status[snd_ch]<>SND_TX) and KISSServ then KISS_send_ack1(snd_ch);
+}
+
+TAX25Port * get_free_port(int snd_ch)
+{
+	int i = 0;
+		
+	while (i < port_num)
+	{
+		if (AX25Port[snd_ch][i].status == STAT_NO_LINK)
+			return &AX25Port[snd_ch][i];
+
+		i++;
+	} 
+	return FALSE;
+}
+
+
+TAX25Port * get_user_port(int snd_ch, Byte * path)
+                                                                                                                                                                                                                                                                                                                                                                       {
+	TAX25Port * AX25Sess = NULL;
+
+	int i = 0;
+
+
+	while (i < port_num)
+	{
+		AX25Sess = &AX25Port[snd_ch][i];
+
+		if (AX25Sess->status != STAT_NO_LINK && memcmp(AX25Sess->ReversePath, path, AX25Sess->pathLen) == 0)
+			return AX25Sess;
+
+		i++;
+	}
+
+	return FALSE;
+}
+
+boolean get_user_dupe(int snd_ch, Byte * path)
+{
+	int i = 0;
+	TAX25Port * AX25Sess;
+
+	while (i < port_num)
+	{
+		AX25Sess = &AX25Port[snd_ch][i];
+
+		if (AX25Sess->status != STAT_NO_LINK && memcmp(AX25Sess->ReversePath, path, AX25Sess->pathLen) == 0)
+			return TRUE;
+
+		i++;
+	}
+
+	return FALSE;
+}
+
+TAX25Port * get_user_port_by_calls(int snd_ch, char *  CallFrom, char *  CallTo)
+{
+	int  i = 0;
+	TAX25Port * AX25Sess = NULL;
+
+	while (i < port_num)
+	{
+		AX25Sess = &AX25Port[snd_ch][i];
+
+		if (AX25Sess->status != STAT_NO_LINK &&
+			strcmp(CallFrom, AX25Sess->mycall) == 0 && strcmp(CallTo, AX25Sess->corrcall) == 0)
+
+			return AX25Sess;
+
+		i++;
+	}
+
+	return NULL;
+}
+
+void * get_sock_by_port(TAX25Port * AX25Sess)
+{
+	void * socket = (void *)-1;
+
+	if (AX25Sess)
+		socket = AX25Sess->socket;
+
+	return socket;
+}
+
+void Digipeater(int snd_ch, string * frame)
+{
+	char call[16];
+	Byte * addr = &frame->Data[7];					// Origin
+	string * frameCopy;
+
+	int n = 8;										// Max digis
+
+	if (list_digi_callsigns[snd_ch].Count == 0)
+		return;
+
+	// Look for first unused digi
+
+	while ((addr[6] & 1) == 0 && n--)					// until end of address
+	{
+		addr += 7;
+
+		if ((addr[6] & 128) == 0)
+		{
+			// unused digi - is it addressed to us?
+
+			memcpy(call, addr, 7);
+			call[6] &= 0x7E;				// Mask end of call 
+
+			// See if in digi list
+
+			int i;
+
+			for (i = 0; i < list_digi_callsigns->Count; i++)
+			{
+				if (memcmp(list_digi_callsigns->Items[i]->Data, call, 7) == 0)
+				{
+					UCHAR KISSBuffer[512];
+					int Length;
+
+					// for us
+
+					addr[6] |= 128;				// set digi'ed
+
+					// TX Frames need a KISS control on front
+
+					frameCopy = newString();
+
+					frameCopy->Data[0] = 0;
+					frameCopy->Length = 1;
+
+					stringAdd(frameCopy, frame->Data, frame->Length);		// Exclude CRC
+
+					addr[6] &= 0x7f;				// clear digi'ed from original;
+
+					// Send to TNC
+					
+					// ? Don't we just send to TNC? 
+
+					Length = KISS_encode(KISSBuffer, 0, frameCopy);
+
+					KISSSendtoServer(KISSSockCopy[snd_ch], KISSBuffer, Length);
+
+					monitor_frame(0, frameCopy, "", 1, 0);				// Monitor
+					freeString(frameCopy);
+
+					return;
+				}
+			}
+		}
+	}
+}
+
+void analiz_frame(int snd_ch, string * frame, void * socket, boolean fecflag)
+{
+	Byte path[80];
+	string * data = 0;
+	Byte  pid, nr, ns, f_type, f_id, rpt, cr, pf;
+	Byte * ptr;
+
+	int excluded = 0;
+	int len;
+
+	TAX25Port * AX25Sess;
+
+	//	mod_icon_status = mod_rx;
+
+	len = frame->Length;
+
+	if (len < PKT_ERR)
+		return;
+
+	data = newString();
+
+	decode_frame(frame->Data, frame->Length, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
+
+	//  if is_excluded_call(snd_ch,path) then excluded:=TRUE;
+	 // if is_excluded_frm(snd_ch,f_id,data) then excluded:=TRUE;	
+
+	// CRC Collision Check
+
+	if (!is_correct_path(path, pid))
+	{
+		// Duff path - if Non-AX25 filter active log and discard
+	}
+
+	monitor_frame(snd_ch, frame, "", 0, excluded);				// Monitor
+
+	// Digipeat frame
+
+	Digipeater(snd_ch, frame);
+
+	if (!is_last_digi(path))
+	{
+		freeString(data);
+		return;							// Don't process if still unused digis
+	}
+
+	// Clear repeated bits from digi path
+
+	ptr = &path[13];
+
+	while ((*ptr & 1) == 0)				// end of address
+	{
+		ptr += 7;
+		*(ptr) &= 0x7f;					// Clear digi'd bit
+	}
+
+	// search for port of correspondent
+
+	AX25Sess = get_user_port(snd_ch, path);
+
+	// if not an active session, AX25Sess will be NULL
+
+//	if (AX25Sess == NULL)
+//		socket = in_list_incoming_mycall(path);
+//	else
+//		socket = get_sock_by_port(AX25Sess);
+
+	// link analysis
+
+	if (AX25Sess == NULL)
+	{
+		if (f_id == U_UI)
+		{
+			CheckUIFrame(path, data);
+			freeString(data);
+			return;						// Don't precess UI at the moment
+		}
+
+		// No Session. If socket is set (so call is in incoming calls list) and SABM set up session
+
+		// Check addresses to us
+
+		if (memcmp(path, axMYCALL, 7) != 0)
+			return;								// ignore
+
+		if (KISSListen == 0)
+		{
+			set_DM(snd_ch, path);
+			freeString(data);
+			return;
+		}
+
+		if (f_id != U_SABM)				// Not SABM
+		{
+			// send DM if P set
+
+			if (cr == SET_C)
+			{
+				switch (f_id)
+				{
+				case U_DISC:
+				case S_RR:
+				case S_REJ:
+				case S_RNR:
+				case I_I:
+
+					set_DM(snd_ch, path);
+					break;
+
+				case U_UI:
+					break;
+
+				default:
+					set_FRMR(snd_ch, path, f_id);
+				}
+
+
+			}
+			freeString(data);
+			return;
+		}
+
+		// Must be SABM. See if it would duplicate an existing session (but could it - wouldn't that be found earlier ??
+
+		// Make sure it is for us
+
+
+
+		if (get_user_dupe(snd_ch, path))		// Not SABM or a duplicate call pair
+		{
+			freeString(data);
+			return;
+		}
+
+		AX25Sess = get_free_port(snd_ch);
+
+		if (AX25Sess == NULL)
+		{
+			// if there are no free ports for connection - reject
+
+			Byte Rev[80];
+
+			reverse_addr(path, Rev, strlen(path));
+			set_DM(snd_ch, Rev);
+			freeString(data);
+			return;
+		}
+
+		// initialise new session
+
+		AX25Sess->snd_ch = snd_ch;
+
+		AX25Sess->corrcall[ConvFromAX25(&path[7], AX25Sess->corrcall)] = 0;
+		AX25Sess->mycall[ConvFromAX25(path, AX25Sess->mycall)] = 0;
+		AX25Sess->digi[0] = 0;
+
+		//		rst_timer(snd_ch, free_port);
+
+		strcpy(AX25Sess->kind, "Incoming");
+		AX25Sess->socket = socket;
+
+		Debugprintf("incoming call socket = %x", socket);
+
+		// I think we need to reverse the path
+
+		AX25Sess->pathLen = strlen(path);
+		strcpy(AX25Sess->ReversePath, path);
+		reverse_addr(path, AX25Sess->Path, strlen(path));
+	}
+
+	// we process a packet on the necessary port
+
+	memcpy(path, AX25Sess->Path, AX25Sess->pathLen);
+
+	switch (f_id)
+	{
+	case I_I:
+
+		on_I(socket, AX25Sess, pid, path, data, nr, ns, pf, cr, fecflag);
+		break;
+
+	case S_RR:
+
+		on_RR(AX25Sess, path, nr, pf, cr);
+		break;
+
+	case S_RNR:
+
+		on_RNR(AX25Sess, path, nr, pf, cr);
+		break;
+
+	case S_REJ:
+
+		on_REJ(AX25Sess, path, nr, pf, cr);
+		break;
+
+	case S_SREJ:
+
+		on_SREJ(AX25Sess, path, nr, pf, cr);
+		break;
+
+	case U_SABM:
+
+		on_SABM(socket, AX25Sess);
+		break;
+
+	case U_DISC:
+
+		on_DISC(AX25Sess);
+		break;
+
+	case U_UA:
+
+		on_UA(AX25Sess);
+		break;
+
+	case U_DM:
+
+		on_DM(AX25Sess);
+		break;
+
+	case U_UI:
+
+		on_UI(AX25Sess, pf, cr);
+		break;
+
+	case U_FRMR:
+
+		on_FRMR(socket, AX25Sess, path);
+		break;
+	}
+	freeString(data);
+}
+
+int get_addr(char * Calls, UCHAR * AXCalls);
+
+void Send_UI(int port, Byte PID, char * CallFrom, char *CallTo, char * via, Byte *  Msg, int MsgLen)
+{
+	char Addrs[256];
+	Byte path[256];
+	int destlen = 0;
+
+	string * Data = newString();
+	string * Frame;
+
+	UCHAR KISSBuffer[512];
+	int Length;
+
+	stringAdd(Data, Msg, MsgLen);
+
+	// We Need Dest, Source, Digis in path, with end of address bit set appropriately.
+
+	sprintf(Addrs, "%s %s %s", CallTo, CallFrom, via);
+
+	destlen = get_addr(Addrs, path);
+
+	Frame = make_frame(Data, path, PID, 0, 0, U_FRM, U_UI, FALSE, SET_F, SET_C);
+
+	// ? Don't we just send to TNC? 
+
+	Length = KISS_encode(KISSBuffer, port, Frame);
+
+	KISSSendtoServer(KISSSockCopy[0], KISSBuffer, Length);
+
+	monitor_frame(0, Frame, "", 1, 0);				// Monitor
+	freeString(Frame);
+
+}
+
+
+
+
--- qttermtcp-0.0.0.79.orig/debug/moc_predefs.h
+++ qttermtcp-0.0.0.79/debug/moc_predefs.h
@@ -1,12 +1,12 @@
-#define _MSC_EXTENSIONS 
-#define _INTEGRAL_MAX_BITS 64
-#define _MSC_VER 1916
-#define _MSC_FULL_VER 191627051
-#define _MSC_BUILD 0
-#define _WIN32 
-#define _M_IX86 600
-#define _M_IX86_FP 2
-#define _CPPRTTI 
-#define _DEBUG 
-#define _MT 
-#define _DLL 
+#define _MSC_EXTENSIONS 
+#define _INTEGRAL_MAX_BITS 64
+#define _MSC_VER 1916
+#define _MSC_FULL_VER 191627051
+#define _MSC_BUILD 0
+#define _WIN32 
+#define _M_IX86 600
+#define _M_IX86_FP 2
+#define _CPPRTTI 
+#define _DEBUG 
+#define _MT 
+#define _DLL 
--- qttermtcp-0.0.0.79.orig/hid.c
+++ qttermtcp-0.0.0.79/hid.c
@@ -1,910 +1,910 @@
-/*******************************************************
- HIDAPI - Multi-Platform library for
- communication with HID devices.
-
- Alan Ott
- Signal 11 Software
-
- 8/22/2009
-
- Copyright 2009, All Rights Reserved.
- 
- At the discretion of the user of this library,
- this software may be licensed under the terms of the
- GNU Public License v3, a BSD-Style license, or the
- original HIDAPI license as outlined in the LICENSE.txt,
- LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
- files located at the root of the source distribution.
- These files may also be found in the public source
- code repository located at:
-        http://github.com/signal11/hidapi .
-********************************************************/
-
-// Hacked about a bit for BPQ32. John Wiseman G8BPQ April 2018
-
-
-
-#include <windows.h>
-
-#ifndef _NTDEF_
-typedef LONG NTSTATUS;
-#endif
-
-#ifdef __MINGW32__
-#include <ntdef.h>
-#include <winbase.h>
-#endif
-
-#ifdef __CYGWIN__
-#include <ntdef.h>
-#define _wcsdup wcsdup
-#endif
-
-//#define HIDAPI_USE_DDK
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-	#include <setupapi.h>
-	#include <winioctl.h>
-	#ifdef HIDAPI_USE_DDK
-		#include <hidsdi.h>
-	#endif
-
-	// Copied from inc/ddk/hidclass.h, part of the Windows DDK.
-	#define HID_OUT_CTL_CODE(id)  \
-		CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
-	#define IOCTL_HID_GET_FEATURE                   HID_OUT_CTL_CODE(100)
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-
-#include "hidapi.h"
-
-#ifdef _MSC_VER
-	// Thanks Microsoft, but I know how to use strncpy().
-	#pragma warning(disable:4996)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef HIDAPI_USE_DDK
-	// Since we're not building with the DDK, and the HID header
-	// files aren't part of the SDK, we have to define all this
-	// stuff here. In lookup_functions(), the function pointers
-	// defined below are set.
-	typedef struct _HIDD_ATTRIBUTES{
-		ULONG Size;
-		USHORT VendorID;
-		USHORT ProductID;
-		USHORT VersionNumber;
-	} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
-
-	typedef USHORT USAGE;
-	typedef struct _HIDP_CAPS {
-		USAGE Usage;
-		USAGE UsagePage;
-		USHORT InputReportByteLength;
-		USHORT OutputReportByteLength;
-		USHORT FeatureReportByteLength;
-		USHORT Reserved[17];
-		USHORT fields_not_used_by_hidapi[10];
-	} HIDP_CAPS, *PHIDP_CAPS;
-	typedef char* HIDP_PREPARSED_DATA;
-	#define HIDP_STATUS_SUCCESS 0x0
-
-	typedef BOOLEAN(__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
-	typedef BOOLEAN(__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
-	typedef BOOLEAN(__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
-	typedef BOOLEAN(__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
-	typedef BOOLEAN(__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
-	typedef BOOLEAN(__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
-	typedef BOOLEAN(__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
-	typedef BOOLEAN(__stdcall *HidD_GetPreparsedData_)(HANDLE handle, HIDP_PREPARSED_DATA **preparsed_data);
-	typedef BOOLEAN(__stdcall *HidD_FreePreparsedData_)(HIDP_PREPARSED_DATA *preparsed_data);
-	typedef BOOLEAN(__stdcall *HidP_GetCaps_)(HIDP_PREPARSED_DATA *preparsed_data, HIDP_CAPS *caps);
-
-	static HidD_GetAttributes_ HidD_GetAttributes;
-	static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
-	static HidD_GetManufacturerString_ HidD_GetManufacturerString;
-	static HidD_GetProductString_ HidD_GetProductString;
-	static HidD_SetFeature_ HidD_SetFeature;
-	static HidD_GetFeature_ HidD_GetFeature;
-	static HidD_GetIndexedString_ HidD_GetIndexedString;
-	static HidD_GetPreparsedData_ HidD_GetPreparsedData;
-	static HidD_FreePreparsedData_ HidD_FreePreparsedData;
-	static HidP_GetCaps_ HidP_GetCaps;
-
-	static HMODULE lib_handle = NULL;
-	static BOOLEAN initialized = FALSE;
-#endif // HIDAPI_USE_DDK
-
-struct hid_device_ {
-		HANDLE device_handle;
-		BOOLEAN blocking;
-		int input_report_length;
-		void *last_error_str;
-		DWORD last_error_num;
-		BOOLEAN read_pending;
-		char *read_buf;
-		OVERLAPPED ol;
-};
-
-static hid_device *new_hid_device()
-{
-	hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
-	dev->device_handle = INVALID_HANDLE_VALUE;
-	dev->blocking = TRUE;
-	dev->input_report_length = 0;
-	dev->last_error_str = NULL;
-	dev->last_error_num = 0;
-	dev->read_pending = FALSE;
-	dev->read_buf = NULL;
-	memset(&dev->ol, 0, sizeof(dev->ol));
-	dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL);
-
-	return dev;
-}
-
-
-static void register_error(hid_device *device, const char *op)
-{
-	WCHAR *ptr, *msg;
-
-	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-		FORMAT_MESSAGE_FROM_SYSTEM |
-		FORMAT_MESSAGE_IGNORE_INSERTS,
-		NULL,
-		GetLastError(),
-		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-		(LPWSTR)&msg, 0/*sz*/,
-		NULL);
-	
-	// Get rid of the CR and LF that FormatMessage() sticks at the
-	// end of the message. Thanks Microsoft!
-	ptr = msg;
-	while (*ptr) {
-		if (*ptr == '\r') {
-			*ptr = 0x0000;
-			break;
-		}
-		ptr++;
-	}
-
-	// Store the message off in the Device entry so that 
-	// the hid_error() function can pick it up.
-	LocalFree(device->last_error_str);
-	device->last_error_str = msg;
-}
-
-#ifndef HIDAPI_USE_DDK
-static int lookup_functions()
-{
-	lib_handle = LoadLibraryA("hid.dll");
-	if (lib_handle) {
-#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1;
-		RESOLVE(HidD_GetAttributes);
-		RESOLVE(HidD_GetSerialNumberString);
-		RESOLVE(HidD_GetManufacturerString);
-		RESOLVE(HidD_GetProductString);
-		RESOLVE(HidD_SetFeature);
-		RESOLVE(HidD_GetFeature);
-		RESOLVE(HidD_GetIndexedString);
-		RESOLVE(HidD_GetPreparsedData);
-		RESOLVE(HidD_FreePreparsedData);
-		RESOLVE(HidP_GetCaps);
-#undef RESOLVE
-	}
-	else
-		return -1;
-
-	return 0;
-}
-#endif
-
-static HANDLE open_device(const char *path)
-{
-	HANDLE handle;
-
-	/* First, try to open with sharing mode turned off. This will make it so
-	   that a HID device can only be opened once. This is to be consistent
-	   with the behavior on the other platforms. */
-	handle = CreateFileA(path,
-		GENERIC_WRITE |GENERIC_READ,
-		0, /*share mode*/
-		NULL,
-		OPEN_EXISTING,
-		FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
-		0);
-
-	if (handle == INVALID_HANDLE_VALUE) {
-		/* Couldn't open the device. Some devices must be opened
-		   with sharing enabled (even though they are only opened once),
-		   so try it here. */
-		handle = CreateFileA(path,
-			GENERIC_WRITE |GENERIC_READ,
-			FILE_SHARE_READ|FILE_SHARE_WRITE, /*share mode*/
-			NULL,
-			OPEN_EXISTING,
-			FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
-			0);
-	}
-
-	return handle;
-}
-
-int HID_API_EXPORT hid_init(void)
-{
-#ifndef HIDAPI_USE_DDK
-	if (!initialized) {
-		if (lookup_functions() < 0) {
-			hid_exit();
-			return -1;
-		}
-		initialized = TRUE;
-	}
-#endif
-	return 0;
-}
-
-int HID_API_EXPORT hid_exit(void)
-{
-#ifndef HIDAPI_USE_DDK
-	if (lib_handle)
-		FreeLibrary(lib_handle);
-	lib_handle = NULL;
-	initialized = FALSE;
-#endif
-	return 0;
-}
-
-struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
-{
-	BOOLEAN res;
-	struct hid_device_info *root = NULL; // return object
-	struct hid_device_info *cur_dev = NULL;
-
-	// Windows objects for interacting with the driver.
-	GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
-	SP_DEVINFO_DATA devinfo_data;
-	SP_DEVICE_INTERFACE_DATA device_interface_data;
-	SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
-	HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
-	int device_index = 0;
-
-	if (hid_init() < 0)
-		return NULL;
-
-	// Initialize the Windows objects.
-	devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
-	device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
-
-	// Get information for all the devices belonging to the HID class.
-	device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
-	
-	// Iterate over each device in the HID class, looking for the right one.
-	
-	for (;;) {
-		HANDLE write_handle = INVALID_HANDLE_VALUE;
-		DWORD required_size = 0;
-		HIDD_ATTRIBUTES attrib;
-
-		res = SetupDiEnumDeviceInterfaces(device_info_set,
-			NULL,
-			&InterfaceClassGuid,
-			device_index,
-			&device_interface_data);
-		
-		if (!res) {
-			// A return of FALSE from this function means that
-			// there are no more devices.
-			break;
-		}
-
-		// Call with 0-sized detail size, and let the function
-		// tell us how long the detail struct needs to be. The
-		// size is put in &required_size.
-		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
-			&device_interface_data,
-			NULL,
-			0,
-			&required_size,
-			NULL);
-
-		// Allocate a long enough structure for device_interface_detail_data.
-		device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
-		device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
-
-		// Get the detailed data for this device. The detail data gives us
-		// the device path for this device, which is then passed into
-		// CreateFile() to get a handle to the device.
-		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
-			&device_interface_data,
-			device_interface_detail_data,
-			required_size,
-			NULL,
-			NULL);
-
-		if (!res) {
-			//register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
-			// Continue to the next device.
-			goto cont;
-		}
-
-		//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
-
-		// Open a handle to the device
-		write_handle = open_device(device_interface_detail_data->DevicePath);
-
-		// Check validity of write_handle.
-		if (write_handle == INVALID_HANDLE_VALUE) {
-			// Unable to open the device.
-			//register_error(dev, "CreateFile");
-			goto cont_close;
-		}		
-
-
-		// Get the Vendor ID and Product ID for this device.
-		attrib.Size = sizeof(HIDD_ATTRIBUTES);
-		HidD_GetAttributes(write_handle, &attrib);
-		//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
-
-		// Check the VID/PID to see if we should add this
-		// device to the enumeration list.
-		if ((vendor_id == 0x0 && product_id == 0x0) || 
-			(attrib.VendorID == vendor_id && attrib.ProductID == product_id))
-		{
-			#define WSTR_LEN 512
-			const char *str;
-			struct hid_device_info *tmp;
-			HIDP_PREPARSED_DATA *pp_data = NULL;
-			HIDP_CAPS caps;
-			BOOLEAN res;
-			NTSTATUS nt_res;
-			wchar_t wstr[WSTR_LEN]; // TODO: Determine Size
-			int len;
-
-			/* VID/PID match. Create the record. */
-			tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
-			if (cur_dev) {
-				cur_dev->next = tmp;
-			}
-			else {
-				root = tmp;
-			}
-			cur_dev = tmp;
-
-			// Get the Usage Page and Usage for this device.
-			res = HidD_GetPreparsedData(write_handle, &pp_data);
-			if (res) {
-				nt_res = HidP_GetCaps(pp_data, &caps);
-				if (nt_res == HIDP_STATUS_SUCCESS) {
-					cur_dev->usage_page = caps.UsagePage;
-					cur_dev->usage = caps.Usage;
-				}
-
-				HidD_FreePreparsedData(pp_data);
-			}
-			
-			/* Fill out the record */
-			cur_dev->next = NULL;
-			str = device_interface_detail_data->DevicePath;
-			if (str) {
-				len = (int)strlen(str);
-				cur_dev->path = (char*) calloc(len+1, sizeof(char));
-				strncpy(cur_dev->path, str, len+1);
-				cur_dev->path[len] = '\0';
-			}
-			else
-				cur_dev->path = NULL;
-
-			/* Serial Number */
-			res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr));
-			wstr[WSTR_LEN-1] = 0x0000;
-			if (res) {
-				cur_dev->serial_number = _wcsdup(wstr);
-			}
-
-			/* Manufacturer String */
-			res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr));
-			wstr[WSTR_LEN-1] = 0x0000;
-			if (res) {
-				cur_dev->manufacturer_string = _wcsdup(wstr);
-			}
-
-			/* Product String */
-			res = HidD_GetProductString(write_handle, wstr, sizeof(wstr));
-			wstr[WSTR_LEN-1] = 0x0000;
-			if (res) {
-				cur_dev->product_string = _wcsdup(wstr);
-			}
-
-			/* VID/PID */
-			cur_dev->vendor_id = attrib.VendorID;
-			cur_dev->product_id = attrib.ProductID;
-
-			/* Release Number */
-			cur_dev->release_number = attrib.VersionNumber;
-
-			/* Interface Number. It can sometimes be parsed out of the path
-			   on Windows if a device has multiple interfaces. See
-			   http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or
-			   search for "Hardware IDs for HID Devices" at MSDN. If it's not
-			   in the path, it's set to -1. */
-			cur_dev->interface_number = -1;
-			if (cur_dev->path) {
-				char *interface_component = strstr(cur_dev->path, "&mi_");
-				if (interface_component) {
-					char *hex_str = interface_component + 4;
-					char *endptr = NULL;
-					cur_dev->interface_number = strtol(hex_str, &endptr, 16);
-					if (endptr == hex_str) {
-						/* The parsing failed. Set interface_number to -1. */
-						cur_dev->interface_number = -1;
-					}
-				}
-			}
-		}
-
-cont_close:
-		CloseHandle(write_handle);
-cont:
-		// We no longer need the detail data. It can be freed
-		free(device_interface_detail_data);
-
-		device_index++;
-
-	}
-
-	// Close the device information handle.
-	SetupDiDestroyDeviceInfoList(device_info_set);
-
-	return root;
-
-}
-
-void  HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
-{
-	// TODO: Merge this with the Linux version. This function is platform-independent.
-	struct hid_device_info *d = devs;
-	while (d) {
-		struct hid_device_info *next = d->next;
-		free(d->path);
-		free(d->serial_number);
-		free(d->manufacturer_string);
-		free(d->product_string);
-		free(d);
-		d = next;
-	}
-}
-
-
-HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number)
-{
-	// TODO: Merge this functions with the Linux version. This function should be platform independent.
-	struct hid_device_info *devs, *cur_dev;
-	const char *path_to_open = NULL;
-	hid_device *handle = NULL;
-	
-	devs = hid_enumerate(vendor_id, product_id);
-	cur_dev = devs;
-	while (cur_dev) {
-		if (cur_dev->vendor_id == vendor_id &&
-		    cur_dev->product_id == product_id) {
-			if (serial_number) {
-				if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
-					path_to_open = cur_dev->path;
-					break;
-				}
-			}
-			else {
-				path_to_open = cur_dev->path;
-				break;
-			}
-		}
-		cur_dev = cur_dev->next;
-	}
-
-	if (path_to_open) {
-		/* Open the device */
-		handle = hid_open_path(path_to_open);
-	}
-
-	hid_free_enumeration(devs);
-	
-	return handle;
-}
-
-HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
-{
-	hid_device *dev;
-	HIDP_CAPS caps;
-	HIDP_PREPARSED_DATA *pp_data = NULL;
-	BOOLEAN res;
-	NTSTATUS nt_res;
-
-	if (hid_init() < 0) {
-		return NULL;
-	}
-
-	dev = new_hid_device();
-
-	// Open a handle to the device
-	dev->device_handle = open_device(path);
-
-	// Check validity of write_handle.
-	if (dev->device_handle == INVALID_HANDLE_VALUE) {
-		// Unable to open the device.
-		register_error(dev, "CreateFile");
-		goto err;
-	}
-
-	// Get the Input Report length for the device.
-	res = HidD_GetPreparsedData(dev->device_handle, &pp_data);
-	if (!res) {
-		register_error(dev, "HidD_GetPreparsedData");
-		goto err;
-	}
-	nt_res = HidP_GetCaps(pp_data, &caps);
-	if (nt_res != HIDP_STATUS_SUCCESS) {
-		register_error(dev, "HidP_GetCaps");	
-		goto err_pp_data;
-	}
-	dev->input_report_length = caps.InputReportByteLength;
-	HidD_FreePreparsedData(pp_data);
-
-	dev->read_buf = (char*) malloc(dev->input_report_length);
-
-	return dev;
-
-err_pp_data:
-		HidD_FreePreparsedData(pp_data);
-err:	
-		CloseHandle(dev->device_handle);
-		free(dev);
-		return NULL;
-}
-
-int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
-{
-	DWORD bytes_written;
-	BOOLEAN res;
-
-	OVERLAPPED ol;
-	memset(&ol, 0, sizeof(ol));
-
-	res = WriteFile(dev->device_handle, data, length, NULL, &ol);
-	
-	if (!res) {
-		if (GetLastError() != ERROR_IO_PENDING) {
-			// WriteFile() failed. Return error.
-			register_error(dev, "WriteFile");
-			return -1;
-		}
-	}
-
-	// Wait here until the write is done. This makes
-	// hid_write() synchronous.
-	res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/);
-	if (!res) {
-		// The Write operation failed.
-		register_error(dev, "WriteFile");
-		return -1;
-	}
-
-	return bytes_written;
-}
-
-int HID_API_EXPORT HID_API_CALL hid_set_ptt(int state)
-{
-	int res;
-	hid_device *handle;
-	unsigned char buf[16];
-
-	handle = hid_open(0xd8c, 0x8, NULL);
-	if (!handle) {
-		printf("unable to open device\n");
- 		return 1;
-	}
-
-
-	// Toggle PTT
-
-	buf[0] = 0;
-	buf[1] = 0;
-	buf[2]= 1 << (3 - 1);
-	buf[3] = state << (3 - 1);
-	buf[4] = 0;
-
-
-	res = hid_write(handle, buf, 5);
-	if (res < 0)
-	{
-		printf("Unable to write()\n");
-		printf("Error: %ls\n", hid_error(handle));
-	}
-	
-	hid_close(handle);
-	return res;
-}
-
-
-int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
-{
-	DWORD bytes_read = 0;
-	BOOLEAN res;
-
-	// Copy the handle for convenience.
-	HANDLE ev = dev->ol.hEvent;
-
-	if (!dev->read_pending) {
-		// Start an Overlapped I/O read.
-		dev->read_pending = TRUE;
-		ResetEvent(ev);
-		res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol);
-		
-		if (!res) {
-			if (GetLastError() != ERROR_IO_PENDING) {
-				// ReadFile() has failed.
-				// Clean up and return error.
-				CancelIo(dev->device_handle);
-				dev->read_pending = FALSE;
-				goto end_of_function;
-			}
-		}
-	}
-
-	if (milliseconds >= 0) {
-		// See if there is any data yet.
-		res = WaitForSingleObject(ev, milliseconds);
-		if (res != WAIT_OBJECT_0) {
-			// There was no data this time. Return zero bytes available,
-			// but leave the Overlapped I/O running.
-			return 0;
-		}
-	}
-
-	// Either WaitForSingleObject() told us that ReadFile has completed, or
-	// we are in non-blocking mode. Get the number of bytes read. The actual
-	// data has been copied to the data[] array which was passed to ReadFile().
-	res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/);
-	
-	// Set pending back to false, even if GetOverlappedResult() returned error.
-	dev->read_pending = FALSE;
-
-	if (res && bytes_read > 0) {
-		if (dev->read_buf[0] == 0x0) {
-			/* If report numbers aren't being used, but Windows sticks a report
-			   number (0x0) on the beginning of the report anyway. To make this
-			   work like the other platforms, and to make it work more like the
-			   HID spec, we'll skip over this byte. */
-			bytes_read--;
-			memcpy(data, dev->read_buf+1, length);
-		}
-		else {
-			/* Copy the whole buffer, report number and all. */
-			memcpy(data, dev->read_buf, length);
-		}
-	}
-	
-end_of_function:
-	if (!res) {
-		register_error(dev, "GetOverlappedResult");
-		return -1;
-	}
-	
-	return bytes_read;
-}
-
-int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
-{
-	return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
-}
-
-int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock)
-{
-	dev->blocking = !nonblock;
-	return 0; /* Success */
-}
-
-int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
-{
-	BOOLEAN res = HidD_SetFeature(dev->device_handle, (PVOID)data, length);
-	if (!res) {
-		register_error(dev, "HidD_SetFeature");
-		return -1;
-	}
-
-	return length;
-}
-
-
-int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
-{
-	BOOLEAN res;
-#if 0
-	res = HidD_GetFeature(dev->device_handle, data, length);
-	if (!res) {
-		register_error(dev, "HidD_GetFeature");
-		return -1;
-	}
-	return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */
-#else
-	DWORD bytes_returned;
-
-	OVERLAPPED ol;
-	memset(&ol, 0, sizeof(ol));
-
-	res = DeviceIoControl(dev->device_handle,
-		IOCTL_HID_GET_FEATURE,
-		data, length,
-		data, length,
-		&bytes_returned, &ol);
-
-	if (!res) {
-		if (GetLastError() != ERROR_IO_PENDING) {
-			// DeviceIoControl() failed. Return error.
-			register_error(dev, "Send Feature Report DeviceIoControl");
-			return -1;
-		}
-	}
-
-	// Wait here until the write is done. This makes
-	// hid_get_feature_report() synchronous.
-	res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
-	if (!res) {
-		// The operation failed.
-		register_error(dev, "Send Feature Report GetOverLappedResult");
-		return -1;
-	}
-	return bytes_returned;
-#endif
-}
-
-void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
-{
-	if (!dev)
-		return;
-	CancelIo(dev->device_handle);
-	CloseHandle(dev->ol.hEvent);
-	CloseHandle(dev->device_handle);
-	LocalFree(dev->last_error_str);
-	free(dev->read_buf);
-	free(dev);
-}
-
-int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
-{
-	BOOLEAN res;
-
-	res = HidD_GetManufacturerString(dev->device_handle, string, 2 * maxlen);
-	if (!res) {
-		register_error(dev, "HidD_GetManufacturerString");
-		return -1;
-	}
-
-	return 0;
-}
-
-int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
-{
-	BOOLEAN res;
-
-	res = HidD_GetProductString(dev->device_handle, string, 2 * maxlen);
-	if (!res) {
-		register_error(dev, "HidD_GetProductString");
-		return -1;
-	}
-
-	return 0;
-}
-
-int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
-{
-	BOOLEAN res;
-
-	res = HidD_GetSerialNumberString(dev->device_handle, string, 2 * maxlen);
-	if (!res) {
-		register_error(dev, "HidD_GetSerialNumberString");
-		return -1;
-	}
-
-	return 0;
-}
-
-int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
-{
-	BOOLEAN res;
-
-	res = HidD_GetIndexedString(dev->device_handle, string_index, string, 2 * maxlen);
-	if (!res) {
-		register_error(dev, "HidD_GetIndexedString");
-		return -1;
-	}
-
-	return 0;
-}
-
-
-HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
-{
-	return (wchar_t*)dev->last_error_str;
-}
-
-
-//#define PICPGM
-//#define S11
-#define P32
-#ifdef S11 
-  unsigned short VendorID = 0xa0a0;
-	unsigned short ProductID = 0x0001;
-#endif
-
-#ifdef P32
-  unsigned short VendorID = 0x04d8;
-	unsigned short ProductID = 0x3f;
-#endif
-
-
-#ifdef PICPGM
-  unsigned short VendorID = 0x04d8;
-  unsigned short ProductID = 0x0033;
-#endif
-
-
-#if 0
-int __cdecl main(int argc, char* argv[])
-{
-	int res;
-	unsigned char buf[65];
-
-	UNREFERENCED_PARAMETER(argc);
-	UNREFERENCED_PARAMETER(argv);
-
-	// Set up the command buffer.
-	memset(buf,0x00,sizeof(buf));
-	buf[0] = 0;
-	buf[1] = 0x81;
-	
-
-	// Open the device.
-	int handle = open(VendorID, ProductID, L"12345");
-	if (handle < 0)
-		printf("unable to open device\n");
-
-
-	// Toggle LED (cmd 0x80)
-	buf[1] = 0x80;
-	res = write(handle, buf, 65);
-	if (res < 0)
-		printf("Unable to write()\n");
-
-	// Request state (cmd 0x81)
-	buf[1] = 0x81;
-	write(handle, buf, 65);
-	if (res < 0)
-		printf("Unable to write() (2)\n");
-
-	// Read requested state
-	read(handle, buf, 65);
-	if (res < 0)
-		printf("Unable to read()\n");
-
-	// Print out the returned buffer.
-	for (int i = 0; i < 4; i++)
-		printf("buf[%d]: %d\n", i, buf[i]);
-
-	return 0;
-}
-#endif
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ Alan Ott
+ Signal 11 Software
+
+ 8/22/2009
+
+ Copyright 2009, All Rights Reserved.
+ 
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+        http://github.com/signal11/hidapi .
+********************************************************/
+
+// Hacked about a bit for BPQ32. John Wiseman G8BPQ April 2018
+
+
+
+#include <windows.h>
+
+#ifndef _NTDEF_
+typedef LONG NTSTATUS;
+#endif
+
+#ifdef __MINGW32__
+#include <ntdef.h>
+#include <winbase.h>
+#endif
+
+#ifdef __CYGWIN__
+#include <ntdef.h>
+#define _wcsdup wcsdup
+#endif
+
+//#define HIDAPI_USE_DDK
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	#include <setupapi.h>
+	#include <winioctl.h>
+	#ifdef HIDAPI_USE_DDK
+		#include <hidsdi.h>
+	#endif
+
+	// Copied from inc/ddk/hidclass.h, part of the Windows DDK.
+	#define HID_OUT_CTL_CODE(id)  \
+		CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+	#define IOCTL_HID_GET_FEATURE                   HID_OUT_CTL_CODE(100)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#include "hidapi.h"
+
+#ifdef _MSC_VER
+	// Thanks Microsoft, but I know how to use strncpy().
+	#pragma warning(disable:4996)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HIDAPI_USE_DDK
+	// Since we're not building with the DDK, and the HID header
+	// files aren't part of the SDK, we have to define all this
+	// stuff here. In lookup_functions(), the function pointers
+	// defined below are set.
+	typedef struct _HIDD_ATTRIBUTES{
+		ULONG Size;
+		USHORT VendorID;
+		USHORT ProductID;
+		USHORT VersionNumber;
+	} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
+
+	typedef USHORT USAGE;
+	typedef struct _HIDP_CAPS {
+		USAGE Usage;
+		USAGE UsagePage;
+		USHORT InputReportByteLength;
+		USHORT OutputReportByteLength;
+		USHORT FeatureReportByteLength;
+		USHORT Reserved[17];
+		USHORT fields_not_used_by_hidapi[10];
+	} HIDP_CAPS, *PHIDP_CAPS;
+	typedef char* HIDP_PREPARSED_DATA;
+	#define HIDP_STATUS_SUCCESS 0x0
+
+	typedef BOOLEAN(__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
+	typedef BOOLEAN(__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
+	typedef BOOLEAN(__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
+	typedef BOOLEAN(__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
+	typedef BOOLEAN(__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
+	typedef BOOLEAN(__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
+	typedef BOOLEAN(__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
+	typedef BOOLEAN(__stdcall *HidD_GetPreparsedData_)(HANDLE handle, HIDP_PREPARSED_DATA **preparsed_data);
+	typedef BOOLEAN(__stdcall *HidD_FreePreparsedData_)(HIDP_PREPARSED_DATA *preparsed_data);
+	typedef BOOLEAN(__stdcall *HidP_GetCaps_)(HIDP_PREPARSED_DATA *preparsed_data, HIDP_CAPS *caps);
+
+	static HidD_GetAttributes_ HidD_GetAttributes;
+	static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
+	static HidD_GetManufacturerString_ HidD_GetManufacturerString;
+	static HidD_GetProductString_ HidD_GetProductString;
+	static HidD_SetFeature_ HidD_SetFeature;
+	static HidD_GetFeature_ HidD_GetFeature;
+	static HidD_GetIndexedString_ HidD_GetIndexedString;
+	static HidD_GetPreparsedData_ HidD_GetPreparsedData;
+	static HidD_FreePreparsedData_ HidD_FreePreparsedData;
+	static HidP_GetCaps_ HidP_GetCaps;
+
+	static HMODULE lib_handle = NULL;
+	static BOOLEAN initialized = FALSE;
+#endif // HIDAPI_USE_DDK
+
+struct hid_device_ {
+		HANDLE device_handle;
+		BOOLEAN blocking;
+		int input_report_length;
+		void *last_error_str;
+		DWORD last_error_num;
+		BOOLEAN read_pending;
+		char *read_buf;
+		OVERLAPPED ol;
+};
+
+static hid_device *new_hid_device()
+{
+	hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
+	dev->device_handle = INVALID_HANDLE_VALUE;
+	dev->blocking = TRUE;
+	dev->input_report_length = 0;
+	dev->last_error_str = NULL;
+	dev->last_error_num = 0;
+	dev->read_pending = FALSE;
+	dev->read_buf = NULL;
+	memset(&dev->ol, 0, sizeof(dev->ol));
+	dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL);
+
+	return dev;
+}
+
+
+static void register_error(hid_device *device, const char *op)
+{
+	WCHAR *ptr, *msg;
+
+	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+		FORMAT_MESSAGE_FROM_SYSTEM |
+		FORMAT_MESSAGE_IGNORE_INSERTS,
+		NULL,
+		GetLastError(),
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		(LPWSTR)&msg, 0/*sz*/,
+		NULL);
+	
+	// Get rid of the CR and LF that FormatMessage() sticks at the
+	// end of the message. Thanks Microsoft!
+	ptr = msg;
+	while (*ptr) {
+		if (*ptr == '\r') {
+			*ptr = 0x0000;
+			break;
+		}
+		ptr++;
+	}
+
+	// Store the message off in the Device entry so that 
+	// the hid_error() function can pick it up.
+	LocalFree(device->last_error_str);
+	device->last_error_str = msg;
+}
+
+#ifndef HIDAPI_USE_DDK
+static int lookup_functions()
+{
+	lib_handle = LoadLibraryA("hid.dll");
+	if (lib_handle) {
+#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1;
+		RESOLVE(HidD_GetAttributes);
+		RESOLVE(HidD_GetSerialNumberString);
+		RESOLVE(HidD_GetManufacturerString);
+		RESOLVE(HidD_GetProductString);
+		RESOLVE(HidD_SetFeature);
+		RESOLVE(HidD_GetFeature);
+		RESOLVE(HidD_GetIndexedString);
+		RESOLVE(HidD_GetPreparsedData);
+		RESOLVE(HidD_FreePreparsedData);
+		RESOLVE(HidP_GetCaps);
+#undef RESOLVE
+	}
+	else
+		return -1;
+
+	return 0;
+}
+#endif
+
+static HANDLE open_device(const char *path)
+{
+	HANDLE handle;
+
+	/* First, try to open with sharing mode turned off. This will make it so
+	   that a HID device can only be opened once. This is to be consistent
+	   with the behavior on the other platforms. */
+	handle = CreateFileA(path,
+		GENERIC_WRITE |GENERIC_READ,
+		0, /*share mode*/
+		NULL,
+		OPEN_EXISTING,
+		FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
+		0);
+
+	if (handle == INVALID_HANDLE_VALUE) {
+		/* Couldn't open the device. Some devices must be opened
+		   with sharing enabled (even though they are only opened once),
+		   so try it here. */
+		handle = CreateFileA(path,
+			GENERIC_WRITE |GENERIC_READ,
+			FILE_SHARE_READ|FILE_SHARE_WRITE, /*share mode*/
+			NULL,
+			OPEN_EXISTING,
+			FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
+			0);
+	}
+
+	return handle;
+}
+
+int HID_API_EXPORT hid_init(void)
+{
+#ifndef HIDAPI_USE_DDK
+	if (!initialized) {
+		if (lookup_functions() < 0) {
+			hid_exit();
+			return -1;
+		}
+		initialized = TRUE;
+	}
+#endif
+	return 0;
+}
+
+int HID_API_EXPORT hid_exit(void)
+{
+#ifndef HIDAPI_USE_DDK
+	if (lib_handle)
+		FreeLibrary(lib_handle);
+	lib_handle = NULL;
+	initialized = FALSE;
+#endif
+	return 0;
+}
+
+struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
+{
+	BOOLEAN res;
+	struct hid_device_info *root = NULL; // return object
+	struct hid_device_info *cur_dev = NULL;
+
+	// Windows objects for interacting with the driver.
+	GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
+	SP_DEVINFO_DATA devinfo_data;
+	SP_DEVICE_INTERFACE_DATA device_interface_data;
+	SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
+	HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
+	int device_index = 0;
+
+	if (hid_init() < 0)
+		return NULL;
+
+	// Initialize the Windows objects.
+	devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
+	device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+
+	// Get information for all the devices belonging to the HID class.
+	device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+	
+	// Iterate over each device in the HID class, looking for the right one.
+	
+	for (;;) {
+		HANDLE write_handle = INVALID_HANDLE_VALUE;
+		DWORD required_size = 0;
+		HIDD_ATTRIBUTES attrib;
+
+		res = SetupDiEnumDeviceInterfaces(device_info_set,
+			NULL,
+			&InterfaceClassGuid,
+			device_index,
+			&device_interface_data);
+		
+		if (!res) {
+			// A return of FALSE from this function means that
+			// there are no more devices.
+			break;
+		}
+
+		// Call with 0-sized detail size, and let the function
+		// tell us how long the detail struct needs to be. The
+		// size is put in &required_size.
+		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
+			&device_interface_data,
+			NULL,
+			0,
+			&required_size,
+			NULL);
+
+		// Allocate a long enough structure for device_interface_detail_data.
+		device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
+		device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
+
+		// Get the detailed data for this device. The detail data gives us
+		// the device path for this device, which is then passed into
+		// CreateFile() to get a handle to the device.
+		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
+			&device_interface_data,
+			device_interface_detail_data,
+			required_size,
+			NULL,
+			NULL);
+
+		if (!res) {
+			//register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
+			// Continue to the next device.
+			goto cont;
+		}
+
+		//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
+
+		// Open a handle to the device
+		write_handle = open_device(device_interface_detail_data->DevicePath);
+
+		// Check validity of write_handle.
+		if (write_handle == INVALID_HANDLE_VALUE) {
+			// Unable to open the device.
+			//register_error(dev, "CreateFile");
+			goto cont_close;
+		}		
+
+
+		// Get the Vendor ID and Product ID for this device.
+		attrib.Size = sizeof(HIDD_ATTRIBUTES);
+		HidD_GetAttributes(write_handle, &attrib);
+		//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
+
+		// Check the VID/PID to see if we should add this
+		// device to the enumeration list.
+		if ((vendor_id == 0x0 && product_id == 0x0) || 
+			(attrib.VendorID == vendor_id && attrib.ProductID == product_id))
+		{
+			#define WSTR_LEN 512
+			const char *str;
+			struct hid_device_info *tmp;
+			HIDP_PREPARSED_DATA *pp_data = NULL;
+			HIDP_CAPS caps;
+			BOOLEAN res;
+			NTSTATUS nt_res;
+			wchar_t wstr[WSTR_LEN]; // TODO: Determine Size
+			int len;
+
+			/* VID/PID match. Create the record. */
+			tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
+			if (cur_dev) {
+				cur_dev->next = tmp;
+			}
+			else {
+				root = tmp;
+			}
+			cur_dev = tmp;
+
+			// Get the Usage Page and Usage for this device.
+			res = HidD_GetPreparsedData(write_handle, &pp_data);
+			if (res) {
+				nt_res = HidP_GetCaps(pp_data, &caps);
+				if (nt_res == HIDP_STATUS_SUCCESS) {
+					cur_dev->usage_page = caps.UsagePage;
+					cur_dev->usage = caps.Usage;
+				}
+
+				HidD_FreePreparsedData(pp_data);
+			}
+			
+			/* Fill out the record */
+			cur_dev->next = NULL;
+			str = device_interface_detail_data->DevicePath;
+			if (str) {
+				len = (int)strlen(str);
+				cur_dev->path = (char*) calloc(len+1, sizeof(char));
+				strncpy(cur_dev->path, str, len+1);
+				cur_dev->path[len] = '\0';
+			}
+			else
+				cur_dev->path = NULL;
+
+			/* Serial Number */
+			res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr));
+			wstr[WSTR_LEN-1] = 0x0000;
+			if (res) {
+				cur_dev->serial_number = _wcsdup(wstr);
+			}
+
+			/* Manufacturer String */
+			res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr));
+			wstr[WSTR_LEN-1] = 0x0000;
+			if (res) {
+				cur_dev->manufacturer_string = _wcsdup(wstr);
+			}
+
+			/* Product String */
+			res = HidD_GetProductString(write_handle, wstr, sizeof(wstr));
+			wstr[WSTR_LEN-1] = 0x0000;
+			if (res) {
+				cur_dev->product_string = _wcsdup(wstr);
+			}
+
+			/* VID/PID */
+			cur_dev->vendor_id = attrib.VendorID;
+			cur_dev->product_id = attrib.ProductID;
+
+			/* Release Number */
+			cur_dev->release_number = attrib.VersionNumber;
+
+			/* Interface Number. It can sometimes be parsed out of the path
+			   on Windows if a device has multiple interfaces. See
+			   http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or
+			   search for "Hardware IDs for HID Devices" at MSDN. If it's not
+			   in the path, it's set to -1. */
+			cur_dev->interface_number = -1;
+			if (cur_dev->path) {
+				char *interface_component = strstr(cur_dev->path, "&mi_");
+				if (interface_component) {
+					char *hex_str = interface_component + 4;
+					char *endptr = NULL;
+					cur_dev->interface_number = strtol(hex_str, &endptr, 16);
+					if (endptr == hex_str) {
+						/* The parsing failed. Set interface_number to -1. */
+						cur_dev->interface_number = -1;
+					}
+				}
+			}
+		}
+
+cont_close:
+		CloseHandle(write_handle);
+cont:
+		// We no longer need the detail data. It can be freed
+		free(device_interface_detail_data);
+
+		device_index++;
+
+	}
+
+	// Close the device information handle.
+	SetupDiDestroyDeviceInfoList(device_info_set);
+
+	return root;
+
+}
+
+void  HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
+{
+	// TODO: Merge this with the Linux version. This function is platform-independent.
+	struct hid_device_info *d = devs;
+	while (d) {
+		struct hid_device_info *next = d->next;
+		free(d->path);
+		free(d->serial_number);
+		free(d->manufacturer_string);
+		free(d->product_string);
+		free(d);
+		d = next;
+	}
+}
+
+
+HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number)
+{
+	// TODO: Merge this functions with the Linux version. This function should be platform independent.
+	struct hid_device_info *devs, *cur_dev;
+	const char *path_to_open = NULL;
+	hid_device *handle = NULL;
+	
+	devs = hid_enumerate(vendor_id, product_id);
+	cur_dev = devs;
+	while (cur_dev) {
+		if (cur_dev->vendor_id == vendor_id &&
+		    cur_dev->product_id == product_id) {
+			if (serial_number) {
+				if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
+					path_to_open = cur_dev->path;
+					break;
+				}
+			}
+			else {
+				path_to_open = cur_dev->path;
+				break;
+			}
+		}
+		cur_dev = cur_dev->next;
+	}
+
+	if (path_to_open) {
+		/* Open the device */
+		handle = hid_open_path(path_to_open);
+	}
+
+	hid_free_enumeration(devs);
+	
+	return handle;
+}
+
+HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
+{
+	hid_device *dev;
+	HIDP_CAPS caps;
+	HIDP_PREPARSED_DATA *pp_data = NULL;
+	BOOLEAN res;
+	NTSTATUS nt_res;
+
+	if (hid_init() < 0) {
+		return NULL;
+	}
+
+	dev = new_hid_device();
+
+	// Open a handle to the device
+	dev->device_handle = open_device(path);
+
+	// Check validity of write_handle.
+	if (dev->device_handle == INVALID_HANDLE_VALUE) {
+		// Unable to open the device.
+		register_error(dev, "CreateFile");
+		goto err;
+	}
+
+	// Get the Input Report length for the device.
+	res = HidD_GetPreparsedData(dev->device_handle, &pp_data);
+	if (!res) {
+		register_error(dev, "HidD_GetPreparsedData");
+		goto err;
+	}
+	nt_res = HidP_GetCaps(pp_data, &caps);
+	if (nt_res != HIDP_STATUS_SUCCESS) {
+		register_error(dev, "HidP_GetCaps");	
+		goto err_pp_data;
+	}
+	dev->input_report_length = caps.InputReportByteLength;
+	HidD_FreePreparsedData(pp_data);
+
+	dev->read_buf = (char*) malloc(dev->input_report_length);
+
+	return dev;
+
+err_pp_data:
+		HidD_FreePreparsedData(pp_data);
+err:	
+		CloseHandle(dev->device_handle);
+		free(dev);
+		return NULL;
+}
+
+int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
+{
+	DWORD bytes_written;
+	BOOLEAN res;
+
+	OVERLAPPED ol;
+	memset(&ol, 0, sizeof(ol));
+
+	res = WriteFile(dev->device_handle, data, length, NULL, &ol);
+	
+	if (!res) {
+		if (GetLastError() != ERROR_IO_PENDING) {
+			// WriteFile() failed. Return error.
+			register_error(dev, "WriteFile");
+			return -1;
+		}
+	}
+
+	// Wait here until the write is done. This makes
+	// hid_write() synchronous.
+	res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/);
+	if (!res) {
+		// The Write operation failed.
+		register_error(dev, "WriteFile");
+		return -1;
+	}
+
+	return bytes_written;
+}
+
+int HID_API_EXPORT HID_API_CALL hid_set_ptt(int state)
+{
+	int res;
+	hid_device *handle;
+	unsigned char buf[16];
+
+	handle = hid_open(0xd8c, 0x8, NULL);
+	if (!handle) {
+		printf("unable to open device\n");
+ 		return 1;
+	}
+
+
+	// Toggle PTT
+
+	buf[0] = 0;
+	buf[1] = 0;
+	buf[2]= 1 << (3 - 1);
+	buf[3] = state << (3 - 1);
+	buf[4] = 0;
+
+
+	res = hid_write(handle, buf, 5);
+	if (res < 0)
+	{
+		printf("Unable to write()\n");
+		printf("Error: %ls\n", hid_error(handle));
+	}
+	
+	hid_close(handle);
+	return res;
+}
+
+
+int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
+{
+	DWORD bytes_read = 0;
+	BOOLEAN res;
+
+	// Copy the handle for convenience.
+	HANDLE ev = dev->ol.hEvent;
+
+	if (!dev->read_pending) {
+		// Start an Overlapped I/O read.
+		dev->read_pending = TRUE;
+		ResetEvent(ev);
+		res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol);
+		
+		if (!res) {
+			if (GetLastError() != ERROR_IO_PENDING) {
+				// ReadFile() has failed.
+				// Clean up and return error.
+				CancelIo(dev->device_handle);
+				dev->read_pending = FALSE;
+				goto end_of_function;
+			}
+		}
+	}
+
+	if (milliseconds >= 0) {
+		// See if there is any data yet.
+		res = WaitForSingleObject(ev, milliseconds);
+		if (res != WAIT_OBJECT_0) {
+			// There was no data this time. Return zero bytes available,
+			// but leave the Overlapped I/O running.
+			return 0;
+		}
+	}
+
+	// Either WaitForSingleObject() told us that ReadFile has completed, or
+	// we are in non-blocking mode. Get the number of bytes read. The actual
+	// data has been copied to the data[] array which was passed to ReadFile().
+	res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/);
+	
+	// Set pending back to false, even if GetOverlappedResult() returned error.
+	dev->read_pending = FALSE;
+
+	if (res && bytes_read > 0) {
+		if (dev->read_buf[0] == 0x0) {
+			/* If report numbers aren't being used, but Windows sticks a report
+			   number (0x0) on the beginning of the report anyway. To make this
+			   work like the other platforms, and to make it work more like the
+			   HID spec, we'll skip over this byte. */
+			bytes_read--;
+			memcpy(data, dev->read_buf+1, length);
+		}
+		else {
+			/* Copy the whole buffer, report number and all. */
+			memcpy(data, dev->read_buf, length);
+		}
+	}
+	
+end_of_function:
+	if (!res) {
+		register_error(dev, "GetOverlappedResult");
+		return -1;
+	}
+	
+	return bytes_read;
+}
+
+int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
+{
+	return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
+}
+
+int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock)
+{
+	dev->blocking = !nonblock;
+	return 0; /* Success */
+}
+
+int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
+{
+	BOOLEAN res = HidD_SetFeature(dev->device_handle, (PVOID)data, length);
+	if (!res) {
+		register_error(dev, "HidD_SetFeature");
+		return -1;
+	}
+
+	return length;
+}
+
+
+int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
+{
+	BOOLEAN res;
+#if 0
+	res = HidD_GetFeature(dev->device_handle, data, length);
+	if (!res) {
+		register_error(dev, "HidD_GetFeature");
+		return -1;
+	}
+	return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */
+#else
+	DWORD bytes_returned;
+
+	OVERLAPPED ol;
+	memset(&ol, 0, sizeof(ol));
+
+	res = DeviceIoControl(dev->device_handle,
+		IOCTL_HID_GET_FEATURE,
+		data, length,
+		data, length,
+		&bytes_returned, &ol);
+
+	if (!res) {
+		if (GetLastError() != ERROR_IO_PENDING) {
+			// DeviceIoControl() failed. Return error.
+			register_error(dev, "Send Feature Report DeviceIoControl");
+			return -1;
+		}
+	}
+
+	// Wait here until the write is done. This makes
+	// hid_get_feature_report() synchronous.
+	res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
+	if (!res) {
+		// The operation failed.
+		register_error(dev, "Send Feature Report GetOverLappedResult");
+		return -1;
+	}
+	return bytes_returned;
+#endif
+}
+
+void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
+{
+	if (!dev)
+		return;
+	CancelIo(dev->device_handle);
+	CloseHandle(dev->ol.hEvent);
+	CloseHandle(dev->device_handle);
+	LocalFree(dev->last_error_str);
+	free(dev->read_buf);
+	free(dev);
+}
+
+int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
+{
+	BOOLEAN res;
+
+	res = HidD_GetManufacturerString(dev->device_handle, string, 2 * maxlen);
+	if (!res) {
+		register_error(dev, "HidD_GetManufacturerString");
+		return -1;
+	}
+
+	return 0;
+}
+
+int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
+{
+	BOOLEAN res;
+
+	res = HidD_GetProductString(dev->device_handle, string, 2 * maxlen);
+	if (!res) {
+		register_error(dev, "HidD_GetProductString");
+		return -1;
+	}
+
+	return 0;
+}
+
+int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
+{
+	BOOLEAN res;
+
+	res = HidD_GetSerialNumberString(dev->device_handle, string, 2 * maxlen);
+	if (!res) {
+		register_error(dev, "HidD_GetSerialNumberString");
+		return -1;
+	}
+
+	return 0;
+}
+
+int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
+{
+	BOOLEAN res;
+
+	res = HidD_GetIndexedString(dev->device_handle, string_index, string, 2 * maxlen);
+	if (!res) {
+		register_error(dev, "HidD_GetIndexedString");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
+{
+	return (wchar_t*)dev->last_error_str;
+}
+
+
+//#define PICPGM
+//#define S11
+#define P32
+#ifdef S11 
+  unsigned short VendorID = 0xa0a0;
+	unsigned short ProductID = 0x0001;
+#endif
+
+#ifdef P32
+  unsigned short VendorID = 0x04d8;
+	unsigned short ProductID = 0x3f;
+#endif
+
+
+#ifdef PICPGM
+  unsigned short VendorID = 0x04d8;
+  unsigned short ProductID = 0x0033;
+#endif
+
+
+#if 0
+int __cdecl main(int argc, char* argv[])
+{
+	int res;
+	unsigned char buf[65];
+
+	UNREFERENCED_PARAMETER(argc);
+	UNREFERENCED_PARAMETER(argv);
+
+	// Set up the command buffer.
+	memset(buf,0x00,sizeof(buf));
+	buf[0] = 0;
+	buf[1] = 0x81;
+	
+
+	// Open the device.
+	int handle = open(VendorID, ProductID, L"12345");
+	if (handle < 0)
+		printf("unable to open device\n");
+
+
+	// Toggle LED (cmd 0x80)
+	buf[1] = 0x80;
+	res = write(handle, buf, 65);
+	if (res < 0)
+		printf("Unable to write()\n");
+
+	// Request state (cmd 0x81)
+	buf[1] = 0x81;
+	write(handle, buf, 65);
+	if (res < 0)
+		printf("Unable to write() (2)\n");
+
+	// Read requested state
+	read(handle, buf, 65);
+	if (res < 0)
+		printf("Unable to read()\n");
+
+	// Print out the returned buffer.
+	for (int i = 0; i < 4; i++)
+		printf("buf[%d]: %d\n", i, buf[i]);
+
+	return 0;
+}
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- qttermtcp-0.0.0.79.orig/main.cpp
+++ qttermtcp-0.0.0.79/main.cpp
@@ -1,26 +1,26 @@
-#include "QtTermTCP.h"
-#include <QApplication>
-#include <qscreen.h>
-
-QApplication * a;
-
-int screenHeight = 0;				// used to control dialog sizes on Android
-int screenWidth = 0;
-
-int main(int argc, char *argv[])
-{
-	a = new QApplication (argc, argv);
-
-	QSize r = a->screens()[0]->size();
-
-	screenHeight = r.height();
-	screenWidth = r.width();
-
-	QtTermTCP w;
-
-//#ifdef ANDROID
-//	w.setWindowFlags(Qt::Window | Qt::CustomizeWindowHint); // Qt::FramelessWindowHint);
-//#endif
-	w.show();
-	return a->exec();
-}
+#include "QtTermTCP.h"
+#include <QApplication>
+#include <qscreen.h>
+
+QApplication * a;
+
+int screenHeight = 0;				// used to control dialog sizes on Android
+int screenWidth = 0;
+
+int main(int argc, char *argv[])
+{
+	a = new QApplication (argc, argv);
+
+	QSize r = a->screens()[0]->size();
+
+	screenHeight = r.height();
+	screenWidth = r.width();
+
+	QtTermTCP w;
+
+//#ifdef ANDROID
+//	w.setWindowFlags(Qt::Window | Qt::CustomizeWindowHint); // Qt::FramelessWindowHint);
+//#endif
+	w.show();
+	return a->exec();
+}
--- qttermtcp-0.0.0.79.orig/release/moc_predefs.h
+++ qttermtcp-0.0.0.79/release/moc_predefs.h
@@ -1,11 +1,11 @@
-#define _MSC_EXTENSIONS 
-#define _INTEGRAL_MAX_BITS 64
-#define _MSC_VER 1916
-#define _MSC_FULL_VER 191627051
-#define _MSC_BUILD 0
-#define _WIN32 
-#define _M_IX86 600
-#define _M_IX86_FP 2
-#define _CPPRTTI 
-#define _MT 
-#define _DLL 
+#define _MSC_EXTENSIONS 
+#define _INTEGRAL_MAX_BITS 64
+#define _MSC_VER 1916
+#define _MSC_FULL_VER 191627051
+#define _MSC_BUILD 0
+#define _WIN32 
+#define _M_IX86 600
+#define _M_IX86_FP 2
+#define _CPPRTTI 
+#define _MT 
+#define _DLL 
--- qttermtcp-0.0.0.79.orig/utf8Routines.cpp
+++ qttermtcp-0.0.0.79/utf8Routines.cpp
@@ -1,597 +1,597 @@
-/*
-Copyright 2001-2018 John Wiseman G8BPQ
-
-This file is part of LinBPQ/BPQ32.
-
-LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-LinBPQ/BPQ32 is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
-*/	
-
-// Routines to convert to and from UTF8
-
-#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
-
-#define _CRT_SECURE_NO_DEPRECATE
-
-
-#ifndef WIN32
-
-#define VOID void
-#define BOOL int
-#define TRUE 1
-#define FALSE 0
-
-#include <string.h>
-
-
-#else
-#include <windows.h>
-#endif
-
-int convUTF8 = 0;
-
-unsigned int CP437toUTF8Data[128] = {
-  34755, 48323, 43459, 41667,  
-  42179, 41155, 42435, 42947,  
-  43715, 43971, 43203, 44995,  
-  44739, 44227, 33987, 34243,  
-  35267, 42691, 34499, 46275,		// 90
-  46787, 45763, 48067, 47555,  
-  49091, 38595, 40131, 41666,  
-  41922, 42434, 10978018, 37574,  
-  41411, 44483, 46019, 47811,		// A0
-  45507, 37315, 43714, 47810,  
-  49090, 9473250, 44226, 48578,  
-  48322, 41410, 43970, 48066,  
-  9541346, 9606882, 9672418, 8557794,  //B0
-  10786018, 10589666, 10655202, 9868770,  
-  9803234, 10720738, 9541090, 9934306,  
-  10327522, 10261986, 10196450, 9475298,  
-  9737442, 11834594, 11310306, 10261730,  //C0
-  8426722, 12358882, 10393058, 10458594,  
-  10130914, 9737698, 11113954, 10917346,  
-  10524130, 9475554, 11310562, 10982882,  
-  11048418, 10786274, 10851810, 10065378,  //D0
-  9999842, 9606626, 9672162, 11245026,  
-  11179490, 9999586, 9213154, 8951522,  
-  8689378, 9213666, 9475810, 8427234,  
-  45518, 40899, 37838, 32975,				// E0
-  41934, 33743, 46530, 33999,  
-  42702, 39118, 43470, 46286,  
-  10389730, 34511, 46542, 11110626,  
-  10586594, 45506, 10848738, 10783202,		// F0
-  10521826, 10587362, 47043, 8948194,  
-  45250, 10062050, 47042, 10127586,  
-  12550626, 45762, 10524386, 41154,  
-};
-unsigned int CP437toUTF8DataLen[128] = {
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 3, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 3, 2, 2,  
-  2, 2, 2, 2,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  3, 3, 3, 3,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  3, 2, 2, 3,  
-  3, 2, 3, 3,  
-  3, 3, 2, 3,  
-  2, 3, 2, 3,  
-  3, 2, 3, 2,  
-};
-
-unsigned int CP1251toUTF8Data[128] = {
-  33488, 33744, 10125538, 37841,  
-  10387682, 10911970, 10518754, 10584290,  
-  11305698, 11567330, 35280, 12157154,  
-  35536, 36048, 35792, 36816,  
-  37585, 9994466, 10060002, 10256610,  
-  10322146, 10649826, 9666786, 9732322,  
-  39106, 10650850, 39377, 12222690,  
-  39633, 40145, 39889, 40913,  
-  41154, 36560, 40657, 35024,  
-  42178, 37074, 42690, 42946,  
-  33232, 43458, 34000, 43970,  
-  44226, 44482, 44738, 34768,  
-  45250, 45506, 34512, 38609,  
-  37330, 46530, 46786, 47042,  
-  37329, 9864418, 38097, 48066,  
-  39121, 34256, 38353, 38865,  
-  37072, 37328, 37584, 37840,  
-  38096, 38352, 38608, 38864,  
-  39120, 39376, 39632, 39888,  
-  40144, 40400, 40656, 40912,  
-  41168, 41424, 41680, 41936,  
-  42192, 42448, 42704, 42960,  
-  43216, 43472, 43728, 43984,  
-  44240, 44496, 44752, 45008,  
-  45264, 45520, 45776, 46032,  
-  46288, 46544, 46800, 47056,  
-  47312, 47568, 47824, 48080,  
-  48336, 48592, 48848, 49104,  
-  32977, 33233, 33489, 33745,  
-  34001, 34257, 34513, 34769,  
-  35025, 35281, 35537, 35793,  
-  36049, 36305, 36561, 36817,  
-};
-unsigned int CP1251toUTF8DataLen[128] = {
-  2, 2, 3, 2,  
-  3, 3, 3, 3,  
-  3, 3, 2, 3,  
-  2, 2, 2, 2,  
-  2, 3, 3, 3,  
-  3, 3, 3, 3,  
-  2, 3, 2, 3,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 3, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-};
-
-
-unsigned int CP1252toUTF8Data[128] = {
-  11305698, 33218, 10125538, 37574,  
-  10387682, 10911970, 10518754, 10584290,  
-  34507, 11567330, 41157, 12157154,  
-  37573, 36290, 48581, 36802,  
-  37058, 9994466, 10060002, 10256610,  
-  10322146, 10649826, 9666786, 9732322,  
-  40139, 10650850, 41413, 12222690,  
-  37829, 40386, 48837, 47301,  
-  41154, 41410, 41666, 41922,  
-  42178, 42434, 42690, 42946,  
-  43202, 43458, 43714, 43970,  
-  44226, 44482, 44738, 44994,  
-  45250, 45506, 45762, 46018,  
-  46274, 46530, 46786, 47042,  
-  47298, 47554, 47810, 48066,  
-  48322, 48578, 48834, 49090,  
-  32963, 33219, 33475, 33731,  
-  33987, 34243, 34499, 34755,  
-  35011, 35267, 35523, 35779,  
-  36035, 36291, 36547, 36803,  
-  37059, 37315, 37571, 37827,  
-  38083, 38339, 38595, 38851,  
-  39107, 39363, 39619, 39875,  
-  40131, 40387, 40643, 40899,  
-  41155, 41411, 41667, 41923,  
-  42179, 42435, 42691, 42947,  
-  43203, 43459, 43715, 43971,  
-  44227, 44483, 44739, 44995,  
-  45251, 45507, 45763, 46019,  
-  46275, 46531, 46787, 47043,  
-  47299, 47555, 47811, 48067,  
-  48323, 48579, 48835, 49091,  
-};
-unsigned int CP1252toUTF8DataLen[128] = {
-  3, 2, 3, 2,  
-  3, 3, 3, 3,  
-  2, 3, 2, 3,  
-  2, 2, 2, 2,  
-  2, 3, 3, 3,  
-  3, 3, 3, 3,  
-  2, 3, 2, 3,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-  2, 2, 2, 2,  
-};
-
-#ifdef __BIG_ENDIAN__
-BOOL initUTF8Done = FALSE;
-#else
-BOOL initUTF8Done = TRUE;
-#endif
-
-VOID initUTF8()
-{
-	// Swap bytes of UTF-8 COde on Big-endian systems
-	
-	int n;
-	char temp[4];
-	char rev[4];
-
-	if (initUTF8Done)
-		return;
-	
-	for (n = 0; n <128; n++)
-	{
-		memcpy(temp, &CP437toUTF8Data[n], 4);
-		rev[0] = temp[3];
-		rev[1] = temp[2];
-		rev[2] = temp[1];
-		rev[3] = temp[0];
-
-		memcpy(&CP437toUTF8Data[n], rev, 4);
-
-		memcpy(temp, &CP1251toUTF8Data[n], 4);
-		rev[0] = temp[3];
-		rev[1] = temp[2];
-		rev[2] = temp[1];
-		rev[3] = temp[0];
-
-		memcpy(&CP1251toUTF8Data[n], rev, 4);
-
-		memcpy(temp, &CP1252toUTF8Data[n], 4);
-		rev[0] = temp[3];
-		rev[1] = temp[2];
-		rev[2] = temp[1];
-		rev[3] = temp[0];
-
-		memcpy(&CP1252toUTF8Data[n], rev, 4);
-	}
-
-	initUTF8Done = TRUE;
-}
-
-
-
-int Is8Bit(unsigned char *cpt, int len)
-{
-	int n; 
-
-	cpt--;
-										
-	for (n = 0; n < len; n++)
-	{
-		cpt++;
-		
-		if (*cpt > 127)
-			return TRUE; 
-	}
-
-    return FALSE;
-}
-
-
-int IsUTF8(unsigned char *ptr, int len)
-{
-	int n; 
-	unsigned char * cpt = ptr;
-
-	// This has to be a bit loose, as UTF8 sequences may split over packets
-
-	memcpy(&ptr[len], "\x80\x80\x80", 3);		// in case trailing bytes are in next packet
-
-	// Don't check first 3 if could be part of sequence
-	
-	if ((*(cpt) & 0xC0) == 0x80)				// Valid continuation
-	{
-		cpt++;
-		len--;
-		if ((*(cpt) & 0xC0) == 0x80)			// Valid continuation
-		{
-			cpt++;
-			len--;
-			if ((*(cpt) & 0xC0) == 0x80)		// Valid continuation
-			{
-				cpt++;
-				len--;
-			}
-		}
-	}
-
-	cpt--;
-										
-	for (n = 0; n < len; n++)
-	{
-		cpt++;
-		
-		if (*cpt < 128)
-			continue;
-
-		if ((*cpt & 0xF8) == 0xF0)
-		{ // start of 4-byte sequence
-			if (((*(cpt + 1) & 0xC0) == 0x80)
-		     && ((*(cpt + 2) & 0xC0) == 0x80)
-			 && ((*(cpt + 3) & 0xC0) == 0x80))
-			{
-				cpt += 3;
-				n += 3;
-				continue;
-			}
-			return FALSE;
-	    }
-		else if ((*cpt & 0xF0) == 0xE0)
-		{ // start of 3-byte sequence
-	        if (((*(cpt + 1) & 0xC0) == 0x80)
-		     && ((*(cpt + 2) & 0xC0) == 0x80))
-			{
-				cpt += 2;
-				n += 2;
-				continue;
-			}
-			return FALSE;
-		}
-		else if ((*cpt & 0xE0) == 0xC0)
-		{ // start of 2-byte sequence
-	        if ((*(cpt + 1) & 0xC0) == 0x80)
-			{
-				cpt++;
-				n++;
-				continue;
-			}
-			return FALSE;
-		}
-		return FALSE;
-	}
-
-    return TRUE;
-}
-
-int WebIsUTF8(unsigned char *ptr, int len)
-{
-	int n; 
-	unsigned char * cpt = ptr;
-
-	// This is simpler than the Term version, as it only handles complete lines of text, so cant get split sequences
-
-	cpt--;
-										
-	for (n = 0; n < len; n++)
-	{
-		cpt++;
-		
-		if (*cpt < 128)
-			continue;
-
-		if ((*cpt & 0xF8) == 0xF0)
-		{ // start of 4-byte sequence
-			if (((*(cpt + 1) & 0xC0) == 0x80)
-		     && ((*(cpt + 2) & 0xC0) == 0x80)
-			 && ((*(cpt + 3) & 0xC0) == 0x80))
-			{
-				cpt += 3;
-				n += 3;
-				continue;
-			}
-			return FALSE;
-	    }
-		else if ((*cpt & 0xF0) == 0xE0)
-		{ // start of 3-byte sequence
-	        if (((*(cpt + 1) & 0xC0) == 0x80)
-		     && ((*(cpt + 2) & 0xC0) == 0x80))
-			{
-				cpt += 2;
-				n += 2;
-				continue;
-			}
-			return FALSE;
-		}
-		else if ((*cpt & 0xE0) == 0xC0)
-		{ // start of 2-byte sequence
-	        if ((*(cpt + 1) & 0xC0) == 0x80)
-			{
-				cpt++;
-				n++;
-				continue;
-			}
-			return FALSE;
-		}
-		return FALSE;
-	}
-
-    return TRUE;
-}
-
-
-
-int Convert437toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF)
-{
-	unsigned char * ptr1 = MsgPtr;
-	unsigned char * ptr2 = UTF;
-	int n;
-	unsigned int c;
-
-	for (n = 0; n < len; n++)
-	{
-		c = *(ptr1++);
-
-		if (c < 128)
-		{
-			*(ptr2++) = c;
-			continue;
-		}
-
-		memcpy(ptr2, &CP437toUTF8Data[c - 128], CP437toUTF8DataLen[c - 128]);
-		ptr2 += CP437toUTF8DataLen[c - 128];
-	}
-
-	return (int)(ptr2 - UTF);
-}
-
-int Convert1251toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF)
-{
-	unsigned char * ptr1 = MsgPtr;
-	unsigned char * ptr2 = UTF;
-	int n;
-	unsigned int c;
-
-	for (n = 0; n < len; n++)
-	{
-		c = *(ptr1++);
-
-		if (c < 128)
-		{
-			*(ptr2++) = c;
-			continue;
-		}
-
-		memcpy(ptr2, &CP1251toUTF8Data[c - 128], CP1251toUTF8DataLen[c - 128]);
-		ptr2 += CP1251toUTF8DataLen[c - 128];
-	}
-
-	return (int)(ptr2 - UTF);
-}
-
-int Convert1252toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF)
-{
-	unsigned char * ptr1 = MsgPtr;
-	unsigned char * ptr2 = UTF;
-	int n;
-	unsigned int c;
-
-	for (n = 0; n < len; n++)
-	{
-		c = *(ptr1++);
-
-		if (c < 128)
-		{
-			*(ptr2++) = c;
-			continue;
-		}
-
-		memcpy(ptr2, &CP1252toUTF8Data[c - 128], CP1252toUTF8DataLen[c - 128]);
-		ptr2 += CP1252toUTF8DataLen[c - 128];
-	}
-
-	return (int)(ptr2 - UTF);
-}
-
-int TrytoGuessCode(unsigned char * Char, int Len)
-{
-	int Above127 = 0;
-	int LineDraw = 0;
-	int NumericAndSpaces = 0;
-	int n;
-
-	for (n = 0; n < Len; n++)
-	{
-		if (Char[n] < 65)
-		{
-			NumericAndSpaces++;
-		}
-		else
-		{
-			if (Char[n] > 127)
-			{
-				Above127++;
-				if (Char[n] == 0xF8 || (Char[n] > 178 && Char[n] < 224))
-				{
-					LineDraw++;
-				}
-			}
-		}
-	}
-
-	if (Above127 == 0)		// Doesn't really matter!
-		return 1252;
-
-	if (Above127 == LineDraw)
-		return 437;			// If only Line Draw chars, assume line draw
-
-	// If mainly below 128, it is probably Latin if mainly above, probably Cyrillic
-
-	if ((Len - (NumericAndSpaces + Above127)) < Above127) 
-		return 1251;
-	else
-		return 1252;
-}
-
-unsigned char outbuffer[16384];		// I don't think this needs to be thread safe
-
-int checkUTF8(unsigned char * in, int len, unsigned char * out)
-{
-	// We mustn't mess with input string
-
-	unsigned char Msg[8192];
-	int u, code = convUTF8;
-
-	if (convUTF8 == -1 || !Is8Bit(in, len))
-	{
-		// just copy to output
-
-		memcpy(out, in, len);
-		return len;
-	}
-
-	// Convert 
-
-	memcpy(Msg, in, len);
-	Msg[len] = 0;
-
-	if (convUTF8 == 0)		// Auto - Try to guess encoding
-		code = TrytoGuessCode(Msg, len);
-
-	if (code == 437)
-		u = Convert437toUTF8(Msg, len, out);
-	else if (code == 1251)
-		u = Convert1251toUTF8(Msg, len, out);
-	else
-		u = Convert1252toUTF8(Msg, len, out);
-
-	return u;
-
-}
-
+/*
+Copyright 2001-2018 John Wiseman G8BPQ
+
+This file is part of LinBPQ/BPQ32.
+
+LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+LinBPQ/BPQ32 is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
+*/	
+
+// Routines to convert to and from UTF8
+
+#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+
+#ifndef WIN32
+
+#define VOID void
+#define BOOL int
+#define TRUE 1
+#define FALSE 0
+
+#include <string.h>
+
+
+#else
+#include <windows.h>
+#endif
+
+int convUTF8 = 0;
+
+unsigned int CP437toUTF8Data[128] = {
+  34755, 48323, 43459, 41667,  
+  42179, 41155, 42435, 42947,  
+  43715, 43971, 43203, 44995,  
+  44739, 44227, 33987, 34243,  
+  35267, 42691, 34499, 46275,		// 90
+  46787, 45763, 48067, 47555,  
+  49091, 38595, 40131, 41666,  
+  41922, 42434, 10978018, 37574,  
+  41411, 44483, 46019, 47811,		// A0
+  45507, 37315, 43714, 47810,  
+  49090, 9473250, 44226, 48578,  
+  48322, 41410, 43970, 48066,  
+  9541346, 9606882, 9672418, 8557794,  //B0
+  10786018, 10589666, 10655202, 9868770,  
+  9803234, 10720738, 9541090, 9934306,  
+  10327522, 10261986, 10196450, 9475298,  
+  9737442, 11834594, 11310306, 10261730,  //C0
+  8426722, 12358882, 10393058, 10458594,  
+  10130914, 9737698, 11113954, 10917346,  
+  10524130, 9475554, 11310562, 10982882,  
+  11048418, 10786274, 10851810, 10065378,  //D0
+  9999842, 9606626, 9672162, 11245026,  
+  11179490, 9999586, 9213154, 8951522,  
+  8689378, 9213666, 9475810, 8427234,  
+  45518, 40899, 37838, 32975,				// E0
+  41934, 33743, 46530, 33999,  
+  42702, 39118, 43470, 46286,  
+  10389730, 34511, 46542, 11110626,  
+  10586594, 45506, 10848738, 10783202,		// F0
+  10521826, 10587362, 47043, 8948194,  
+  45250, 10062050, 47042, 10127586,  
+  12550626, 45762, 10524386, 41154,  
+};
+unsigned int CP437toUTF8DataLen[128] = {
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 3, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 3, 2, 2,  
+  2, 2, 2, 2,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  3, 3, 3, 3,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  3, 2, 2, 3,  
+  3, 2, 3, 3,  
+  3, 3, 2, 3,  
+  2, 3, 2, 3,  
+  3, 2, 3, 2,  
+};
+
+unsigned int CP1251toUTF8Data[128] = {
+  33488, 33744, 10125538, 37841,  
+  10387682, 10911970, 10518754, 10584290,  
+  11305698, 11567330, 35280, 12157154,  
+  35536, 36048, 35792, 36816,  
+  37585, 9994466, 10060002, 10256610,  
+  10322146, 10649826, 9666786, 9732322,  
+  39106, 10650850, 39377, 12222690,  
+  39633, 40145, 39889, 40913,  
+  41154, 36560, 40657, 35024,  
+  42178, 37074, 42690, 42946,  
+  33232, 43458, 34000, 43970,  
+  44226, 44482, 44738, 34768,  
+  45250, 45506, 34512, 38609,  
+  37330, 46530, 46786, 47042,  
+  37329, 9864418, 38097, 48066,  
+  39121, 34256, 38353, 38865,  
+  37072, 37328, 37584, 37840,  
+  38096, 38352, 38608, 38864,  
+  39120, 39376, 39632, 39888,  
+  40144, 40400, 40656, 40912,  
+  41168, 41424, 41680, 41936,  
+  42192, 42448, 42704, 42960,  
+  43216, 43472, 43728, 43984,  
+  44240, 44496, 44752, 45008,  
+  45264, 45520, 45776, 46032,  
+  46288, 46544, 46800, 47056,  
+  47312, 47568, 47824, 48080,  
+  48336, 48592, 48848, 49104,  
+  32977, 33233, 33489, 33745,  
+  34001, 34257, 34513, 34769,  
+  35025, 35281, 35537, 35793,  
+  36049, 36305, 36561, 36817,  
+};
+unsigned int CP1251toUTF8DataLen[128] = {
+  2, 2, 3, 2,  
+  3, 3, 3, 3,  
+  3, 3, 2, 3,  
+  2, 2, 2, 2,  
+  2, 3, 3, 3,  
+  3, 3, 3, 3,  
+  2, 3, 2, 3,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 3, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+};
+
+
+unsigned int CP1252toUTF8Data[128] = {
+  11305698, 33218, 10125538, 37574,  
+  10387682, 10911970, 10518754, 10584290,  
+  34507, 11567330, 41157, 12157154,  
+  37573, 36290, 48581, 36802,  
+  37058, 9994466, 10060002, 10256610,  
+  10322146, 10649826, 9666786, 9732322,  
+  40139, 10650850, 41413, 12222690,  
+  37829, 40386, 48837, 47301,  
+  41154, 41410, 41666, 41922,  
+  42178, 42434, 42690, 42946,  
+  43202, 43458, 43714, 43970,  
+  44226, 44482, 44738, 44994,  
+  45250, 45506, 45762, 46018,  
+  46274, 46530, 46786, 47042,  
+  47298, 47554, 47810, 48066,  
+  48322, 48578, 48834, 49090,  
+  32963, 33219, 33475, 33731,  
+  33987, 34243, 34499, 34755,  
+  35011, 35267, 35523, 35779,  
+  36035, 36291, 36547, 36803,  
+  37059, 37315, 37571, 37827,  
+  38083, 38339, 38595, 38851,  
+  39107, 39363, 39619, 39875,  
+  40131, 40387, 40643, 40899,  
+  41155, 41411, 41667, 41923,  
+  42179, 42435, 42691, 42947,  
+  43203, 43459, 43715, 43971,  
+  44227, 44483, 44739, 44995,  
+  45251, 45507, 45763, 46019,  
+  46275, 46531, 46787, 47043,  
+  47299, 47555, 47811, 48067,  
+  48323, 48579, 48835, 49091,  
+};
+unsigned int CP1252toUTF8DataLen[128] = {
+  3, 2, 3, 2,  
+  3, 3, 3, 3,  
+  2, 3, 2, 3,  
+  2, 2, 2, 2,  
+  2, 3, 3, 3,  
+  3, 3, 3, 3,  
+  2, 3, 2, 3,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+  2, 2, 2, 2,  
+};
+
+#ifdef __BIG_ENDIAN__
+BOOL initUTF8Done = FALSE;
+#else
+BOOL initUTF8Done = TRUE;
+#endif
+
+VOID initUTF8()
+{
+	// Swap bytes of UTF-8 COde on Big-endian systems
+	
+	int n;
+	char temp[4];
+	char rev[4];
+
+	if (initUTF8Done)
+		return;
+	
+	for (n = 0; n <128; n++)
+	{
+		memcpy(temp, &CP437toUTF8Data[n], 4);
+		rev[0] = temp[3];
+		rev[1] = temp[2];
+		rev[2] = temp[1];
+		rev[3] = temp[0];
+
+		memcpy(&CP437toUTF8Data[n], rev, 4);
+
+		memcpy(temp, &CP1251toUTF8Data[n], 4);
+		rev[0] = temp[3];
+		rev[1] = temp[2];
+		rev[2] = temp[1];
+		rev[3] = temp[0];
+
+		memcpy(&CP1251toUTF8Data[n], rev, 4);
+
+		memcpy(temp, &CP1252toUTF8Data[n], 4);
+		rev[0] = temp[3];
+		rev[1] = temp[2];
+		rev[2] = temp[1];
+		rev[3] = temp[0];
+
+		memcpy(&CP1252toUTF8Data[n], rev, 4);
+	}
+
+	initUTF8Done = TRUE;
+}
+
+
+
+int Is8Bit(unsigned char *cpt, int len)
+{
+	int n; 
+
+	cpt--;
+										
+	for (n = 0; n < len; n++)
+	{
+		cpt++;
+		
+		if (*cpt > 127)
+			return TRUE; 
+	}
+
+    return FALSE;
+}
+
+
+int IsUTF8(unsigned char *ptr, int len)
+{
+	int n; 
+	unsigned char * cpt = ptr;
+
+	// This has to be a bit loose, as UTF8 sequences may split over packets
+
+	memcpy(&ptr[len], "\x80\x80\x80", 3);		// in case trailing bytes are in next packet
+
+	// Don't check first 3 if could be part of sequence
+	
+	if ((*(cpt) & 0xC0) == 0x80)				// Valid continuation
+	{
+		cpt++;
+		len--;
+		if ((*(cpt) & 0xC0) == 0x80)			// Valid continuation
+		{
+			cpt++;
+			len--;
+			if ((*(cpt) & 0xC0) == 0x80)		// Valid continuation
+			{
+				cpt++;
+				len--;
+			}
+		}
+	}
+
+	cpt--;
+										
+	for (n = 0; n < len; n++)
+	{
+		cpt++;
+		
+		if (*cpt < 128)
+			continue;
+
+		if ((*cpt & 0xF8) == 0xF0)
+		{ // start of 4-byte sequence
+			if (((*(cpt + 1) & 0xC0) == 0x80)
+		     && ((*(cpt + 2) & 0xC0) == 0x80)
+			 && ((*(cpt + 3) & 0xC0) == 0x80))
+			{
+				cpt += 3;
+				n += 3;
+				continue;
+			}
+			return FALSE;
+	    }
+		else if ((*cpt & 0xF0) == 0xE0)
+		{ // start of 3-byte sequence
+	        if (((*(cpt + 1) & 0xC0) == 0x80)
+		     && ((*(cpt + 2) & 0xC0) == 0x80))
+			{
+				cpt += 2;
+				n += 2;
+				continue;
+			}
+			return FALSE;
+		}
+		else if ((*cpt & 0xE0) == 0xC0)
+		{ // start of 2-byte sequence
+	        if ((*(cpt + 1) & 0xC0) == 0x80)
+			{
+				cpt++;
+				n++;
+				continue;
+			}
+			return FALSE;
+		}
+		return FALSE;
+	}
+
+    return TRUE;
+}
+
+int WebIsUTF8(unsigned char *ptr, int len)
+{
+	int n; 
+	unsigned char * cpt = ptr;
+
+	// This is simpler than the Term version, as it only handles complete lines of text, so cant get split sequences
+
+	cpt--;
+										
+	for (n = 0; n < len; n++)
+	{
+		cpt++;
+		
+		if (*cpt < 128)
+			continue;
+
+		if ((*cpt & 0xF8) == 0xF0)
+		{ // start of 4-byte sequence
+			if (((*(cpt + 1) & 0xC0) == 0x80)
+		     && ((*(cpt + 2) & 0xC0) == 0x80)
+			 && ((*(cpt + 3) & 0xC0) == 0x80))
+			{
+				cpt += 3;
+				n += 3;
+				continue;
+			}
+			return FALSE;
+	    }
+		else if ((*cpt & 0xF0) == 0xE0)
+		{ // start of 3-byte sequence
+	        if (((*(cpt + 1) & 0xC0) == 0x80)
+		     && ((*(cpt + 2) & 0xC0) == 0x80))
+			{
+				cpt += 2;
+				n += 2;
+				continue;
+			}
+			return FALSE;
+		}
+		else if ((*cpt & 0xE0) == 0xC0)
+		{ // start of 2-byte sequence
+	        if ((*(cpt + 1) & 0xC0) == 0x80)
+			{
+				cpt++;
+				n++;
+				continue;
+			}
+			return FALSE;
+		}
+		return FALSE;
+	}
+
+    return TRUE;
+}
+
+
+
+int Convert437toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF)
+{
+	unsigned char * ptr1 = MsgPtr;
+	unsigned char * ptr2 = UTF;
+	int n;
+	unsigned int c;
+
+	for (n = 0; n < len; n++)
+	{
+		c = *(ptr1++);
+
+		if (c < 128)
+		{
+			*(ptr2++) = c;
+			continue;
+		}
+
+		memcpy(ptr2, &CP437toUTF8Data[c - 128], CP437toUTF8DataLen[c - 128]);
+		ptr2 += CP437toUTF8DataLen[c - 128];
+	}
+
+	return (int)(ptr2 - UTF);
+}
+
+int Convert1251toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF)
+{
+	unsigned char * ptr1 = MsgPtr;
+	unsigned char * ptr2 = UTF;
+	int n;
+	unsigned int c;
+
+	for (n = 0; n < len; n++)
+	{
+		c = *(ptr1++);
+
+		if (c < 128)
+		{
+			*(ptr2++) = c;
+			continue;
+		}
+
+		memcpy(ptr2, &CP1251toUTF8Data[c - 128], CP1251toUTF8DataLen[c - 128]);
+		ptr2 += CP1251toUTF8DataLen[c - 128];
+	}
+
+	return (int)(ptr2 - UTF);
+}
+
+int Convert1252toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF)
+{
+	unsigned char * ptr1 = MsgPtr;
+	unsigned char * ptr2 = UTF;
+	int n;
+	unsigned int c;
+
+	for (n = 0; n < len; n++)
+	{
+		c = *(ptr1++);
+
+		if (c < 128)
+		{
+			*(ptr2++) = c;
+			continue;
+		}
+
+		memcpy(ptr2, &CP1252toUTF8Data[c - 128], CP1252toUTF8DataLen[c - 128]);
+		ptr2 += CP1252toUTF8DataLen[c - 128];
+	}
+
+	return (int)(ptr2 - UTF);
+}
+
+int TrytoGuessCode(unsigned char * Char, int Len)
+{
+	int Above127 = 0;
+	int LineDraw = 0;
+	int NumericAndSpaces = 0;
+	int n;
+
+	for (n = 0; n < Len; n++)
+	{
+		if (Char[n] < 65)
+		{
+			NumericAndSpaces++;
+		}
+		else
+		{
+			if (Char[n] > 127)
+			{
+				Above127++;
+				if (Char[n] == 0xF8 || (Char[n] > 178 && Char[n] < 224))
+				{
+					LineDraw++;
+				}
+			}
+		}
+	}
+
+	if (Above127 == 0)		// Doesn't really matter!
+		return 1252;
+
+	if (Above127 == LineDraw)
+		return 437;			// If only Line Draw chars, assume line draw
+
+	// If mainly below 128, it is probably Latin if mainly above, probably Cyrillic
+
+	if ((Len - (NumericAndSpaces + Above127)) < Above127) 
+		return 1251;
+	else
+		return 1252;
+}
+
+unsigned char outbuffer[16384];		// I don't think this needs to be thread safe
+
+int checkUTF8(unsigned char * in, int len, unsigned char * out)
+{
+	// We mustn't mess with input string
+
+	unsigned char Msg[8192];
+	int u, code = convUTF8;
+
+	if (convUTF8 == -1 || !Is8Bit(in, len))
+	{
+		// just copy to output
+
+		memcpy(out, in, len);
+		return len;
+	}
+
+	// Convert 
+
+	memcpy(Msg, in, len);
+	Msg[len] = 0;
+
+	if (convUTF8 == 0)		// Auto - Try to guess encoding
+		code = TrytoGuessCode(Msg, len);
+
+	if (code == 437)
+		u = Convert437toUTF8(Msg, len, out);
+	else if (code == 1251)
+		u = Convert1251toUTF8(Msg, len, out);
+	else
+		u = Convert1252toUTF8(Msg, len, out);
+
+	return u;
+
+}
+
