Mumpster
http://mumpster.org/

Wait for single character
http://mumpster.org/viewtopic.php?f=16&t=1703
Page 1 of 1

Author:  jollis [ Mon May 21, 2012 6:13 pm ]
Post subject:  Wait for single character

Hello all!

I'm working on an XMODEM send routine in GT.M. I have a fairly decent understanding of the protocol, but I'm having trouble in the section where I wait for the receiver to send the NCGbyte (NAK, or ASCII code 21 decimal). It's supposed to wait up to one minute for the NAK to be received, and go on with the transfer once it is. But it just hangs at
Code:
R *INCHAR:60
. Here's the code so far. If anyone has any pointers for me, that would be much appreciated!

Code:
KBBMXMDM ;JPW;5/2012; XMODEM PROTOCOL IMPLEMENTATION

SEND(INFILE)
  ;**
  ; NEW all our variables, defining some locals
  ; like the control characters we'll need.
  ;
  N XFER,DBUG,SOH,EOT,ACK,NAK,CAN,I,BLKTRIES
  S SOH=$C(1),EOT=$C(4),ACK=$C(6),NAK=$C(21),CAN=$C(24)
  N PKTCT,PKTNUM,BYTECT
  N IGOT S IGOT=0,PKTNUM=0
  ;**
  ; Open the file
  ;
  O INFILE:(READONLY:FIXED:WRAP:CHSET="M")
  U INFILE
  D DBGMSG("FILE OPEN "_$ZIO)
  ;**
  ; Read the file into XFER, one byte at a time
  ;
  F I=1:1 D  QUIT:$ZEOF
  .R XFER("R",I)#1
  .S BYTECT=I
  U 0
  CLOSE INFILE
  ;**
  ; Now, divide the file into 128-byte chunks
  ;
  S PKTCT=BYTECT\128  ; this is how many chunks the file becomes
  I BYTECT#128>0 S PKTCT=PKTCT+1
  S XFER("C",PKTNUM)=""
  F I=1:1:BYTECT  D
  .S XFER("C",PKTNUM)=XFER("C",PKTNUM)_XFER("R",I)
  .S IGOT=IGOT+1
  .I IGOT=128 S PKTNUM=PKTNUM+1,IGOT=0,XFER("C",PKTNUM)=""
  D DBGMSG("FILE SPLIT COMPLETE")
  ;**
  ; Now, we wait for the receiver to send the XMODEM NCGbyte (NAK)
  ;
  U $P:(NOESCAPE) ; disable escape processing on $principal
  N INCHAR S INCHAR=""
  R *INCHAR:60
  I $TEST=0 U $P W !,"File transfer timeout. Please try again." G FILEDONE
  I INCHAR'=$ASCII(NAK) U $P W !,"NCGbyte invalid. Please try again." G FILEDONE
  S INCHAR=""
  D DBGMSG("NAK RECEIVED")
  ;**
  ; Start spitting out XMODEM blocks (SOH, packet number, one's complement of packet number, packet data, checksum)
  ;
  ; We are going to send one block, and wait for the receiver to send one of ACK, NAK, or CAN.
  ;
  ; If we get ACK, go on to the next block.
  ; If we get NAK, retry the current block (up to 10 times).
  ; After 10 retries on a single block, abort the transfer.
  ; If we get CAN, abort the whole transfer.
  ; If we get nothing within 10 seconds, abort the transfer.
  ;
  S BLKTRIES=0
  F I=1:1:PKTCT D  QUIT:INCHAR=$ASCII(CAN)
retryBlock
  .W SOH,I-1,$$ONESCMPL(I-1),XFER("C",I-1),$$CHECKSUM(XFER("C",I-1))
  .R *INCHAR:10
  .I $TEST=0 U $P W !,"The receiver has stopped acknowledging our packets. Aborting transfer." G FILEDONE
  .I INCHAR=$ASCII(NAK) D
  ..I BLKTRIES>9 U $P W !,"We have tried sending block "_I_" 10 times with no success. Aborting transfer." G FILEDONE
  ..S BLKTRIES=BLKTRIES+1
  ..G retryBlock
  .I INCHAR=$ASCII(CAN) U $P W !,"The receiver has cancelled the transfer." G FILEDONE
  .I INCHAR'=$ASCII(ACK) D
  ..I BLKTRIES>9 U $P W !,"We have tried sending block "_I_" 10 times with no success. Aborting transfer." G FILEDONE
  ..S BLKTRIES=BLKTRIES+1
  ..G retryBlock
  D DBGMSG("SEND COMPLETE")
  I INCHAR=$ASCII(CAN) G FILEDONE
  ; transfer completed
  W EOT
  F  R *INCHAR QUIT:INCHAR=$ASCII(NAK)
  W EOT
  F  R *INCHAR QUIT:INCHAR=$ASCII(NAK)
FILEDONE
  U $P:(ESCAPE)   ; re-enable escape processing on $principal
  Q

ONESCMPL(NUM)
  Q 255-NUM

CHECKSUM(STR)
  N SUM,I S SUM=0
  F I=1:1:$L(STR)  D
  .S SUM=SUM+$ASCII($E(STR,I))
  Q $$RANGIFY(SUM)

RANGIFY(VAL)
  F  D  QUIT:VAL<256
  .S VAL=VAL-256
  Q VAL

DBGMSG(MSG)
  N SAVEIO S SAVEIO=$IO
  I $G(^KBBMDBUG)="ON" U $P W "DEBUG: "_MSG,! U SAVEIO
  Q


Thanks in advance,
John W.

Author:  raynewman [ Wed May 23, 2012 4:23 pm ]
Post subject:  Re: Wait for single character

I don't know GTM specifics for the terminal open modes but what you are looking for is <Ctrl><U> which would need a special terminal mode to allow it through.

Ray

Page 1 of 1 All times are UTC - 8 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/