diff --git a/AGWAPI.c b/AGWAPI.c index dcf3494..126a72a 100644 --- a/AGWAPI.c +++ b/AGWAPI.c @@ -36,7 +36,8 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses struct AGWHeader { - unsigned int Port; + uint8_t Port; + uint8_t filler1[3]; unsigned char DataKind; unsigned char filler2; unsigned char PID; @@ -128,7 +129,7 @@ int DataSocket_Write(struct AGWSocketConnectionInfo * sockptr, SOCKET sock); int AGWGetSessionKey(char * key, struct AGWSocketConnectionInfo * sockptr); int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr); int SendDataToAppl(int Stream, byte * Buffer, int Length); -int InternalAGWDecodeFrame(char * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int doNodes); +int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int doNodes); int AGWDataSocket_Disconnect( struct AGWSocketConnectionInfo * sockptr); int SendRawPacket(struct AGWSocketConnectionInfo * sockptr, char *txmsg, int Length); int ShowApps(); @@ -720,7 +721,7 @@ int AGWDoMonitorData() RawLen = monbuff->LENGTH; - if (RawLen < 7 || RawLen > 350) + if (RawLen < MSGHDDRLEN || RawLen > 350) { ReleaseBuffer(monbuff); FreeSemaphore(&Semaphore); @@ -734,12 +735,16 @@ int AGWDoMonitorData() ReleaseBuffer(monbuff); FreeSemaphore(&Semaphore); + + // Set monbuff to point to the copy + + monbuff = (MESSAGE *)Buffer; //' 4 byte chain //' 1 byte port - top bit = transmit //' 2 byte length (LO-HI) - Port = Buffer[4]; + Port = monbuff->PORT; if (Port > 127) { @@ -751,6 +756,12 @@ int AGWDoMonitorData() RXFlag = TRUE; } + if (Port == 0) + { + Debugprintf("AGWMON Port number is zero"); + return 0; + } + // Can now have different mon flags per connection, so need to run decode for each socket for (n = 1; n<= CurrentSockets; n++) @@ -759,7 +770,7 @@ int AGWDoMonitorData() if (sockptr->SocketActive && sockptr->MonFlag && (RXFlag || LoopMonFlag)) { - Length = InternalAGWDecodeFrame(Buffer, AGWBuffer, Stamp, &Frametype, sockptr->useLocalTime, sockptr->doNodes); + Length = InternalAGWDecodeFrame(monbuff, AGWBuffer, Stamp, &Frametype, sockptr->useLocalTime, sockptr->doNodes); if (Length > 0) { @@ -803,7 +814,7 @@ int AGWDoMonitorData() } } - RawLen = RawLen - 6; + RawLen = RawLen - (MSGHDDRLEN - 1); // One more for KISS control if (RXFlag || Loopflag) // Send transmitted frames if requested { @@ -811,8 +822,12 @@ int AGWDoMonitorData() // // Send raw data to any sockets that have requested Raw frames // - - Buffer[6]=0; + + // Format is ax.25 packet prceeded by a KISS command byte 00 for channel 1 0x10 for channel 2 etc + // As this is an application API I think all should go as Port 1 + + + Buffer[MSGHDDRLEN - 1] = 0; // Just in case big-endian AGWTXHeader.Port = Port - 1; // AGW Ports start from 0 AGWTXHeader.DataKind = 'K'; @@ -824,14 +839,12 @@ int AGWDoMonitorData() sockptr=&Sockets[n]; if (sockptr->SocketActive && sockptr->RawFlag) - SendRawPacket(sockptr, &Buffer[6], RawLen); + SendRawPacket(sockptr, &Buffer[MSGHDDRLEN - 1], RawLen); } } } - - return 0; - + return 0; } int DeleteConnection(struct BPQConnectionInfo * Con) @@ -1128,6 +1141,7 @@ int AGWDataSocket_Read(struct AGWSocketConnectionInfo * sockptr, SOCKET sock) int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) { int AGWVersion[2]={2003,999}; + byte AGWPortCaps[12] = { 0, 255, 30, 10, 63, 10, 4, 0, 1, 0, 0, 0 }; char AGWRegReply[1]; struct BPQConnectionInfo * Connection; int Stream; @@ -1195,7 +1209,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) // Need to convert port index (used by AGW) to port number - conport=GetPortNumber(VisiblePortToRealPort[key[0]-48]); + conport=GetPortNumber(VisiblePortToRealPort[key[0]-49] + 1); n = sprintf(ConnectMsg,"C %d %s",conport,ToCall); @@ -1293,9 +1307,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) // Version memset(&AGWTXHeader,0,36); - AGWTXHeader.DataKind = 'R'; - AGWTXHeader.DataLength = 8; // Length SendtoSocket(sockptr->socket, (char *)&AGWVersion[0]); @@ -1309,15 +1321,27 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) memset(&AGWTXHeader,0,36); - AGWTXHeader.DataKind = 'G'; - AGWTXHeader.DataLength =(int)strlen(AGWPorts)+1; // Length SendtoSocket(sockptr->socket, AGWPorts); return 0; + + case 'g': + + // Port capabilities. Currently hard-coded. + + AGWTXHeader.Port = sockptr->AGWRXHeader.Port; + AGWTXHeader.DataKind = 'g'; + AGWTXHeader.DataLength = 12; + + SendtoSocket(sockptr->socket, (char *)&AGWPortCaps[0]); + + return 0; + + case 'k': @@ -1416,6 +1440,8 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) AGWTXHeader.DataKind = 'X'; + memcpy(&AGWTXHeader.callfrom, RegCall, 10); + AGWTXHeader.DataLength = 1; // Length AGWRegReply[0] = 1; diff --git a/AGWMoncode.c b/AGWMoncode.c index 7427804..2c26191 100644 --- a/AGWMoncode.c +++ b/AGWMoncode.c @@ -49,9 +49,14 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses #define DM 0x0F #define UA 0x63 #define FRMR 0x87 +#define XID 0xAF +#define TEST 0xE3 #define RR 1 #define RNR 5 #define REJ 9 +#define SREJ 0x0D +#define SABME 0x6F + #define PFBIT 0x10 // POLL/FINAL BIT IN CONTROL BYTE @@ -261,6 +266,18 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra strcpy(SUP, "FRMR"); FRMRFLAG = 1; break; + + case XID: + + strcpy(SUP, "XID"); + XIDFLAG = 1; + break; + + case TEST: + + strcpy(SUP, "TEST"); + TESTFLAG = 1; + break; } Output += sprintf((char *)Output, "<%s%s%s>", SUP, CRCHAR, PFCHAR); @@ -270,7 +287,7 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra // Super int NR = (CTL >> 5) & 7; - char SUP[4] = "??"; + char SUP[5] = "??"; switch (CTL & 0x0F) { @@ -288,6 +305,13 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra strcpy(SUP, "REJ"); break; + + + case SREJ: + + strcpy(SUP, "SREJ"); + break; + } Output += sprintf((char *)Output, "<%s%s%s R%d>", SUP, CRCHAR, PFCHAR, NR); @@ -300,6 +324,72 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra if (FRMRFLAG) Output += sprintf((char *)Output, "%02X %02X %02X", ADJBUFFER->PID, ADJBUFFER->L2DATA[0], ADJBUFFER->L2DATA[1]); + if (XIDFLAG) + { + // Decode and display XID + + UCHAR * ptr = &ADJBUFFER->PID; + + if (*ptr++ == 0x82 && *ptr++ == 0x80) + { + int Type; + int Len; + unsigned int value; + int xidlen = *(ptr++) << 8; + xidlen += *ptr++; + + // XID is set of Type, Len, Value n-tuples + +// G8BPQ-2>G8BPQ:(XID cmd, p=1) Half-Duplex SREJ modulo-128 I-Field-Length-Rx=256 Window-Size-Rx=32 Ack-Timer=3000 Retries=10 + + + while (xidlen > 0) + { + Type = *ptr++; + Len = *ptr++; + + value = 0; + xidlen -= (Len + 2); + + while (Len--) + { + value <<=8; + value += *ptr++; + } + switch(Type) + { + case 2: //Bin fields + case 3: + + Output += sprintf((char *)Output, " %d=%x", Type, value); + break; + + case 6: //RX Size + + Output += sprintf((char *)Output, " RX Paclen=%d", value / 8); + break; + + case 8: //RX Window + + Output += sprintf((char *)Output, " RX Window=%d", value); + break; + + case 16: + + Output += sprintf((char *)Output, " Can Compress"); + break; + + case 17: + + Output += sprintf((char *)Output, " Compress ok"); + break; + } + } + } + } + + + if (Info) { // We have an info frame diff --git a/ARDOP.c b/ARDOP.c index a46fe3e..ade0ecf 100644 --- a/ARDOP.c +++ b/ARDOP.c @@ -888,6 +888,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) { if (TNC->SessionTimeLimit && STREAM->ConnectTime && time(NULL) > (TNC->SessionTimeLimit + STREAM->ConnectTime)) { + Debugprintf("ARDOP closing session on SessionTimelimit"); ARDOPSendCommand(TNC, "DISCONNECT", TRUE); STREAM->ReportDISC = 1; STREAM->AttachTime = 0; @@ -900,6 +901,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) { if (STREAM->AttachTime && TNC->AttachTimeLimit && time(NULL) > (TNC->AttachTimeLimit + STREAM->AttachTime)) { + Debugprintf("ARDOP closing session on AttachTimelimit"); STREAM->ReportDISC = 1; STREAM->AttachTime = 0; } @@ -2059,21 +2061,12 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry) strcat(TempScript, "ARQTIMEOUT 90\r"); // strcat(TempScript, "ROBUST False\r"); - strcat(TempScript, TNC->InitScript); - - free(TNC->InitScript); - TNC->InitScript = TempScript; - - // Set MYCALL - -// strcat(TNC->InitScript,"FECRCV True\r"); -// strcat(TNC->InitScript,"AUTOBREAK True\r"); + // Make MYAUX and MYCALL overridable + sprintf(Msg, "MYCALL %s\r", TNC->NodeCall); - strcat(TNC->InitScript, Msg); -// strcat(TNC->InitScript,"PROCESSID\r"); -// strcat(TNC->InitScript,"CODEC TRUE\r"); -// strcat(TNC->InitScript,"LISTEN TRUE\r"); + strcat(TempScript, Msg); + for (i = 0; i < 32; i++) { @@ -2097,9 +2090,25 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry) if (strlen(Aux) > 8) { Aux[strlen(Aux) - 1] = '\r'; - strcat(TNC->InitScript, Aux); + strcat(TempScript, Aux); } + + strcat(TempScript, TNC->InitScript); + + free(TNC->InitScript); + TNC->InitScript = TempScript; + + + +// strcat(TNC->InitScript,"FECRCV True\r"); +// strcat(TNC->InitScript,"AUTOBREAK True\r"); +// strcat(TNC->InitScript,"PROCESSID\r"); +// strcat(TNC->InitScript,"CODEC TRUE\r"); +// strcat(TNC->InitScript,"LISTEN TRUE\r"); + + + strcpy(TNC->CurrentMYC, TNC->NodeCall); if (TNC->WL2K == NULL) @@ -3141,6 +3150,7 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen) // Incoming Connect TNC->SessionTimeLimit = TNC->DefaultSessionTimeLimit; // Reset Limit + STREAM->AttachTime = time(NULL); // Stop other ports in same group diff --git a/BBSHTMLConfig.c b/BBSHTMLConfig.c index 6207298..027c786 100644 --- a/BBSHTMLConfig.c +++ b/BBSHTMLConfig.c @@ -117,6 +117,7 @@ struct UserInfo * FindBBS(char * Name); void ReleaseWebMailStruct(WebMailInfo * WebMail); VOID TidyWelcomeMsg(char ** pPrompt); int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param, char * Token); +void UndoTransparency(char * input); char UNC[] = ""; char CHKD[] = "checked=checked "; @@ -186,7 +187,7 @@ char RefreshMainPage[] = "
" char StatusPage [] = "