ABSPOSAR ; IHS/FCS/DRS - low-level Receive response ; [ 09/12/2002 10:06 AM ]
;;1.0;PHARMACY POINT OF SALE;**3,11**;JUN 21, 2001;Build 38
;---------------------------------------------------------------------
;Gather message from host until ETX, EOT control characters have been
;received or timeout has occurred
;
;Parameters: DIALOUT
; .RESPMSG - Message text gathered from modem
; .RESPLRC - Longitudinal redundancy checker character
; TIMEOUT - Number of seconds before process terminates
;
;Returns: "EOT" - an EOT was received from the host
; "" - process timed out
; "ETX" - ETX received; we have a message & LRC
;---------------------------------------------------------------------
;IHS/SD/lwj 10/13/04 patch 11
; With NCPDP 5.1 the limitation on the response length is now extended
; with the repeating segments and fields. Due to this, the limitation
; originally set (2048 characters) needs to be extended and the number
; of prescriptions sent on a claim for some processors needs to be
; reduced to help limit the size of the response coming back.
; Limitation extended to 4096, and for now Pharmacare 5.1 altered to
; 2 rxs per claim.
;---------------------------------------------------------------------
Q
GETMSG(DIALOUT,RESPMSG,RESPLRC,TIMEOUT) ;EP - from ABSPOSAM
;
; Since we cannot USE:(parameters) to set the READ terminator,
; we must read one character at a time and check for STX,ETX,EOT
;
;FIXED128 = how many times we had to clear unwanted high bit
;ZB mimics a terminal device's $ZB, the READ terminator
N IO S IO=$$IO^ABSPOSA(DIALOUT) U IO
D LOG^ABSPOSL($T(+0)_" - RESP - Begin gathering host system's response",$G(ECHO))
1 N FIXED128,MAXMSG,ZA,ZB,I,X,T1LENGTH,T1LINE
;IHS/SD/lwj 10/13/04 patch 11 nxt line rmkd out, following added
;S FIXED128=0,MAXMSG=2048
S FIXED128=0,MAXMSG=4096
;IHS/SD/lwj 10/13/04 patch 11 end changes
S T1LINE=$$T1DIRECT^ABSPOSA(DIALOUT) ; true if this is a T1 connection
;
START S (RESPMSG,RESPLRC,RET)="",(T1LENGTH,ZB)=0
S X="GETZE^"_$T(+0),@^%ZOSF("TRAP")
F I=1:1:MAXMSG D Q:ZB ; loop to read characters
4 . R *X:0
. I '$T S ZB=-1 D ; timed out; retry for up to TIMEOUT secs more
. . N J F J=1:1:TIMEOUT U IO R *X:1 I $T S ZB=0 Q
. I ZB D S RET="+++" Q ; Timed out, retried, still couldn't get more
. . D LOG^ABSPOSL($T(+0)_" - RESP - Timed out after "_$L(RESPMSG)_" characters",$G(ECHO))
. I X<1 Q ; Something's wrong: got a character but it's 0 or negative
5 . I X>127 S X=X-128,FIXED128=FIXED128+1 ; clear unwanted high bit
. ;
. ; Did not time out; process the character
. ;
. S X=$C(X)
. ;
. ; If it's a T1 connection, first four bytes are the length
. ; But if a length contains a nonnumeric byte, you have an error.
. ;
. I T1LINE,I<5 D Q:X?1N
. . I X'?1N D S X=EOT
. . . D LOG^ABSPOSL($T(+0)_" - RESP - Character #"_I_" of length prefix was nonnumeric $C("_$A(X)_")")
. . S T1LENGTH=T1LENGTH*10+$A(X)-$A("0")
. ;
. ; Handle special control characters for modem connections:
. ;
. I 'T1LINE,X=STX!(X=ETX)!(X=EOT) D Q ; a terminator was received
. . S ZB=$A(X) ; remember what terminated the READ
. . I X=ETX D ; (and this terminator is our favorite one)
7 . . . S RESPMSG=RESPMSG_X
. . . S RESPLRC=$$GETCH(5) ; got the RESPMSG,now get the LRC
. . . I RESPLRC="" D S ZB=-1 ; reset ZB to indicate timeout in GETLRC()
. . . . D LOG^ABSPOSL($T(+0)_" - RESP - Timed out - got "_$L(RESPMSG)_" characters but not LRC character",$G(ECHO))
8 . S RESPMSG=RESPMSG_X
. ;
. ; If T1 line and you've got the entire message gathered,
. ; then fake out an ETX. This will cause the outer loop to stop.
. ;
. I T1LINE,I=(T1LENGTH+4) S ZB=$A(ETX),RESPLRC=0
;
; The READ loop is done - now act on the results
;
;D SAVECOPY^ABSPOSAY(RESPMSG,"R",RESPLRC)
I FIXED128 D LOG^ABSPOSL($T(+0)_" - RESP - Had to clear high bit "_FIXED128_" times",$G(ECHO))
I ZB=$A(EOT) D Q "EOT" ; EOT received from host
.D LOG^ABSPOSL($T(+0)_" - RESP - received EOT",$G(ECHO))
I ZB=$A(STX) D G START ; 03/08/2000
. D LOG^ABSPOSL($T(+0)_" - RESP - received STX, read again",$G(ECHO))
I ZB=-1 D Q "" ; timed out
.D LOG^ABSPOSL($T(+0)_" - RESP - timed out",$G(ECHO))
I ZB=0 D Q "" ; must have gotten to MAXMSG !?
.D LOG^ABSPOSL($T(+0)_" - RESP - got to MAXMSG characters",$G(ECHO))
I ZB'=$A(ETX) D Q "" ;ZT ; must be ETX, then, right?
.D LOG^ABSPOSL($T(+0)_" - RESP - unexpected ZB = "_ZB_" (should have gotten ETX)",$G(ECHO))
. D IMPOSS^ABSPOSUE("P","TRI","ZB="_ZB,,"GETMSG",$T(+0))
D LOG^ABSPOSL($T(+0)_" - RESP - Received "_$L(RESPMSG)_" characters",$G(ECHO))
9999999 Q "ETX"
;
; GETCH(timeout) - read one character
; Returns the character obtained, if any.
; Returns "" if it timed out.
GETCH(TO) ; read one character, timeout TO ; returns "" if timed out
;
; If a character is ready immediately, grab it and get out.
;
N X U IO R *X:0 I $T Q $C(X)
;
; Otherwise, loop and keep trying; maybe timeout.
;
N J,RET S RET="" F J=1:1:TO R *X:1 I $T S RET=$C(X) Q
Q RET
;
GETZE D LOGZE("GETMSG") Q:$Q "" Q
LOGZE(WHERE) D LOG^ABSPOSL($T(+0)_" - MODEM - "_WHERE_" - $ZE="_$$ZE^ABSPOS) Q
ABSPOSAR ; IHS/FCS/DRS - low-level Receive response ; [ 09/12/2002 10:06 AM ]
+1 ;;1.0;PHARMACY POINT OF SALE;**3,11**;JUN 21, 2001;Build 38
+2 ;---------------------------------------------------------------------
+3 ;Gather message from host until ETX, EOT control characters have been
+4 ;received or timeout has occurred
+5 ;
+6 ;Parameters: DIALOUT
+7 ; .RESPMSG - Message text gathered from modem
+8 ; .RESPLRC - Longitudinal redundancy checker character
+9 ; TIMEOUT - Number of seconds before process terminates
+10 ;
+11 ;Returns: "EOT" - an EOT was received from the host
+12 ; "" - process timed out
+13 ; "ETX" - ETX received; we have a message & LRC
+14 ;---------------------------------------------------------------------
+15 ;IHS/SD/lwj 10/13/04 patch 11
+16 ; With NCPDP 5.1 the limitation on the response length is now extended
+17 ; with the repeating segments and fields. Due to this, the limitation
+18 ; originally set (2048 characters) needs to be extended and the number
+19 ; of prescriptions sent on a claim for some processors needs to be
+20 ; reduced to help limit the size of the response coming back.
+21 ; Limitation extended to 4096, and for now Pharmacare 5.1 altered to
+22 ; 2 rxs per claim.
+23 ;---------------------------------------------------------------------
+24 QUIT
GETMSG(DIALOUT,RESPMSG,RESPLRC,TIMEOUT) ;EP - from ABSPOSAM
+1 ;
+2 ; Since we cannot USE:(parameters) to set the READ terminator,
+3 ; we must read one character at a time and check for STX,ETX,EOT
+4 ;
+5 ;FIXED128 = how many times we had to clear unwanted high bit
+6 ;ZB mimics a terminal device's $ZB, the READ terminator
+7 NEW IO
SET IO=$$IO^ABSPOSA(DIALOUT)
USE IO
+8 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - Begin gathering host system's response",$GET(ECHO))
1 NEW FIXED128,MAXMSG,ZA,ZB,I,X,T1LENGTH,T1LINE
+1 ;IHS/SD/lwj 10/13/04 patch 11 nxt line rmkd out, following added
+2 ;S FIXED128=0,MAXMSG=2048
+3 SET FIXED128=0
SET MAXMSG=4096
+4 ;IHS/SD/lwj 10/13/04 patch 11 end changes
+5 ; true if this is a T1 connection
SET T1LINE=$$T1DIRECT^ABSPOSA(DIALOUT)
+6 ;
START SET (RESPMSG,RESPLRC,RET)=""
SET (T1LENGTH,ZB)=0
+1 SET X="GETZE^"_$TEXT(+0)
SET @^%ZOSF("TRAP")
+2 ; loop to read characters
FOR I=1:1:MAXMSG
Begin DoDot:1
4 READ *X:0
+1 ; timed out; retry for up to TIMEOUT secs more
IF '$TEST
SET ZB=-1
Begin DoDot:2
+2 NEW J
FOR J=1:1:TIMEOUT
USE IO
READ *X:1
IF $TEST
SET ZB=0
QUIT
End DoDot:2
+3 ; Timed out, retried, still couldn't get more
IF ZB
Begin DoDot:2
+4 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - Timed out after "_$LENGTH(RESPMSG)_" characters",$GET(ECHO))
End DoDot:2
SET RET="+++"
QUIT
+5 ; Something's wrong: got a character but it's 0 or negative
IF X<1
QUIT
5 ; clear unwanted high bit
IF X>127
SET X=X-128
SET FIXED128=FIXED128+1
+1 ;
+2 ; Did not time out; process the character
+3 ;
+4 SET X=$CHAR(X)
+5 ;
+6 ; If it's a T1 connection, first four bytes are the length
+7 ; But if a length contains a nonnumeric byte, you have an error.
+8 ;
+9 IF T1LINE
IF I<5
Begin DoDot:2
+10 IF X'?1N
Begin DoDot:3
+11 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - Character #"_I_" of length prefix was nonnumeric $C("_$ASCII(X)_")")
End DoDot:3
SET X=EOT
+12 SET T1LENGTH=T1LENGTH*10+$ASCII(X)-$ASCII("0")
End DoDot:2
IF X?1N
QUIT
+13 ;
+14 ; Handle special control characters for modem connections:
+15 ;
+16 ; a terminator was received
IF 'T1LINE
IF X=STX!(X=ETX)!(X=EOT)
Begin DoDot:2
+17 ; remember what terminated the READ
SET ZB=$ASCII(X)
+18 ; (and this terminator is our favorite one)
IF X=ETX
Begin DoDot:3
7 SET RESPMSG=RESPMSG_X
+1 ; got the RESPMSG,now get the LRC
SET RESPLRC=$$GETCH(5)
+2 ; reset ZB to indicate timeout in GETLRC()
IF RESPLRC=""
Begin DoDot:4
+3 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - Timed out - got "_$LENGTH(RESPMSG)_" characters but not LRC character",$GET(ECHO))
End DoDot:4
SET ZB=-1
End DoDot:3
End DoDot:2
QUIT
8 SET RESPMSG=RESPMSG_X
+1 ;
+2 ; If T1 line and you've got the entire message gathered,
+3 ; then fake out an ETX. This will cause the outer loop to stop.
+4 ;
+5 IF T1LINE
IF I=(T1LENGTH+4)
SET ZB=$ASCII(ETX)
SET RESPLRC=0
End DoDot:1
IF ZB
QUIT
+6 ;
+7 ; The READ loop is done - now act on the results
+8 ;
+9 ;D SAVECOPY^ABSPOSAY(RESPMSG,"R",RESPLRC)
+10 IF FIXED128
DO LOG^ABSPOSL($TEXT(+0)_" - RESP - Had to clear high bit "_FIXED128_" times",$GET(ECHO))
+11 ; EOT received from host
IF ZB=$ASCII(EOT)
Begin DoDot:1
+12 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - received EOT",$GET(ECHO))
End DoDot:1
QUIT "EOT"
+13 ; 03/08/2000
IF ZB=$ASCII(STX)
Begin DoDot:1
+14 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - received STX, read again",$GET(ECHO))
End DoDot:1
GOTO START
+15 ; timed out
IF ZB=-1
Begin DoDot:1
+16 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - timed out",$GET(ECHO))
End DoDot:1
QUIT ""
+17 ; must have gotten to MAXMSG !?
IF ZB=0
Begin DoDot:1
+18 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - got to MAXMSG characters",$GET(ECHO))
End DoDot:1
QUIT ""
+19 ;ZT ; must be ETX, then, right?
IF ZB'=$ASCII(ETX)
Begin DoDot:1
+20 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - unexpected ZB = "_ZB_" (should have gotten ETX)",$GET(ECHO))
+21 DO IMPOSS^ABSPOSUE("P","TRI","ZB="_ZB,,"GETMSG",$TEXT(+0))
End DoDot:1
QUIT ""
+22 DO LOG^ABSPOSL($TEXT(+0)_" - RESP - Received "_$LENGTH(RESPMSG)_" characters",$GET(ECHO))
9999999 QUIT "ETX"
+1 ;
+2 ; GETCH(timeout) - read one character
+3 ; Returns the character obtained, if any.
+4 ; Returns "" if it timed out.
GETCH(TO) ; read one character, timeout TO ; returns "" if timed out
+1 ;
+2 ; If a character is ready immediately, grab it and get out.
+3 ;
+4 NEW X
USE IO
READ *X:0
IF $TEST
QUIT $CHAR(X)
+5 ;
+6 ; Otherwise, loop and keep trying; maybe timeout.
+7 ;
+8 NEW J,RET
SET RET=""
FOR J=1:1:TO
READ *X:1
IF $TEST
SET RET=$CHAR(X)
QUIT
+9 QUIT RET
+10 ;
GETZE DO LOGZE("GETMSG")
IF $QUIT
QUIT ""
QUIT
LOGZE(WHERE) DO LOG^ABSPOSL($TEXT(+0)_" - MODEM - "_WHERE_" - $ZE="_$$ZE^ABSPOS)
QUIT