- HLZTCP ;MILW/JMC - HL7 TCP/IP Hybrid Lower Level Protocol Receiver/Sender ;5/18/99 15:42 [ 04/02/2003 8:37 AM ]
- ;;1.6;HEALTH LEVEL SEVEN;**1004**;APR 1, 2003
- ;;1.5;HEALTH LEVEL SEVEN;;JUL 09, 1993
- ;
- INIT ;Initialize Variables
- ;REDIRECTED BY FROM HLLP IF IOT IS A CHANNEL DEVICE 08/19/02
- ;I.E. TERMINAL TYPE = CHAN
- N HLZIO,HLZOS,HLZSTATE
- ;S HLZOS=^%ZPSF("OS")
- ;BEGIN IHS MODE **1004** IHS/ITSC/TPF
- S HLZOS=$$VERSION^%ZOSV(1) ;e.g. Cache for Windows NT (Intel)
- ; MSM for RedHat Linux
- ;END IHS MOD **1004**
- ;
- ;I $D(ZTQUEUED) S ZTREQ="@"
- ;
- I $$NEWERR^%ZTER N $ETRAP S $ETRAP=""
- S X="ERR^HLZTCP",@^%ZOSF("TRAP")
- ;
- I '$D(HLION) D Q:POP
- . D HOME^%ZIS
- . I POP Q
- . S HLION=$S(ION']"":"UNKNOWN",1:ION)
- ;
- S HLZIO(0)=IO
- ;
- ; Figure out type of connection: 1=Server, 2=Client.
- I HLZOS["DSM" S HLZTCP=$S(IOPAR["ADDRESS":2,1:1)
- I HLZOS["Cache" D
- . N IP
- . S IP=$P(IOPAR,"""",2) ; Extract IP address
- . S HLZTCP=$S(IP?1.3N1P1.3N1P1.3N1P1.3N:2,1:1)
- ;
- ;BEGIN IHS MODE **1004** CHECK FOR MSM SYSTEM IHS/ITSC/TPF 08/19/02
- I HLZOS["MSM" D
- .S IOP=HLION
- .S %ZIS="N" ;TROUBLE GETTING 'NO OPEN' TO WORK.
- .D ^%ZIS
- .D ^%ZISC ;DEVICE 56 STILL OPENED SO HAD TO CLOSE
- .;USE 'USE PARAMETERS' IN DEVICE FILE TO PARSE IP AND PORT
- .S IP=$TR($P($P(IOUPAR,"(",2),","),"""")
- .S PORT=$P($P(IOUPAR,")"),",",2)
- .D CALL^%ZISTCP(IP,PORT,30)
- ;END IHS MOD **1004**
- ;
- S IOP="NULL DEVICE" D ^%ZIS
- I POP G EXIT
- S HLZIO=IO K IOP
- ;
- S HLTIME=$$NOW^XLFDT
- ;
- ;U HLZIO(0)
- ; If TCP client, send a "space" to initiate connection.
- ;I HLZTCP=2 W " ",!
- ;BEGIN IHS MOD **1004** REPLACES THREE LINES ABOVE
- ;IHS/ITSC/TPF 08/19/02 I FOUND THE FOLLOWING THREE LINES
- ;NOT NEEDED FOR MSM CONNECTION
- I HLZOS'["MSM" D
- .U HLZIO(0)
- .; If TCP client, send a "space" to initiate connection.
- .I HLZTCP=2 W " ",!
- ;END IHS MOD **1004**
- ;
- K %,%H,%I,X
- S DTIME=$P($G(HLNDAP0),"^",9),HLTRIES=$P($G(HLNDAP0),"^",5)
- S:DTIME'>0 DTIME=60 S:HLTRIES'>0 HLTRIES=3
- S HLLPC=^%ZOSF("LPC")
- ;
- ;
- LOOP ; Infinite loop to check for HL7 messages to send/receive
- F D I $$S^%ZTLOAD S ZTSTOP=1 Q
- . S HLLOG=$S($D(^HL(770,"ALOG",HLION)):1,1:0)
- . D CHKREC,CHKSEND
- EXIT Q
- ;
- ERR ; Trap error
- ; Reset current device to "NULL DEVICE".
- U:$G(HLZIO)'="" HLZIO
- ; Reschedule task.
- I $$EC^%ZOSV["WRITE"!($$EC^%ZOSV["READ") D
- . N ZTDTH,ZTSK
- . S ZTSK=ZTQUEUED,ZTDTH="60S",ZTREQ=""
- . D REQ^%ZTLOAD ; Requeue task in 60 seconds.
- K HLL(1),^TMP("HLR",$J),^TMP("HLS",$J)
- Q
- ;
- CHKREC ; Check if there are HL7 messages to receive
- ; Set flag to receive state.
- S HLZSTATE="recv"
- D REC
- ; Received "NAK" message don't know what it goes to.
- I $G(HLZNAK) K HLERR Q
- I '$D(HLDTOUT),'HLERR D SENDNAK G CHKREC
- I '$D(HLDTOUT) U HLZIO K HLERR D ^HLCHK
- U HLZIO
- Q
- ;
- CHKSEND ; Check if there are HL7 messages to send
- ; Set flag to send state.
- S HLZSTATE="send"
- Q:'$D(HLNDAP)
- I '$D(HLNDAP0) S HLNDAP0=$G(^HL(770,HLNDAP,0))
- S HLDA=+$O(^HL(772,"AC","O",+$P(HLNDAP0,U,12),0)) G:'HLDA EX
- S HLDA0=$G(^HL(772,HLDA,0)) G:HLDA0']"" EX
- S HLXMZ=+$P(HLDA0,"^",5)
- I 'HLXMZ D G EX
- . D STATUS^HLTF0(HLDA,4,"","No pointer to Message file(#3.9)")
- I '$D(^XMB(3.9,HLXMZ)) D G EX
- . D STATUS^HLTF0(HLDA,4,"","No message found at #"_HLXMZ_" in Message file(#3.9)")
- I '$O(^XMB(3.9,HLXMZ,2,0)) D G EX
- . D STATUS^HLTF0(HLDA,4,"","No message contents at #"_HLXMZ_" in Message file(#3.9)")
- S (HLI,HLTRIED)=0,HLSDT=+HLDA0
- F HLJ=1:1 S HLI=$O(^XMB(3.9,HLXMZ,2,HLI)) Q:HLI'>0 S ^TMP("HLS",$J,HLSDT,HLJ)=$G(^XMB(3.9,HLXMZ,2,HLI,0))
- CS1 ;
- S HLTRIED=HLTRIED+1
- K ^TMP("HLR",$J),HLSDATA
- D SEND
- ; Set flag to awaiting acknowledgement state.
- S HLZSTATE="awaiting ack"
- D REC
- I HLTRIED'=HLTRIES G CS1:$D(HLDTOUT) G CS1:HLZNAK
- G EX:$D(HLDTOUT)
- I HLZNAK D G EX
- . S HLAC=4,HLMSG="Lower Level Protocol Error - "_$S($E(HLL(1))="X":"Checksum",1:"Character Count")_" Did Not Match"
- . D STATUS^HLTF0(HLDA,HLAC,HLMSG)
- I $S('$D(HLL(1)):1,"BHS,MSH"'[$E(HLL(1),1,3):1,1:0) D G EX
- . S HLAC=4,HLMSG="Application Level error - Header Segment Missing"
- . D STATUS^HLTF0(HLDA,HLAC,HLMSG)
- K HLXMZ
- U HLZIO
- D CHK^HLCHK,IN^HLTF(HLMTN,HLMID,HLTIME)
- ;
- EX K HLAC,HLDA,HLDA0,HLERR,HLMSG,HLI,HLJ,HLSDATA,HLSDT,HLTRIED
- K ^TMP("HLS",$J),^TMP("HLR",$J)
- Q
- ;
- CSUM ;Calculate Checksum
- S HLC1=HLC1+$L(X),X=X_HLC2 X HLLPC S HLC2=$C(Y)
- Q
- ;
- REC ;Receive a Message
- S %=$$NOW^XLFDT
- I HLTIME<% S HLTIME=%
- E S HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- I HLLOG F Q:'$D(^TMP("HL",HLION,HLTIME)) S HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- K HLL,^TMP("HLR",$J)
- S (HLC2,X0)="",(HLC1,HLI,HLK,HLZEB,HLZNAK)=0
- U HLZIO(0)
- F R X1#1:DTIME Q:X1=$C(11) I '$T S HLDTOUT=1 Q
- ; Did not find "Start of block" character.
- I X1'=$C(11) Q
- S X0=X1,HLZLEN=1
- REC1 ;
- U HLZIO(0) K HLDTOUT
- R X1#1:DTIME I '$T S HLDTOUT=1
- ; Timed out and buffer empty.
- I $G(HLDTOUT),'$L(X1) Q
- ;
- S X0=X0_X1,HLZLEN=HLZLEN+1
- ; Set "NAK" block type flag.
- I X1="N",HLZLEN=2 S HLZNAK=1
- ; Set "End Block" flag.
- I X1=$C(28) S HLZEB=1
- I X1'=$C(13) G REC1
- I HLZEB,HLZNAK D RECNAK Q
- ;
- ; Process "End Block" if not a "NAK" record.
- I HLZEB S HLC=+$E(X0,6,8),HLB=+$E(X0,1,5),X0=""
- I $L(X0) D
- . I HLLOG D ;Record Incoming Transmission in Log
- . . S HLII=X0 S:$P(X0,$E(X0,5))="MSH" $P(X0,$E(X0,5),8)=""
- . . S HLI=HLI+1,^TMP("HL",HLION,HLTIME,"REC",HLI)=$TR(X0,$C(11,13)),X0=HLII
- . I HLK,HLK'>2 S HLL(HLK)=$TR(X0,$C(11,13))
- . I HLK S ^TMP("HLR",$J,HLTIME,HLK)=$TR(X0,$C(11,13))
- . S HLK=HLK+1,X=X0 D CSUM
- . S X0=""
- I 'HLZEB G REC1
- S X=HLC2 X HLLPC S HLCSUM=Y,HLERR=$S(HLCSUM'=HLC:"X",HLC1'=HLB:"C",1:1)
- I HLLOG S ^TMP("HL",HLION,HLTIME,"REC","CKS")="Our checksum="_HLCSUM_"/Their checksum="_HLC_"^Our character count="_HLC1_"/Their character count="_HLB
- Q
- ;
- RECNAK ; Process Received "NAK" message.
- S HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- S HLC=+$E(X0,7,9),HLB=+$E(X0,2,6),X=$E(X0,1) D CSUM
- S X=HLC2 X HLLPC S HLCSUM=Y,HLERR=$S(HLCSUM'=HLC:"X",HLC1'=HLB:"C",1:1)
- S HLL(1)=$TR(X0,$C(11,13,28)),^TMP("HLR",$J,HLTIME,1)=HLL(1)
- I HLLOG D
- . S ^TMP("HL",HLION,HLTIME,"REC",1)=HLL(1)
- . S ^TMP("HL",HLION,HLTIME,"REC","CKS")="Our checksum="_HLCSUM_"/Their checksum="_HLC_"^Our character count="_HLC1_"/Their character count="_HLB
- Q
- ;
- SEND ;Send a Message
- N X,Y
- S %=$$NOW^XLFDT
- I HLTIME<% S HLTIME=%
- E S HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- I HLLOG F Q:'$D(^TMP("HL",HLION,HLTIME)) S HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- S (HLI,HLC1)=0,HLC2=""
- D WRITE($C(11)_"D21"_$C(13))
- I '$D(HLSDT) F S HLI=$O(HLSDATA(HLI)) Q:HLI="" D WRITE(HLSDATA(HLI)_$C(13))
- I $D(HLSDT) F S HLI=$O(^TMP("HLS",$J,HLSDT,HLI)) Q:HLI="" S HLSDATA=^(HLI) D WRITE(HLSDATA_$C(13))
- D FLUSH
- Q
- ;
- SENDNAK ; Send a "NAK" message.
- S (HLC1,HLI)=0,HLC2="",HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- D WRITE($C(11)_"N21"_$C(13)_HLERR)
- D FLUSH
- K HLSDATA,HLERR
- Q
- ;
- WRITE(X) ; Write data in buffer.
- U HLZIO(0)
- W X,!
- I HLLOG S ^TMP("HL",HLION,HLTIME,"SEND",HLI)=$TR(X,$C(11,13))
- D CSUM
- Q
- ;
- FLUSH ; Write checksum and flush buffer.
- S X=HLC2 X HLLPC S X=$E("0000",1,(5-$L(HLC1)))_HLC1_$E("00",1,(3-$L(Y)))_Y_$C(28)_$C(13)
- U HLZIO(0)
- ; Do final write for this block and flush buffer.
- W X,!
- I HLLOG S ^TMP("HL",HLION,HLTIME,"SEND","CKS")=$TR(X,$C(11,13,28))
- Q
- HLZTCP ;MILW/JMC - HL7 TCP/IP Hybrid Lower Level Protocol Receiver/Sender ;5/18/99 15:42 [ 04/02/2003 8:37 AM ]
- +1 ;;1.6;HEALTH LEVEL SEVEN;**1004**;APR 1, 2003
- +2 ;;1.5;HEALTH LEVEL SEVEN;;JUL 09, 1993
- +3 ;
- INIT ;Initialize Variables
- +1 ;REDIRECTED BY FROM HLLP IF IOT IS A CHANNEL DEVICE 08/19/02
- +2 ;I.E. TERMINAL TYPE = CHAN
- +3 NEW HLZIO,HLZOS,HLZSTATE
- +4 ;S HLZOS=^%ZPSF("OS")
- +5 ;BEGIN IHS MODE **1004** IHS/ITSC/TPF
- +6 ;e.g. Cache for Windows NT (Intel)
- SET HLZOS=$$VERSION^%ZOSV(1)
- +7 ; MSM for RedHat Linux
- +8 ;END IHS MOD **1004**
- +9 ;
- +10 ;I $D(ZTQUEUED) S ZTREQ="@"
- +11 ;
- +12 IF $$NEWERR^%ZTER
- NEW $ETRAP
- SET $ETRAP=""
- +13 SET X="ERR^HLZTCP"
- SET @^%ZOSF("TRAP")
- +14 ;
- +15 IF '$DATA(HLION)
- Begin DoDot:1
- +16 DO HOME^%ZIS
- +17 IF POP
- QUIT
- +18 SET HLION=$SELECT(ION']"":"UNKNOWN",1:ION)
- End DoDot:1
- IF POP
- QUIT
- +19 ;
- +20 SET HLZIO(0)=IO
- +21 ;
- +22 ; Figure out type of connection: 1=Server, 2=Client.
- +23 IF HLZOS["DSM"
- SET HLZTCP=$SELECT(IOPAR["ADDRESS":2,1:1)
- +24 IF HLZOS["Cache"
- Begin DoDot:1
- +25 NEW IP
- +26 ; Extract IP address
- SET IP=$PIECE(IOPAR,"""",2)
- +27 SET HLZTCP=$SELECT(IP?1.3N1P1.3N1P1.3N1P1.3N:2,1:1)
- End DoDot:1
- +28 ;
- +29 ;BEGIN IHS MODE **1004** CHECK FOR MSM SYSTEM IHS/ITSC/TPF 08/19/02
- +30 IF HLZOS["MSM"
- Begin DoDot:1
- +31 SET IOP=HLION
- +32 ;TROUBLE GETTING 'NO OPEN' TO WORK.
- SET %ZIS="N"
- +33 DO ^%ZIS
- +34 ;DEVICE 56 STILL OPENED SO HAD TO CLOSE
- DO ^%ZISC
- +35 ;USE 'USE PARAMETERS' IN DEVICE FILE TO PARSE IP AND PORT
- +36 SET IP=$TRANSLATE($PIECE($PIECE(IOUPAR,"(",2),","),"""")
- +37 SET PORT=$PIECE($PIECE(IOUPAR,")"),",",2)
- +38 DO CALL^%ZISTCP(IP,PORT,30)
- End DoDot:1
- +39 ;END IHS MOD **1004**
- +40 ;
- +41 SET IOP="NULL DEVICE"
- DO ^%ZIS
- +42 IF POP
- GOTO EXIT
- +43 SET HLZIO=IO
- KILL IOP
- +44 ;
- +45 SET HLTIME=$$NOW^XLFDT
- +46 ;
- +47 ;U HLZIO(0)
- +48 ; If TCP client, send a "space" to initiate connection.
- +49 ;I HLZTCP=2 W " ",!
- +50 ;BEGIN IHS MOD **1004** REPLACES THREE LINES ABOVE
- +51 ;IHS/ITSC/TPF 08/19/02 I FOUND THE FOLLOWING THREE LINES
- +52 ;NOT NEEDED FOR MSM CONNECTION
- +53 IF HLZOS'["MSM"
- Begin DoDot:1
- +54 USE HLZIO(0)
- +55 ; If TCP client, send a "space" to initiate connection.
- +56 IF HLZTCP=2
- WRITE " ",!
- End DoDot:1
- +57 ;END IHS MOD **1004**
- +58 ;
- +59 KILL %,%H,%I,X
- +60 SET DTIME=$PIECE($GET(HLNDAP0),"^",9)
- SET HLTRIES=$PIECE($GET(HLNDAP0),"^",5)
- +61 IF DTIME'>0
- SET DTIME=60
- IF HLTRIES'>0
- SET HLTRIES=3
- +62 SET HLLPC=^%ZOSF("LPC")
- +63 ;
- +64 ;
- LOOP ; Infinite loop to check for HL7 messages to send/receive
- +1 FOR
- Begin DoDot:1
- +2 SET HLLOG=$SELECT($DATA(^HL(770,"ALOG",HLION)):1,1:0)
- +3 DO CHKREC
- DO CHKSEND
- End DoDot:1
- IF $$S^%ZTLOAD
- SET ZTSTOP=1
- QUIT
- EXIT QUIT
- +1 ;
- ERR ; Trap error
- +1 ; Reset current device to "NULL DEVICE".
- +2 IF $GET(HLZIO)'=""
- USE HLZIO
- +3 ; Reschedule task.
- +4 IF $$EC^%ZOSV["WRITE"!($$EC^%ZOSV["READ")
- Begin DoDot:1
- +5 NEW ZTDTH,ZTSK
- +6 SET ZTSK=ZTQUEUED
- SET ZTDTH="60S"
- SET ZTREQ=""
- +7 ; Requeue task in 60 seconds.
- DO REQ^%ZTLOAD
- End DoDot:1
- +8 KILL HLL(1),^TMP("HLR",$JOB),^TMP("HLS",$JOB)
- +9 QUIT
- +10 ;
- CHKREC ; Check if there are HL7 messages to receive
- +1 ; Set flag to receive state.
- +2 SET HLZSTATE="recv"
- +3 DO REC
- +4 ; Received "NAK" message don't know what it goes to.
- +5 IF $GET(HLZNAK)
- KILL HLERR
- QUIT
- +6 IF '$DATA(HLDTOUT)
- IF 'HLERR
- DO SENDNAK
- GOTO CHKREC
- +7 IF '$DATA(HLDTOUT)
- USE HLZIO
- KILL HLERR
- DO ^HLCHK
- +8 USE HLZIO
- +9 QUIT
- +10 ;
- CHKSEND ; Check if there are HL7 messages to send
- +1 ; Set flag to send state.
- +2 SET HLZSTATE="send"
- +3 IF '$DATA(HLNDAP)
- QUIT
- +4 IF '$DATA(HLNDAP0)
- SET HLNDAP0=$GET(^HL(770,HLNDAP,0))
- +5 SET HLDA=+$ORDER(^HL(772,"AC","O",+$PIECE(HLNDAP0,U,12),0))
- IF 'HLDA
- GOTO EX
- +6 SET HLDA0=$GET(^HL(772,HLDA,0))
- IF HLDA0']""
- GOTO EX
- +7 SET HLXMZ=+$PIECE(HLDA0,"^",5)
- +8 IF 'HLXMZ
- Begin DoDot:1
- +9 DO STATUS^HLTF0(HLDA,4,"","No pointer to Message file(#3.9)")
- End DoDot:1
- GOTO EX
- +10 IF '$DATA(^XMB(3.9,HLXMZ))
- Begin DoDot:1
- +11 DO STATUS^HLTF0(HLDA,4,"","No message found at #"_HLXMZ_" in Message file(#3.9)")
- End DoDot:1
- GOTO EX
- +12 IF '$ORDER(^XMB(3.9,HLXMZ,2,0))
- Begin DoDot:1
- +13 DO STATUS^HLTF0(HLDA,4,"","No message contents at #"_HLXMZ_" in Message file(#3.9)")
- End DoDot:1
- GOTO EX
- +14 SET (HLI,HLTRIED)=0
- SET HLSDT=+HLDA0
- +15 FOR HLJ=1:1
- SET HLI=$ORDER(^XMB(3.9,HLXMZ,2,HLI))
- IF HLI'>0
- QUIT
- SET ^TMP("HLS",$JOB,HLSDT,HLJ)=$GET(^XMB(3.9,HLXMZ,2,HLI,0))
- CS1 ;
- +1 SET HLTRIED=HLTRIED+1
- +2 KILL ^TMP("HLR",$JOB),HLSDATA
- +3 DO SEND
- +4 ; Set flag to awaiting acknowledgement state.
- +5 SET HLZSTATE="awaiting ack"
- +6 DO REC
- +7 IF HLTRIED'=HLTRIES
- IF $DATA(HLDTOUT)
- GOTO CS1
- IF HLZNAK
- GOTO CS1
- +8 IF $DATA(HLDTOUT)
- GOTO EX
- +9 IF HLZNAK
- Begin DoDot:1
- +10 SET HLAC=4
- SET HLMSG="Lower Level Protocol Error - "_$SELECT($EXTRACT(HLL(1))="X":"Checksum",1:"Character Count")_" Did Not Match"
- +11 DO STATUS^HLTF0(HLDA,HLAC,HLMSG)
- End DoDot:1
- GOTO EX
- +12 IF $SELECT('$DATA(HLL(1)):1,"BHS,MSH"'[$EXTRACT(HLL(1),1,3):1,1:0)
- Begin DoDot:1
- +13 SET HLAC=4
- SET HLMSG="Application Level error - Header Segment Missing"
- +14 DO STATUS^HLTF0(HLDA,HLAC,HLMSG)
- End DoDot:1
- GOTO EX
- +15 KILL HLXMZ
- +16 USE HLZIO
- +17 DO CHK^HLCHK
- DO IN^HLTF(HLMTN,HLMID,HLTIME)
- +18 ;
- EX KILL HLAC,HLDA,HLDA0,HLERR,HLMSG,HLI,HLJ,HLSDATA,HLSDT,HLTRIED
- +1 KILL ^TMP("HLS",$JOB),^TMP("HLR",$JOB)
- +2 QUIT
- +3 ;
- CSUM ;Calculate Checksum
- +1 SET HLC1=HLC1+$LENGTH(X)
- SET X=X_HLC2
- XECUTE HLLPC
- SET HLC2=$CHAR(Y)
- +2 QUIT
- +3 ;
- REC ;Receive a Message
- +1 SET %=$$NOW^XLFDT
- +2 IF HLTIME<%
- SET HLTIME=%
- +3 IF '$TEST
- SET HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- +4 IF HLLOG
- FOR
- IF '$DATA(^TMP("HL",HLION,HLTIME))
- QUIT
- SET HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- +5 KILL HLL,^TMP("HLR",$JOB)
- +6 SET (HLC2,X0)=""
- SET (HLC1,HLI,HLK,HLZEB,HLZNAK)=0
- +7 USE HLZIO(0)
- +8 FOR
- READ X1#1:DTIME
- IF X1=$CHAR(11)
- QUIT
- IF '$TEST
- SET HLDTOUT=1
- QUIT
- +9 ; Did not find "Start of block" character.
- +10 IF X1'=$CHAR(11)
- QUIT
- +11 SET X0=X1
- SET HLZLEN=1
- REC1 ;
- +1 USE HLZIO(0)
- KILL HLDTOUT
- +2 READ X1#1:DTIME
- IF '$TEST
- SET HLDTOUT=1
- +3 ; Timed out and buffer empty.
- +4 IF $GET(HLDTOUT)
- IF '$LENGTH(X1)
- QUIT
- +5 ;
- +6 SET X0=X0_X1
- SET HLZLEN=HLZLEN+1
- +7 ; Set "NAK" block type flag.
- +8 IF X1="N"
- IF HLZLEN=2
- SET HLZNAK=1
- +9 ; Set "End Block" flag.
- +10 IF X1=$CHAR(28)
- SET HLZEB=1
- +11 IF X1'=$CHAR(13)
- GOTO REC1
- +12 IF HLZEB
- IF HLZNAK
- DO RECNAK
- QUIT
- +13 ;
- +14 ; Process "End Block" if not a "NAK" record.
- +15 IF HLZEB
- SET HLC=+$EXTRACT(X0,6,8)
- SET HLB=+$EXTRACT(X0,1,5)
- SET X0=""
- +16 IF $LENGTH(X0)
- Begin DoDot:1
- +17 ;Record Incoming Transmission in Log
- IF HLLOG
- Begin DoDot:2
- +18 SET HLII=X0
- IF $PIECE(X0,$EXTRACT(X0,5))="MSH"
- SET $PIECE(X0,$EXTRACT(X0,5),8)=""
- +19 SET HLI=HLI+1
- SET ^TMP("HL",HLION,HLTIME,"REC",HLI)=$TRANSLATE(X0,$CHAR(11,13))
- SET X0=HLII
- End DoDot:2
- +20 IF HLK
- IF HLK'>2
- SET HLL(HLK)=$TRANSLATE(X0,$CHAR(11,13))
- +21 IF HLK
- SET ^TMP("HLR",$JOB,HLTIME,HLK)=$TRANSLATE(X0,$CHAR(11,13))
- +22 SET HLK=HLK+1
- SET X=X0
- DO CSUM
- +23 SET X0=""
- End DoDot:1
- +24 IF 'HLZEB
- GOTO REC1
- +25 SET X=HLC2
- XECUTE HLLPC
- SET HLCSUM=Y
- SET HLERR=$SELECT(HLCSUM'=HLC:"X",HLC1'=HLB:"C",1:1)
- +26 IF HLLOG
- SET ^TMP("HL",HLION,HLTIME,"REC","CKS")="Our checksum="_HLCSUM_"/Their checksum="_HLC_"^Our character count="_HLC1_"/Their character count="_HLB
- +27 QUIT
- +28 ;
- RECNAK ; Process Received "NAK" message.
- +1 SET HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- +2 SET HLC=+$EXTRACT(X0,7,9)
- SET HLB=+$EXTRACT(X0,2,6)
- SET X=$EXTRACT(X0,1)
- DO CSUM
- +3 SET X=HLC2
- XECUTE HLLPC
- SET HLCSUM=Y
- SET HLERR=$SELECT(HLCSUM'=HLC:"X",HLC1'=HLB:"C",1:1)
- +4 SET HLL(1)=$TRANSLATE(X0,$CHAR(11,13,28))
- SET ^TMP("HLR",$JOB,HLTIME,1)=HLL(1)
- +5 IF HLLOG
- Begin DoDot:1
- +6 SET ^TMP("HL",HLION,HLTIME,"REC",1)=HLL(1)
- +7 SET ^TMP("HL",HLION,HLTIME,"REC","CKS")="Our checksum="_HLCSUM_"/Their checksum="_HLC_"^Our character count="_HLC1_"/Their character count="_HLB
- End DoDot:1
- +8 QUIT
- +9 ;
- SEND ;Send a Message
- +1 NEW X,Y
- +2 SET %=$$NOW^XLFDT
- +3 IF HLTIME<%
- SET HLTIME=%
- +4 IF '$TEST
- SET HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- +5 IF HLLOG
- FOR
- IF '$DATA(^TMP("HL",HLION,HLTIME))
- QUIT
- SET HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- +6 SET (HLI,HLC1)=0
- SET HLC2=""
- +7 DO WRITE($CHAR(11)_"D21"_$CHAR(13))
- +8 IF '$DATA(HLSDT)
- FOR
- SET HLI=$ORDER(HLSDATA(HLI))
- IF HLI=""
- QUIT
- DO WRITE(HLSDATA(HLI)_$CHAR(13))
- +9 IF $DATA(HLSDT)
- FOR
- SET HLI=$ORDER(^TMP("HLS",$JOB,HLSDT,HLI))
- IF HLI=""
- QUIT
- SET HLSDATA=^(HLI)
- DO WRITE(HLSDATA_$CHAR(13))
- +10 DO FLUSH
- +11 QUIT
- +12 ;
- SENDNAK ; Send a "NAK" message.
- +1 SET (HLC1,HLI)=0
- SET HLC2=""
- SET HLTIME=$$FMADD^XLFDT(HLTIME,0,0,0,1)
- +2 DO WRITE($CHAR(11)_"N21"_$CHAR(13)_HLERR)
- +3 DO FLUSH
- +4 KILL HLSDATA,HLERR
- +5 QUIT
- +6 ;
- WRITE(X) ; Write data in buffer.
- +1 USE HLZIO(0)
- +2 WRITE X,!
- +3 IF HLLOG
- SET ^TMP("HL",HLION,HLTIME,"SEND",HLI)=$TRANSLATE(X,$CHAR(11,13))
- +4 DO CSUM
- +5 QUIT
- +6 ;
- FLUSH ; Write checksum and flush buffer.
- +1 SET X=HLC2
- XECUTE HLLPC
- SET X=$EXTRACT("0000",1,(5-$LENGTH(HLC1)))_HLC1_$EXTRACT("00",1,(3-$LENGTH(Y)))_Y_$CHAR(28)_$CHAR(13)
- +2 USE HLZIO(0)
- +3 ; Do final write for this block and flush buffer.
- +4 WRITE X,!
- +5 IF HLLOG
- SET ^TMP("HL",HLION,HLTIME,"SEND","CKS")=$TRANSLATE(X,$CHAR(11,13,28))
- +6 QUIT