-- File: PressNetSender.mesa: Routines for sending a file to a printing server.
-- Last Edited: February 8, 1982 1:59 PM By: GWilliams
--
Call PupPackageDestroy before raising any error from SendBlock (now matches Pilot version, except for LONG POINTERS).
DIRECTORY
EFTPDefs USING [eftpExternalReceiverAbort, EFTPFinishSending, EFTPNotSending, eftpOK, EFTPOpenForSending, eftpOutOfSyncAbort, eftpReceiverBusyAbort, eftpRejected, EFTPSendBlock, EFTPTimeOut, EFTPTroubleSending],
PressNetDefs USING [attributesCode, imageCode, DLP1Attributes, PageAttributes, PressNetErr, Printer, StingerAttributes, PrinterAttributes],
PupDefs USING [GetPupAddress, PupNameTrouble, PupPackageDestroy, PupPackageMake],
PupTypes USING[PupAddress, PupSocketID],
Storage USING [CopyString, FreeStringNil];
PressNetSender: PROGRAM
IMPORTS EFTPDefs, PupDefs, Storage
EXPORTS PressNetDefs =
BEGIN OPEN EFTPDefs, PressNetDefs, PupDefs, PupTypes, Storage;

--Pack Variables
firstScan, lastScan: CARDINAL;
pupPtr: POINTER TO PupAddress ← @sendToAddress;
sendErrorText: STRING ← NIL;
sendToAddress: PupAddress;
sendingRetries: CARDINAL ← 1;
scanLineLength: CARDINAL;

PressSendError
: PUBLIC ERROR [err: PressNetErr, s: STRING]= CODE;
SendBuf: TYPE = MACHINE DEPENDENT RECORD
[code: CARDINAL,
pageAttributes: PageAttributes
];

--
Procs
GetPrinterAttributes: PUBLIC PROCEDURE[printer: Printer] RETURNS [pa: PrinterAttributes]=
{
SELECT printer FROM
Stinger => RETURN[StingerAttributes];
DLP1 => RETURN[DLP1Attributes];
ENDCASE;
};--
GetPrinterAttributes

PrinterReady: PUBLIC PROCEDURE [printer: Printer, retries: CARDINAL ← 1] RETURNS [goAhead: BOOLEAN ← FALSE]=
--If returns successfully, you have a connection.
--Later may return reason for no connection (i.e., printer down, not listening etc)
{pressNetErr: PressNetErr ← noError;
deviceString: STRING;
stingerString: STRING ← "Stinger";
dLP1String: STRING ← "Platemaker";

SELECT printer FROM
Stinger => deviceString ← stingerString;
DLP1 => deviceString ← dLP1String;
ENDCASE;

BEGIN

PupPackageMake[];
GetPupAddress[pupPtr, deviceString!
PupNameTrouble =>
{SELECT code FROM
noRoute => pressNetErr ← errorNoRoute;
noResponse => pressNetErr ← errorNoResponse;
errorFromServer => pressNetErr ← errorFromServer;
ENDCASE;
GOTO exit;};--do the GOTO to start UNWIND
];
pupPtr.socket ← PupSocketID[1, 25B];--[0, 20B] is the normal printer socket

EFTPOpenForSending[pupPtr↑, TRUE!
EFTPTroubleSending =>
{IF s # NIL THEN sendErrorText ← CopyString[s, 0];
SELECT e FROM
eftpOK => pressNetErr ← errorEftpOK;
eftpExternalReceiverAbort => pressNetErr ← errorEftpExternalReceiverAbort;
eftpReceiverBusyAbort => pressNetErr ← errorEftpReceiverBusyAbort;
eftpOutOfSyncAbort => pressNetErr ← errorEftpOutOfSyncAbort;
eftpRejected => pressNetErr ← errorEftpRejected;
ENDCASE;
GOTO exit;
};
EFTPTimeOut =>
IF (retries ← retries - 1) > 0
THEN RESUME
ELSE {pressNetErr ← errorTimedOut; GOTO exit};
];

goAhead ← TRUE;

EXITS
exit =>
BEGIN ENABLE UNWIND => IF sendErrorText # NIL THEN sendErrorText←FreeStringNil[sendErrorText];
PupPackageDestroy[];
SELECT pressNetErr FROM
errorNoRoute => ERROR PressSendError[pressNetErr, "Can’t Get there from here"];
errorNoResponse => ERROR PressSendError[pressNetErr, "Lookup Server doesn’t respond"];
errorFromServer => ERROR PressSendError[pressNetErr, "Lookup Server error."];
errorEftpOK, errorEftpExternalReceiverAbort, errorEftpReceiverBusyAbort, errorEftpOutOfSyncAbort =>
ERROR PressSendError[pressNetErr, sendErrorText];
errorEftpRejected, errorTimedOut => NULL;--simply return FALSE
ENDCASE;
END;
--of ENABLE for UNWIND
END;
}
;--PrinterReady

SetRetries:
PUBLIC PROC[n: CARDINAL]=
--this sets the retry count for all transfers after the connection is established
{
sendingRetries ← n};

SendLine: PUBLIC PROC[p: POINTER]=
BEGIN
SendBuffer[p, scanLineLength, sendingRetries, imageCode];--length in words
END;
--of SendLine

