Home   Package List   Routine Alphabetical List   Global Alphabetical List   FileMan Files List   FileMan Sub-Files List   Package Component Lists   Package-Namespace Mapping  
Routine: INHUSEQ

INHUSEQ.m

Go to the documentation of this file.
  1. INHUSEQ ;DGH; 6 Dec 94 12:41;SEQuence number protocol functions
  1. ;;3.01;BHL IHS Interfaces with GIS;;JUL 01, 2001
  1. ;COPYRIGHT 1991-2000 SAIC
  1. ;
  1. SEQOUT(INUIF,INERR) ;Process outbound messages under seq # protocol.
  1. ;INPUT:
  1. ; INUIF = (req) entry in INTHU
  1. ; INERR = (opt) error message array (Pass by reference)
  1. ;OUTPUT:
  1. ; 0=success 1=error 2=fatal error
  1. N SEQ,X,DEST
  1. S DEST=$P($G(^INTHU(INUIF,0)),U,2)
  1. I 'DEST S ERR="No destination specified in UIF for message "_MESSID Q 2
  1. I '$D(^INRHD(DEST)) S ERR="Destination does not exist for message "_MESSID Q 2
  1. ;Determine if seq. # protocol is in effect--If .09 field is not 1,
  1. ;no need to assign seq. no.
  1. Q:'$P(^INRHD(DEST,0),U,9) 0
  1. F I=1:1:5 L +^INRHD(DEST,3):3 Q:$T
  1. I '$T S ERR="Lock failed on LAST SEQUENCE NUMBER field for destination "_$P(^INRHD(DEST,0),U)_" for "_MESSID Q 1
  1. S SEQ=$P($G(^INRHD(DEST,3)),U)+1
  1. ;Stuff sequence number in MSH of uif entry
  1. S X=$$FORMAT(INUIF,SEQ,.INERR)
  1. I 'X S $P(^INRHD(DEST,3),U)=SEQ
  1. L -^INRHD(DEST,3)
  1. Q X
  1. ;
  1. ;
  1. FORMAT(UIF,SEQ,INERR) ;Entry point to add a SEQuence number to the MSH
  1. ;and to the SEQUENCE NUMBER field of an entry in INTHU(UIF
  1. ;INPUT:
  1. ;--UIF=ien in Universal Interface File
  1. ;--SEQ=seqence number to be inserted in the MSH segment of the message
  1. ;--INERR (opt)=array in which to place any error messages
  1. ;OUTPUT: 0=sucessful update, 2=unsuccessful update (fatal)
  1. ;LOCAL:
  1. ;--MSH0 = Base message MSH segment. May be an array
  1. ;--MSH = New MSH w SEQ inserted. Array may be one node larger than MSH0
  1. ;
  1. N C,CP,I,INDELIM,INSMIN,INV,INVS,L,LCT,MSH,MSH0,CNT,DIF,CPSEQ
  1. ;---Store original MSH in MSH0
  1. S LCT=0 D GETLINE^INHOU(UIF,.LCT,.MSH0)
  1. I $E(MSH0,1,3)'="MSH" S INERR="Error in FORMAT^INHUSEQ. No MSH segment in message "_UIF Q 2
  1. S INDELIM=$E(MSH0,4)
  1. ;Create string of first 12 pieces, insert sequence # in 13, then
  1. ;string out remaining pieces.
  1. S CPSEQ=13,CP=CPSEQ-1,MSH=$P(MSH0,INDELIM,1,CP)
  1. S CNT=$L(MSH0,INDELIM)
  1. I $D(MSH0)>9 F I=1:1 Q:'$D(MSH0(I)) S CNT=CNT+$L(MSH0(I),INDELIM)
  1. S I=CPSEQ,L=SEQ D SETPIECE^INHU(.MSH,INDELIM,I,L,.CP)
  1. F I=CPSEQ+1:1:CNT S L=$$PIECE^INHU(.MSH0,INDELIM,I) D SETPIECE^INHU(.MSH,INDELIM,I,L,.CP)
  1. ;If the number of overflow nodes DIFfers from old MSH0 and new MSH...
  1. S DIF=$O(MSH(""),-1)-$O(MSH0(""),-1) I 'DIF D MSH,XREF Q 0
  1. ;
  1. ;Unless the addition of SEQ has created an overflow node, the following
  1. ;will not occur.
  1. ;Store message body in array and reformat entire entry in UIF
  1. K ^UTILITY("INV",$J)
  1. S INVS=$P(^INRHSITE(1,0),U,12),INV=$S(INVS<2:"INV",1:"^UTILITY(""INV"",$J)")
  1. S INSMIN=$S($P($G(^INRHSITE(1,0)),U,14):$P(^(0),U,14),1:2500)
  1. ;Place new MSH at top of new array
  1. S C=1,@INV@(C)=MSH
  1. I $D(MSH)>9 F Q:'$D(MSH(C)) S C=C+1,@INV@(C)=MSH(C-1)
  1. S @INV@(C)=@INV@(C)_"|CR|"
  1. ;If overflow node(s) created, lines in ^INTHU will "move" DIF
  1. F S LCT=$O(^INTHU(UIF,3,LCT)) Q:'LCT D
  1. .S @INV@(LCT+DIF)=^INTHU(UIF,3,LCT,0)
  1. .D:'INVS MC^INHS
  1. K ^INTHU(UIF,3)
  1. ;Store data from global INV
  1. S C=0 F S C=$O(@INV@(C)) Q:'C S ^INTHU(UIF,3,C,0)=@INV@(C),L=C
  1. S ^INTHU(UIF,3,0)="^^"_L_"^"_L
  1. D XREF
  1. Q 0
  1. ;
  1. MSH ;Store replacement MSH with overflow nodes if needed
  1. I $D(MSH)<10 S ^INTHU(UIF,3,1,0)=MSH_"|CR|" Q
  1. S ^INTHU(UIF,3,1,0)=MSH
  1. F I=1:1 Q:'$D(MSH(I)) S C=I+1,^INTHU(UIF,3,C,0)=MSH(I)
  1. S ^INTHU(UIF,3,C,0)=^(0)_"|CR|"
  1. Q
  1. ;
  1. XREF ;Store SEQ in .17 field and set x-ref.
  1. S $P(^INTHU(UIF,0),U,17)=SEQ,^INTHU("ASEQ",DEST,SEQ,UIF)=""
  1. Q
  1. ;
  1. SEQIN(INDSTR,INSEQ,STAT,TXT,EXPCT) ;Process incoming sequenced messages.
  1. ;This will verify sequence number and set variables
  1. ;needed for accept ack. It does not send the ack.
  1. ;VARIABLES
  1. ; INDSTR = Entry in Interface Destination File
  1. ; INSEQ = Sequence number (piece 13 of MSH) (pass by reference)
  1. ; This may be reset to 0 within this tag. SEQ is later stored
  1. ; in LAST SEQUENCE NUMBER field of the Int. Dest. File.
  1. ; STAT = Status to include in ack (PBR)
  1. ; TXT = Message text to include in ack (PBR)
  1. ; EXPCT = Expected sequence number for ack (PBR)
  1. ;OUTPUT:
  1. ; 0=success 1=non-fatal error
  1. ;INSEQ=0 indicates start or restart
  1. I INSEQ=0 D Q 0
  1. .I '$G(^INRHD(INDSTR,3)) S STAT="CA",TXT="Starting link",EXPCT=-1 Q
  1. .S STAT="CA",TXT="Re-starting link",EXPCT=1+^INRHD(INDSTR,3)
  1. ;INSEQ=-1 indicates re-synch. Receiver will need to reset LAST SENT to 0
  1. I INSEQ=-1 S INEQ=0,STAT="CA",TXT="Synchronizing link",EXPCT=-1 Q 0
  1. ;Else sequence is greater than 0
  1. I '$D(^INRHD(INDSTR,3)) S STAT="CA",TXT="Link is not initialized",EXPCT="" Q 1
  1. S EXPCT=1+^INRHD(INDSTR,3)
  1. I INSEQ=EXPCT S STAT="CA",TXT="" Q 0
  1. ;else sequence number is incorrect
  1. S STAT="CR",TXT="Out of sequence" Q 1
  1. ;
  1. ACKINSEQ(MSASTAT,INDSTR,EXPCT,INSEND,INERR) ;Process incoming app ack
  1. ;under seq # protocol
  1. ;INPUT
  1. ;--MSASTAT = CA,CE,CR
  1. ;--INDSTR = ien of entry in Int. Dest. File.
  1. ;--EXPCT = Expected sequence number from MSA segment from other system.
  1. ;--INSEND = Variable to contain ien(s) of previously-sent messages
  1. ; which must be resent to match EXPCT. (PBR)
  1. ; Format of array is INSEND(SEQ)=UIF
  1. ;--INERR = variable to contain error array (PBR)
  1. ;RETURN
  1. ;0 = ok 3 = out of synch
  1. N SEQ,LAST
  1. I MSASTAT["CA" Q 0
  1. I EXPCT=1+^INRHD(INDSTR,3) Q 0
  1. I EXPCT>1+^INRHD(INDSTR,3) S INVL=1,INERR="Expected sequence number is higher than current" Q 3
  1. ;else EXPCT<1, so EXPCT is a previously sent message. Find ien of that
  1. ;entry so it can be resent, and reque all subsequent entries.
  1. I '$D(^INTHU("ASEQ",INDSTR,EXPCT)) S INERR="Can not locate expected message "_EXPCT Q 3
  1. S INSEND=$O(^INTHU("ASEQ",INDSTR,EXPCT,"")) I 'INSEND S INERR="Can not locate expected message "_EXPCT Q 3
  1. S SEQ=EXPCT,LAST=+^INRHD(INSTR,3)
  1. ;create array of all values between last sent and expected.
  1. ;Note: current HL7 spec indicates there will not be more than one
  1. ;entry in this array (ie resend only the last message).
  1. F I=1:1 S SEQ=$O(^INTHU("ASEQ",INDSTR,SEQ)) Q:SEQ'<LAST!'SEQ S INSEND(SEQ)=$O(^INTHU("ASEQ",INDSTR,EXPCT,""))
  1. Q 0
  1. ;