Changeset 623 for WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOSRVR1.m
- Timestamp:
- Dec 4, 2009, 12:11:15 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOSRVR1.m
r613 r623 1 HLOSRVR1 ;IRMFO-ALB/CJM - Reading messages, sending acks;03/24/2004 14:43 ;07/17/2007 2 ;;1.6;HEALTH LEVEL SEVEN;**126,130,131,133,134,137**;Oct 13, 1995;Build 21 3 ;Per VHA Directive 2004-038, this routine should not be modified. 4 ; 5 READMSG(HLCSTATE,HLMSTATE) ; 6 ;Reads a message. The header is parsed. Does these checks: 7 ; 1) Duplicate? 8 ; 2) Wrong Receiving Facility? 9 ; 3) Can the Receiving App accept this message, based message type & event? 10 ; 4) Processing ID must match the receiving system 11 ; 5) Must have an ID 12 ; 6) Header must be BHS or MSH 13 ; 14 ;Output: 15 ; Function returns 1 if the message was read fully, 0 otherwise 16 ; HLMSTATE (pass by reference) the message. It will include the fields for the return ack in HLMSTATE("MSA") 17 ; 18 N ACK,SEG,STORE,I 19 ; 20 S STORE=1 21 Q:'$$READHDR^HLOT(.HLCSTATE,.SEG) 0 22 D SPLITHDR(.SEG) 23 ; 24 ;parse the header, stop if unsuccessful because the server cannot know what to do next 25 I '$$PARSEHDR^HLOPRS(.SEG) D Q 0 26 .S HLCSTATE("MESSAGE ENDED")=0 27 .D CLOSE^HLOT(.HLCSTATE) 28 D NEWMSG^HLOSRVR2(.HLCSTATE,.HLMSTATE,.SEG) 29 I HLMSTATE("ID")="" D 30 .S STORE=0 31 .I HLMSTATE("HDR","ACCEPT ACK TYPE")="AL" S HLMSTATE("MSA",1)="CE",HLMSTATE("MSA",3)="CONTROL ID MISSING" 32 I STORE,$$DUP(.HLMSTATE) S STORE=0 33 ; 34 ;if the message is not to be stored, just read it and discard the segments 35 I 'STORE D 36 .F Q:'$$READSEG^HLOT(.HLCSTATE,.SEG) 37 ; 38 E D 39 .N FS 40 .S FS=HLMSTATE("HDR","FIELD SEPARATOR") 41 .F Q:'$$READSEG^HLOT(.HLCSTATE,.SEG) D 42 ..N MSA,SEGTYPE,OLDMSGID,CODE,IEN,NEWMSGID,TEXT 43 ..S SEGTYPE=$E($E(SEG(1),1,3)_$E($G(SEG(2)),1,2),1,3) 44 ..I SEGTYPE="MSA" D 45 ...S MSA=SEG(1)_$G(SEG(2))_$G(SEG(3)) 46 ...S OLDMSGID=$P(MSA,FS,3),CODE=$P(MSA,FS,2),TEXT=$E($P(MSA,FS,4),1,30) 47 ...I $E(CODE,1)'="A" S SEGTYPE="" Q 48 ...S:$P(OLDMSGID,"-")]"" IEN=$O(^HLB("B",$P(OLDMSGID,"-"),0)) 49 ...S:$G(IEN) IEN=IEN_"^"_$P(OLDMSGID,"-",2) 50 ..I 'HLMSTATE("BATCH") D 51 ...D:SEGTYPE="MSA" 52 ....S HLMSTATE("ACK TO")=OLDMSGID 53 ....S HLMSTATE("ACK TO","ACK BY")=HLMSTATE("ID") 54 ....S HLMSTATE("ACK TO","STATUS")=$S(CODE="AA":"SU",1:"ER") 55 ....I $G(IEN) D 56 .....S HLMSTATE("ACK TO","IEN")=IEN 57 .....S HLMSTATE("ACK TO","SEQUENCE QUEUE")=$P($G(^HLB(+IEN,5)),"^") 58 ....S HLMSTATE("ACK TO","ERROR TEXT")=TEXT 59 ...D ADDSEG^HLOMSG(.HLMSTATE,.SEG) 60 ..E D ;batch 61 ...I SEGTYPE="MSH" D 62 ....D SPLITHDR(.SEG) 63 ....S NEWMSGID=$P(SEG(2),FS,5) 64 ....D ADDMSG2^HLOMSG(.HLMSTATE,.SEG) 65 ...E D ;not MSH 66 ....D:SEGTYPE="MSA" 67 .....N SUBIEN S SUBIEN=HLMSTATE("BATCH","CURRENT MESSAGE") 68 .....S HLMSTATE("BATCH","ACK TO",SUBIEN)=OLDMSGID 69 .....S HLMSTATE("BATCH","ACK TO",SUBIEN,"ACK BY")=NEWMSGID 70 .....S HLMSTATE("BATCH","ACK TO",SUBIEN,"STATUS")=$S(CODE="AA":"SU",1:"ER") 71 .....S:$D(IEN) HLMSTATE("BATCH","ACK TO",SUBIEN,"IEN")=IEN 72 ....D ADDSEG^HLOMSG(.HLMSTATE,.SEG) 73 .I HLMSTATE("UNSTORED LINES"),HLCSTATE("MESSAGE ENDED"),$$SAVEMSG^HLOF778(.HLMSTATE) 74 ; 75 I STORE,'HLCSTATE("MESSAGE ENDED") D 76 .;reading failed, don't store 77 .D:HLMSTATE("IEN") DEL778(HLMSTATE("IEN")) D:HLMSTATE("BODY") DEL777(HLMSTATE("BODY")) 78 .S HLMSTATE("IEN")="",HLMSTATE("BODY")="" 79 E D:STORE 80 .D CHECKMSG(.HLMSTATE) 81 .D ADDAC(.HLMSTATE) ;so future duplicates are detected 82 .D COUNT^HLOSTAT(.HLCSTATE,HLMSTATE("HDR","RECEIVING APPLICATION"),HLMSTATE("HDR","SENDING APPLICATION"),$S(HLMSTATE("BATCH"):"BATCH",1:HLMSTATE("HDR","MESSAGE TYPE")_"~"_HLMSTATE("HDR","EVENT"))) 83 ; 84 D:'HLCSTATE("MESSAGE ENDED") CLOSE^HLOT(.HLCSTATE) 85 Q HLCSTATE("MESSAGE ENDED") 86 ; 87 ADDAC(HLMSTATE) ;adds the AC xref for duplicates detection 88 ; 89 N FROM 90 S FROM=$S(HLMSTATE("HDR","SENDING FACILITY",2)]"":HLMSTATE("HDR","SENDING FACILITY",2),1:HLMSTATE("HDR","SENDING FACILITY",1)) 91 S ^HLB("AC",FROM_HLMSTATE("HDR","SENDING APPLICATION")_HLMSTATE("ID"),HLMSTATE("IEN"))="" 92 Q 93 ; 94 DUP(HLMSTATE) ; 95 ;Returns 1 if the message is a duplicate and its ack (if requested) is found, 0 otherwise 96 ;Input: 97 ; HLMSTATE (pass by reference) the message being read 98 ;Output: 99 ; Function returns 1 if the message is a duplicate, 0 otherwise 100 ; HLMSTATE (pass by reference) IF the message is a duplicate: 101 ; returns the prior MSA segment in HLMSTATE("MSA") 102 ; 103 N IEN,FROM,DUP 104 S (IEN,DUP)=0 105 ; 106 ;no way to determine! Bad header will be rejected 107 Q:(HLMSTATE("ID")="") 0 108 ; 109 S FROM=$S(HLMSTATE("HDR","SENDING FACILITY",2)]"":HLMSTATE("HDR","SENDING FACILITY",2),1:HLMSTATE("HDR","SENDING FACILITY",1)) 110 F S IEN=$O(^HLB("AC",FROM_HLMSTATE("HDR","SENDING APPLICATION")_HLMSTATE("ID"),IEN)) Q:'IEN D Q:DUP 111 .I HLMSTATE("HDR","ACCEPT ACK TYPE")="NE" S DUP=1 Q 112 .;need the MSA to return 113 .D Q 114 ..N NODE 115 ..S NODE=$P($G(^HLB(IEN,4)),"^",3,10) 116 ..S HLMSTATE("MSA",1)=$P(NODE,"|",2) 117 ..Q:$L(HLMSTATE("MSA",1))'=2 118 ..S HLMSTATE("MSA",2)=$P(NODE,"|",3) 119 ..S HLMSTATE("MSA",3)=$P(NODE,"|",4,10) 120 ..S DUP=1 121 ; 122 Q DUP 123 ; 124 CHECKMSG(HLMSTATE) ; 125 ;Checks the header & MSA segment, sets HLMSTATE("STATUS","ACTION") if the message needs to be passed, determines if completion status should be set 126 ;Input: 127 ; HLMSTATE("HDR") - the parsed header segment 128 ;Output: 129 ; HLMSTATE("STATUS")="ER" if an error is detected 130 ; HLMSTATE("STATUS","QUEUE") queue to put the message on 131 ; HLMSTATE("STATUS","ACTION") <tag^rtn> that is the processing routine for the receiving application 132 ; HLMSTATE("MSA") - MSA(1)=accept code to be returned, MSA(3)= error txt 133 ; 134 N WANTACK,PASS,ACTION,QUEUE,ERROR 135 M HDR=HLMSTATE("HDR") 136 S ERROR=0 137 I HDR("ACCEPT ACK TYPE")="NE",'HLMSTATE("ORIGINAL MODE") D 138 .S WANTACK=0 139 E D 140 .S WANTACK=1 141 I HLMSTATE("ORIGINAL MODE") S HLMSTATE("MSA",1)="AE",HLMSTATE("MSA",3)="THIS INTERFACE DOES NOT IMPLEMENT ORIGINAL MODE APPLICATION ACKOWLEDGMENTS",HLMSTATE("STATUS")="ER" Q 142 I $G(HLMSTATE("ACK TO"))="" D Q:ERROR 143 .I '$$ACTION^HLOAPP(.HDR,.ACTION,.QUEUE) S ERROR=1 S:WANTACK HLMSTATE("MSA",1)="CR" S HLMSTATE("MSA",3)="RECEIVING APPLICATION NOT DEFINED",HLMSTATE("STATUS")="ER" Q 144 .S HLMSTATE("STATUS","ACTION")=$G(ACTION),HLMSTATE("STATUS","QUEUE")=$G(QUEUE) 145 E D Q:ERROR ;this is an app ack 146 .;does the original message exist? 147 .N NODE 148 .S:+$G(HLMSTATE("ACK TO","IEN")) NODE=$G(^HLB(+HLMSTATE("ACK TO","IEN"),0)) 149 .I $G(NODE)="" S ERROR=1,HLMSTATE("STATUS")="ER",HLMSTATE("ACK TO","IEN")="" S:WANTACK HLMSTATE("MSA",1)="CE" S HLMSTATE("MSA",3)="INITIAL MESSAGE TO APPLICATION ACKNOWLEDGMENT NOT FOUND" Q 150 .I $P(NODE,"^",7)'="",$P(NODE,"^",7)'=HLMSTATE("ID") S ERROR=1,HLMSTATE("STATUS")="ER",HLMSTATE("ACK TO","IEN")="" S:WANTACK HLMSTATE("MSA",1)="CE" S HLMSTATE("MSA",3)="INITIAL MESSAGE WAS ALREADY ACKED" Q 151 .I ($P(NODE,"^",11)]"") S HLMSTATE("STATUS","ACTION")=$P(NODE,"^",10,11),HLMSTATE("STATUS","QUEUE")=$S($P(NODE,"^",6)]"":$P(NODE,"^",6),1:"DEFAULT") Q 152 .;processing routine for the app ack wasn't found with the original message, look in the HLO Application Registry 153 .I HLMSTATE("HDR","MESSAGE TYPE")="ACK",HLMSTATE("HDR","EVENT")="" S HDR("EVENT")=$$GETEVENT^HLOCLNT2(+HLMSTATE("ACK TO","IEN")) 154 .I $$ACTION^HLOAPP(.HDR,.ACTION,.QUEUE) S HLMSTATE("STATUS","ACTION")=$G(ACTION),HLMSTATE("STATUS","QUEUE")=$G(QUEUE) 155 ; 156 I HDR("PROCESSING ID")'=HLCSTATE("SYSTEM","PROCESSING ID") S:WANTACK HLMSTATE("MSA",1)="CR" S HLMSTATE("STATUS")="ER",HLMSTATE("MSA",3)="SYSTEM PROCESSING ID="_HLCSTATE("SYSTEM","PROCESSING ID") Q 157 ; 158 ;wrong receiving facility? This is hard to check if the sender is not VistA, because the HL7 standard permits different coding systems to be used. This check is only for DNS or station number. 159 S PASS=0 160 D 161 .;if its an ack to an existing message, don't check the receiving facility 162 .I $G(HLMSTATE("ACK TO"))]"" S PASS=1 Q 163 .I HDR("RECEIVING FACILITY",1)=HLCSTATE("SYSTEM","STATION") S PASS=1 Q 164 .I HDR("RECEIVING FACILITY",3)'="DNS" S PASS=1 Q 165 .I HDR("RECEIVING FACILITY",2)="" S PASS=1 Q 166 .I $P(HDR("RECEIVING FACILITY",2),":")[HLCSTATE("SYSTEM","DOMAIN") S PASS=1 Q 167 .I HLCSTATE("SYSTEM","DOMAIN")[$P(HDR("RECEIVING FACILITY",2),":") S PASS=1 Q 168 I 'PASS S HLMSTATE("STATUS")="ER",HLMSTATE("MSA",3)="RECEIVING FACILITY IS "_HLCSTATE("SYSTEM","DOMAIN") S:WANTACK HLMSTATE("MSA",1)="CE" 169 I PASS,WANTACK S HLMSTATE("MSA",1)="CA" 170 Q 171 ; 172 DEL777(IEN777) ;delete a record from file 777 where the read did not complete 173 ; 174 K ^HLA(IEN777,0) 175 Q 176 DEL778(IEN778) ;delete a record from file 778 where the read did not complete 177 ; 178 K ^HLB(IEN778,0) 179 Q 180 ; 181 SPLITHDR(HDR) ; 182 ;splits hdr segment into two lines, first being just components 1-6 183 ; 184 N TEMP,FS 185 D SQUISH(.HDR) 186 S FS=$E($G(HDR(1)),4) 187 S TEMP(1)=$P($G(HDR(1)),FS,1,6) 188 S TEMP(2)="" 189 I $L(TEMP(1))<$L($G(HDR(1))) S TEMP(2)=FS_$P($G(HDR(1)),FS,7,20) 190 S HDR(2)=TEMP(2)_$G(HDR(2)) 191 S HDR(1)=TEMP(1) 192 Q 193 ; 194 SQUISH(SEG) ; 195 ;reformat the segment array into full lines 196 ; 197 ;nothing to do if less than 2 lines 198 Q:'$O(SEG(1)) 199 ; 200 N A,I,J,K,MAX,COUNT,LEN 201 S MAX=$S($G(HLCSTATE("SYSTEM","MAXSTRING"))>256:HLCSTATE("SYSTEM","MAXSTRING"),1:256) 202 S (COUNT,I)=0,J=1 203 F S I=$O(SEG(I)) Q:'I D 204 .S LEN=$L(SEG(I)) 205 .F K=1:1:LEN D 206 ..S A(J)=$G(A(J))_$E(SEG(I),K) 207 ..S COUNT=COUNT+1 208 ..I (COUNT>(MAX-1)) S COUNT=0,J=J+1 209 K SEG 210 M SEG=A 211 Q 212 ; 213 ERROR ;error trap 214 S $ETRAP="Q:$QUIT """" Q" 215 D END^HLOSRVR 216 ; 217 ;multi-listener should stop execution, only a single server may continue 218 I $P($G(HLCSTATE("LINK","SERVER")),"^",2)'="S" D Q:$QUIT "" Q 219 .;don't log these errors 220 .I ($ECODE["READ")!($ECODE["NOTOPEN")!($ECODE["DEVNOTOPN")!($ECODE["WRITE")!($ECODE["OPENERR") D 221 ..; 222 .E D 223 ..D ^%ZTER 224 ; 225 ;debugging? 226 I $G(^HLTMP("LOG ALL ERRORS"))!($ECODE["EDITED") Q:$QUIT "" Q 227 ; 228 ;possibly an endless loop? 229 N HOUR 230 S HOUR=$E($$NOW^XLFDT,1,10) 231 I ($G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))>30) Q:$QUIT "" Q 232 ; 233 ;resume execution for the single listener 234 S ^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2))=$G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))+1 235 D UNWIND^%ZTER 236 Q 1 HLOSRVR1 ;IRMFO-ALB/CJM - Reading messages, sending acks;03/24/2004 14:43 ;03/26/2007 2 ;;1.6;HEALTH LEVEL SEVEN;**126,130,131,133,134**;Oct 13, 1995;Build 30 3 ;Per VHA Directive 2004-038, this routine should not be modified. 4 ; 5 READMSG(HLCSTATE,HLMSTATE) ; 6 ;Reads a message. The header is parsed. Does these checks: 7 ; 1) Duplicate? 8 ; 2) Wrong Receiving Facility? 9 ; 3) Can the Receiving App accept this message, based message type & event? 10 ; 4) Processing ID must match the receiving system 11 ; 5) Must have an ID 12 ; 6) Header must be BHS or MSH 13 ; 14 ;Output: 15 ; Function returns 1 if the message was read fully, 0 otherwise 16 ; HLMSTATE (pass by reference) the message. It will include the fields for the return ack in HLMSTATE("MSA") 17 ; 18 N ACK,SEG,STORE,I 19 ; 20 S STORE=1 21 Q:'$$READHDR^HLOT(.HLCSTATE,.SEG) 0 22 D SPLITHDR(.SEG) 23 ; 24 ;parse the header, stop if unsuccessful because the server cannot know what to do next 25 I '$$PARSEHDR^HLOPRS(.SEG) D Q 0 26 .S HLCSTATE("MESSAGE ENDED")=0 27 .D CLOSE^HLOT(.HLCSTATE) 28 D NEWMSG^HLOSRVR2(.HLCSTATE,.HLMSTATE,.SEG) 29 I HLMSTATE("ID")="" D 30 .S STORE=0 31 .I HLMSTATE("HDR","ACCEPT ACK TYPE")="AL" S HLMSTATE("MSA",1)="CE",HLMSTATE("MSA",3)="CONTROL ID MISSING" 32 I STORE,$$DUP(.HLMSTATE) S STORE=0 33 ; 34 ;if the message is not to be stored, just read it and discard the segments 35 I 'STORE D 36 .F Q:'$$READSEG^HLOT(.HLCSTATE,.SEG) 37 ; 38 E D 39 .N FS 40 .S FS=HLMSTATE("HDR","FIELD SEPARATOR") 41 .F Q:'$$READSEG^HLOT(.HLCSTATE,.SEG) D 42 ..N MSA,SEGTYPE,OLDMSGID,CODE,IEN,NEWMSGID,TEXT 43 ..S SEGTYPE=$E($E(SEG(1),1,3)_$E($G(SEG(2)),1,2),1,3) 44 ..I SEGTYPE="MSA" D 45 ...S MSA=SEG(1)_$G(SEG(2))_$G(SEG(3)) 46 ...S OLDMSGID=$P(MSA,FS,3),CODE=$P(MSA,FS,2),TEXT=$E($P(MSA,FS,4),1,30) 47 ...I $E(CODE,1)'="A" S SEGTYPE="" Q 48 ...S:$P(OLDMSGID,"-")]"" IEN=$O(^HLB("B",$P(OLDMSGID,"-"),0)) 49 ...S:$G(IEN) IEN=IEN_"^"_$P(OLDMSGID,"-",2) 50 ..I 'HLMSTATE("BATCH") D 51 ...D:SEGTYPE="MSA" 52 ....S HLMSTATE("ACK TO")=OLDMSGID 53 ....S HLMSTATE("ACK TO","ACK BY")=HLMSTATE("ID") 54 ....S HLMSTATE("ACK TO","STATUS")=$S(CODE="AA":"SU",1:"AE") 55 ....S:$D(IEN) HLMSTATE("ACK TO","IEN")=IEN 56 ....S HLMSTATE("ACK TO","ERROR TEXT")=TEXT 57 ...D ADDSEG^HLOMSG(.HLMSTATE,.SEG) 58 ..E D ;batch 59 ...I SEGTYPE="MSH" D 60 ....D SPLITHDR(.SEG) 61 ....S NEWMSGID=$P(SEG(2),FS,5) 62 ....D ADDMSG2^HLOMSG(.HLMSTATE,.SEG) 63 ...E D ;not MSH 64 ....D:SEGTYPE="MSA" 65 .....N SUBIEN S SUBIEN=HLMSTATE("BATCH","CURRENT MESSAGE") 66 .....S HLMSTATE("BATCH","ACK TO",SUBIEN)=OLDMSGID 67 .....S HLMSTATE("BATCH","ACK TO",SUBIEN,"ACK BY")=NEWMSGID 68 .....S HLMSTATE("BATCH","ACK TO",SUBIEN,"STATUS")=$S(CODE="AA":"SU",1:"AE") 69 .....S:$D(IEN) HLMSTATE("BATCH","ACK TO",SUBIEN,"IEN")=IEN 70 ....D ADDSEG^HLOMSG(.HLMSTATE,.SEG) 71 .I HLMSTATE("UNSTORED LINES"),HLCSTATE("MESSAGE ENDED"),$$SAVEMSG^HLOF778(.HLMSTATE) 72 ; 73 I STORE,'HLCSTATE("MESSAGE ENDED") D 74 .;reading failed, don't store 75 .D:HLMSTATE("IEN") DEL778(HLMSTATE("IEN")) D:HLMSTATE("BODY") DEL777(HLMSTATE("BODY")) 76 .S HLMSTATE("IEN")="",HLMSTATE("BODY")="" 77 E D:STORE 78 .D CHECKMSG(.HLMSTATE) 79 .D ADDAC(.HLMSTATE) ;so future duplicates are detected 80 .D COUNT^HLOSTAT(.HLCSTATE,HLMSTATE("HDR","RECEIVING APPLICATION"),HLMSTATE("HDR","SENDING APPLICATION"),$S(HLMSTATE("BATCH"):"BATCH",1:HLMSTATE("HDR","MESSAGE TYPE")_"~"_HLMSTATE("HDR","EVENT"))) 81 ; 82 D:'HLCSTATE("MESSAGE ENDED") CLOSE^HLOT(.HLCSTATE) 83 Q HLCSTATE("MESSAGE ENDED") 84 ; 85 ADDAC(HLMSTATE) ;adds the AC xref for duplicates detection 86 ; 87 N FROM 88 S FROM=$S(HLMSTATE("HDR","SENDING FACILITY",2)]"":HLMSTATE("HDR","SENDING FACILITY",2),1:HLMSTATE("HDR","SENDING FACILITY",1)) 89 S ^HLB("AC",FROM_HLMSTATE("HDR","SENDING APPLICATION")_HLMSTATE("ID"),HLMSTATE("IEN"))="" 90 Q 91 ; 92 DUP(HLMSTATE) ; 93 ;Returns 1 if the message is a duplicate and its ack (if requested) is found, 0 otherwise 94 ;Input: 95 ; HLMSTATE (pass by reference) the message being read 96 ;Output: 97 ; Function returns 1 if the message is a duplicate, 0 otherwise 98 ; HLMSTATE (pass by reference) IF the message is a duplicate: 99 ; returns the prior MSA segment in HLMSTATE("MSA") 100 ; 101 N IEN,FROM,DUP 102 S (IEN,DUP)=0 103 ; 104 ;no way to determine! Bad header will be rejected 105 Q:(HLMSTATE("ID")="") 0 106 ; 107 S FROM=$S(HLMSTATE("HDR","SENDING FACILITY",2)]"":HLMSTATE("HDR","SENDING FACILITY",2),1:HLMSTATE("HDR","SENDING FACILITY",1)) 108 F S IEN=$O(^HLB("AC",FROM_HLMSTATE("HDR","SENDING APPLICATION")_HLMSTATE("ID"),IEN)) Q:'IEN D Q:DUP 109 .I HLMSTATE("HDR","ACCEPT ACK TYPE")="NE" S DUP=1 Q 110 .;need the MSA to return 111 .D Q 112 ..N NODE 113 ..S NODE=$P($G(^HLB(IEN,4)),"^",3,10) 114 ..S HLMSTATE("MSA",1)=$P(NODE,"|",2) 115 ..Q:$L(HLMSTATE("MSA",1))'=2 116 ..S HLMSTATE("MSA",2)=$P(NODE,"|",3) 117 ..S HLMSTATE("MSA",3)=$P(NODE,"|",4,10) 118 ..S DUP=1 119 ; 120 Q DUP 121 ; 122 CHECKMSG(HLMSTATE) ; 123 ;Checks the header & MSA segment, sets HLMSTATE("STATUS","ACTION") if the message needs to be passed, determines if completion status should be set 124 ;Input: 125 ; HLMSTATE("HDR") - the parsed header segment 126 ;Output: 127 ; HLMSTATE("STATUS")="SE" if an error is detected 128 ; HLMSTATE("STATUS","QUEUE") queue to put the message on 129 ; HLMSTATE("STATUS","ACTION") <tag^rtn> that is the processing routine for the receiving application 130 ; HLMSTATE("MSA") - MSA(1)=accept code to be returned, MSA(3)= error txt 131 ; 132 N WANTACK,PASS,ACTION,QUEUE,ERROR 133 M HDR=HLMSTATE("HDR") 134 S ERROR=0 135 I HDR("ACCEPT ACK TYPE")="NE",'HLMSTATE("ORIGINAL MODE") D 136 .S WANTACK=0 137 E D 138 .S WANTACK=1 139 I HLMSTATE("ORIGINAL MODE") S HLMSTATE("MSA",1)="AE",HLMSTATE("MSA",3)="THIS INTERFACE DOES NOT IMPLEMENT ORIGINAL MODE APPLICATION ACKOWLEDGMENTS",HLMSTATE("STATUS")="SE" Q 140 I $G(HLMSTATE("ACK TO"))="" D Q:ERROR 141 .I '$$ACTION^HLOAPP(.HDR,.ACTION,.QUEUE) S ERROR=1 S:WANTACK HLMSTATE("MSA",1)="CR" S HLMSTATE("MSA",3)="RECEIVING APPLICATION NOT DEFINED",HLMSTATE("STATUS")="SE" Q 142 .S HLMSTATE("STATUS","ACTION")=$G(ACTION),HLMSTATE("STATUS","QUEUE")=$G(QUEUE) 143 E D Q:ERROR ;this is an app ack 144 .;does the original message exist? 145 .N NODE 146 .S:+$G(HLMSTATE("ACK TO","IEN")) NODE=$G(^HLB(+HLMSTATE("ACK TO","IEN"),0)) 147 .I $G(NODE)="" S ERROR=1,HLMSTATE("STATUS")="SE",HLMSTATE("ACK TO","IEN")="" S:WANTACK HLMSTATE("MSA",1)="CE" S HLMSTATE("MSA",3)="INITIAL MESSAGE TO APPLICATION ACKNOWLEDGMENT NOT FOUND" Q 148 .I $P(NODE,"^",7)'="",$P(NODE,"^",7)'=HLMSTATE("ID") S ERROR=1,HLMSTATE("STATUS")="SE",HLMSTATE("ACK TO","IEN")="" S:WANTACK HLMSTATE("MSA",1)="CE" S HLMSTATE("MSA",3)="INITIAL MESSAGE WAS ALREADY ACKED" Q 149 .I ($P(NODE,"^",11)]"") S HLMSTATE("STATUS","ACTION")=$P(NODE,"^",10,11),HLMSTATE("STATUS","QUEUE")=$S($P(NODE,"^",6)]"":$P(NODE,"^",6),1:"DEFAULT") Q 150 .;processing routine for the app ack wasn't found with the original message, look in the HLO Application Registry 151 .I HLMSTATE("HDR","MESSAGE TYPE")="ACK",HLMSTATE("HDR","EVENT")="" S HDR("EVENT")=$$GETEVENT^HLOCLNT2(+HLMSTATE("ACK TO","IEN")) 152 .I $$ACTION^HLOAPP(.HDR,.ACTION,.QUEUE) S HLMSTATE("STATUS","ACTION")=$G(ACTION),HLMSTATE("STATUS","QUEUE")=$G(QUEUE) 153 ; 154 I HDR("PROCESSING ID")'=HLCSTATE("SYSTEM","PROCESSING ID") S:WANTACK HLMSTATE("MSA",1)="CR" S HLMSTATE("STATUS")="SE",HLMSTATE("MSA",3)="SYSTEM PROCESSING ID="_HLCSTATE("SYSTEM","PROCESSING ID") Q 155 ; 156 ;wrong receiving facility? This is hard to check if the sender is not VistA, because the HL7 standard permits different coding systems to be used. This check is only for DNS or station number. 157 S PASS=0 158 D 159 .;if its an ack to an existing message, don't check the receiving facility 160 .I $G(HLMSTATE("ACK TO"))]"" S PASS=1 Q 161 .I HDR("RECEIVING FACILITY",1)=HLCSTATE("SYSTEM","STATION") S PASS=1 Q 162 .I HDR("RECEIVING FACILITY",3)'="DNS" S PASS=1 Q 163 .I HDR("RECEIVING FACILITY",2)="" S PASS=1 Q 164 .I $P(HDR("RECEIVING FACILITY",2),":")[HLCSTATE("SYSTEM","DOMAIN") S PASS=1 Q 165 .I HLCSTATE("SYSTEM","DOMAIN")[$P(HDR("RECEIVING FACILITY",2),":") S PASS=1 Q 166 I 'PASS S HLMSTATE("STATUS")="SE",HLMSTATE("MSA",3)="RECEIVING FACILITY IS "_HLCSTATE("SYSTEM","DOMAIN") S:WANTACK HLMSTATE("MSA",1)="CE" 167 I PASS,WANTACK S HLMSTATE("MSA",1)="CA" 168 Q 169 ; 170 DEL777(IEN777) ;delete a record from file 777 where the read did not complete 171 ; 172 K ^HLA(IEN777,0) 173 Q 174 DEL778(IEN778) ;delete a record from file 778 where the read did not complete 175 ; 176 K ^HLB(IEN778,0) 177 Q 178 ; 179 SPLITHDR(HDR) ; 180 ;splits hdr segment into two lines, first being just components 1-6 181 ; 182 N TEMP,FS 183 D SQUISH(.HDR) 184 S FS=$E($G(HDR(1)),4) 185 S TEMP(1)=$P($G(HDR(1)),FS,1,6) 186 S TEMP(2)="" 187 I $L(TEMP(1))<$L($G(HDR(1))) S TEMP(2)=FS_$P($G(HDR(1)),FS,7,20) 188 S HDR(2)=TEMP(2)_$G(HDR(2)) 189 S HDR(1)=TEMP(1) 190 Q 191 ; 192 SQUISH(SEG) ; 193 ;reformat the segment array into full lines 194 ; 195 ;nothing to do if less than 2 lines 196 Q:'$O(SEG(1)) 197 ; 198 N A,I,J,K,MAX,COUNT,LEN 199 S MAX=$S($G(HLCSTATE("SYSTEM","MAXSTRING"))>256:HLCSTATE("SYSTEM","MAXSTRING"),1:256) 200 S (COUNT,I)=0,J=1 201 F S I=$O(SEG(I)) Q:'I D 202 .S LEN=$L(SEG(I)) 203 .F K=1:1:LEN D 204 ..S A(J)=$G(A(J))_$E(SEG(I),K) 205 ..S COUNT=COUNT+1 206 ..I (COUNT>(MAX-1)) S COUNT=0,J=J+1 207 K SEG 208 M SEG=A 209 Q 210 ; 211 ERROR ;error trap 212 S $ETRAP="Q:$QUIT """" Q" 213 D END^HLOSRVR 214 ; 215 ;concurrent server connections (multi-listener) should stop execution, only a single server may continue 216 I $P($G(HLCSTATE("LINK","SERVER")),"^",2)'="S" D Q:$QUIT "" Q 217 .;don't log these common errors 218 .I ($ECODE["READ")!($ECODE["NOTOPEN")!($ECODE["DEVNOTOPN")!($ECODE["WRITE")!($ECODE["OPENERR") D 219 ..; 220 .E D 221 ..D ^%ZTER 222 ; 223 ;while debugging quit on all errors 224 I $G(^HLTMP("LOG ALL ERRORS"))!($ECODE["EDITED") Q:$QUIT "" Q 225 ; 226 ;a lot of errors of the same time may indicate an endless loop, so keep a count and quit if large count 227 N HOUR 228 S HOUR=$E($$NOW^XLFDT,1,10) 229 ; 230 I ($G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))>30) Q:$QUIT "" Q 231 ; 232 ;resume execution for the single listener 233 S ^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2))=$G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))+1 234 D UNWIND^%ZTER 235 Q
Note:
See TracChangeset
for help on using the changeset viewer.