SendPageAttributes:
PUBLIC PROCEDURE[attrPt: POINTER TO PageAttributes]=
--this routine sends the page attributes to the printer.
--If goAhead returns FALSE, there was trouble with the parameters and the connection is closed.
{
sendBuf: SendBuf;
--let PressNetListener figure out all the PageG entries.

scanLineLength ← attrPt.bitWc;
firstScan ← attrPt.firstScan; lastScan ← attrPt.lastScan;
sendBuf.pageAttributes ← attrPt↑;--will this copy the whole record?
sendBuf.code ← attributesCode;

--send the info
SendBuffer[@sendBuf, SIZE[SendBuf], sendingRetries, ];--code is already in block

};
--SendPageAttributes


SendBuffer
: PROC[p: POINTER, len, timeout: CARDINAL, code: CARDINAL ← 0]=
--This routine calls SendBlock and renames all Errors for user
BEGIN
pressNetErr: PressNetErr ← noError;
BEGIN
--every buffer sent to the printer has a 1-word code at the beginning
IF code # 0 THEN
{EFTPSendBlock[@code, 2!--send the 2-byte code
EFTPTroubleSending =>
{IF s # NIL THEN sendErrorText ← CopyString[s, 0];
SELECT e FROM
eftpOK => pressNetErr ← errorEftpOK;
eftpExternalReceiverAbort => pressNetErr ← errorEftpExternalReceiverAbort;
eftpReceiverBusyAbort => pressNetErr ← errorEftpReceiverBusyAbort;
eftpOutOfSyncAbort => pressNetErr ← errorEftpOutOfSyncAbort;
eftpRejected => pressNetErr ← errorEftpRejected;
ENDCASE;
GOTO exit;
};
EFTPNotSending => {pressNetErr ← errorNotSending; GOTO exit};
EFTPTimeOut => IF (timeout ← timeout - 1) # 0
THEN RETRY
ELSE {pressNetErr ← errorTimedOut; GOTO exit};
];
};

EFTPSendBlock[p, len*2!
EFTPTroubleSending =>
{IF s # NIL THEN sendErrorText ← CopyString[s, 0];
SELECT e FROM
eftpOK => pressNetErr ← errorEftpOK;
eftpExternalReceiverAbort => pressNetErr ← errorEftpExternalReceiverAbort;
eftpReceiverBusyAbort => pressNetErr ← errorEftpReceiverBusyAbort;
eftpOutOfSyncAbort => pressNetErr ← errorEftpOutOfSyncAbort;
eftpRejected => pressNetErr ← errorEftpRejected;
ENDCASE;
GOTO exit;
};
EFTPNotSending => {pressNetErr ← errorNotSending; GOTO exit};
EFTPTimeOut => IF (timeout ← timeout - 1) # 0
THEN RETRY
ELSE {pressNetErr ← errorTimedOut; GOTO exit};
];
EXITS

exit =>
BEGIN ENABLE UNWIND => IF sendErrorText # NIL THEN sendErrorText←FreeStringNil[sendErrorText];
PupPackageDestroy[];
SELECT pressNetErr FROM
errorNoRoute => ERROR PressSendError[pressNetErr, "Can’t Get there from here"L];
errorNoResponse => ERROR PressSendError[pressNetErr, "Lookup Server doesn’t respond"L];
errorFromServer => ERROR PressSendError[pressNetErr, "Lookup Server error."L];
errorEftpOK, errorEftpExternalReceiverAbort, errorEftpReceiverBusyAbort, errorEftpOutOfSyncAbort, errorEftpRejected
=> ERROR PressSendError[pressNetErr, sendErrorText];
errorTimedOut => ERROR PressSendError[pressNetErr, "Timed out while sending data."L];
ENDCASE;
END;
--of ENABLE for UNWIND
END;
END;
--SendBuffer

CloseConnection:
PUBLIC PROC[]=
--A connection will be kept open until this routine is called. Don’t forget to call it!
{
nRetries: CARDINAL ← 5;

EFTPFinishSending[!
EFTPNotSending => CONTINUE;
EFTPTimeOut => IF (nRetries ← nRetries - 1) # 0 THEN RESUME ELSE GOTO timeout;];
PupPackageDestroy[];

EXITS
timeout => PupPackageDestroy[];
};
--CloseConnection

END.
-- PressNetSender.mesa
-- Last Edited: October 20, 1981 4:13 PM By: GWilliams
-- Last Edited: October 27, 1981 5:15 PM By: GWilliams
-- added totalBytesRead
-- Last Edited: November 17, 1981 3:17 PM By: GWilliams
-- Changing the thrust of the program to transmit the image information on a scan-line basis rather than by trying to send press.bits as an intact file. This decouples knowledge of press.bits from the image.
-- Last Edited: December 8, 1981 5:33 PM By: GWilliams
-- Started debugging.
-- Last Edited: December 10, 1981 11:22 AM By: GWilliams
-- in PrinterReady, now just return FALSE if I catch eftpRejected ("no such port"). This is raised if EFTP is running on another port at the printer.
-- Last Edited: December 15, 1981 11:51 AM By: GWilliams
-- Changed CloseConnection to not do an EFTPFinishSending. If the transfer was successful, the receiving end closed the connection already and the finishsending causes the printer to botch the print.
-- Last Edited: December 22, 1981 2:42 PM By: GWilliams
-- Changed CloseConnection back to do EFTPFinishSending. The Listener has been changed to accomodate this.
-- Last Edited: February 8, 1982 11:48 AM By: GWilliams
-- Can now talk to the Platemaker too.