Detect when Marinetti has disconnected, and close all sessions at that time.

Also, detect and give an error when invalid session numbers are used.
This commit is contained in:
Stephen Heumann 2017-04-23 19:38:50 -05:00
parent 13e4f4d72f
commit a38e2f716a
4 changed files with 65 additions and 13 deletions

View File

@ -7,6 +7,7 @@
#include <desk.h>
#include <orca.h>
#include <gsos.h>
#include <scheduler.h>
#include <string.h>
#include "installcmds.h"
#include "aspinterface.h"
@ -17,6 +18,8 @@ LongWord version = 0x01006001; /* in rVersion format */
const char versionMessageString[] = "\pSTH~AFPBridge~Version~";
const char requestNameString[] = "\pTCP/IP~STH~AFPBridge~";
typedef struct VersionMessageRec {
Word blockLen;
char nameString[23];
@ -28,6 +31,7 @@ extern void resetRoutine(void);
void pollTask(void);
void notificationProc(void);
static pascal Word requestProc(Word reqCode, Long dataIn, Long dataOut);
static struct RunQRec {
Long reserved1;
@ -51,6 +55,8 @@ static struct NotificationProcRec {
#define SoftResetPtr ((LongWord *)0xE11010)
extern LongWord oldSoftReset;
#define busyFlagPtr ((Byte*)0xE100FF)
#define JML 0x5C
void setUnloadFlag(void) {
@ -126,6 +132,8 @@ int main(void) {
addNotifyProcRec.procPointer = (ProcPtr)&notificationProcRec;
AddNotifyProcGS(&addNotifyProcRec);
AcceptRequests(requestNameString, userid(), &requestProc);
oldSoftReset = *SoftResetPtr;
*SoftResetPtr = ((LongWord)&resetRoutine << 8) | JML;
@ -167,9 +175,46 @@ void notificationProc(void) {
IncBusyFlag();
stateReg = ForceRomIn();
CloseAllSessions(0);
CloseAllSessions(0, TRUE);
RestoreStateReg(stateReg);
DecBusyFlag();
}
#pragma databank 0
#pragma databank 1
void handleDisconnect(void) {
Word stateReg;
IncBusyFlag();
stateReg = ForceRomIn();
CloseAllSessions(aspAttenClosed, FALSE);
RestoreStateReg(stateReg);
DecBusyFlag();
}
#pragma databank 0
/*
* Request procedure called by Marinetti with its notifications.
* If the network has gone down, we immediately close all sessions.
* We check the busy flag to avoid doing this within our code
* (which runs with the busy flag set), although I don't think that
* can really happen with current versions of Marinetti.
*/
#pragma databank 1
#pragma toolparms 1
static pascal Word requestProc(Word reqCode, Long dataIn, Long dataOut) {
if (reqCode == TCPIPSaysNetworkDown) {
if (*busyFlagPtr) {
SchAddTask(&handleDisconnect);
} else {
handleDisconnect();
}
}
return 0;
}
#pragma toolparms 0
#pragma databank 0

View File

@ -97,7 +97,7 @@ top:
for (i = 0; i < MAX_SESSIONS; i++) {
if (sessionTbl[i].dsiStatus == needsReset)
EndASPSession(&sessionTbl[i], 0);
EndASPSession(&sessionTbl[i], 0, TRUE);
}
for (i = 0; i < MAX_SESSIONS; i++) {
if (sessionTbl[i].dsiStatus == unused)
@ -150,6 +150,11 @@ top:
sess = &sessionTbl[commandRec->refNum - SESSION_NUM_START];
if (sess->dsiStatus == unused) {
CompleteASPCommand(commandRec, aspRefErr);
goto ret;
}
if (sess->commandPending) {
if (commandRec->command != aspCloseSessionCommand) {
CompleteASPCommand(commandRec, aspSessNumErr);
@ -419,7 +424,7 @@ void FlagFatalError(Session *sess, Word errorCode) {
CompleteCurrentASPCommand(sess, errorCode);
}
EndASPSession(sess, aspAttenTimeout);
EndASPSession(sess, aspAttenTimeout, TRUE);
}
@ -491,7 +496,7 @@ void CompleteCurrentASPCommand(Session *sess, Word result) {
if (sess->spCommandRec->command == aspGetStatusCommand
|| sess->spCommandRec->command == aspCloseSessionCommand)
{
EndASPSession(sess, 0);
EndASPSession(sess, 0, TRUE);
} else {
sess->commandPending = FALSE;
if (sess->dsiStatus != error) {
@ -517,12 +522,13 @@ static void CompleteASPCommand(SPCommandRec *commandRec, Word result) {
}
void EndASPSession(Session *sess, Byte attentionCode) {
void EndASPSession(Session *sess, Byte attentionCode, Boolean doLogout) {
if (attentionCode != 0) {
CallAttentionRoutine(sess, attentionCode, 0);
}
EndTCPConnection(sess);
if (doLogout)
EndTCPConnection(sess);
memset(sess, 0, sizeof(*sess));
}
@ -562,22 +568,23 @@ void PollAllSessions(void) {
break;
case needsReset:
EndASPSession(&sessionTbl[i], 0);
EndASPSession(&sessionTbl[i], 0, TRUE);
break;
}
}
}
/* Close all sessions -- used when we're shutting down */
void CloseAllSessions(Byte attentionCode) {
void CloseAllSessions(Byte attentionCode, Boolean doLogout) {
unsigned int i;
Session *sess;
for (i = 0; i < MAX_SESSIONS; i++) {
sess = &sessionTbl[i];
if (sess->dsiStatus != unused) {
DoSPCloseSession(sess);
EndASPSession(sess, attentionCode);
if (doLogout)
DoSPCloseSession(sess);
EndASPSession(sess, attentionCode, doLogout);
}
}
}

View File

@ -18,10 +18,10 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec);
void CompleteCurrentASPCommand(Session *sess, Word result);
void FinishASPCommand(Session *sess);
void FlagFatalError(Session *sess, Word errorCode);
void EndASPSession(Session *sess, Byte attentionCode);
void EndASPSession(Session *sess, Byte attentionCode, Boolean doLogout);
void CallAttentionRoutine(Session *sess, Byte attenType, Word atten);
void PollAllSessions(void);
void CloseAllSessions(Byte attentionCode);
void CloseAllSessions(Byte attentionCode, Boolean doLogout);
void ResetAllSessions(void);
#endif

2
dsi.c
View File

@ -158,7 +158,7 @@ top:
SendDSIMessage(sess, &attentionReplyRec, NULL, NULL);
CallAttentionRoutine(sess, aspAttenNormal, sess->attentionCode);
} else if (sess->reply.command == DSICloseSession) {
EndASPSession(sess, aspAttenClosed);
EndASPSession(sess, aspAttenClosed, TRUE);
return;
} else if (sess->reply.command == DSITickle) {
tickleRequestRec.requestID = htons(sess->nextRequestID++);