1 | HLCSDR2 ;ALB/RJS - HYBRID LOWER LAYER PROTOCOL UTILITIES 2.2 - ;08/22/2001 11:23
|
---|
2 | ;;1.6;HEALTH LEVEL SEVEN;**2,9,62,109**;Oct 13, 1995
|
---|
3 | Q
|
---|
4 | WRITE(HLDOUT0,HLDOUT1) ; This function writes a message from the Logical
|
---|
5 | ; Link file (#870) to the specified device in the following format:
|
---|
6 | ; <Start Block><Data Block><End Block>
|
---|
7 | ; The data block is the complete HL7 message terminated by a <CR>.
|
---|
8 | ; INPUT : HLDOUT0 - IFN of file 870
|
---|
9 | ; HLDOUT1 - IFN of Out Queue Multiple
|
---|
10 | ; OUTPUT: None
|
---|
11 | I HLDOUT0']""!(HLDOUT1']"") Q
|
---|
12 | ;-- HLLINE,HLC1,HLC2 are initialized in INITIZE
|
---|
13 | N HLCLN,HLCHK,I,X
|
---|
14 | D INITIZE
|
---|
15 | ;
|
---|
16 | ;-- write start block
|
---|
17 | S X=$C(HLDSTRT)_"D"_HLDVER_$C(13) D CHKSUM
|
---|
18 | U IO W X
|
---|
19 | ;
|
---|
20 | S HLWFLG=0
|
---|
21 | ;-- process and write data block
|
---|
22 | F S HLLINE=$$NEXTLINE^HLCSUTL(HLDOUT0,HLDOUT1,HLLINE,"HLCLN","OUT") Q:'HLLINE D
|
---|
23 | . S HLCHK=$$CHKSUM^HLCSUTL("HLCLN")
|
---|
24 | . S HLC2=HLC2_$C($P(HLCHK,U)),HLC1=HLC1+$P(HLCHK,U,2)
|
---|
25 | . I $E(HLCLN(1),1,3)="MSA" S HLWFLG=1
|
---|
26 | . ;U IO
|
---|
27 | . S I=0 F S I=$O(HLCLN(I)) Q:'I W $G(HLCLN(I))
|
---|
28 | . K HLCLN,HLCHK
|
---|
29 | ;
|
---|
30 | D CHKSUM1
|
---|
31 | ;-- store checksum values
|
---|
32 | D MONITOR(HLC1,4,HLDP,HLDOUT1,"OUT"),MONITOR(HLC2,5,HLDP,HLDOUT1,"OUT")
|
---|
33 | ;
|
---|
34 | S HLC1=$$RJ(HLC1,5)
|
---|
35 | S HLC2=$$RJ(HLC2,3)
|
---|
36 | ;
|
---|
37 | ;-- write end block
|
---|
38 | S X=HLC1_HLC2_$C(HLDEND)_$C(13)
|
---|
39 | U IO W X
|
---|
40 | Q
|
---|
41 | SETNODE(HLD0,HLD1,CR) ;
|
---|
42 | S HLLINE=HLLINE+1,^HLCS(870,HLD0,1,HLD1,1,HLLINE,0)=$G(X)
|
---|
43 | I CR="CR" S HLLINE=HLLINE+1,^HLCS(870,HLD0,1,HLD1,1,HLLINE,0)=""
|
---|
44 | Q
|
---|
45 | SETNODE2 ;
|
---|
46 | S HLLINE=HLLINE+1,^TMP("HLCSDR1",$J,HLDP,HLLINE)=$G(X)
|
---|
47 | Q
|
---|
48 | TRANS(HLTOUT,HLTRANS) ; This function returns the state of the read operation.
|
---|
49 | ; INPUT : HLTOUT - Data returned from read (Will contain TIMEOUT)
|
---|
50 | ; HLTRANS - Variable passed by reference containing how
|
---|
51 | ; the read was terminated.
|
---|
52 | ; OUTPUT: HLTRANS - Translation of read termination.
|
---|
53 | S HLTRANS=$S($G(HLTOUT)["TIMEOUT":"TIMEOUT",HLTRANS=0:"LONGLINE",HLTRANS=1:"SOH",HLTRANS=4:"EOT",HLTRANS=HLDSTRT:"VT",HLTRANS=13:"CR",HLTRANS=HLDEND:"FS",1:"OTHER")
|
---|
54 | I $D(HLTRACE) U IO(0) W !,"HLTRANS=",HLTRANS
|
---|
55 | Q
|
---|
56 | INITIZE ;Initialize Line counter and Checksum variables
|
---|
57 | S (HLLINE,HLC1)=0,HLC2=""
|
---|
58 | Q
|
---|
59 | NAK(HLTRANS) ; Send NAK
|
---|
60 | N HLDATA
|
---|
61 | D INITIZE
|
---|
62 | ;-- start block and data
|
---|
63 | S (X,HLDATA)=$C(HLDSTRT)_"N"_HLDVER_$C(13)_HLTRANS
|
---|
64 | D CHKSUM,CHKSUM1
|
---|
65 | S HLC1=$$RJ(HLC1,5)
|
---|
66 | S HLC2=$$RJ(HLC2,3)
|
---|
67 | ;-- end block
|
---|
68 | S X=HLDATA_HLC1_HLC2_$C(HLDEND)_$C(13)
|
---|
69 | U IO W X
|
---|
70 | Q
|
---|
71 | ACK ; Send ACK
|
---|
72 | N HLDATA
|
---|
73 | D INITIZE
|
---|
74 | ;-- start block and data
|
---|
75 | S (X,HLDATA)=$C(HLDSTRT)_"D"_HLDVER_$C(13)
|
---|
76 | D CHKSUM,CHKSUM1
|
---|
77 | S HLC1=$$RJ(HLC1,5)
|
---|
78 | S HLC2=$$RJ(HLC2,3)
|
---|
79 | ;-- end block
|
---|
80 | S X=HLDATA_HLC1_HLC2_$C(HLDEND)_$C(13)
|
---|
81 | U IO W X
|
---|
82 | Q
|
---|
83 | DUMP ;
|
---|
84 | Q:'$D(HLTRACE)
|
---|
85 | U IO(0)
|
---|
86 | W !,"DUMP"
|
---|
87 | I '$D(HLC1) S HLC1=-1
|
---|
88 | I '$D(HLC2) S HLC2=-1
|
---|
89 | I '$D(HLBLOCK) S HLBLOCK=-1
|
---|
90 | I '$D(HLXOR) S HLXOR=-1
|
---|
91 | W !,"HLC1=",HLC1," ","HLBLOCK=",HLBLOCK
|
---|
92 | W !,"HLC2=",HLC2," ","HLXOR=",HLXOR
|
---|
93 | Q
|
---|
94 | CHKSUM ;
|
---|
95 | X ^%ZOSF("LPC") S HLC1=HLC1+$L(X),HLC2=HLC2_$C(Y)
|
---|
96 | I $L(HLC2)>240 D CHKSUM1
|
---|
97 | Q
|
---|
98 | CHKSUM1 ;
|
---|
99 | S X=HLC2 X ^%ZOSF("LPC") S HLC2=Y
|
---|
100 | Q
|
---|
101 | VALID1(FLAG,CHK,HLIND0,HLIND1) ;
|
---|
102 | ;This function extracts the checksum sent with a message and then
|
---|
103 | ;compares it to the checksums that have been calculated and stored
|
---|
104 | ;in the HLC1 and HLC2 variables. HLC1 and HLC2 are not passed as
|
---|
105 | ;parameters, their scope is "communication server-wide"
|
---|
106 | ;FLAG tells the function what type of message this is, should the
|
---|
107 | ;last block of data be written to an "in queue" ? or a TMP variable ?
|
---|
108 | ;this depends on whether the incoming message is a message or just
|
---|
109 | ;a lower level acknowledgement "LLP-ACK"
|
---|
110 | ;CHK contains the 8 character cheksum that was sent with the message
|
---|
111 | ;HLIND0,HLIND1 are just D0 and D1 for the "input queue" in file #870
|
---|
112 | N HLBLOCK,HLXOR
|
---|
113 | ;WRITE LAST BLOCK 'O DATA TO GLOBAL
|
---|
114 | I $G(X)'="",FLAG="INCOMING MESSAGE" D SETNODE(HLIND0,HLIND1,HLTRANS),CHKSUM
|
---|
115 | I $G(X)'="",FLAG="LLP-ACK" D SETNODE2,CHKSUM
|
---|
116 | ;Extract checksums
|
---|
117 | S HLBLOCK=+$E(CHK,1,5),HLXOR=+$E(CHK,6,8)
|
---|
118 | D CHKSUM1,DUMP
|
---|
119 | S X="$$CHK$$^"_CHK_"^HLCHK^"_$$RJ(HLC1,5)_$$RJ(HLC2,3)
|
---|
120 | I FLAG="INCOMING MESSAGE" D MONITOR(HLBLOCK,5,HLDP,HLIND1,"IN"),MONITOR(HLXOR,6,HLDP,HLIND1,"IN"),MONITOR(HLC1,7,HLDP,HLIND1,"IN"),MONITOR(HLC2,8,HLDP,HLIND1,"IN")
|
---|
121 | I FLAG="LLP-ACK" D SETNODE2
|
---|
122 | I HLXOR="999" Q "VALID"
|
---|
123 | I HLBLOCK=HLC1,HLC2=HLXOR Q "VALID"
|
---|
124 | I HLBLOCK'=HLC1 Q "C"
|
---|
125 | I HLXOR'=HLC2 Q "X"
|
---|
126 | Q "G"
|
---|
127 | TRACE ;When HLTRACE is instantiated this subroutine simply writes out the
|
---|
128 | ;states that the finite state machine (Lower Layer Protocol) goes thru
|
---|
129 | Q:'$D(HLTRACE)
|
---|
130 | U IO(0) W !,"IN STATE ",HLNXST
|
---|
131 | Q
|
---|
132 | MONITOR(VALUE,PIECE,HLD0,HLD1,QUEUE) ;
|
---|
133 | ;This subroutine simply updates a particular piece in a global node
|
---|
134 | ;in file #870. It can be a zero node, or a node in a queue multiple
|
---|
135 | I '$D(^HLCS(870,HLD0,0)) Q
|
---|
136 | I $G(HLD1)']"" S $P(^HLCS(870,HLD0,0),U,PIECE)=VALUE Q
|
---|
137 | I PIECE=2,$G(QUEUE)="IN" D Q
|
---|
138 | . N HLJ
|
---|
139 | . S HLJ(870.019,HLD1_","_HLD0_",",1)=VALUE
|
---|
140 | . D FILE^HLDIE("","HLJ","","MONITOR","HLCSDR2") ; HL*1.6*109
|
---|
141 | S $P(^HLCS(870,HLD0,$S(QUEUE="IN":1,1:2),HLD1,0),U,PIECE)=VALUE
|
---|
142 | Q
|
---|
143 | FORMAT(HLC,LENGTH) ;Function to stuff leading zeroes for checksums
|
---|
144 | ;HLC is the checksum, Length is self-documenting
|
---|
145 | Q $E("00000",1,LENGTH-$L(HLC))
|
---|
146 | RJ(HLC,LENGTH) ;Function to stuff leading zeroes for checksums
|
---|
147 | ;HLC is the checksum, Length is self-documenting
|
---|
148 | ;Functionally equivalent to $$RJ^XLFSTR(HLC,LENGTH,"0")
|
---|
149 | ;Also equivalent to $$FORMAT(HLC,LENGTH)_HLC
|
---|
150 | Q $E("00000",1,LENGTH-$L(HLC))_HLC
|
---|