linbpq/TNCCode.c

400 lines
8.3 KiB
C
Raw Permalink Normal View History

2022-08-28 09:35:46 +01:00
/*
2022-11-14 14:02:28 +00:00
Copyright 2001-2022 John Wiseman G8BPQ
2022-08-28 09:35:46 +01:00
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
*/
//
// C replacement for TNCCode.asm
//
#define Kernel
#define _CRT_SECURE_NO_DEPRECATE
#pragma data_seg("_BPQDATA")
#include "time.h"
#include "stdio.h"
#include <fcntl.h>
#include "CHeaders.h"
#include "tncinfo.h"
int C_Q_COUNT(VOID *PQ);
VOID SENDUIMESSAGE(struct DATAMESSAGE * Msg);
VOID TNCTimerProc()
{
// CALLED AT 10 HZ
int n = BPQHOSTSTREAMS;
PBPQVECSTRUC HOSTSESS = BPQHOSTVECTOR;
TRANSPORTENTRY * Session;
UCHAR DISCFLAG = 0;
while (n--)
{
// Action any DISC Requests (must be done in timer owning process)
if (HOSTSESS->HOSTFLAGS & 0x40) // DISC REQUEST
{
if (HOSTSESS->HOSTFLAGS & 0x20) // Stay?
DISCFLAG = 'S';
HOSTSESS->HOSTFLAGS &= 0x9F; // Clear Flags
Session = HOSTSESS->HOSTSESSION;
if (Session == 0) // Gone??
{
HOSTSESS->HOSTFLAGS |= 3; // STATE CHANGE
#ifndef LINBPQ
if (HOSTSESS->HOSTHANDLE);
{
PostMessage(HOSTSESS->HOSTHANDLE, BPQMsg, HOSTSESS->HOSTSTREAM, 4);
}
#endif
continue;
}
if (Session->L4CROSSLINK)
Session->L4CROSSLINK->STAYFLAG = DISCFLAG;
HOSTSESS->HOSTSESSION = 0;
HOSTSESS->HOSTFLAGS |= 3; // STATE CHANGE
PostStateChange(Session);
CloseSessionPartner(Session); // SEND CLOSE TO PARTNER (IF PRESENT)
}
// Check Trace Q
if (HOSTSESS->HOSTAPPLFLAGS & 0x80)
{
if (HOSTSESS->HOSTTRACEQ)
{
int Count = C_Q_COUNT(&HOSTSESS->HOSTTRACEQ);
if (Count > 100)
ReleaseBuffer((void *)Q_REM((void *)&HOSTSESS->HOSTTRACEQ));
}
}
HOSTSESS++;
}
}
2022-11-14 14:02:28 +00:00
VOID SendSmartID(struct PORTCONTROL * PORT)
{
struct _MESSAGE * ID = IDMSG;
struct _MESSAGE * Buffer;
PORT->SmartIDNeeded = 0;
Buffer = GetBuff();
if (Buffer)
{
memcpy(Buffer, ID, ID->LENGTH);
Buffer->PORT = PORT->PORTNUMBER;
// IF PORT HAS A CALLSIGN DEFINED, SEND THAT INSTEAD
if (PORT->PORTCALL[0] > 0x40)
{
memcpy(Buffer->ORIGIN, PORT->PORTCALL, 7);
Buffer->ORIGIN[6] |= 1; // SET END OF CALL BIT
}
// If Pactor Style add to UI_Q
if (PORT->PROTOCOL == 10 && PORT->TNC && PORT->TNC->Hardware != H_KISSHF && PORT->UICAPABLE)
{
EXTPORTDATA * EXTPORT = (EXTPORTDATA *) PORT;
C_Q_ADD(&EXTPORT->UI_Q, Buffer);
return;
}
PUT_ON_PORT_Q(PORT, Buffer);
}
}
2022-08-28 09:35:46 +01:00
VOID SENDIDMSG()
{
struct PORTCONTROL * PORT = PORTTABLE;
struct _MESSAGE * ID = IDMSG;
struct _MESSAGE * Buffer;
while (PORT)
{
if (PORT->PROTOCOL < 10) // Not Pactor-style
{
Buffer = GetBuff();
if (Buffer)
{
memcpy(Buffer, ID, ID->LENGTH);
Buffer->PORT = PORT->PORTNUMBER;
// IF PORT HAS A CALLSIGN DEFINED, SEND THAT INSTEAD
if (PORT->PORTCALL[0] > 0x40)
{
memcpy(Buffer->ORIGIN, PORT->PORTCALL, 7);
Buffer->ORIGIN[6] |= 1; // SET END OF CALL BIT
}
C_Q_ADD(&IDMSG_Q, Buffer);
}
}
PORT = PORT->PORTPOINTER;
}
}
VOID SENDBTMSG()
{
struct PORTCONTROL * PORT = PORTTABLE;
struct _MESSAGE * Buffer;
char * ptr1, * ptr2;
while (PORT)
{
if (PORT->PROTOCOL >= 10 || PORT->PORTUNPROTO == 0) // Pactor-style or no UNPROTO ADDR?
{
PORT = PORT->PORTPOINTER;
continue;
}
Buffer = GetBuff();
if (Buffer)
{
memcpy(Buffer->DEST, PORT->PORTUNPROTO, 7);
2023-10-10 22:07:04 +01:00
Buffer->DEST[6] |= 0xC0; // Set Command bits
2022-08-28 09:35:46 +01:00
// Send from BBSCALL unless PORTBCALL defined
if (PORT->PORTBCALL[0] > 32)
memcpy(Buffer->ORIGIN, PORT->PORTBCALL, 7);
else if (APPLCALLTABLE->APPLCALL[0] > 32)
memcpy(Buffer->ORIGIN, APPLCALLTABLE->APPLCALL, 7);
else
memcpy(Buffer->ORIGIN, MYCALL, 7);
ptr1 = &PORT->PORTUNPROTO[7]; // First Digi
ptr2 = &Buffer->CTL; // Digi field in buffer
// Copy any digis
while (*(ptr1))
{
memcpy(ptr2, ptr1, 7);
ptr1 += 7;
ptr2 += 7;
}
*(ptr2 - 1) |= 1; // Set End of Address
*(ptr2++) = UI;
memcpy(ptr2, &BTHDDR.PID, BTHDDR.LENGTH);
ptr2 += BTHDDR.LENGTH;
Buffer->LENGTH = (int)(ptr2 - (char *)Buffer);
Buffer->PORT = PORT->PORTNUMBER;
C_Q_ADD(&IDMSG_Q, Buffer);
}
PORT = PORT->PORTPOINTER;
}
}
VOID SENDUIMESSAGE(struct DATAMESSAGE * Msg)
{
struct PORTCONTROL * PORT = PORTTABLE;
struct _MESSAGE * Buffer;
char * ptr1, * ptr2;
Msg->LENGTH -= MSGHDDRLEN; // Remove Header
while (PORT)
{
if ((PORT->PROTOCOL == 10 && PORT->UICAPABLE == 0) || PORT->PORTUNPROTO == 0) // Pactor-style or no UNPROTO ADDR?
{
PORT = PORT->PORTPOINTER;
continue;
}
Buffer = GetBuff();
if (Buffer)
{
memcpy(Buffer->DEST, PORT->PORTUNPROTO, 7);
Buffer->DEST[6] |= 0xC0; // Set Command bits
// Send from BBSCALL unless PORTBCALL defined
if (PORT->PORTBCALL[0] > 32)
memcpy(Buffer->ORIGIN, PORT->PORTBCALL, 7);
else if (APPLCALLTABLE->APPLCALL[0] > 32)
memcpy(Buffer->ORIGIN, APPLCALLTABLE->APPLCALL, 7);
else
memcpy(Buffer->ORIGIN, MYCALL, 7);
ptr1 = &PORT->PORTUNPROTO[7]; // First Digi
ptr2 = &Buffer->CTL; // Digi field in buffer
// Copy any digis
while (*(ptr1))
{
memcpy(ptr2, ptr1, 7);
ptr1 += 7;
ptr2 += 7;
}
*(ptr2 - 1) |= 1; // Set End of Address
*(ptr2++) = UI;
memcpy(ptr2, &Msg->PID, Msg->LENGTH);
ptr2 += Msg->LENGTH;
Buffer->LENGTH = (int)(ptr2 - (char *)Buffer);
Buffer->PORT = PORT->PORTNUMBER;
if (PORT->PROTOCOL == 10)
{
EXTPORTDATA * EXTPORT = (EXTPORTDATA *) PORT;
C_Q_ADD(&EXTPORT->UI_Q, Buffer);
}
else
C_Q_ADD(&IDMSG_Q, Buffer);
}
PORT = PORT->PORTPOINTER;
}
}
Dll VOID APIENTRY Send_AX(UCHAR * Block, DWORD Len, UCHAR Port)
{
// Block included the 7/11 byte header, Len does not
struct PORTCONTROL * PORT;
PMESSAGE Copy;
if (Len > 360 - 15)
return;
if (QCOUNT < 50)
return; // Running low
PORT = GetPortTableEntryFromPortNum(Port);
if (PORT == 0)
return;
Copy = GetBuff();
if (Copy == 0)
return;
memcpy(&Copy->DEST[0], &Block[MSGHDDRLEN], Len);
Copy->LENGTH = (USHORT)Len + MSGHDDRLEN;
if (PORT->PROTOCOL == 10 && PORT->TNC && PORT->TNC->Hardware != H_KISSHF)
{
// Pactor Style. Probably will only be used for Tracker uneless we do APRS over V4 or WINMOR
EXTPORTDATA * EXTPORT = (EXTPORTDATA *) PORT;
C_Q_ADD(&EXTPORT->UI_Q, Copy);
return;
}
Copy->PORT = Port;
PUT_ON_PORT_Q(PORT, Copy);
}
TRANSPORTENTRY * SetupSessionFromHost(PBPQVECSTRUC HOST, UINT ApplMask)
{
// Create a Transport (L4) session linked to an incoming HOST (API) Session
TRANSPORTENTRY * NewSess = L4TABLE;
int Index = 0;
while (Index < MAXCIRCUITS)
{
if (NewSess->L4USER[0] == 0)
{
// Got One
UCHAR * ourcall = &MYCALL[0];
// IF APPL PORT USE APPL CALL, ELSE NODE CALL
if (ApplMask)
{
// Circuit for APPL - look for an APPLCALL
APPLCALLS * APPL = APPLCALLTABLE;
while ((ApplMask & 1) == 0)
{
ApplMask >>= 1;
APPL++;
}
if (APPL->APPLCALL[0] > 0x40) // We have an applcall
ourcall = &APPL->APPLCALL[0];
}
memcpy(NewSess->L4USER, ourcall, 7);
memcpy(NewSess->L4MYCALL, ourcall, 7);
NewSess->CIRCUITINDEX = Index; //OUR INDEX
NewSess->CIRCUITID = NEXTID;
NEXTID++;
if (NEXTID == 0)
NEXTID++; // Keep Non-Zero
NewSess->L4TARGET.HOST = HOST;
NewSess->L4STATE = 5;
NewSess->SESSIONT1 = L4T1;
NewSess->L4WINDOW = (UCHAR)L4DEFAULTWINDOW;
NewSess->SESSPACLEN = PACLEN; // Default;
return NewSess;
}
Index++;
NewSess++;
}
// Table Full
return NULL;
}