Implement support for DSIWrite, plus a few other cleanups.
This commit is contained in:
parent
275f3456ba
commit
ee83e402f8
106
aspinterface.c
106
aspinterface.c
|
@ -10,11 +10,14 @@
|
||||||
#include "endian.h"
|
#include "endian.h"
|
||||||
#include "readtcp.h"
|
#include "readtcp.h"
|
||||||
|
|
||||||
void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec);
|
static void CompleteCommand(Session *sess, Word result);
|
||||||
void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec);
|
static void EndSession(Session *sess, Boolean callAttnRoutine);
|
||||||
void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec);
|
|
||||||
void DoSPCommand(Session *sess, ASPCommandRec *commandRec);
|
static void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec);
|
||||||
void DoSPWrite(Session *sess, ASPWriteRec *commandRec);
|
static void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec);
|
||||||
|
static void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec);
|
||||||
|
static void DoSPCommand(Session *sess, ASPCommandRec *commandRec);
|
||||||
|
static void DoSPWrite(Session *sess, ASPWriteRec *commandRec);
|
||||||
|
|
||||||
|
|
||||||
Session sessionTbl[MAX_SESSIONS];
|
Session sessionTbl[MAX_SESSIONS];
|
||||||
|
@ -31,16 +34,14 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == MAX_SESSIONS) {
|
if (i == MAX_SESSIONS) {
|
||||||
commandRec->result = aspTooManySessions;
|
CompleteCommand(sess, aspTooManySessions);
|
||||||
CompleteCommand(sess);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sess = &sessionTbl[i];
|
sess = &sessionTbl[i];
|
||||||
sess->spCommandRec = commandRec;
|
sess->spCommandRec = commandRec;
|
||||||
|
|
||||||
if (!StartTCPConnection(sess)) {
|
if (!StartTCPConnection(sess)) {
|
||||||
// Error code was set in TCPIPConnect
|
FlagFatalError(sess, 0);
|
||||||
CompleteCommand(sess);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sess->dsiStatus = awaitingHeader;
|
sess->dsiStatus = awaitingHeader;
|
||||||
|
@ -59,8 +60,7 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
|
||||||
// one is in progress
|
// one is in progress
|
||||||
if (commandRec->command != aspCloseSessionCommand) {
|
if (commandRec->command != aspCloseSessionCommand) {
|
||||||
if (sess->commandPending) {
|
if (sess->commandPending) {
|
||||||
commandRec->result = aspSessNumErr;
|
CompleteCommand(sess, aspSessNumErr);
|
||||||
CompleteCommand(sess);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sess->commandPending = TRUE;
|
sess->commandPending = TRUE;
|
||||||
|
@ -100,7 +100,7 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec) {
|
static void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec) {
|
||||||
static const Word kFPGetSrvrInfo = 15;
|
static const Word kFPGetSrvrInfo = 15;
|
||||||
sess->request.flags = DSI_REQUEST;
|
sess->request.flags = DSI_REQUEST;
|
||||||
sess->request.command = DSIGetStatus;
|
sess->request.command = DSIGetStatus;
|
||||||
|
@ -110,10 +110,10 @@ void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec) {
|
||||||
sess->replyBuf = (void*)commandRec->bufferAddr;
|
sess->replyBuf = (void*)commandRec->bufferAddr;
|
||||||
sess->replyBufLen = commandRec->bufferLength;
|
sess->replyBufLen = commandRec->bufferLength;
|
||||||
|
|
||||||
SendDSIMessage(sess, &sess->request, &kFPGetSrvrInfo);
|
SendDSIMessage(sess, &sess->request, &kFPGetSrvrInfo, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec) {
|
static void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec) {
|
||||||
sess->request.flags = DSI_REQUEST;
|
sess->request.flags = DSI_REQUEST;
|
||||||
sess->request.command = DSIOpenSession;
|
sess->request.command = DSIOpenSession;
|
||||||
sess->request.requestID = htons(sess->nextRequestID++);
|
sess->request.requestID = htons(sess->nextRequestID++);
|
||||||
|
@ -122,10 +122,10 @@ void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec) {
|
||||||
sess->replyBuf = NULL;
|
sess->replyBuf = NULL;
|
||||||
sess->replyBufLen = 0;
|
sess->replyBufLen = 0;
|
||||||
|
|
||||||
SendDSIMessage(sess, &sess->request, NULL);
|
SendDSIMessage(sess, &sess->request, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec) {
|
static void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec) {
|
||||||
sess->request.flags = DSI_REQUEST;
|
sess->request.flags = DSI_REQUEST;
|
||||||
sess->request.command = DSICloseSession;
|
sess->request.command = DSICloseSession;
|
||||||
sess->request.requestID = htons(sess->nextRequestID++);
|
sess->request.requestID = htons(sess->nextRequestID++);
|
||||||
|
@ -134,10 +134,10 @@ void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec) {
|
||||||
sess->replyBuf = NULL;
|
sess->replyBuf = NULL;
|
||||||
sess->replyBufLen = 0;
|
sess->replyBufLen = 0;
|
||||||
|
|
||||||
SendDSIMessage(sess, &sess->request, NULL);
|
SendDSIMessage(sess, &sess->request, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSPCommand(Session *sess, ASPCommandRec *commandRec) {
|
static void DoSPCommand(Session *sess, ASPCommandRec *commandRec) {
|
||||||
sess->request.flags = DSI_REQUEST;
|
sess->request.flags = DSI_REQUEST;
|
||||||
sess->request.command = DSICommand;
|
sess->request.command = DSICommand;
|
||||||
sess->request.requestID = htons(sess->nextRequestID++);
|
sess->request.requestID = htons(sess->nextRequestID++);
|
||||||
|
@ -146,13 +146,39 @@ void DoSPCommand(Session *sess, ASPCommandRec *commandRec) {
|
||||||
sess->replyBuf = (void*)commandRec->replyBufferAddr;
|
sess->replyBuf = (void*)commandRec->replyBufferAddr;
|
||||||
sess->replyBufLen = commandRec->replyBufferLen;
|
sess->replyBufLen = commandRec->replyBufferLen;
|
||||||
|
|
||||||
SendDSIMessage(sess, &sess->request, (void*)commandRec->cmdBlkAddr);
|
SendDSIMessage(sess, &sess->request, (void*)commandRec->cmdBlkAddr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSPWrite(Session *sess, ASPWriteRec *commandRec) {
|
static void DoSPWrite(Session *sess, ASPWriteRec *commandRec) {
|
||||||
// TODO
|
sess->request.flags = DSI_REQUEST;
|
||||||
|
sess->request.command = DSIWrite;
|
||||||
|
sess->request.requestID = htons(sess->nextRequestID++);
|
||||||
|
sess->request.writeOffset = htonl(commandRec->cmdBlkLength);
|
||||||
|
sess->request.totalDataLength =
|
||||||
|
htonl(commandRec->cmdBlkLength + commandRec->writeDataLength);
|
||||||
|
sess->replyBuf = (void*)commandRec->replyBufferAddr;
|
||||||
|
sess->replyBufLen = commandRec->replyBufferLen;
|
||||||
|
|
||||||
|
SendDSIMessage(sess, &sess->request, (void*)commandRec->cmdBlkAddr,
|
||||||
|
(void*)commandRec->writeDataAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FlagFatalError(Session *sess, Word errorCode) {
|
||||||
|
sess->dsiStatus = error;
|
||||||
|
if (errorCode == 0) {
|
||||||
|
// TODO deduce better error code from Marinetti errors?
|
||||||
|
errorCode = aspNetworkErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sess->commandPending) {
|
||||||
|
CompleteCommand(sess, errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndSession(sess, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fill in any necessary data in the ASP command rec for a successful return
|
// Fill in any necessary data in the ASP command rec for a successful return
|
||||||
void FinishASPCommand(Session *sess) {
|
void FinishASPCommand(Session *sess) {
|
||||||
LongWord dataLength;
|
LongWord dataLength;
|
||||||
|
@ -181,30 +207,44 @@ void FinishASPCommand(Session *sess) {
|
||||||
((ASPCommandRec*)(sess->spCommandRec))->replyLength = dataLength;
|
((ASPCommandRec*)(sess->spCommandRec))->replyLength = dataLength;
|
||||||
break;
|
break;
|
||||||
case aspWriteCommand:
|
case aspWriteCommand:
|
||||||
// TODO
|
((ASPWriteRec*)(sess->spCommandRec))->cmdResult =
|
||||||
|
sess->reply.errorCode;
|
||||||
|
((ASPWriteRec*)(sess->spCommandRec))->replyLength = dataLength;
|
||||||
|
((ASPWriteRec*)(sess->spCommandRec))->writtenLength =
|
||||||
|
((ASPWriteRec*)(sess->spCommandRec))->writeDataLength;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
complete:
|
complete:
|
||||||
CompleteCommand(sess);
|
CompleteCommand(sess, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actions to complete a command, whether successful or not */
|
/* Actions to complete a command, whether successful or not */
|
||||||
void CompleteCommand(Session *sess) {
|
static void CompleteCommand(Session *sess, Word result) {
|
||||||
|
SPCommandRec *commandRec;
|
||||||
|
|
||||||
|
commandRec = sess->spCommandRec;
|
||||||
|
|
||||||
if (sess->spCommandRec->command == aspGetStatusCommand
|
if (sess->spCommandRec->command == aspGetStatusCommand
|
||||||
|| sess->spCommandRec->command == aspCloseSessionCommand)
|
|| sess->spCommandRec->command == aspCloseSessionCommand)
|
||||||
{
|
{
|
||||||
EndTCPConnection(sess);
|
EndSession(sess, FALSE);
|
||||||
}
|
|
||||||
|
|
||||||
// TODO call completion routine
|
|
||||||
|
|
||||||
if (sess->spCommandRec->command == aspGetStatusCommand
|
|
||||||
|| sess->spCommandRec->command == aspCloseSessionCommand)
|
|
||||||
{
|
|
||||||
memset(sess, 0, sizeof(*sess));
|
|
||||||
} else {
|
} else {
|
||||||
sess->commandPending = FALSE;
|
sess->commandPending = FALSE;
|
||||||
InitReadTCP(sess, DSI_HEADER_SIZE, &sess->reply);
|
InitReadTCP(sess, DSI_HEADER_SIZE, &sess->reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commandRec->result = result;
|
||||||
|
|
||||||
|
// TODO call completion routine
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void EndSession(Session *sess, Boolean callAttnRoutine) {
|
||||||
|
if (callAttnRoutine) {
|
||||||
|
// TODO call the attention routine to report end of session
|
||||||
|
}
|
||||||
|
|
||||||
|
EndTCPConnection(sess);
|
||||||
|
memset(sess, 0, sizeof(*sess));
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,6 @@ extern Session sessionTbl[MAX_SESSIONS];
|
||||||
|
|
||||||
void DispatchASPCommand(SPCommandRec *commandRec);
|
void DispatchASPCommand(SPCommandRec *commandRec);
|
||||||
void FinishASPCommand(Session *sess);
|
void FinishASPCommand(Session *sess);
|
||||||
void CompleteCommand(Session *sess);
|
void FlagFatalError(Session *sess, Word errorCode);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
45
dsi.c
45
dsi.c
|
@ -30,43 +30,40 @@ static DSIRequestHeader attentionReplyRec = {
|
||||||
0 /* reserved */
|
0 /* reserved */
|
||||||
};
|
};
|
||||||
|
|
||||||
void FlagFatalError(Session *sess, Word errorCode) {
|
|
||||||
sess->dsiStatus = error;
|
|
||||||
if (errorCode) {
|
|
||||||
if (sess->commandPending) {
|
|
||||||
sess->spCommandRec->result = errorCode;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO deduce error code from Marinetti errors
|
|
||||||
}
|
|
||||||
|
|
||||||
CompleteCommand(sess);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void SendDSIMessage(Session *sess, DSIRequestHeader *header, void *payload,
|
||||||
void SendDSIMessage(Session *sess, DSIRequestHeader *header, void *payload) {
|
void *extraPayload) {
|
||||||
Boolean hasData;
|
LongWord cmdLen;
|
||||||
|
LongWord extraLen;
|
||||||
hasData = header->totalDataLength != 0;
|
|
||||||
|
|
||||||
sess->tcperr = TCPIPWriteTCP(sess->ipid, (void*)header,
|
sess->tcperr = TCPIPWriteTCP(sess->ipid, (void*)header,
|
||||||
DSI_HEADER_SIZE,
|
DSI_HEADER_SIZE,
|
||||||
!hasData, FALSE);
|
!header->totalDataLength, FALSE);
|
||||||
sess->toolerr = toolerror();
|
sess->toolerr = toolerror();
|
||||||
if (sess->tcperr || sess->toolerr) {
|
if (sess->tcperr || sess->toolerr) {
|
||||||
FlagFatalError(sess, 0);
|
FlagFatalError(sess, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasData) {
|
if (header->writeOffset) {
|
||||||
sess->tcperr = TCPIPWriteTCP(sess->ipid, payload,
|
cmdLen = ntohl(header->writeOffset);
|
||||||
ntohl(header->totalDataLength),
|
extraLen = ntohl(header->totalDataLength) - cmdLen;
|
||||||
TRUE, FALSE);
|
} else {
|
||||||
|
cmdLen = ntohl(header->totalDataLength);
|
||||||
|
extraLen = 0;
|
||||||
|
}
|
||||||
|
while (cmdLen) {
|
||||||
|
sess->tcperr = TCPIPWriteTCP(sess->ipid, payload, cmdLen,
|
||||||
|
!extraLen, FALSE);
|
||||||
sess->toolerr = toolerror();
|
sess->toolerr = toolerror();
|
||||||
if (sess->tcperr || sess->toolerr) {
|
if (sess->tcperr || sess->toolerr) {
|
||||||
FlagFatalError(sess, 0);
|
FlagFatalError(sess, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmdLen = extraLen;
|
||||||
|
payload = extraPayload;
|
||||||
|
extraLen = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,13 +155,13 @@ top:
|
||||||
{
|
{
|
||||||
if (sess->reply.command == DSIAttention) {
|
if (sess->reply.command == DSIAttention) {
|
||||||
attentionReplyRec.requestID = sess->reply.requestID;
|
attentionReplyRec.requestID = sess->reply.requestID;
|
||||||
SendDSIMessage(sess, &attentionReplyRec, NULL);
|
SendDSIMessage(sess, &attentionReplyRec, NULL, NULL);
|
||||||
//TODO call attention routine.
|
//TODO call attention routine.
|
||||||
} else if (sess->reply.command == DSICloseSession) {
|
} else if (sess->reply.command == DSICloseSession) {
|
||||||
// TODO handle close
|
// TODO handle close
|
||||||
} else if (sess->reply.command == DSITickle) {
|
} else if (sess->reply.command == DSITickle) {
|
||||||
tickleRequestRec.requestID = htons(sess->nextRequestID++);
|
tickleRequestRec.requestID = htons(sess->nextRequestID++);
|
||||||
SendDSIMessage(sess, &tickleRequestRec, NULL);
|
SendDSIMessage(sess, &tickleRequestRec, NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
FlagFatalError(sess, aspNetworkErr);
|
FlagFatalError(sess, aspNetworkErr);
|
||||||
return;
|
return;
|
||||||
|
|
3
dsi.h
3
dsi.h
|
@ -4,7 +4,8 @@
|
||||||
#include "dsiproto.h"
|
#include "dsiproto.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
void SendDSIMessage(Session *sess, DSIRequestHeader *header, void *payload);
|
void SendDSIMessage(Session *sess, DSIRequestHeader *header, void *payload,
|
||||||
|
void *extraPayload);
|
||||||
void PollForData(Session *sess);
|
void PollForData(Session *sess);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
43
dsitest.c
43
dsitest.c
|
@ -5,13 +5,32 @@
|
||||||
#include <orca.h>
|
#include <orca.h>
|
||||||
#include "aspinterface.h"
|
#include "aspinterface.h"
|
||||||
#include "atipmapping.h"
|
#include "atipmapping.h"
|
||||||
|
#include "endian.h"
|
||||||
|
|
||||||
ASPGetStatusRec getStatusRec;
|
ASPGetStatusRec getStatusRec;
|
||||||
ASPOpenSessionRec openSessionRec;
|
ASPOpenSessionRec openSessionRec;
|
||||||
ASPCommandRec commandRec;
|
ASPCommandRec commandRec;
|
||||||
|
ASPWriteRec writeRec;
|
||||||
ASPCloseSessionRec closeSessionRec;
|
ASPCloseSessionRec closeSessionRec;
|
||||||
Byte replyBuffer[1024];
|
Byte replyBuffer[1024];
|
||||||
|
|
||||||
|
struct FPFlushRec {
|
||||||
|
Byte CommandCode;
|
||||||
|
Byte Pad;
|
||||||
|
Word VolumeID;
|
||||||
|
} fpFlushRec;
|
||||||
|
|
||||||
|
struct FPWriteRec {
|
||||||
|
Byte CommandCode;
|
||||||
|
Byte Flag;
|
||||||
|
Word OForkRefNum;
|
||||||
|
LongWord Offset;
|
||||||
|
LongWord ReqCount;
|
||||||
|
} fpWriteRec;
|
||||||
|
|
||||||
|
#define kFPFlush 10
|
||||||
|
#define kFPWrite 33
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Boolean loadedTCP = FALSE;
|
Boolean loadedTCP = FALSE;
|
||||||
|
@ -81,14 +100,32 @@ int main(int argc, char **argv)
|
||||||
printf("result code = %04x\n", openSessionRec.result);
|
printf("result code = %04x\n", openSessionRec.result);
|
||||||
if (openSessionRec.result)
|
if (openSessionRec.result)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
writeRec.async = AT_SYNC;
|
||||||
|
writeRec.command = aspWriteCommand;
|
||||||
|
writeRec.completionPtr = 0;
|
||||||
|
writeRec.refNum = openSessionRec.refNum;
|
||||||
|
writeRec.cmdBlkLength = sizeof(fpWriteRec);
|
||||||
|
writeRec.cmdBlkAddr = (LongWord)&fpWriteRec;
|
||||||
|
fpWriteRec.CommandCode = kFPWrite;
|
||||||
|
fpWriteRec.ReqCount = htonl(16);
|
||||||
|
writeRec.writeDataLength = 16;
|
||||||
|
writeRec.writeDataAddr = (LongWord)&openSessionRec;
|
||||||
|
writeRec.replyBufferLen = sizeof(replyBuffer);
|
||||||
|
writeRec.replyBufferAddr = (LongWord)&replyBuffer;
|
||||||
|
|
||||||
|
printf("Sending write...\n");
|
||||||
|
DispatchASPCommand((SPCommandRec *)&writeRec);
|
||||||
|
printf("result code = %04x, write result = %08lx\n",
|
||||||
|
writeRec.result, writeRec.cmdResult);
|
||||||
|
|
||||||
commandRec.async = AT_SYNC;
|
commandRec.async = AT_SYNC;
|
||||||
commandRec.command = aspCommandCommand;
|
commandRec.command = aspCommandCommand;
|
||||||
commandRec.completionPtr = 0;
|
commandRec.completionPtr = 0;
|
||||||
commandRec.refNum = openSessionRec.refNum;
|
commandRec.refNum = openSessionRec.refNum;
|
||||||
// FIXME this sends meaningless garbage, not a real AFP request
|
commandRec.cmdBlkLength = sizeof(fpFlushRec);
|
||||||
commandRec.cmdBlkLength = 10;
|
commandRec.cmdBlkAddr = (LongWord)&fpFlushRec;
|
||||||
commandRec.cmdBlkAddr = (LongWord)&openSessionRec;
|
fpFlushRec.CommandCode = kFPFlush;
|
||||||
commandRec.replyBufferLen = sizeof(replyBuffer);
|
commandRec.replyBufferLen = sizeof(replyBuffer);
|
||||||
commandRec.replyBufferAddr = (LongWord)&replyBuffer;
|
commandRec.replyBufferAddr = (LongWord)&replyBuffer;
|
||||||
|
|
||||||
|
|
5
endian.h
5
endian.h
|
@ -3,7 +3,10 @@
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
/* Undefine these in case they're defined as macros */
|
/*
|
||||||
|
* Undefine these in case they're defined as macros.
|
||||||
|
* (In particular, GNO has broken macro definitions for these.)
|
||||||
|
*/
|
||||||
#undef htons
|
#undef htons
|
||||||
#undef ntohs
|
#undef ntohs
|
||||||
#undef htonl
|
#undef htonl
|
||||||
|
|
Loading…
Reference in New Issue