Updates to support opening and closing a session.

This commit is contained in:
Stephen Heumann 2017-03-19 17:23:42 -05:00
parent b5c3a29f37
commit 0b0a422c33
6 changed files with 95 additions and 47 deletions

View File

@ -15,7 +15,6 @@ void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec);
void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec);
void DoSPCommand(Session *sess, ASPCommandRec *commandRec);
void DoSPWrite(Session *sess, ASPWriteRec *commandRec);
void CompleteCommand(Session *sess);
Session sessionTbl[MAX_SESSIONS];
@ -59,12 +58,12 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
// TODO properly handle all cases of getting a command while
// one is in progress
if (commandRec->command != aspCloseSessionCommand) {
if (sess->commandStatus != noCommand) {
if (sess->commandPending) {
commandRec->result = aspSessNumErr;
CompleteCommand(sess);
return;
}
sess->commandStatus = commandPending;
sess->commandPending = TRUE;
}
switch (commandRec->command) {
@ -85,19 +84,19 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
break;
}
if (commandRec->async & AT_ASYNC) {
if (sess->commandStatus == commandDone) {
CompleteCommand(sess);
} else {
commandRec->result = aspBusyErr; // indicate call in process
}
if ((commandRec->async & AT_ASYNC) && sess->commandPending) {
commandRec->result = aspBusyErr; // indicate call in process
return;
}
// if we're here, the call is synchronous -- we must complete it
while (sess->commandStatus != commandDone) {
PollForData(sess);
if (commandRec->command == aspCloseSessionCommand) {
FinishASPCommand(sess);
} else {
while (sess->commandPending) {
PollForData(sess);
}
}
}
@ -114,11 +113,27 @@ void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec) {
}
void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec) {
// TODO
sess->request.flags = DSI_REQUEST;
sess->request.command = DSIOpenSession;
sess->request.requestID = htons(sess->nextRequestID++);
sess->request.writeOffset = 0;
sess->request.totalDataLength = 0;
sess->replyBuf = NULL;
sess->replyBufLen = 0;
SendDSIMessage(sess, &sess->request, NULL);
}
void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec) {
// TODO
sess->request.flags = DSI_REQUEST;
sess->request.command = DSICloseSession;
sess->request.requestID = htons(sess->nextRequestID++);
sess->request.writeOffset = 0;
sess->request.totalDataLength = 0;
sess->replyBuf = NULL;
sess->replyBufLen = 0;
SendDSIMessage(sess, &sess->request, NULL);
}
void DoSPCommand(Session *sess, ASPCommandRec *commandRec) {
@ -146,11 +161,10 @@ void FinishASPCommand(Session *sess) {
((ASPGetStatusRec*)(sess->spCommandRec))->dataLength = dataLength;
break;
case aspOpenSessionCommand:
// TODO set session ref num
((ASPOpenSessionRec*)(sess->spCommandRec))->refNum =
(sess - &sessionTbl[0]) + SESSION_NUM_START;
break;
case aspCloseSessionCommand:
((ASPCloseSessionRec*)(sess->spCommandRec))->refNum =
(sess - &sessionTbl[0]) + SESSION_NUM_START;
break;
case aspCommandCommand:
((ASPCommandRec*)(sess->spCommandRec))->cmdResult =
@ -175,5 +189,11 @@ void CompleteCommand(Session *sess) {
// TODO call completion routine
memset(sess, 0, sizeof(*sess));
if (sess->spCommandRec->command == aspGetStatusCommand
|| sess->spCommandRec->command == aspCloseSessionCommand)
{
memset(sess, 0, sizeof(*sess));
} else {
sess->commandPending = FALSE;
}
}

View File

@ -14,7 +14,8 @@
extern Session sessionTbl[MAX_SESSIONS];
void FinishASPCommand(Session *sess);
void DispatchASPCommand(SPCommandRec *commandRec);
void FinishASPCommand(Session *sess);
void CompleteCommand(Session *sess);
#endif

14
dsi.c
View File

@ -33,17 +33,14 @@ static DSIRequestHeader attentionReplyRec = {
void FlagFatalError(Session *sess, Word errorCode) {
sess->dsiStatus = error;
if (errorCode) {
if (sess->commandStatus == commandPending) {
if (sess->commandPending) {
sess->spCommandRec->result = errorCode;
}
} else {
// TODO deduce error code from Marinetti errors
}
// TODO close TCP connection, anything else?
// call completion routing if needed
sess->commandStatus = commandDone;
CompleteCommand(sess);
}
@ -94,7 +91,7 @@ top:
if (sess->reply.totalDataLength != 0) {
dataLength = ntohl(sess->reply.totalDataLength);
if (sess->commandStatus == commandPending
if (sess->commandPending
&& sess->reply.flags == DSI_REPLY
&& sess->reply.requestID == sess->request.requestID
&& sess->reply.command == sess->request.command)
@ -135,7 +132,7 @@ top:
// If we're here, we got a full message.
// Handle a command that is now done, if any.
if (sess->commandStatus == commandPending
if (sess->commandPending
&& sess->reply.flags == DSI_REPLY
&& sess->reply.requestID == sess->request.requestID
&& sess->reply.command == sess->request.command)
@ -154,7 +151,6 @@ top:
// TODO correct logic for all cases
FinishASPCommand(sess);
sess->commandStatus = commandDone;
return;
}
//Handle a request from the server

View File

@ -6,7 +6,9 @@
#include "aspinterface.h"
#include "atipmapping.h"
ASPGetStatusRec commandRec;
ASPGetStatusRec getStatusRec;
ASPOpenSessionRec openSessionRec;
ASPCloseSessionRec closeSessionRec;
Byte replyBuffer[1024];
int main(int argc, char **argv)
@ -37,30 +39,56 @@ int main(int argc, char **argv)
atipMapping.port = 548;
// Do the call
commandRec.async = AT_SYNC;
commandRec.command = aspGetStatusCommand;
commandRec.completionPtr = 0;
commandRec.slsNet = atipMapping.networkNumber;
commandRec.slsNode = atipMapping.node;
commandRec.slsSocket = atipMapping.socket;
commandRec.bufferLength = sizeof(replyBuffer);
commandRec.bufferAddr = (LongWord)&replyBuffer;
getStatusRec.async = AT_SYNC;
getStatusRec.command = aspGetStatusCommand;
getStatusRec.completionPtr = 0;
getStatusRec.slsNet = atipMapping.networkNumber;
getStatusRec.slsNode = atipMapping.node;
getStatusRec.slsSocket = atipMapping.socket;
getStatusRec.bufferLength = sizeof(replyBuffer);
getStatusRec.bufferAddr = (LongWord)&replyBuffer;
DispatchASPCommand((SPCommandRec *)&commandRec);
DispatchASPCommand((SPCommandRec *)&getStatusRec);
for (i=0; i<commandRec.dataLength;i++) {
#if 0
for (i=0; i<getStatusRec.dataLength;i++) {
printf("%02x ", replyBuffer[i]);
if ((i+1)%16 == 0) printf("\n");
}
printf("\n");
for (i=0; i<commandRec.dataLength;i++) {
#endif
for (i=0; i<getStatusRec.dataLength;i++) {
if (replyBuffer[i] >= ' ' && replyBuffer[i] <= 126)
printf("%c", replyBuffer[i]);
else
printf(" ");
}
printf("\n");
openSessionRec.async = AT_SYNC;
openSessionRec.command = aspOpenSessionCommand;
openSessionRec.completionPtr = 0;
openSessionRec.slsNet = atipMapping.networkNumber;
openSessionRec.slsNode = atipMapping.node;
openSessionRec.slsSocket = atipMapping.socket;
openSessionRec.attnRtnAddr = NULL; // not used for now
printf("Opening...\n");
DispatchASPCommand((SPCommandRec *)&openSessionRec);
printf("refnum = %i\n", openSessionRec.refNum);
printf("result code = %04x\n", openSessionRec.result);
if (openSessionRec.result)
goto error;
closeSessionRec.async = AT_SYNC;
closeSessionRec.command = aspCloseSessionCommand;
closeSessionRec.completionPtr = 0;
closeSessionRec.refNum = openSessionRec.refNum;
printf("Closing...\n");
DispatchASPCommand((SPCommandRec *)&closeSessionRec);
printf("result code = %04x\n", closeSessionRec.result);
error:
if (startedTCP)

View File

@ -21,12 +21,6 @@ typedef enum DSISessionStatus {
error
} DSISessionStatus;
typedef enum CommandStatus {
noCommand = 0,
commandPending,
commandDone
} CommandStatus;
typedef struct Session {
/* Marinetti TCP connection status */
Word ipid;
@ -35,7 +29,7 @@ typedef struct Session {
DSISessionStatus dsiStatus;
/* Information on command currently being processed, if any. */
CommandStatus commandStatus;
Boolean commandPending;
SPCommandRec *spCommandRec;
DSIRequestHeader request;

View File

@ -70,7 +70,16 @@ BOOLEAN StartTCPConnection(Session *sess) {
}
void EndTCPConnection(Session *sess) {
srBuff mySRBuff;
if (sess->tcpLoggedIn) {
do {
TCPIPPoll();
} while (TCPIPStatusTCP(sess->ipid, &mySRBuff) == tcperrOK
&& !toolerror()
&& mySRBuff.srState == TCPSESTABLISHED
&& mySRBuff.srSndQueued > 0);
TCPIPAbortTCP(sess->ipid);
TCPIPLogout(sess->ipid);
sess->tcpLoggedIn = FALSE;