1 | HLCSTCP ;SFIRMFO/TNV-ALB/JFP,PKE - (TCP/IP) MLLP ;09/19/2007 10:21
|
---|
2 | ;;1.6;HEALTH LEVEL SEVEN;**19,43,49,57,58,64,84,109,133,122**;Oct 13, 1995;Build 14
|
---|
3 | ;Per VHA Directive 2004-038, this routine should not be modified.
|
---|
4 | ;
|
---|
5 | ; This is an implementation of the HL7 Minimal Lower Layer Protocol
|
---|
6 | ; taskman entry/startup option, HLDP defined in menu entry.
|
---|
7 | ;
|
---|
8 | Q:'$D(HLDP)
|
---|
9 | ; patch HL*1.6*122 start
|
---|
10 | L +^HLCS("HLTCPLINK",HLDP):5 I '$T D Q
|
---|
11 | . D MON^HLCSTCP("TskLcked")
|
---|
12 | N HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT,HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET
|
---|
13 | N HLZRULE
|
---|
14 | ;HLCSOUT= 1-error
|
---|
15 | I '$$INIT D EXITS("Init Error") Q
|
---|
16 | S HLDP("$J")=$J
|
---|
17 | S HLDP("$J",0,"LENGTH")=$L(HLDP("$J"))
|
---|
18 | ; Start the client
|
---|
19 | I $G(HLTCPCS)="C" D Q
|
---|
20 | . S HLDP("$J",0,"START")=HLDP("$J",0,"LENGTH")-8+$L(HLTCPORT)+$L(HLDP)
|
---|
21 | . I HLDP("$J",0,"START")<1 S HLDP("$J",0,"START")=1
|
---|
22 | . S HLDP("$J",0)=$E(HLDP("$J"),HLDP("$J",0,"START"),HLDP("$J",0,"LENGTH"))
|
---|
23 | . ; identify process for ^%SY
|
---|
24 | . ; D SETNM^%ZOSV($E("HLClnt:"_HLDP,1,15))
|
---|
25 | . D SETNM^%ZOSV($E("HLc:"_HLTCPORT_"-"_HLDP_"-"_HLDP("$J",0),1,15))
|
---|
26 | . K HLDP("$J",0)
|
---|
27 | . D ST1
|
---|
28 | . F D ^HLCSTCP2 Q:$$STOP!$G(HLCSOUT)
|
---|
29 | . ; I $G(HLCSOUT)=1 D MON("Error") H 1 Q
|
---|
30 | . I $G(HLCSOUT)=1 D Q
|
---|
31 | .. D MON("Error") H 1
|
---|
32 | .. L -^HLCS("HLTCPLINK",HLDP)
|
---|
33 | . I $G(HLCSOUT)=2 D EXITS("Inactive") Q
|
---|
34 | . D EXITS("Shutdown")
|
---|
35 | ;
|
---|
36 | S HLDP("$J",0,"START")=HLDP("$J",0,"LENGTH")-9+$L(HLTCPORT)
|
---|
37 | I HLDP("$J",0,"START")<1 S HLDP("$J",0,"START")=1
|
---|
38 | S HLDP("$J",0)=$E(HLDP("$J"),HLDP("$J",0,"START"),HLDP("$J",0,"LENGTH"))
|
---|
39 | ; identify process for ^%SY
|
---|
40 | ; D SETNM^%ZOSV($E("HLSrv:"_HLDP,1,15))
|
---|
41 | D SETNM^%ZOSV($E("HLs:"_HLTCPORT_"-"_HLDP("$J",0),1,15))
|
---|
42 | K HLDP("$J",0)
|
---|
43 | ; to stop the listener via updated Kernel API, need to pass the
|
---|
44 | ; listener logical link (HLDP)
|
---|
45 | S HLZRULE="S HLDP="_HLDP_" S ZISQUIT=$$STOP^HLCSTCP"
|
---|
46 | ;single threaded listener
|
---|
47 | I $G(HLTCPCS)="S" D Q
|
---|
48 | . D ST1,MON("Listen"),LISTEN^%ZISTCP(HLTCPORT,"SERVER^HLCSTCP("""_HLDP_""")",HLZRULE)
|
---|
49 | . I $$STOP D EXITS("Shutdown") Q
|
---|
50 | . D EXITS("Openfail")
|
---|
51 | ;
|
---|
52 | ;multi-threaded listener (for OpenM/NT)
|
---|
53 | I ($G(HLTCPCS)'="M")!(^%ZOSF("OS")'["OpenM") D Q
|
---|
54 | . L -^HLCS("HLTCPLINK",HLDP)
|
---|
55 | I $$OS^%ZOSV["VMS" L -^HLCS("HLTCPLINK",HLDP) Q
|
---|
56 | D ST1,MON("Listen"),LISTEN^%ZISTCPS(HLTCPORT,"SERVERS^HLCSTCP("""_HLDP_""")",HLZRULE)
|
---|
57 | ; update status of listener
|
---|
58 | I $$STOP D EXITS("Shutdown") Q
|
---|
59 | D EXITS("Openfail")
|
---|
60 | ; HL*1.6*122 end
|
---|
61 | Q
|
---|
62 | ;
|
---|
63 | SERVER(HLDP) ; single server using Taskman
|
---|
64 | I '$$INIT D EXITS("Init error") Q
|
---|
65 | D ^HLCSTCP1
|
---|
66 | I $$STOP D CLOSE^%ZISTCP,EXITS("Shutdown") S IO("C")="" Q
|
---|
67 | Q:$G(HLCSOUT)=1
|
---|
68 | D MON("Idle")
|
---|
69 | Q
|
---|
70 | ;
|
---|
71 | SERVERS(HLDP) ; Multi-threaded server using Taskman
|
---|
72 | I '$$INIT D EXITS("Init error") Q
|
---|
73 | G LISTEN
|
---|
74 | ;
|
---|
75 | ;multiple process servers, called from an external utility
|
---|
76 | MSM ;MSM entry point, called from User-Defined Services
|
---|
77 | ;HLDP=ien in the HL LOWER LEVEL PROTOCOL PARAMETER file for the
|
---|
78 | ;HL7 Multi-Threaded SERVER
|
---|
79 | S (IO,IO(0))=$P
|
---|
80 | G LISTEN
|
---|
81 | ;
|
---|
82 | LISTEN ;
|
---|
83 | N HLLSTN,HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT,HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET
|
---|
84 | I '$$INIT D ^%ZTER Q
|
---|
85 | ; patch HL*1.6*122 start
|
---|
86 | S HLDP("$J")=$J
|
---|
87 | S HLDP("$J",0,"LENGTH")=$L(HLDP("$J"))
|
---|
88 | S HLDP("$J",0,"START")=HLDP("$J",0,"LENGTH")-9+$L(HLTCPORT)
|
---|
89 | I HLDP("$J",0,"START")<1 S HLDP("$J",0,"START")=1
|
---|
90 | S HLDP("$J",0)=$E(HLDP("$J"),HLDP("$J",0,"START"),HLDP("$J",0,"LENGTH"))
|
---|
91 | ; identify process for ^%SY
|
---|
92 | ; D SETNM^%ZOSV($E("HLSrv:"_HLDP,1,15))
|
---|
93 | D SETNM^%ZOSV($E("HLs:"_HLTCPORT_"-"_HLDP("$J",0),1,15))
|
---|
94 | K HLDP("$J",0)
|
---|
95 | ; patch HL*1.6*122 end
|
---|
96 | ;HLLSTN used to identify a listener to tag MON
|
---|
97 | S HLLSTN=1
|
---|
98 | ;increment job count, run server
|
---|
99 | D UPDT(1),^HLCSTCP1,EXITM
|
---|
100 | Q
|
---|
101 | ;
|
---|
102 | DCOPEN(HLDP) ;open direct connect - called from HLMA2
|
---|
103 | Q:'$$INIT 0
|
---|
104 | Q:HLTCPADD=""!(HLTCPORT="") 0
|
---|
105 | Q:'$$OPEN^HLCSTCP2 0
|
---|
106 | Q 1
|
---|
107 | ;
|
---|
108 | INIT() ; Initialize Variables
|
---|
109 | ; HLDP should be set to the IEN or name of Logical Link, file 870
|
---|
110 | S HLOS=$P($G(^%ZOSF("OS")),"^")
|
---|
111 | N DA,DIQUIET,DR,TMP,X,Y
|
---|
112 | S IOF=$$FLUSHCHR^%ZISTCP ; HL*1.6*122 set device flush character
|
---|
113 | S DIQUIET=1
|
---|
114 | D DT^DICRW
|
---|
115 | I 'HLDP S HLDP=$O(^HLCS(870,"B",HLDP,0)) I 'HLDP Q 0
|
---|
116 | S DA=HLDP
|
---|
117 | ; patch HL*1.6*122 for field 400.09
|
---|
118 | S DR="200.02;200.021;200.022;200.03;200.04;200.05;200.09;400.01;400.02;400.03;400.04;400.05;400.09"
|
---|
119 | D GETS^DIQ(870,DA,DR,"IN","TMP","TMP")
|
---|
120 | ;
|
---|
121 | I $D(TMP("DIERR")) QUIT 0
|
---|
122 | ; -- re-transmit attempts
|
---|
123 | S HLDRETR=+$G(TMP(870,DA_",",200.02,"I"))
|
---|
124 | S HLDRETR("CLOSE")=+$G(TMP(870,DA_",",200.022,"I"))
|
---|
125 | ; -- exceed re-transmit action
|
---|
126 | S HLRETRA=$G(TMP(870,DA_",",200.021,"I"))
|
---|
127 | ; -- block size
|
---|
128 | S HLDBSIZE=+$G(TMP(870,DA_",",200.03,"I"))
|
---|
129 | ; -- read timeout
|
---|
130 | S HLDREAD=+$G(TMP(870,DA_",",200.04,"I"))
|
---|
131 | ; -- ack timeout
|
---|
132 | S HLDBACK=+$G(TMP(870,DA_",",200.05,"I"))
|
---|
133 | ; -- uni-directional wait
|
---|
134 | S HLDWAIT=$G(TMP(870,DA_",",200.09,"I"))
|
---|
135 | ; -- tcp address
|
---|
136 | S HLTCPADD=$G(TMP(870,DA_",",400.01,"I"))
|
---|
137 | ; -- tcp port
|
---|
138 | S HLTCPORT=$G(TMP(870,DA_",",400.02,"I"))
|
---|
139 | ; -- tcp/ip service type
|
---|
140 | S HLTCPCS=$G(TMP(870,DA_",",400.03,"I"))
|
---|
141 | ; -- link persistence
|
---|
142 | S HLTCPLNK=$G(TMP(870,DA_",",400.04,"I"))
|
---|
143 | ; -- retention
|
---|
144 | S HLTCPRET=$G(TMP(870,DA_",",400.05,"I"))
|
---|
145 | ;
|
---|
146 | ; patch HL*1.6*122 for field 400.09
|
---|
147 | ; -- tcp/ip openfail timeout
|
---|
148 | S HLTCPLNK("TIMEOUT")=$G(TMP(870,DA_",",400.09,"I"))
|
---|
149 | ;
|
---|
150 | ; -- set defaults in case something's not set
|
---|
151 | S:HLDREAD=0 HLDREAD=10
|
---|
152 | S:HLDBACK=0 HLDBACK=60
|
---|
153 | ; patch HL*1.6*122
|
---|
154 | ; S:HLDBSIZE=0 HLDBSIZE=245
|
---|
155 | S:HLDBSIZE<245 HLDBSIZE=245
|
---|
156 | S:HLDRETR=0 HLDRETR=5
|
---|
157 | S:HLTCPRET="" X=$P($$PARAM^HLCS2,U,12),HLTCPRET=$S(X:X,1:15)
|
---|
158 | ;
|
---|
159 | ; patch HL*1.6*122 for field 400.09
|
---|
160 | S:HLTCPLNK("TIMEOUT")=0 HLTCPLNK("TIMEOUT")=5
|
---|
161 | ;
|
---|
162 | Q 1
|
---|
163 | ;
|
---|
164 | ST1 ;record startup in 870 for single server
|
---|
165 | ;4=status 9=Time Started, 10=Time Stopped, 11=Task Number
|
---|
166 | ;14=Shutdown LLP, 3=LLP Online, 18=Gross Errors
|
---|
167 | N HLJ,X
|
---|
168 | ; HL*1.6*122 remove unnecessary locks
|
---|
169 | ;F L +^HLCS(870,HLDP,0):2 Q:$T
|
---|
170 | S X="HLJ(870,"""_HLDP_","")"
|
---|
171 | S @X@(4)="Init",(@X@(10),@X@(18))="@",@X@(14)=0
|
---|
172 | I HLTCPCS["C" S @X@(3)=$S(HLTCPLNK["Y":"PC",1:"NC")
|
---|
173 | E S @X@(3)=$S(HLTCPCS["S":"SS",HLTCPCS["M":"MS",1:"")
|
---|
174 | I @X@(3)'="NC" S @X@(9)=$$NOW^XLFDT
|
---|
175 | S:$G(ZTSK) @X@(11)=ZTSK
|
---|
176 | D FILE^HLDIE("","HLJ","","ST1","HLCSTCP") ;HL*1.6*109
|
---|
177 | ;L -^HLCS(870,HLDP,0)
|
---|
178 | Q
|
---|
179 | ;
|
---|
180 | MON(Y) ;Display current state & check for shutdown
|
---|
181 | ;don't display for multiple server
|
---|
182 | Q:$G(HLLSTN)
|
---|
183 | ; HL*1.6*122 remove unnecessary locks
|
---|
184 | ;F L +^HLCS(870,HLDP,0):2 Q:$T
|
---|
185 | S $P(^HLCS(870,HLDP,0),U,5)=Y
|
---|
186 | ;L -^HLCS(870,HLDP,0)
|
---|
187 | Q:'$D(HLTRACE)
|
---|
188 | N X U IO(0)
|
---|
189 | W !,"IN State: ",Y
|
---|
190 | I '$$STOP D
|
---|
191 | . ; patch HL*1.6*122
|
---|
192 | . ; R !,"Type Q to Quit: ",X#1:1
|
---|
193 | . R !,"Type Q to Quit: ",X:1
|
---|
194 | . ; I $L(X),"Qq"[X S $P(^HLCS(870,HLDP,0),U,15)=1
|
---|
195 | . I $L(X),"Qq"[$E(X) S $P(^HLCS(870,HLDP,0),U,15)=1
|
---|
196 | . ; patch HL*1.6*122 end
|
---|
197 | U IO
|
---|
198 | Q
|
---|
199 | UPDT(Y) ;update job count for multiple servers,X=1 increment
|
---|
200 | N HLJ,X
|
---|
201 | ;
|
---|
202 | ; HL*1.6*122 start
|
---|
203 | ; F L +^HLCS(870,HLDP,0):2 Q:$T
|
---|
204 | Q:'$G(HLDP)
|
---|
205 | Q:'$D(^HLCS(870,"E","M",HLDP))
|
---|
206 | F L +^HLCS(870,HLDP,0):10 Q:$T H 1
|
---|
207 | ; S X=+$P(^HLCS(870,HLDP,0),U,5),$P(^(0),U,5)=$S(Y:X+1,1:X-1)_" server"
|
---|
208 | S X=+$P(^HLCS(870,HLDP,0),U,5)
|
---|
209 | I X<0 S X=0
|
---|
210 | S $P(^HLCS(870,HLDP,0),U,5)=$S(Y:(X+1),X<1:0,1:X-1)_" server"
|
---|
211 | ;if incrementing, set the Device Type field to Multi-Server
|
---|
212 | ; I X S HLJ(870,HLDP_",",3)="MS" D FILE^HLDIE("","HLJ","","UPDT","HLCSTCP")
|
---|
213 | I $P(^HLCS(870,HLDP,0),"^",4)']"" S $P(^HLCS(870,HLDP,0),"^",4)="MS"
|
---|
214 | ; HL*1.6*122 end
|
---|
215 | ;
|
---|
216 | L -^HLCS(870,HLDP,0)
|
---|
217 | Q
|
---|
218 | STOP() ;stop flag set
|
---|
219 | N X
|
---|
220 | F L +^HLCS(870,HLDP,0):2 Q:$T
|
---|
221 | S X=+$P(^HLCS(870,HLDP,0),U,15)
|
---|
222 | L -^HLCS(870,HLDP,0)
|
---|
223 | Q X
|
---|
224 | ;
|
---|
225 | LLCNT(DP,Y,Z) ;update Logical Link counters
|
---|
226 | ;DP=ien of Logical Link in file 870
|
---|
227 | ;Y: 1=msg rec, 2=msg proc, 3=msg to send, 4=msg sent
|
---|
228 | ;Z: ""=add to counter, 1=subtract from counter
|
---|
229 | Q:'$D(^HLCS(870,+$G(DP),0))!('$G(Y))
|
---|
230 | N P,X
|
---|
231 | S P=$S(Y<3:"IN",1:"OUT")_" QUEUE "_$S(Y#2:"BACK",1:"FRONT")_" POINTER"
|
---|
232 | ; patch HL*1.6*122 start
|
---|
233 | ; F L +^HLCS(870,DP,P):2 Q:$T
|
---|
234 | ; S X=+$G(^HLCS(870,DP,P)),^(P)=X+$S($G(Z):-1,1:1)
|
---|
235 | I '$L($G(OS)) N OS S OS=$G(^%ZOSF("OS"))
|
---|
236 | I OS'["DSM",OS'["OpenM" D
|
---|
237 | . F L +^HLCS(870,DP,P):10 Q:$T H 1
|
---|
238 | . S X=+$G(^HLCS(870,DP,P)),^(P)=X+$S($G(Z):-1,1:1)
|
---|
239 | . L -^HLCS(870,DP,P)
|
---|
240 | E D
|
---|
241 | . S X=$I(^HLCS(870,DP,P),$S($G(Z):-1,1:1))
|
---|
242 | ; L -^HLCS(870,DP,P)
|
---|
243 | ; patch HL*1.6*122 end
|
---|
244 | Q
|
---|
245 | SDFLD ; set Shutdown? field to yes
|
---|
246 | Q:'$G(HLDP)
|
---|
247 | ; HL*1.6*122 remove unnecessary lock and call to FM
|
---|
248 | S $P(^HLCS(870,HLDP,0),U,15)=1
|
---|
249 | ;N HLJ,X
|
---|
250 | ;F L +^HLCS(870,HLDP,0):2 Q:$T
|
---|
251 | ;14=Shutdown LLP?
|
---|
252 | ;S HLJ(870,HLDP_",",14)=1
|
---|
253 | ;D FILE^HLDIE("","HLJ","","SDFLD","HLCSTCP") ;HL*1.6*109
|
---|
254 | ;L -^HLCS(870,HLDP,0)
|
---|
255 | Q
|
---|
256 | ;
|
---|
257 | EXITS(Y) ; shutdown and clean up the listener process for either
|
---|
258 | ; single-threaded or multi-threaded
|
---|
259 | N HLJ,X
|
---|
260 | F L +^HLCS(870,HLDP,0):2 Q:$T
|
---|
261 | ;4=status,10=Time Stopped,9=Time Started,11=Task Number
|
---|
262 | S X="HLJ(870,"""_HLDP_","")"
|
---|
263 | S @X@(4)=Y,@X@(11)="@"
|
---|
264 | S:$G(HLCSOUT)'=2 @X@(10)=$$NOW^XLFDT,@X@(9)="@"
|
---|
265 | D FILE^HLDIE("","HLJ","","EXITS","HLCSTCP") ; HL*1.6*109
|
---|
266 | L -^HLCS(870,HLDP,0)
|
---|
267 | I $D(ZTQUEUED) S ZTREQ="@"
|
---|
268 | ; HL*1.6*122
|
---|
269 | L -^HLCS("HLTCPLINK",HLDP)
|
---|
270 | Q
|
---|
271 | ;
|
---|
272 | EXITM ;Multiple service shutdown and clean up
|
---|
273 | ; shutdown and clean up a connection spawned by the listener
|
---|
274 | ; process for a multi-threaded listener
|
---|
275 | D UPDT(0)
|
---|
276 | I $D(ZTQUEUED) S ZTREQ="@"
|
---|
277 | Q
|
---|