Ignore:
Timestamp:
Dec 4, 2009, 12:11:15 AM (15 years ago)
Author:
George Lilly
Message:

revised back to 6/30/08 version

Location:
WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL
Files:
49 edited

Legend:

Unmodified
Added
Removed
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCS.m

    r613 r623  
    1 HLCS    ;ALB/RJS,MTC,JRP - COMMUNICATIONS SERVER - ;10/04/2007  14:34
    2         ;;1.6;HEALTH LEVEL SEVEN;**2,9,14,19,43,57,109,132,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;The SEND function is invoked by the transaction processor.
    6         ;It's function is to $O through the ITEM multiple of the Event Driver
    7         ;Protocol and create child entries in the Message Text file (#772)
    8         ;for the message at HLMTIEN.  These child messages point back
    9         ;to the parent message so that message text does not need to
    10         ;be duplicated when a message is sent to multiple applications.
    11         ;
    12         ;The SENDACK function is also invoked by the transaction processor.
    13         ;It's function is to create a child entry in the Message Text file
    14         ;for the message at HLMTIENA and deliver the message to the
    15         ;application the requested/sent information.
    16         ;
    17         ;For DHCP to DHCP messaging (i.e. internal to internal), an incoming
    18         ;message is created in the Message Text file which is a duplication
    19         ;of the outgoing message.  The incoming message is then processed by
    20         ;calling the transaction processor.
    21         ;
    22         ;For DHCP to COTS messaging (i.e. internal to external), the message
    23         ;is filed in the Message Text file with the Logical Link defined and
    24         ;a status of PENDING TRANSMISSION.  These entries are picked up by
    25         ;the background filer and transmitted to the appropriate COTS system.
    26         ;
    27 SEND(HLMTIEN,HLEID,HLRESULT)    ;Send an HL7 message
    28         ;HLMTIEN=The IEN of the parent message in file # 772
    29         ;HLEID=The IEN of the Event Driver protocol in file #101
    30         ;HLRESULT=Variable for any error text (pass by reference)
    31         ;
    32         ;Declare variables
    33         N HLARY,HLERROR,HLEIDS,HLCLIENT,HLOGLINK,HLMTIENS,HLMSGPTR
    34         S HLERROR=""
    35         ;Direct connect
    36         I HLPRIO="I" D  Q
    37         . D DC^HLMA2
    38         . S HLRESULT=HLERROR
    39         ;Get all subscribers to the message
    40         D ITEM^HLUTIL2(HLEID,"PTR")
    41         ;Quit if no subscribers (considered successful delivery)
    42         G:($G(HLARY(0))'>0) EXIT
    43         ;Deliver message to each subscriber
    44         S HLEIDS=0
    45         F  S HLEIDS=$O(HLARY(HLEIDS)) Q:(HLEIDS'>0)  D
    46         .;
    47         .;**132 excluded subscribers **
    48         .N I,EXCLUDE
    49         .S (EXCLUDE,I)=0
    50         . ;
    51         . ; patch HL*1.6*122
    52         . ; F  S I=$O(HLP("EXCLUDE SUBSCRIBER",I)) Q:'I  I $G(HLP("EXCLUDE SUBSCRIBER",I))=HLEIDS S EXCLUDE=1 Q
    53         . F  S I=$O(HLP("EXCLUDE SUBSCRIBER",I)) Q:'I  D  Q:EXCLUDE
    54         .. N TEMP
    55         .. S TEMP=HLP("EXCLUDE SUBSCRIBER",I)
    56         .. I 'TEMP,TEMP]"" S TEMP=$O(^ORD(101,"B",TEMP,0))
    57         .. I TEMP=HLEIDS S EXCLUDE=1
    58         . ; patch HL*1.6*122
    59         . ;
    60         .Q:EXCLUDE
    61         .;** 132 end **
    62         .;
    63         .;Get pointer to receiving application
    64         .S HLCLIENT=+HLARY(HLEIDS),HL("EIDS")=HLEIDS,HLERROR=""
    65         .Q:(HLCLIENT'>0)
    66         .;Check and execute ROUTING LOGIC **CIRN**
    67         .S HLX=$G(^ORD(101,HLEIDS,774))
    68         .I HLX]"" D  Q
    69         ..N HLQUIT,HLNODE,HLNEXT
    70         ..S HLQUIT=0,HLNODE="",HLNEXT="D HLNEXT^HLCSUTL"
    71         ..X HLX I $D(HLL("LINKS")) D FWD^HLCS2 K HLL ;**CIRN**
    72         .;Get pointer to logical link
    73         .S HLOGLINK=$P(HLARY(HLEIDS),"^",2)
    74         .;Determine if receiving application is internal or external
    75         .;  Logical link has a value for external applications
    76         .;  Logical link is NULL for internal applications
    77         .I (HLOGLINK) D COTS Q
    78         .;Create 'incoming' message based on 'outgoing' message (internal)
    79         .D DHCP(HLMTIEN,HLEIDS,HLCLIENT)
    80         .Q:(HLERROR)
    81         .;Process the 'incoming' message
    82         .S HLERROR=""
    83         .D PROCESS^HLTP0(HLMSGPTR,"DHCP","",.HLERROR)
    84         .;Update Status of 'incoming' message to SUCCESSFULLY COMPLETED
    85         .; or ERROR DURING TRANSMISSION
    86         .D STATUS^HLTF0(HLMSGPTR,$S(HLERROR:4,1:3),$S(HLERROR:+HLERROR,1:""),$S(HLERROR:$P(HLERROR,"^",2),1:""),,$S($G(HLERR("SKIP_EVENT"))=1:1,1:0))
    87         .I $D(HLL("LINKS")) D FWD^HLCS2 K HLL ;**CIRN**
    88         D ADD^HLCS2 ;**CIRN**
    89 EXIT    S HLRESULT=HLERROR
    90         Q
    91 COTS    ;Internal to external communication
    92         ;Create child entry in Message Text file
    93         N HLTCP,HLTCPI,HLTCPO
    94         D SEND^HLMA2(HLEIDS,HLMTIEN,HLCLIENT,"D",.HLMTIENS,HLOGLINK)
    95         I ((+HLMTIENS)'>0) S HLERROR=HLMTIENS Q
    96         ;'Pass' message to background filer by setting status of child
    97         ;  to PENDING TRANSMISSION
    98         D STATUS^HLTF0(HLMTIENS,1)
    99         Q
    100 DHCP(HLMTIEN,HLEIDS,HLCLIENT)   ;Internal to internal communication
    101         ;
    102         ;Input  : HLMTIEN - Pointer to parent outgoing message (file #772)
    103         ;         HLEIDS - Pointer to subscribing protocol (file #101)
    104         ;         HLCLIENT - Pointer to receiving application (file # 771)
    105         ;
    106         ;Output : HLMTIENS - Pointer to child outgoing message (file #772)
    107         ;         HLMSGPTR - Pointer to [parent] incoming message (file #772)
    108         ;         HLERROR - ErrorCode ^ ErrorText
    109         ;
    110         ;Notes  : This module only copies the outgoing message into an incoming
    111         ;         message.  Delivery of the message (i.e. processing of it)
    112         ;         must be done by the calling application.
    113         ;       : Message/batch header (MSH/BSH) is built and placed in the
    114         ;         incoming message
    115         ;       : HLMTIENS, HLMSGPTR, and HLERROR will be initialized
    116         ;       : Existance and validity of input is assumed
    117         ;
    118         ;Declare variables
    119         N MSGID,MSGDT,MSGDTH,HDR2BLD,TMP,HLHDR,BHSHDR
    120         S HLERROR=""
    121         S HLMTIENS=0
    122         S HLMSGPTR=0
    123         ;Create child entry in Message Text file
    124         D SEND^HLMA2(HLEIDS,HLMTIEN,HLCLIENT,"D",.HLMTIENS)
    125         I ((+HLMTIENS)'>0) S HLERROR=HLMTIENS Q
    126         ;'Receive' message by making an incoming message
    127         ;Determine type of header to build
    128         S TMP=$G(^HL(772,HLMTIEN,0))
    129         S HDR2BLD=$P(TMP,"^",14)
    130         ;Build message header (MSH)
    131         I (HDR2BLD="M") D  Q:(HLERROR)
    132         .S TMP=""
    133         .D HEADER^HLCSHDR(HLMTIENS,.TMP)
    134         .Q:(TMP="")
    135         .;Error building header
    136         .S HLERROR="4^Unable to build message header => "_TMP
    137         .D STATUS^HLTF0(HLMTIENS,4,0,$P(HLERROR,"^",2))
    138         ;Build batch header (BHS or FHS)
    139         I (HDR2BLD'="M") D  Q:(HLERROR)
    140         .S TMP=""
    141         .D BHSHDR^HLCSHDR(HLMTIENS)
    142         .S:($E(HLHDR(1),1)="-") TMP=$P(HLHDR(1),"^",2)
    143         .Q:(TMP="")
    144         .;Error building header
    145         .S HLERROR="4^Unable to build batch header => "_TMP
    146         .D STATUS^HLTF0(HLMTIENS,4,0,$P(HLERROR,"^",2))
    147         ;Create entry for 'incoming' message
    148         D CREATE^HLTF(.MSGID,.HLMSGPTR,.MSGDT,.MSGDTH)
    149         ;Move header and rest of message into 'incoming' message
    150         I (HDR2BLD="M") D
    151         .;Use MSH as header
    152         .D MRGINT^HLTF1(HLMTIEN,HLMSGPTR,"HLHDR")
    153         I (HDR2BLD'="M") D
    154         .;Use BHS or FHS as header
    155         .D MRGINT^HLTF1(HLMTIEN,HLMSGPTR,"BHSHDR")
    156         ;Set status of outgoing message to AWAITING ACKNOWLEDGEMENT
    157         D STATUS^HLTF0(HLMTIENS,$S($P(^HL(772,HLMTIEN,0),U,7):3,1:2))
    158         ;Set status of 'incoming' message to AWAITING PROCESSING
    159         D STATUS^HLTF0(HLMSGPTR,9)
    160         Q
    161 SENDACK(HLMTIENA,HLEID,HLEIDS,HLRESULT) ;Send an HL7 acknowledgement/response
    162         ;HLMTIENA=The IEN of the parent acknowledgment/response message in
    163         ;         file # 772
    164         ;HLEIDS=The IEN of the Subscribing protocol in file # 101
    165         ;HLEID=The IEN of the Event Driver protocol in file #101
    166         ;HLRESULT=Variable for any error text (pass by reference)
    167         ;
    168         N HLERROR,HLOGLINK,HLCLIENT,HLMTIENS,HLMSGPTR,HLCLNODE
    169         I $G(HLMTIENA)=""!($G(HLEID)="")!($G(HLEIDS)="") S HLERROR="0^7^"_$G(^HL(771.7,7,0))_"at SENDACK^HLCS entry point" G EXIT2
    170         S HLCLNODE=$G(^ORD(101,HLEID,770))
    171         ;Get pointers to Logical Link & receiving application
    172         S HLOGLINK=$P($G(^ORD(101,HLEIDS,770)),U,7)
    173         ;Application needed to dynamically address the ACK (tcp/ip)
    174         ;(set HLL("LINKS") array before calling GENACK)
    175         I $D(HLL("LINKS")) D  Q:'HLOGLINK
    176         .S HLOGLINK=$P(HLL("LINKS",1),"^",2) Q:HLOGLINK=""
    177         .K HLL("LINKS")
    178         .I +HLOGLINK'=HLOGLINK S HLOGLINK=$O(^HLCS(870,"B",HLOGLINK,0))
    179         S HLCLIENT=$P(HLCLNODE,U,1)
    180         Q:('HLCLIENT)
    181         ;Determine if receiving application is internal or external
    182         ;  Logical link has a value for external applications
    183         ;  Logical link is NULL for internal applications
    184         I (HLOGLINK) D COTSACK Q
    185         ;Create 'incoming' message based on 'outgoing' message (internal)
    186         D DHCP(HLMTIENA,HLEID,HLCLIENT)
    187         ;Process the 'incoming' message
    188         I (HLMSGPTR) D
    189         .S HLERROR=""
    190         .D PROCESS^HLTP0(HLMSGPTR,"DHCP","",.HLERROR)
    191         ;Update Status of 'incoming' message to SUCCESSFULLY COMPLETED
    192         ; or ERROR DURING TRANSMISSION
    193         D STATUS^HLTF0(HLMSGPTR,$S(HLERROR:4,1:3),$S(HLERROR:+HLERROR,1:""),$S(HLERROR:$P(HLERROR,"^",2),1:""))
    194 EXIT2   ;
    195         S HLRESULT=$G(HLERROR)
    196         Q
    197 COTSACK ;Internal to external communication of acknowledgements/responses
    198         ;Create child entry in Message Text file
    199         D SEND^HLMA2(HLEID,HLMTIENA,HLCLIENT,"D",.HLMTIENS,HLOGLINK)
    200         ;'Pass' message to background filer by setting status of child
    201         ;  to PENDING TRANSMISSION
    202         D STATUS^HLTF0(HLMTIENS,1)
    203         Q
     1HLCS ;ALB/RJS,MTC,JRP - COMMUNICATIONS SERVER - ;10/31/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**2,9,14,19,43,57,109,132**;Oct 13, 1995;Build 6
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ;The SEND function is invoked by the transaction processor.
     6 ;It's function is to $O through the ITEM multiple of the Event Driver
     7 ;Protocol and create child entries in the Message Text file (#772)
     8 ;for the message at HLMTIEN.  These child messages point back
     9 ;to the parent message so that message text does not need to
     10 ;be duplicated when a message is sent to multiple applications.
     11 ;
     12 ;The SENDACK function is also invoked by the transaction processor.
     13 ;It's function is to create a child entry in the Message Text file
     14 ;for the message at HLMTIENA and deliver the message to the
     15 ;application the requested/sent information.
     16 ;
     17 ;For DHCP to DHCP messaging (i.e. internal to internal), an incoming
     18 ;message is created in the Message Text file which is a duplication
     19 ;of the outgoing message.  The incoming message is then processed by
     20 ;calling the transaction processor.
     21 ;
     22 ;For DHCP to COTS messaging (i.e. internal to external), the message
     23 ;is filed in the Message Text file with the Logical Link defined and
     24 ;a status of PENDING TRANSMISSION.  These entries are picked up by
     25 ;the background filer and transmitted to the appropriate COTS system.
     26 ;
     27SEND(HLMTIEN,HLEID,HLRESULT) ;Send an HL7 message
     28 ;HLMTIEN=The IEN of the parent message in file # 772
     29 ;HLEID=The IEN of the Event Driver protocol in file #101
     30 ;HLRESULT=Variable for any error text (pass by reference)
     31 ;
     32 ;Declare variables
     33 N HLARY,HLERROR,HLEIDS,HLCLIENT,HLOGLINK,HLMTIENS,HLMSGPTR
     34 S HLERROR=""
     35 ;Direct connect
     36 I HLPRIO="I" D  Q
     37 . D DC^HLMA2
     38 . S HLRESULT=HLERROR
     39 ;Get all subscribers to the message
     40 D ITEM^HLUTIL2(HLEID,"PTR")
     41 ;Quit if no subscribers (considered successful delivery)
     42 G:($G(HLARY(0))'>0) EXIT
     43 ;Deliver message to each subscriber
     44 S HLEIDS=0
     45 F  S HLEIDS=$O(HLARY(HLEIDS)) Q:(HLEIDS'>0)  D
     46 .;
     47 .;**132 excluded subscribers **
     48 .N I,EXCLUDE
     49 .S (EXCLUDE,I)=0
     50 .F  S I=$O(HLP("EXCLUDE SUBSCRIBER",I)) Q:'I  I $G(HLP("EXCLUDE SUBSCRIBER",I))=HLEIDS S EXCLUDE=1 Q
     51 .Q:EXCLUDE
     52 .;** 132 end **
     53 .;
     54 .;Get pointer to receiving application
     55 .S HLCLIENT=+HLARY(HLEIDS),HL("EIDS")=HLEIDS,HLERROR=""
     56 .Q:(HLCLIENT'>0)
     57 .;Check and execute ROUTING LOGIC **CIRN**
     58 .S HLX=$G(^ORD(101,HLEIDS,774))
     59 .I HLX]"" D  Q
     60 ..N HLQUIT,HLNODE,HLNEXT
     61 ..S HLQUIT=0,HLNODE="",HLNEXT="D HLNEXT^HLCSUTL"
     62 ..X HLX I $D(HLL("LINKS")) D FWD^HLCS2 K HLL ;**CIRN**
     63 .;Get pointer to logical link
     64 .S HLOGLINK=$P(HLARY(HLEIDS),"^",2)
     65 .;Determine if receiving application is internal or external
     66 .;  Logical link has a value for external applications
     67 .;  Logical link is NULL for internal applications
     68 .I (HLOGLINK) D COTS Q
     69 .;Create 'incoming' message based on 'outgoing' message (internal)
     70 .D DHCP(HLMTIEN,HLEIDS,HLCLIENT)
     71 .Q:(HLERROR)
     72 .;Process the 'incoming' message
     73 .S HLERROR=""
     74 .D PROCESS^HLTP0(HLMSGPTR,"DHCP","",.HLERROR)
     75 .;Update Status of 'incoming' message to SUCCESSFULLY COMPLETED
     76 .; or ERROR DURING TRANSMISSION
     77 .D STATUS^HLTF0(HLMSGPTR,$S(HLERROR:4,1:3),$S(HLERROR:+HLERROR,1:""),$S(HLERROR:$P(HLERROR,"^",2),1:""),,$S($G(HLERR("SKIP_EVENT"))=1:1,1:0))
     78 .I $D(HLL("LINKS")) D FWD^HLCS2 K HLL ;**CIRN**
     79 D ADD^HLCS2 ;**CIRN**
     80EXIT S HLRESULT=HLERROR
     81 Q
     82COTS ;Internal to external communication
     83 ;Create child entry in Message Text file
     84 N HLTCP,HLTCPI,HLTCPO
     85 D SEND^HLMA2(HLEIDS,HLMTIEN,HLCLIENT,"D",.HLMTIENS,HLOGLINK)
     86 I ((+HLMTIENS)'>0) S HLERROR=HLMTIENS Q
     87 ;'Pass' message to background filer by setting status of child
     88 ;  to PENDING TRANSMISSION
     89 D STATUS^HLTF0(HLMTIENS,1)
     90 Q
     91DHCP(HLMTIEN,HLEIDS,HLCLIENT) ;Internal to internal communication
     92 ;
     93 ;Input  : HLMTIEN - Pointer to parent outgoing message (file #772)
     94 ;         HLEIDS - Pointer to subscribing protocol (file #101)
     95 ;         HLCLIENT - Pointer to receiving application (file # 771)
     96 ;
     97 ;Output : HLMTIENS - Pointer to child outgoing message (file #772)
     98 ;         HLMSGPTR - Pointer to [parent] incoming message (file #772)
     99 ;         HLERROR - ErrorCode ^ ErrorText
     100 ;
     101 ;Notes  : This module only copies the outgoing message into an incoming
     102 ;         message.  Delivery of the message (i.e. processing of it)
     103 ;         must be done by the calling application.
     104 ;       : Message/batch header (MSH/BSH) is built and placed in the
     105 ;         incoming message
     106 ;       : HLMTIENS, HLMSGPTR, and HLERROR will be initialized
     107 ;       : Existance and validity of input is assumed
     108 ;
     109 ;Declare variables
     110 N MSGID,MSGDT,MSGDTH,HDR2BLD,TMP,HLHDR,BHSHDR
     111 S HLERROR=""
     112 S HLMTIENS=0
     113 S HLMSGPTR=0
     114 ;Create child entry in Message Text file
     115 D SEND^HLMA2(HLEIDS,HLMTIEN,HLCLIENT,"D",.HLMTIENS)
     116 I ((+HLMTIENS)'>0) S HLERROR=HLMTIENS Q
     117 ;'Receive' message by making an incoming message
     118 ;Determine type of header to build
     119 S TMP=$G(^HL(772,HLMTIEN,0))
     120 S HDR2BLD=$P(TMP,"^",14)
     121 ;Build message header (MSH)
     122 I (HDR2BLD="M") D  Q:(HLERROR)
     123 .S TMP=""
     124 .D HEADER^HLCSHDR(HLMTIENS,.TMP)
     125 .Q:(TMP="")
     126 .;Error building header
     127 .S HLERROR="4^Unable to build message header => "_TMP
     128 .D STATUS^HLTF0(HLMTIENS,4,0,$P(HLERROR,"^",2))
     129 ;Build batch header (BHS or FHS)
     130 I (HDR2BLD'="M") D  Q:(HLERROR)
     131 .S TMP=""
     132 .D BHSHDR^HLCSHDR(HLMTIENS)
     133 .S:($E(HLHDR(1),1)="-") TMP=$P(HLHDR(1),"^",2)
     134 .Q:(TMP="")
     135 .;Error building header
     136 .S HLERROR="4^Unable to build batch header => "_TMP
     137 .D STATUS^HLTF0(HLMTIENS,4,0,$P(HLERROR,"^",2))
     138 ;Create entry for 'incoming' message
     139 D CREATE^HLTF(.MSGID,.HLMSGPTR,.MSGDT,.MSGDTH)
     140 ;Move header and rest of message into 'incoming' message
     141 I (HDR2BLD="M") D
     142 .;Use MSH as header
     143 .D MRGINT^HLTF1(HLMTIEN,HLMSGPTR,"HLHDR")
     144 I (HDR2BLD'="M") D
     145 .;Use BHS or FHS as header
     146 .D MRGINT^HLTF1(HLMTIEN,HLMSGPTR,"BHSHDR")
     147 ;Set status of outgoing message to AWAITING ACKNOWLEDGEMENT
     148 D STATUS^HLTF0(HLMTIENS,$S($P(^HL(772,HLMTIEN,0),U,7):3,1:2))
     149 ;Set status of 'incoming' message to AWAITING PROCESSING
     150 D STATUS^HLTF0(HLMSGPTR,9)
     151 Q
     152SENDACK(HLMTIENA,HLEID,HLEIDS,HLRESULT) ;Send an HL7 acknowledgement/response
     153 ;HLMTIENA=The IEN of the parent acknowledgment/response message in
     154 ;         file # 772
     155 ;HLEIDS=The IEN of the Subscribing protocol in file # 101
     156 ;HLEID=The IEN of the Event Driver protocol in file #101
     157 ;HLRESULT=Variable for any error text (pass by reference)
     158 ;
     159 N HLERROR,HLOGLINK,HLCLIENT,HLMTIENS,HLMSGPTR,HLCLNODE
     160 I $G(HLMTIENA)=""!($G(HLEID)="")!($G(HLEIDS)="") S HLERROR="0^7^"_$G(^HL(771.7,7,0))_"at SENDACK^HLCS entry point" G EXIT2
     161 S HLCLNODE=$G(^ORD(101,HLEID,770))
     162 ;Get pointers to Logical Link & receiving application
     163 S HLOGLINK=$P($G(^ORD(101,HLEIDS,770)),U,7)
     164 ;Application needed to dynamically address the ACK (tcp/ip)
     165 ;(set HLL("LINKS") array before calling GENACK)
     166 I $D(HLL("LINKS")) D  Q:'HLOGLINK
     167 .S HLOGLINK=$P(HLL("LINKS",1),"^",2) Q:HLOGLINK=""
     168 .K HLL("LINKS")
     169 .I +HLOGLINK'=HLOGLINK S HLOGLINK=$O(^HLCS(870,"B",HLOGLINK,0))
     170 S HLCLIENT=$P(HLCLNODE,U,1)
     171 Q:('HLCLIENT)
     172 ;Determine if receiving application is internal or external
     173 ;  Logical link has a value for external applications
     174 ;  Logical link is NULL for internal applications
     175 I (HLOGLINK) D COTSACK Q
     176 ;Create 'incoming' message based on 'outgoing' message (internal)
     177 D DHCP(HLMTIENA,HLEID,HLCLIENT)
     178 ;Process the 'incoming' message
     179 I (HLMSGPTR) D
     180 .S HLERROR=""
     181 .D PROCESS^HLTP0(HLMSGPTR,"DHCP","",.HLERROR)
     182 ;Update Status of 'incoming' message to SUCCESSFULLY COMPLETED
     183 ; or ERROR DURING TRANSMISSION
     184 D STATUS^HLTF0(HLMSGPTR,$S(HLERROR:4,1:3),$S(HLERROR:+HLERROR,1:""),$S(HLERROR:$P(HLERROR,"^",2),1:""))
     185EXIT2 ;
     186 S HLRESULT=$G(HLERROR)
     187 Q
     188COTSACK ;Internal to external communication of acknowledgements/responses
     189 ;Create child entry in Message Text file
     190 D SEND^HLMA2(HLEID,HLMTIENA,HLCLIENT,"D",.HLMTIENS,HLOGLINK)
     191 ;'Pass' message to background filer by setting status of child
     192 ;  to PENDING TRANSMISSION
     193 D STATUS^HLTF0(HLMTIENS,1)
     194 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCS2.m

    r613 r623  
    1 HLCS2   ;SF/JC - More Communication Server utilities ; 10/04/2007  14:31
    2         ;;1.6;HEALTH LEVEL SEVEN;**14,40,43,49,57,58,82,84,109,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4 FWD     ; Add supplemental clients from HLL("LINKS") to HLSUP array
    5         ;This enhancement also supports distribution of a message to
    6         ;the same client over multiple logical links.
    7         Q:'$D(HLL("LINKS"))
    8         N CNT,LNK,CLIAP
    9         S CNT=0,ROUTINE=1 F  S CNT=$O(HLL("LINKS",CNT)) Q:CNT<1  D
    10         . S PTR=$P(HLL("LINKS",CNT),"^"),LNK=$P(HLL("LINKS",CNT),"^",2)
    11         . Q:PTR=""  I +PTR<1 S PTR=$O(^ORD(101,"B",PTR,0)) Q:PTR<1
    12         . ;
    13         . ; patch HL*1.6*122: excluding subscribers defined in
    14         . ; HLP("EXCLUDE SUBSCRIBER",I) = ien of subscriber
    15         . N I,EXCLUDE
    16         . S (EXCLUDE,I)=0
    17         . F  S I=$O(HLP("EXCLUDE SUBSCRIBER",I)) Q:'I  D  Q:EXCLUDE
    18         .. N TEMP
    19         .. S TEMP=HLP("EXCLUDE SUBSCRIBER",I)
    20         .. I 'TEMP,TEMP]"" S TEMP=$O(^ORD(101,"B",TEMP,0))
    21         .. I TEMP=PTR S EXCLUDE=1
    22         . Q:EXCLUDE
    23         . ;
    24         . Q:LNK=""  I +LNK<1 S LNK=$O(^HLCS(870,"B",LNK,0)) Q:LNK<1
    25         . Q:'$D(^HLCS(870,LNK))
    26         . S CLIAP=$$PTR^HLUTIL2(PTR)
    27         . ; patch HL*1.6*122: add the 3rd component as receiving facility
    28         . ; S HLSUP("S",PTR,+LNK)=CLIAP_$S(CLIAP<1:U_HLL("LINKS",CNT),1:"")
    29         . S HLSUP("S",PTR,+LNK)=CLIAP_U_$S(CLIAP<1:HLL("LINKS",CNT),1:$P(HLL("LINKS",CNT),"^",3))
    30         Q
    31 ADD     ;Deliver message to supplemental client list.
    32         ;Invoked by HLTP before and after processing normal clients
    33         ;Only processes remote links. Local clients must be subscribing
    34         ;protocols.
    35         Q:'$D(HLSUP("S"))
    36         N HLTCP,HLTCPI,HLTCPO,ZHLEIDS,ZLCLIENT,ZLOGLINK,ZMTIENS
    37         S ZHLEIDS=0 F  S ZHLEIDS=$O(HLSUP("S",ZHLEIDS)) Q:ZHLEIDS<1  D
    38         .S ZLOGLINK=0 F  S ZLOGLINK=$O(HLSUP("S",ZHLEIDS,ZLOGLINK)) Q:ZLOGLINK<1  D
    39         ..S ZLCLIENT=+HLSUP("S",ZHLEIDS,ZLOGLINK)
    40         ..I ZLCLIENT<1 S:$G(HLERROR)="" HLERROR="15^Invalid Subscriber Protocol in HLL('LINKS'): "_$P(HLSUP("S",ZHLEIDS,ZLOGLINK),U,2,9) Q
    41         .. ; patch HL*1.6*122 start
    42         .. ; S HLOGLINK=ZLOGLINK D SEND^HLMA2(ZHLEIDS,HLMTIEN,ZLCLIENT,"D",.ZMTIENS,ZLOGLINK),STATUS^HLTF0(+ZMTIENS,1)
    43         .. S HLOGLINK=ZLOGLINK
    44         .. ; 3rd component for receiving facility
    45         .. S ZMTIENS("REC-FACILITY")=$P(HLSUP("S",ZHLEIDS,ZLOGLINK),U,3)
    46         .. D SEND^HLMA2(ZHLEIDS,HLMTIEN,ZLCLIENT,"D",.ZMTIENS,ZLOGLINK)
    47         .. D STATUS^HLTF0(+ZMTIENS,1)
    48         .. ; patch HL*1.6*122 end
    49         .. ;
    50         K HLL("LINKS"),HLSUP
    51         Q
    52 STALL   ;STOP ALL LINKS AND FILERS
    53         N DIR,Y
    54         W ! S DIR(0)="Y",DIR("A")="Okay to shut down all Links and Filers"
    55         D ^DIR
    56         I 'Y!($D(DIRUT))!($D(DUOUT)) W !!,"Shutdown Aborted!" Q
    57         W !,"Shutting down all Links and Filers..."
    58         D CLEAR
    59         D LLP(1)
    60         Q
    61 QUE     ;Restart Filers and AUTOSTART Logical Links after system re-boot
    62         N DIR,Y
    63         I '$D(ZTQUEUED) D  Q:'Y!($D(DIRUT))!($D(DUOUT))
    64         .W ! S DIR(0)="Y",DIR("A")="Shutdown and restart ALL AUTOSTART links and filers. Okay"
    65         .D ^DIR
    66         .I 'Y!($D(DIRUT))!($D(DUOUT)) W !!,"RESTART Aborted!" Q
    67         .W !,"Restarting all Autostart-Enabled Links and Filers..."
    68         D CLEAR
    69         D STARTF
    70         D LLP(0)
    71         D STRT
    72         Q
    73 CLEAR   ;Reset state of 869.3
    74         S DA(1)=1,DA=0,DIK="^HLCS(869.3,1,2,"
    75         F  S DA=$O(^HLCS(869.3,DA(1),2,DA)) Q:DA<1  D ^DIK
    76         S DA=0,DIK="^HLCS(869.3,1,3,"
    77         F  S DA=$O(^HLCS(869.3,DA(1),3,DA)) Q:DA<1  D ^DIK
    78         Q
    79 STARTF  ;Start filers
    80         ;Get Defaults
    81         N TMP,PTR,DEFCNT,DA,HLCNT,HLNODE1
    82         S PTR=+$O(^HLCS(869.3,0)) Q:'PTR
    83         ;default # of incoming filers
    84         S HLNODE1=$G(^HLCS(869.3,PTR,1)),DEFCNT=+$P(HLNODE1,U) S:'DEFCNT DEFCNT=1
    85         F HLCNT=1:1:DEFCNT S TMP=$$TASKFLR^HLCS1("IN")
    86         ;default # of outgoing filers
    87         S DEFCNT=+$P(HLNODE1,U,2) S:'DEFCNT DEFCNT=1
    88         F HLCNT=1:1:DEFCNT S TMP=$$TASKFLR^HLCS1("OUT")
    89         Q
    90 LLP(ALL)        ;Stop Logical Links
    91         ;ALL=1 OR 0 IF zero, only AUTOSTART LINKS get stopped
    92         N HLDP,HLDP0,HLPARM0,HLPARM4,HLJ,X,Y S HLDP=0
    93         F  S HLDP=$O(^HLCS(870,HLDP)) Q:'HLDP  S HLDP0=$G(^(HLDP,0)),X=+$P(HLDP0,U,3) D:X
    94         .;skip this link if not stopping all and Autostart not enabled
    95         . I 'ALL&('$P(HLDP0,U,6)) Q
    96         . S HLPARM4=$G(^HLCS(870,HLDP,400))
    97         . ; patch HL*1.6*122
    98         . ; TCP Multi listener: quit if TCP service as GT.M, DSM,
    99         . ; or Cache/VMS
    100         . I $P(HLPARM4,U,3)="M" Q:^%ZOSF("OS")'["OpenM"  Q:$$OS^%ZOSV["VMS"
    101         . ;
    102         . ;4=status,10=Time Stopped,9=Time Started,11=Task Number,3=Device Type,14=shutdown?
    103         . S X="HLJ(870,"""_HLDP_","")",@X@(10)=$$NOW^XLFDT,(@X@(11),@X@(9))="@",@X@(14)=1
    104         . I "Shutdown,SHUTDOWN"'[$P(HLDP0,U,5) S @X@(4)="Halting"
    105         . I $P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4)),'$P(HLDP0,U,12) S @X@(4)="Shutdown"
    106         . D FILE^HLDIE("","HLJ","","LLP","HLCS2") ;HL*1.6*109
    107         . I ^%ZOSF("OS")["OpenM",($P(HLPARM4,U,3)="M"!($P(HLPARM4,U,3)="S")) D
    108         .. ; pass task number to stop listener
    109         .. S:$P(HLDP0,U,12) X=$$ASKSTOP^%ZTLOAD(+$P(HLDP0,U,12))
    110         ; patch HL*1.6*122 start
    111         ; .. D CALL^%ZISTCP($P(HLPARM4,U),$P(HLPARM4,U,2),10)
    112         ; .. I POP D HOME^%ZIS Q
    113         ; .. D CLOSE^%ZISTCP
    114         ; patch HL*1.6*122 end
    115         Q
    116 STRT    ;Start Links
    117         N HLDP,HLDP0,HLDAPP,HLTYPTR,HLBGR,HLENV,HLPARAM0,HLPARM4,HLQUIT,ZTRTN,ZTDESC,ZTSK,ZTCPU
    118         S HLDP=0
    119         F  S HLDP=$O(^HLCS(870,HLDP)) Q:HLDP<1  S HLDP0=$G(^(HLDP,0)) D
    120         . S HLPARM4=$G(^HLCS(870,HLDP,400))
    121         . ;quit if no parameters or AUTOSTART is disabled
    122         . Q:'$P(HLDP0,U,6)
    123         . ;HLDAPP=LL name, HLTYPTR=LL type, HLBGR=routine, HLENV=environment check
    124         . S HLDAPP=$P(HLDP0,U),HLTYPTR=+$P(HLDP0,U,3),HLBGR=$G(^HLCS(869.1,HLTYPTR,100)),HLENV=$G(^(200))
    125         . ;quit if no LL type or no routine
    126         . Q:'HLTYPTR!(HLBGR="")
    127         . I HLENV'="" K HLQUIT X HLENV Q:$D(HLQUIT)
    128         . ; patch HL*1.6*122
    129         . ; TCP Multi listener: quit if TCP service as GT.M, DSM,
    130         . ; or Cache/VMS
    131         . I $P(HLPARM4,U,3)="M" Q:^%ZOSF("OS")'["OpenM"  Q:$$OS^%ZOSV["VMS"
    132         . ;
    133         . I $P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4)) D  Q
    134         .. ;4=status 9=Time Started, 10=Time Stopped, 11=Task Number
    135         .. ;14=Shutdown LLP, 3=Device Type, 18=Gross Errors
    136         .. N HLJ,X
    137         .. I $P(HLDP0,U,15)=0 Q
    138         .. L +^HLCS(870,HLDP,0):2
    139         .. E  Q
    140         .. S X="HLJ(870,"""_HLDP_","")"
    141         .. S @X@(4)="Enabled",@X@(9)=$$NOW^XLFDT,@X@(14)=0
    142         .. D FILE^HLDIE("","HLJ","","STRT","HLCS2") ; HL*1.6*109
    143         .. L -^HLCS(870,HLDP,0)
    144         .. Q
    145         . S ZTRTN=$P(HLBGR," ",2),ZTIO="",ZTDTH=$H,HLTRACE=""
    146         . S ZTDESC=HLDAPP_" Low Level Protocol",ZTSAVE("HLDP")=""
    147         . ;get startup node
    148         . I $P(HLPARM4,U,6),$D(^%ZIS(14.7,+$P(HLPARM4,U,6),0)) S ZTCPU=$P(^(0),U)
    149         . D ^%ZTLOAD
    150         Q
    151 SITEP   ;Edit Site Parameters
    152         S DDSFILE=869.3,DA=1,DR="[HL SITE PARAMETERS]" D ^DDS
    153         Q
    154 PARAM() ;Return HL7 site parameters
    155         ;HLPARAM=domain ien^domain name^production or test^institution ien^
    156         ;institution name^institution number^mail group ien^mail group name^
    157         ;purge completed messages^purge awaiting ack messages^purge all msgs^
    158         ;default retention
    159         N HLX,HLX4,HLX5,HLDOMP,HLDOMN,HLPROD,HLINSP,HLINSN,HLINSNM,HLMAILP,HLMAILN,HLPARAM,HLPRGAA,HLPRGALL,HLPRGCMP,HLDEFRET
    160         S HLX=$G(^HLCS(869.3,1,0))
    161         S HLX4=$G(^HLCS(869.3,1,4))
    162         S HLX5=$G(^HLCS(869.3,1,5))
    163         S HLDOMP=$P(HLX,U,2) I HLDOMP S HLDOMN=$P(^DIC(4.2,HLDOMP,0),U)
    164         S HLPROD=$P(HLX,U,3)
    165         S HLINSP=$P(HLX,U,4) I HLINSP S HLINSN=$P(^DIC(4,HLINSP,0),U),HLINSNM=$P($G(^DIC(4,HLINSP,99)),U)
    166         S HLMAILP=$P(HLX,U,5) I HLMAILP S HLMAILN=$P(^XMB(3.8,HLMAILP,0),U)
    167         S HLPRGCMP=$P(HLX4,U),HLPRGAA=$P(HLX4,U,2),HLPRGALL=$P(HLX4,U,3)
    168         S HLDEFRET=$P(HLX5,U)
    169         S HLPARAM=HLDOMP_U_$G(HLDOMN)_U_$G(HLPROD)_U_HLINSP_U_$G(HLINSN)_U_$G(HLINSNM)_U_HLMAILP_U_$G(HLMAILN)_U_HLPRGCMP_U_HLPRGAA_U_HLPRGALL_U_HLDEFRET
    170         Q HLPARAM
    171         ;
    172 GETAPP(HLAPP)   ;Function to Retrieve parameters pertaining to a specific sending or receiving application
    173         ;HLAPP=APPLICATION NAME OR IEN OF FILE 771
    174         ;Returns MAIL GROUP NAME^'a' or 'i' (active or inactive)
    175         S HLAPP=$G(HLAPP)
    176         I HLAPP]"",'HLAPP S HLAPP=$O(^HL(771,"B",$E(HLAPP,1,30),0))
    177         I 'HLAPP Q ""
    178         I HLAPP S HLM=$P(^HL(771,HLAPP,0),U,4)
    179         I HLM S HLM=$P($G(^XMB(3.8,HLM,0)),U)
    180         Q $G(HLM)_U_$P(^HL(771,HLAPP,0),U,2)
     1HLCS2 ;SF/JC - More Communication Server utilities ; 12/31/2003  17:50
     2 ;;1.6;HEALTH LEVEL SEVEN;**14,40,43,49,57,58,82,84,109**;Oct 13, 1995
     3FWD ; Add supplemental clients from HLL("LINKS") to HLSUP array
     4 ;This enhancement also supports distribution of a message to
     5 ;the same client over multiple logical links.
     6 Q:'$D(HLL("LINKS"))
     7 N CNT,LNK,CLIAP
     8 S CNT=0,ROUTINE=1 F  S CNT=$O(HLL("LINKS",CNT)) Q:CNT<1  D
     9 . S PTR=$P(HLL("LINKS",CNT),"^"),LNK=$P(HLL("LINKS",CNT),"^",2)
     10 . Q:PTR=""  I +PTR<1 S PTR=$O(^ORD(101,"B",PTR,0)) Q:PTR<1
     11 . Q:LNK=""  I +LNK<1 S LNK=$O(^HLCS(870,"B",LNK,0)) Q:LNK<1
     12 . Q:'$D(^HLCS(870,LNK))
     13 . S CLIAP=$$PTR^HLUTIL2(PTR)
     14 . S HLSUP("S",PTR,+LNK)=CLIAP_$S(CLIAP<1:U_HLL("LINKS",CNT),1:"")
     15 Q
     16ADD ;Deliver message to supplemental client list.
     17 ;Invoked by HLTP before and after processing normal clients
     18 ;Only processes remote links. Local clients must be subscribing
     19 ;protocols.
     20 Q:'$D(HLSUP("S"))
     21 N HLTCP,HLTCPI,HLTCPO,ZHLEIDS,ZLCLIENT,ZLOGLINK,ZMTIENS
     22 S ZHLEIDS=0 F  S ZHLEIDS=$O(HLSUP("S",ZHLEIDS)) Q:ZHLEIDS<1  D
     23 .S ZLOGLINK=0 F  S ZLOGLINK=$O(HLSUP("S",ZHLEIDS,ZLOGLINK)) Q:ZLOGLINK<1  D
     24 ..S ZLCLIENT=+HLSUP("S",ZHLEIDS,ZLOGLINK)
     25 ..I ZLCLIENT<1 S:$G(HLERROR)="" HLERROR="15^Invalid Subscriber Protocol in HLL('LINKS'): "_$P(HLSUP("S",ZHLEIDS,ZLOGLINK),U,2,9) Q
     26 ..S HLOGLINK=ZLOGLINK D SEND^HLMA2(ZHLEIDS,HLMTIEN,ZLCLIENT,"D",.ZMTIENS,ZLOGLINK),STATUS^HLTF0(+ZMTIENS,1)
     27 K HLL("LINKS"),HLSUP
     28 Q
     29STALL ;STOP ALL LINKS AND FILERS
     30 N DIR,Y
     31 W ! S DIR(0)="Y",DIR("A")="Okay to shut down all Links and Filers"
     32 D ^DIR
     33 I 'Y!($D(DIRUT))!($D(DUOUT)) W !!,"Shutdown Aborted!" Q
     34 W !,"Shutting down all Links and Filers..."
     35 D CLEAR
     36 D LLP(1)
     37 Q
     38QUE ;Restart Filers and AUTOSTART Logical Links after system re-boot
     39 N DIR,Y
     40 I '$D(ZTQUEUED) D  Q:'Y!($D(DIRUT))!($D(DUOUT))
     41 .W ! S DIR(0)="Y",DIR("A")="Shutdown and restart ALL AUTOSTART links and filers. Okay"
     42 .D ^DIR
     43 .I 'Y!($D(DIRUT))!($D(DUOUT)) W !!,"RESTART Aborted!" Q
     44 .W !,"Restarting all Autostart-Enabled Links and Filers..."
     45 D CLEAR
     46 D STARTF
     47 D LLP(0)
     48 D STRT
     49 Q
     50CLEAR ;Reset state of 869.3
     51 S DA(1)=1,DA=0,DIK="^HLCS(869.3,1,2,"
     52 F  S DA=$O(^HLCS(869.3,DA(1),2,DA)) Q:DA<1  D ^DIK
     53 S DA=0,DIK="^HLCS(869.3,1,3,"
     54 F  S DA=$O(^HLCS(869.3,DA(1),3,DA)) Q:DA<1  D ^DIK
     55 Q
     56STARTF ;Start filers
     57 ;Get Defaults
     58 N TMP,PTR,DEFCNT,DA,HLCNT,HLNODE1
     59 S PTR=+$O(^HLCS(869.3,0)) Q:'PTR
     60 ;default # of incoming filers
     61 S HLNODE1=$G(^HLCS(869.3,PTR,1)),DEFCNT=+$P(HLNODE1,U) S:'DEFCNT DEFCNT=1
     62 F HLCNT=1:1:DEFCNT S TMP=$$TASKFLR^HLCS1("IN")
     63 ;default # of outgoing filers
     64 S DEFCNT=+$P(HLNODE1,U,2) S:'DEFCNT DEFCNT=1
     65 F HLCNT=1:1:DEFCNT S TMP=$$TASKFLR^HLCS1("OUT")
     66 Q
     67LLP(ALL) ;Stop Logical Links
     68 ;ALL=1 OR 0 IF zero, only AUTOSTART LINKS get stopped
     69 N HLDP,HLDP0,HLPARM0,HLPARM4,HLJ,X,Y S HLDP=0
     70 F  S HLDP=$O(^HLCS(870,HLDP)) Q:'HLDP  S HLDP0=$G(^(HLDP,0)),X=+$P(HLDP0,U,3) D:X
     71 .;skip this link if not stopping all and Autostart not enabled
     72 . I 'ALL&('$P(HLDP0,U,6)) Q
     73 . S HLPARM4=$G(^HLCS(870,HLDP,400))
     74 . ;TCP Multi listener for non-Cache uses UCX
     75 . I $P(HLPARM4,U,3)="M" Q:^%ZOSF("OS")'["OpenM"  Q:$$OS^%ZOSV["VMS"
     76 . ;4=status,10=Time Stopped,9=Time Started,11=Task Number,3=Device Type,14=shutdown?
     77 . S X="HLJ(870,"""_HLDP_","")",@X@(4)="Halting",@X@(10)=$$NOW^XLFDT,(@X@(11),@X@(9))="@",@X@(14)=1
     78 . I $P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4)),'$P(HLDP0,U,12) S @X@(4)="Shutdown"
     79 . D FILE^HLDIE("","HLJ","","LLP","HLCS2") ;HL*1.6*109
     80 . ;Cache system, need to open TCP port to release job
     81 . I ^%ZOSF("OS")["OpenM",($P(HLPARM4,U,3)="M"!($P(HLPARM4,U,3)="S")) D
     82 .. ;pass task number to stop listener
     83 .. S:$P(HLDP0,U,12) X=$$ASKSTOP^%ZTLOAD(+$P(HLDP0,U,12))
     84 .. D CALL^%ZISTCP($P(HLPARM4,U),$P(HLPARM4,U,2),10)
     85 .. I POP D HOME^%ZIS Q
     86 .. D CLOSE^%ZISTCP
     87 Q
     88STRT ;Start Links
     89 N HLDP,HLDP0,HLDAPP,HLTYPTR,HLBGR,HLENV,HLPARAM0,HLPARM4,HLQUIT,ZTRTN,ZTDESC,ZTSK,ZTCPU
     90 S HLDP=0
     91 F  S HLDP=$O(^HLCS(870,HLDP)) Q:HLDP<1  S HLDP0=$G(^(HLDP,0)) D
     92 . S HLPARM4=$G(^HLCS(870,HLDP,400))
     93 . ;quit if no parameters or AUTOSTART is disabled
     94 . Q:'$P(HLDP0,U,6)
     95 . ;HLDAPP=LL name, HLTYPTR=LL type, HLBGR=routine, HLENV=environment check
     96 . S HLDAPP=$P(HLDP0,U),HLTYPTR=+$P(HLDP0,U,3),HLBGR=$G(^HLCS(869.1,HLTYPTR,100)),HLENV=$G(^(200))
     97 . ;quit if no LL type or no routine
     98 . Q:'HLTYPTR!(HLBGR="")
     99 . I HLENV'="" K HLQUIT X HLENV Q:$D(HLQUIT)
     100 . ;TCP Multi listener for non-Cache uses UCX
     101 . I $P(HLPARM4,U,3)="M" Q:^%ZOSF("OS")'["OpenM"  Q:$$OS^%ZOSV["VMS"
     102 . I $P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4)) D  Q
     103 .. ;4=status 9=Time Started, 10=Time Stopped, 11=Task Number
     104 .. ;14=Shutdown LLP, 3=Device Type, 18=Gross Errors
     105 .. N HLJ,X
     106 .. I $P(HLDP0,U,15)=0 Q
     107 .. L +^HLCS(870,HLDP,0):2
     108 .. E  Q
     109 .. S X="HLJ(870,"""_HLDP_","")"
     110 .. S @X@(4)="Enabled",@X@(9)=$$NOW^XLFDT,@X@(14)=0
     111 .. D FILE^HLDIE("","HLJ","","STRT","HLCS2") ; HL*1.6*109
     112 .. L -^HLCS(870,HLDP,0)
     113 .. Q
     114 . S ZTRTN=$P(HLBGR," ",2),ZTIO="",ZTDTH=$H,HLTRACE=""
     115 . S ZTDESC=HLDAPP_" Low Level Protocol",ZTSAVE("HLDP")=""
     116 . ;get startup node
     117 . I $P(HLPARM4,U,6),$D(^%ZIS(14.7,+$P(HLPARM4,U,6),0)) S ZTCPU=$P(^(0),U)
     118 . D ^%ZTLOAD
     119 Q
     120SITEP ;Edit Site Parameters
     121 S DDSFILE=869.3,DA=1,DR="[HL SITE PARAMETERS]" D ^DDS
     122 Q
     123PARAM() ;Return HL7 site parameters
     124 ;HLPARAM=domain ien^domain name^production or test^institution ien^
     125 ;institution name^institution number^mail group ien^mail group name^
     126 ;purge completed messages^purge awaiting ack messages^purge all msgs^
     127 ;default retention
     128 N HLX,HLX4,HLX5,HLDOMP,HLDOMN,HLPROD,HLINSP,HLINSN,HLINSNM,HLMAILP,HLMAILN,HLPARAM,HLPRGAA,HLPRGALL,HLPRGCMP,HLDEFRET
     129 S HLX=$G(^HLCS(869.3,1,0))
     130 S HLX4=$G(^HLCS(869.3,1,4))
     131 S HLX5=$G(^HLCS(869.3,1,5))
     132 S HLDOMP=$P(HLX,U,2) I HLDOMP S HLDOMN=$P(^DIC(4.2,HLDOMP,0),U)
     133 S HLPROD=$P(HLX,U,3)
     134 S HLINSP=$P(HLX,U,4) I HLINSP S HLINSN=$P(^DIC(4,HLINSP,0),U),HLINSNM=$P($G(^DIC(4,HLINSP,99)),U)
     135 S HLMAILP=$P(HLX,U,5) I HLMAILP S HLMAILN=$P(^XMB(3.8,HLMAILP,0),U)
     136 S HLPRGCMP=$P(HLX4,U),HLPRGAA=$P(HLX4,U,2),HLPRGALL=$P(HLX4,U,3)
     137 S HLDEFRET=$P(HLX5,U)
     138 S HLPARAM=HLDOMP_U_$G(HLDOMN)_U_$G(HLPROD)_U_HLINSP_U_$G(HLINSN)_U_$G(HLINSNM)_U_HLMAILP_U_$G(HLMAILN)_U_HLPRGCMP_U_HLPRGAA_U_HLPRGALL_U_HLDEFRET
     139 Q HLPARAM
     140 ;
     141GETAPP(HLAPP) ;Function to Retrieve parameters pertaining to a specific sending or receiving application
     142 ;HLAPP=APPLICATION NAME OR IEN OF FILE 771
     143 ;Returns MAIL GROUP NAME^'a' or 'i' (active or inactive)
     144 S HLAPP=$G(HLAPP)
     145 I HLAPP]"",'HLAPP S HLAPP=$O(^HL(771,"B",$E(HLAPP,1,30),0))
     146 I 'HLAPP Q ""
     147 I HLAPP S HLM=$P(^HL(771,HLAPP,0),U,4)
     148 I HLM S HLM=$P($G(^XMB(3.8,HLM,0)),U)
     149 Q $G(HLM)_U_$P(^HL(771,HLAPP,0),U,2)
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSGTM.m

    r613 r623  
    1 HLCSGTM ;OIFO-O/RWF - (TCP/IP) GT.M Linux ;08/13/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ; 1. port number is input from VMS COM file, such as HLSxxxxDSM.COM,
    6         ;    HLSxxxxCACHE.COM, or HLSxxxxGTM.COM file, where xxxx is port
    7         ;    number.
    8         ; 2. find the ien of #870(logical link file) for the multi-listener
    9         Q
    10         ;
    11 IEN(HLPORT)     ;
    12         ; HLIEN870: ien in #870 (logical link file)
    13         ; HLPRTS: port number in entry to be tested
    14         ;
    15         N HLPRTS,HLIEN870
    16         I '$G(HLPORT) D ^%ZTER Q
    17         S HLIEN870=0
    18         F  S HLIEN870=$O(^HLCS(870,"E","M",HLIEN870)) Q:'HLIEN870  D  Q:(HLPRTS=HLPORT)
    19         . S HLPRTS=$P(^HLCS(870,HLIEN870,400),"^",2)
    20         I 'HLIEN870 D ^%ZTER Q
    21         ;
    22         Q HLIEN870
    23         ;
    24 GTMLNX  ; From Linux xinetd script
    25         ;Get port from ZSHOW "D"
    26         S U="^",$ZT="",$ET="D ^%ZTER HALT" ;Setup the error trap
    27         ; GTM specific code
    28         S IO=$P X "U IO:(nowrap:nodelimiter:IOERROR=""TRAP"")" ;Setup device
    29         S @("$ZINTERRUPT=""I $$JOBEXAM^ZU($ZPOSITION)""")
    30         K ^TMP($J) ZSHOW "D":^TMP($J)
    31         F %=1:1 Q:'$D(^TMP($J,"D",%))  S X=^(%) Q:X["LOCAL"
    32         S IO("IP")=$P($P(X,"REMOTE=",2),"@"),IO("PORT")=+$P($P(X,"LOCAL=",2),"@",2)
    33         S %=$P($ZTRNLNM("SSH_CLIENT")," ") S:%="" %=$ZTRNLNM("REMOTEHOST")
    34         S HLDP=$$IEN(IO("PORT"))
    35         ;
    36         D LISTEN^HLCSTCP
    37         Q
    38         ;
    39         ;Sample Linux script
    40         ;#!/bin/bash
    41         ;#HL7 Listener
    42         ;cd /home/vista/dev/
    43         ;. ./gtmprofile
    44         ;#env > hl7log.txt
    45         ;$gtm_dist/mumps -r GTMLNX^HLCSGTM
    46         ;exit 0
    47         ;
    48         ;Sample xinetd config file
    49         ;service hl7tcp
    50         ;{
    51         ;        socket_type     = stream
    52         ;        user            = gtmuser
    53         ;        wait            = no
    54         ;        disable         = no
    55         ;        server          = /bin/bash
    56         ;        server_args     = -l /home/vista/dev/hl7tcp.sh
    57         ;        passenv         = REMOTE_HOST
    58         ;}
     1HLCSGTM ;OIFO-O/RWF - (TCP/IP) GT.M Linux ;08/13/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**122**;Oct 13, 1995;Build 4;WorldVistA 30-Jan-08
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ; 1. port number is input from VMS COM file, such as HLSxxxxDSM.COM,
     6 ;    HLSxxxxCACHE.COM, or HLSxxxxGTM.COM file, where xxxx is port
     7 ;    number.
     8 ; 2. find the ien of #870(logical link file) for the multi-listener
     9 ;Modified from FOIA VISTA,
     10 ;Copyright 2008 WorldVistA.  Licensed under the terms of the GNU
     11 ;General Public License See attached copy of the License.
     12 ;
     13 ;This program is free software; you can redistribute it and/or modify
     14 ;it under the terms of the GNU General Public License as published by
     15 ;the Free Software Foundation; either version 2 of the License, or
     16 ;(at your option) any later version.
     17 ;
     18 ;This program is distributed in the hope that it will be useful,
     19 ;but WITHOUT ANY WARRANTY; without even the implied warranty of
     20 ;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     21 ;GNU General Public License for more details.
     22 ;
     23 ;You should have received a copy of the GNU General Public License along
     24 ;with this program; if not, write to the Free Software Foundation, Inc.,
     25 ;51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     26 Q
     27 ;
     28IEN(HLPORT) ;
     29 ; HLIEN870: ien in #870 (logical link file)
     30 ; HLPRTS: port number in entry to be tested
     31 ;
     32 N HLPRTS,HLIEN870
     33 I '$G(HLPORT) D ^%ZTER Q
     34 S HLIEN870=0
     35 F  S HLIEN870=$O(^HLCS(870,"E","M",HLIEN870)) Q:'HLIEN870  D  Q:(HLPRTS=HLPORT)
     36 . S HLPRTS=$P(^HLCS(870,HLIEN870,400),"^",2)
     37 I 'HLIEN870 D ^%ZTER Q
     38 ;
     39 Q HLIEN870
     40 ;
     41GTMLNX ; From Linux xinetd script
     42 ;Get port from ZSHOW "D"
     43 S U="^",$ZT="",$ET="D ^%ZTER HALT" ;Setup the error trap
     44 ; GTM specific code
     45 S IO=$P X "U IO:(nowrap:nodelimiter:IOERROR=""TRAP"")" ;Setup device
     46 S @("$ZINTERRUPT=""I $$JOBEXAM^ZU($ZPOSITION)""")
     47 K ^TMP($J) ZSHOW "D":^TMP($J)
     48 F %=1:1 Q:'$D(^TMP($J,"D",%))  S X=^(%) Q:X["LOCAL"
     49 S IO("IP")=$P($P(X,"REMOTE=",2),"@"),IO("PORT")=+$P($P(X,"LOCAL=",2),"@",2)
     50 S %=$P($ZTRNLNM("SSH_CLIENT")," ") S:%="" %=$ZTRNLNM("REMOTEHOST")
     51 S HLDP=$$IEN(IO("PORT"))
     52 ;
     53 D LISTEN^HLCSTCP
     54 Q
     55 ;
     56 ;Sample Linux script
     57 ;#!/bin/bash
     58 ;#HL7 Listener
     59 ;cd /home/vista/dev/
     60 ;. ./gtmprofile
     61 ;#env > hl7log.txt
     62 ;$gtm_dist/mumps -r GTMLNX^HLCSGTM
     63 ;exit 0
     64 ;
     65 ;Sample xinetd config file
     66 ;service hl7tcp
     67 ;{
     68 ;        socket_type     = stream
     69 ;        user            = gtmuser
     70 ;        wait            = no
     71 ;        disable         = no
     72 ;        server          = /bin/bash
     73 ;        server_args     = -l /home/vista/dev/hl7tcp.sh
     74 ;        passenv         = REMOTE_HOST
     75 ;}
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSHDR1.m

    r613 r623  
    1 HLCSHDR1        ;SFIRMFO/RSD - Make HL7 header for TCP ;04/17/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**19,57,59,72,80,93,120,133,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4 HEADER(IEN,CLIENT,HLERROR)      ; Create an HL7 MSH segment
    5         ;
    6         ;Input  : IEN - Pointer to entry in Message Administration file (#773)
    7         ;               that HL7 MSH segment is being built for
    8         ;         CLIENT - IEN of the receiving application
    9         ;         HLERROR - Variable to return possible error text in
    10         ;                   (pass by reference - only used when needed)
    11         ;
    12         ;Output : HLHDR(1) - HL7 MSH segment
    13         ;         HLHDR(2) - Continuation of HL7 MSH segment (if needed)
    14         ;         HLHDR(3) - Continuation of HL7 MSH segment (if needed)
    15         ;
    16         ;Notes  : HLERROR will only be defined [on output] if an error occurs
    17         ;       : HLHDR() will not be defined [on output] if an error occurs
    18         ;       : HLHDR(2) & HLHDR(3) are continuation [or roll-over] nodes
    19         ;         and will only be used/defined when needed
    20         ;
    21         N ACKTO,ACCACK,APPACK,CHILD,CLNTAPP,CLNTFAC,CNTRY,EC,EVNTYPE,FS,HLDATE,HLHDRI,HLHDRL,HLID,HLPID,MSGTYPE,PROT,PROTS,SECURITY,SEND,SERAPP,SERFAC,TXTP,TXTP0,X,MSGEVN
    22         N COMFLAG ; patch HL*1.6*120
    23         S HLERROR=""
    24         S HLPARAM=$$PARAM^HLCS2
    25         D VAR Q:$G(HLERROR)]""
    26         ; The following line commented by HL*1.6*72
    27         ;I $D(^HLMA(IEN)) S $P(^HLMA(IEN,0),U,13)=MSGTYPE,$P(^HLMA(IEN,0),U,14)=$G(EVNTYPE)
    28         ;Append event type
    29         I $G(EVNTYPE)]"" S MSGTYPE=MSGTYPE_$E(EC,1)_EVNTYPE
    30         ;Append message structure component
    31         I $G(EVNTYPE)]"",$G(MSGEVN)]"" S MSGTYPE=MSGTYPE_$E(EC,1)_MSGEVN
    32         ;Build MSH array
    33         D RESET^HLCSHDR3 ;HL*1.6*93
    34         ;
    35         ; patch HL*1.6*120 start
    36         ; escape delimiters for SERAPP and CLNTAPP
    37         ; escape component separator if the field is not consisted
    38         ; of 3 components
    39         S EC(1)=$E(EC,1)
    40         S EC(2)=$E(EC,2)
    41         S EC(3)=$E(EC,3)
    42         S EC(4)=$E(EC,4)
    43         S COMFLAG=1
    44         I $L(SERAPP,$E(EC,1))=3 S COMFLAG=0
    45         I (SERAPP[FS)!(SERAPP[EC(1))!(SERAPP[EC(2))!(SERAPP[EC(3))!(SERAPP[EC(4)) D
    46         . S SERAPP=$$ESCAPE(SERAPP,COMFLAG)
    47         S COMFLAG=1
    48         I $L(CLNTAPP,$E(EC,1))=3 S COMFLAG=0
    49         I (CLNTAPP[FS)!(CLNTAPP[EC(1))!(CLNTAPP[EC(2))!(CLNTAPP[EC(3))!(CLNTAPP[EC(4)) D
    50         . S CLNTAPP=$$ESCAPE(CLNTAPP,COMFLAG)
    51         ; patch HL*1.6*120 end
    52         ;
    53         S HLHDRI=1,HLHDR(1)="MSH"_FS_EC_FS_SERAPP,HLHDRL=$L(HLHDR(1))
    54         F X=SERFAC,CLNTAPP,CLNTFAC,HLDATE,SECURITY,MSGTYPE,HLID,HLPID,$P(PROT,U,9),"",$G(^HL(772,TXTP,1)),ACCACK,APPACK,CNTRY D MSH(X)
    55         ;in preceeding line, "" is for sequence number - not supported
    56         Q
    57         ;
    58 MSH(X)  ;add X to HLHDR
    59         S:HLHDRL+$L(X)>245 HLHDRI=HLHDRI+1,HLHDR(HLHDRI)=""
    60         S HLHDR(HLHDRI)=HLHDR(HLHDRI)_FS_X,HLHDRL=$L(HLHDR(HLHDRI))
    61         Q
    62 BHSHDR(IEN,CLIENT,HLERROR)      ; Create Batch Header Segment
    63         ; The BHS has 12 segments, of which 4 are blank.
    64         ; INPUT: IEN - IEN of entry in file #772
    65         ; OUTPUT: HLHDR(1) and HLHDR(2) - the two lines with the 12 segs.
    66         ;   ready for adding to a message directly.
    67         N ACKTO,ACCACK,ACKMID,APPACK,BNAME,BSTATUS,BTACK,CHILD,CLNTAPP ;HL*1.6*80
    68         N CLNTFAC,CNTRY,EC,EVNTYPE,FS,HLDATE,HLHDRI,HLHDRL,HLID,HLPID ;HL*1.6*80 - added HLPID
    69         N PROT,PROTS,SECURITY,SEND,SERAPP,SERFAC,TXTP,TXTP0,X ;HL*1.6*80
    70         N COMFLAG ; patch HL*1.6*120
    71         S HLERROR=""
    72         ;
    73         S HLPARAM=$$PARAM^HLCS2
    74         D VAR Q:$G(HLERROR)]""
    75         ; The following line commented by HL*1.6*72
    76         ;I $D(^HLMA(IEN)) S $P(^HLMA(IEN,0),U,13)=MSGTYPE,$P(^HLMA(IEN,0),U,14)=$G(EVNTYPE)
    77         ;
    78         ;Append event type
    79         I $G(EVNTYPE)]"" S MSGTYPE=MSGTYPE_$E(EC,2)_EVNTYPE,(ACKMID,BTACK)=""
    80         ;batch/name/id/type(#9)=null~process ID~msg type|evnt type~version~CA~AA
    81         S BNAME=$E(EC,1)_HLPID_$E(EC,1)_MSGTYPE_$E(EC,1)_$P(PROT,U,9)_$E(EC,1)_ACCACK_$E(EC,1)_APPACK ;HL*1.6*80
    82         ;for batch ACK
    83         I ACKTO D  S BTACK=X_$E(EC,1)_$P(BSTATUS,U,3)
    84         . ;get msg id and status of message that is being ACKed
    85         . S ACKMID=$P($G(^HLMA(ACKTO,0)),U,2),BSTATUS=$G(^HLMA(ACKTO,"P")) ;HL*1.6*80
    86         . ;set type of ACK based on status
    87         . S X=$S(ACKMID="":"AR",(BSTATUS>3)&(BSTATUS<8):"AE",1:"AA")
    88         ;
    89         D RESET^HLCSHDR3 ;HL*1.6*93
    90         ;
    91         ; patch HL*1.6*120 start
    92         ; escape delimiters for SERAPP and CLNTAPP
    93         ; escape component separator if the field is not consisted
    94         ; of 3 components
    95         S EC(1)=$E(EC,1)
    96         S EC(2)=$E(EC,2)
    97         S EC(3)=$E(EC,3)
    98         S EC(4)=$E(EC,4)
    99         S COMFLAG=1
    100         I $L(SERAPP,$E(EC,1))=3 S COMFLAG=0
    101         I (SERAPP[FS)!(SERAPP[EC(1))!(SERAPP[EC(2))!(SERAPP[EC(3))!(SERAPP[EC(4)) D
    102         . S SERAPP=$$ESCAPE(SERAPP,COMFLAG)
    103         S COMFLAG=1
    104         I $L(CLNTAPP,$E(EC,1))=3 S COMFLAG=0
    105         I (CLNTAPP[FS)!(CLNTAPP[EC(1))!(CLNTAPP[EC(2))!(CLNTAPP[EC(3))!(CLNTAPP[EC(4)) D
    106         . S CLNTAPP=$$ESCAPE(CLNTAPP,COMFLAG)
    107         ; patch HL*1.6*120 end
    108         ;
    109         S HLHDRI=1,HLHDR(1)="BHS"_FS_EC_FS_SERAPP,HLHDRL=$L(HLHDR(1))
    110         F X=SERFAC,CLNTAPP,CLNTFAC,HLDATE,SECURITY,BNAME,BTACK,HLID,ACKMID D MSH(X)
    111         Q
    112 VAR     ;Check input
    113         N APPPRM,HLPROTS,HLPROT
    114         S IEN=+$G(IEN)
    115         I '$G(^HLMA(IEN,0)) S HLERROR="Valid pointer to Message Administration file (#772) not passed" Q
    116         I '$G(CLIENT) S HLERROR="Could not determine receiving application" Q
    117         ;Get child, text pointer,text entry, and sending app.
    118         S CHILD=$G(^HLMA(IEN,0)),SEND=+$P($G(^(0)),U,11),TXTP=+CHILD,TXTP0=$G(^HL(772,TXTP,0))
    119         I ('SEND) S HLERROR="Could not determine sending application" Q
    120         ;Get info for sending & receiving applications
    121         D APPPRM^HLUTIL2(CLIENT),APPPRM^HLUTIL2(SEND)
    122         ;Get name of sending application, facility, and country
    123         S SERAPP=$P(APPPRM(SEND,0),U),SERFAC=$P(APPPRM(SEND,0),U,2),CNTRY=$P(APPPRM(SEND,0),U,3)
    124         ;Get name of receiving application and facility
    125         S CLNTAPP=$P(APPPRM(CLIENT,0),U),CLNTFAC=$P(APPPRM(CLIENT,0),U,2)
    126         ;
    127         ; patch HL*1.6*120
    128         ; for dynamic addressing, overide the receiving facility from the
    129         ; 3rd component of HLL("LINKS") array
    130         I $G(HLP("REC-FACILITY"))]"" S CLNTFAC=HLP("REC-FACILITY")
    131         ;
    132         ;Get field separator & encoding characters
    133         S FS=APPPRM(SEND,"FS"),EC=APPPRM(SEND,"EC")
    134         S:(EC="") EC="~|\&" S:(FS="") FS="^"
    135         ;Determine if it's a response/ACK to another message
    136         S ACKTO=+$P(CHILD,U,10)
    137         ;subscriber protocol is from child (file 773)
    138         ;If response, get MType from subscriber
    139         S HLPROTS=+$P(CHILD,U,8)
    140         S PROTS=$$TYPE^HLUTIL2(HLPROTS)
    141         I ACKTO S MSGTYPE=$P(PROTS,U,10),EVNTYPE=$P(PROTS,U,3),MSGEVN=$P(PROTS,U,4)
    142         ;Get accept ack & application ack type (based on server protocol) it
    143         ; is always in file 772, TXPT0
    144         ;If original message, get MT from Event Driver Protocol
    145         S HLPROT=+$P(TXTP0,U,10)
    146         S PROT=$$TYPE^HLUTIL2(HLPROT)
    147         S:'ACKTO MSGTYPE=$P(PROT,U,2),EVNTYPE=$P(PROT,U,3),MSGEVN=$P(PROT,U,4)
    148         S ACCACK=$P(PROT,U,7),APPACK=$P(PROT,U,8)
    149         ;
    150         ; patch HL*1.6*122
    151         ; setting the MSH-15 and MSH-16 from subscriber protocol
    152         I HLPROTS,$P($G(^ORD(101,HLPROTS,773)),"^",5) D
    153         . S ACCACK=$P(PROTS,U,7)
    154         . S APPACK=$P(PROTS,U,8)
    155         ;
    156 PID     ;Processing ID
    157         ;I PID not 'debug' get from site params
    158         ;If event driver set to 'debug' get from protocol
    159         ;'production' or 'training' comes from site params
    160         S HLPID=$P(PROT,U,5)
    161         I $G(HLPID)'="D" S HLPID=$P(HLPARAM,U,3)
    162         ;
    163         ; patch HL*1.6*120: to include processing mode
    164         I $G(HLP("PMOD"))]"",($G(HLTYPE)="M") D
    165         . S HLPID=HLPID_$E($G(EC),1)_HLP("PMOD")
    166         ;
    167         I $G(HLPID)="" S HLERROR="Missing processing ID Site parameter."
    168         ;acknowledgements have no application ack, link open no commit ack
    169         I ACKTO S:APPACK]"" APPACK="NE" S:ACCACK]""&$G(HLTCPO) ACCACK="NE"
    170         ;Get date/time, Message ID, and security
    171         S HLDATE=+TXTP0,HLDATE=$$FMTHL7^XLFDT(HLDATE),HLID=$P(CHILD,U,2),SECURITY=$P(CHILD,U,9)
    172 HDR23   ;generate extended facility field info based on 'facility required'
    173         ;default format is INSTITUTION_HLCS_DOMAIN_HLCS_'DNS'
    174         ;application parameter entry overrides default
    175         N HLEP773,HLS773
    176         S SERFAC=$G(SERFAC),CLNTFAC=$G(CLNTFAC)
    177         S HLEP773=+$G(^ORD(101,HLPROTS,773))
    178         S HLS773=+$P($G(^ORD(101,HLPROTS,773)),U,2)
    179         Q:'HLEP773&('HLS773)
    180         D GEN^HLCSHDR2
    181         I ACKTO D  Q
    182         .;Find original message
    183         .S X=$G(^HLMA(ACKTO,"MSH",1,0)) ;Find header in TCP nodes
    184         .I X["MSH" D
    185         ..;
    186         ..; patch HL*1.6*120 start
    187         .. N HLEC
    188         ..S HLFS=$E(X,4),HLEC=$E(X,5)
    189         ..S SENDFAC=$P(X,HLFS,4),RECFAC=$P(X,HLFS,6) ;from original msg
    190         ..S CLNTFAC=SENDFAC,SERFAC=RECFAC ;reverse facility info
    191         ..S EC("COMPONENT")=$E($G(EC),1)
    192         ..I $L(EC("COMPONENT"))=1,$L(HLEC)=1,EC("COMPONENT")'=HLEC D
    193         ... ; change the the component separator in the sending and
    194         ... ; receiving facilities for the outgoing message
    195         ... S CLNTFAC=$TR(CLNTFAC,HLEC,EC("COMPONENT"))
    196         ... S SERFAC=$TR(SERFAC,HLEC,EC("COMPONENT"))
    197         ; patch HL*1.6*120 end
    198         ;
    199         I HLEP773,SERFAC="" D EP^HLCSHDR2
    200         I HLS773,CLNTFAC="" D S^HLCSHDR2
    201         Q
    202         ;
    203 ESCAPE(INPUT,COMPONET)  ;
    204         ; patch HL*1.6*120 - escape delimiters:
    205         ; - field separator
    206         ; - component separator
    207         ; - repetition separator
    208         ; - escape character
    209         ; - subcomponent separator
    210         ;
    211         ; input:
    212         ;     INPUT - string data to be escaped
    213         ;  COMPONET - if 1, escape component separator
    214         ;             if 0, do not escape component separator
    215         ;        FS - field separator character
    216         ;        EC - encoding characters
    217         ; result: return the escaped string
    218         ;
    219         N HLDATA,HLESCAPE,HLI,HLCHAR,HLEN,HLOUT,COMFLAG
    220         S HLDATA=$G(INPUT)
    221         S COMFLAG=$G(COMPONET)
    222         Q:$L($G(FS))'=1 HLDATA
    223         ;
    224         ; patch HL*1.6*133
    225         ; Q:$L($G(EC))'=4 HLDATA
    226         Q:($L($G(EC))<3) HLDATA
    227         Q:HLDATA']"" HLDATA
    228         ;
    229         S HLESCAPE=FS_EC
    230         S HLESCAPE("F")=FS
    231         S HLESCAPE("S")=$E(EC,1)
    232         S HLESCAPE("R")=$E(EC,2)
    233         S HLESCAPE("E")=$E(EC,3)
    234         S HLESCAPE("T")=$E(EC,4)
    235         S HLEN=$L(HLDATA)
    236         S HLOUT=""
    237         F HLI=1:1:HLEN D
    238         . S HLCHAR=$E(HLDATA,HLI)
    239         . I HLESCAPE[HLCHAR D  Q
    240         .. I HLCHAR=HLESCAPE("F") S HLOUT=HLOUT_HLESCAPE("E")_"F"_HLESCAPE("E") Q
    241         .. I HLCHAR=HLESCAPE("S") D  Q
    242         ... I COMFLAG=1 S HLOUT=HLOUT_HLESCAPE("E")_"S"_HLESCAPE("E") Q
    243         ... S HLOUT=HLOUT_HLCHAR
    244         .. I HLCHAR=HLESCAPE("R") S HLOUT=HLOUT_HLESCAPE("E")_"R"_HLESCAPE("E") Q
    245         .. I HLCHAR=HLESCAPE("E") S HLOUT=HLOUT_HLESCAPE("E")_"E"_HLESCAPE("E") Q
    246         .. I HLCHAR=HLESCAPE("T") S HLOUT=HLOUT_HLESCAPE("E")_"T"_HLESCAPE("E") Q
    247         . ;
    248         . S HLOUT=HLOUT_HLCHAR
    249         Q HLOUT
     1HLCSHDR1 ;SFIRMFO/RSD - Make HL7 header for TCP ;09/13/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**19,57,59,72,80,93,120,133**;Oct 13, 1995;Build 13
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4HEADER(IEN,CLIENT,HLERROR) ; Create an HL7 MSH segment
     5 ;
     6 ;Input  : IEN - Pointer to entry in Message Administration file (#773)
     7 ;               that HL7 MSH segment is being built for
     8 ;         CLIENT - IEN of the receiving application
     9 ;         HLERROR - Variable to return possible error text in
     10 ;                   (pass by reference - only used when needed)
     11 ;
     12 ;Output : HLHDR(1) - HL7 MSH segment
     13 ;         HLHDR(2) - Continuation of HL7 MSH segment (if needed)
     14 ;         HLHDR(3) - Continuation of HL7 MSH segment (if needed)
     15 ;
     16 ;Notes  : HLERROR will only be defined [on output] if an error occurs
     17 ;       : HLHDR() will not be defined [on output] if an error occurs
     18 ;       : HLHDR(2) & HLHDR(3) are continuation [or roll-over] nodes
     19 ;         and will only be used/defined when needed
     20 ;
     21 N ACKTO,ACCACK,APPACK,CHILD,CLNTAPP,CLNTFAC,CNTRY,EC,EVNTYPE,FS,HLDATE,HLHDRI,HLHDRL,HLID,HLPID,MSGTYPE,PROT,PROTS,SECURITY,SEND,SERAPP,SERFAC,TXTP,TXTP0,X,MSGEVN
     22 N COMFLAG ; patch HL*1.6*120
     23 S HLERROR=""
     24 S HLPARAM=$$PARAM^HLCS2
     25 D VAR Q:$G(HLERROR)]""
     26 ; The following line commented by HL*1.6*72
     27 ;I $D(^HLMA(IEN)) S $P(^HLMA(IEN,0),U,13)=MSGTYPE,$P(^HLMA(IEN,0),U,14)=$G(EVNTYPE)
     28 ;Append event type
     29 I $G(EVNTYPE)]"" S MSGTYPE=MSGTYPE_$E(EC,1)_EVNTYPE
     30 ;Append message structure component
     31 I $G(EVNTYPE)]"",$G(MSGEVN)]"" S MSGTYPE=MSGTYPE_$E(EC,1)_MSGEVN
     32 ;Build MSH array
     33 D RESET^HLCSHDR3 ;HL*1.6*93
     34 ;
     35 ; patch HL*1.6*120 start
     36 ; escape delimiters for SERAPP and CLNTAPP
     37 ; escape component separator if the field is not consisted
     38 ; of 3 components
     39 S EC(1)=$E(EC,1)
     40 S EC(2)=$E(EC,2)
     41 S EC(3)=$E(EC,3)
     42 S EC(4)=$E(EC,4)
     43 S COMFLAG=1
     44 I $L(SERAPP,$E(EC,1))=3 S COMFLAG=0
     45 I (SERAPP[FS)!(SERAPP[EC(1))!(SERAPP[EC(2))!(SERAPP[EC(3))!(SERAPP[EC(4)) D
     46 . S SERAPP=$$ESCAPE(SERAPP,COMFLAG)
     47 S COMFLAG=1
     48 I $L(CLNTAPP,$E(EC,1))=3 S COMFLAG=0
     49 I (CLNTAPP[FS)!(CLNTAPP[EC(1))!(CLNTAPP[EC(2))!(CLNTAPP[EC(3))!(CLNTAPP[EC(4)) D
     50 . S CLNTAPP=$$ESCAPE(CLNTAPP,COMFLAG)
     51 ; patch HL*1.6*120 end
     52 ;
     53 S HLHDRI=1,HLHDR(1)="MSH"_FS_EC_FS_SERAPP,HLHDRL=$L(HLHDR(1))
     54 F X=SERFAC,CLNTAPP,CLNTFAC,HLDATE,SECURITY,MSGTYPE,HLID,HLPID,$P(PROT,U,9),"",$G(^HL(772,TXTP,1)),ACCACK,APPACK,CNTRY D MSH(X)
     55 ;in preceeding line, "" is for sequence number - not supported
     56 Q
     57 ;
     58MSH(X) ;add X to HLHDR
     59 S:HLHDRL+$L(X)>245 HLHDRI=HLHDRI+1,HLHDR(HLHDRI)=""
     60 S HLHDR(HLHDRI)=HLHDR(HLHDRI)_FS_X,HLHDRL=$L(HLHDR(HLHDRI))
     61 Q
     62BHSHDR(IEN,CLIENT,HLERROR) ; Create Batch Header Segment
     63 ; The BHS has 12 segments, of which 4 are blank.
     64 ; INPUT: IEN - IEN of entry in file #772
     65 ; OUTPUT: HLHDR(1) and HLHDR(2) - the two lines with the 12 segs.
     66 ;   ready for adding to a message directly.
     67 N ACKTO,ACCACK,ACKMID,APPACK,BNAME,BSTATUS,BTACK,CHILD,CLNTAPP ;HL*1.6*80
     68 N CLNTFAC,CNTRY,EC,EVNTYPE,FS,HLDATE,HLHDRI,HLHDRL,HLID,HLPID ;HL*1.6*80 - added HLPID
     69 N PROT,PROTS,SECURITY,SEND,SERAPP,SERFAC,TXTP,TXTP0,X ;HL*1.6*80
     70 N COMFLAG ; patch HL*1.6*120
     71 S HLERROR=""
     72 ;
     73 S HLPARAM=$$PARAM^HLCS2
     74 D VAR Q:$G(HLERROR)]""
     75 ; The following line commented by HL*1.6*72
     76 ;I $D(^HLMA(IEN)) S $P(^HLMA(IEN,0),U,13)=MSGTYPE,$P(^HLMA(IEN,0),U,14)=$G(EVNTYPE)
     77 ;
     78 ;Append event type
     79 I $G(EVNTYPE)]"" S MSGTYPE=MSGTYPE_$E(EC,2)_EVNTYPE,(ACKMID,BTACK)=""
     80 ;batch/name/id/type(#9)=null~process ID~msg type|evnt type~version~CA~AA
     81 S BNAME=$E(EC,1)_HLPID_$E(EC,1)_MSGTYPE_$E(EC,1)_$P(PROT,U,9)_$E(EC,1)_ACCACK_$E(EC,1)_APPACK ;HL*1.6*80
     82 ;for batch ACK
     83 I ACKTO D  S BTACK=X_$E(EC,1)_$P(BSTATUS,U,3)
     84 . ;get msg id and status of message that is being ACKed
     85 . S ACKMID=$P($G(^HLMA(ACKTO,0)),U,2),BSTATUS=$G(^HLMA(ACKTO,"P")) ;HL*1.6*80
     86 . ;set type of ACK based on status
     87 . S X=$S(ACKMID="":"AR",(BSTATUS>3)&(BSTATUS<8):"AE",1:"AA")
     88 ;
     89 D RESET^HLCSHDR3 ;HL*1.6*93
     90 ;
     91 ; patch HL*1.6*120 start
     92 ; escape delimiters for SERAPP and CLNTAPP
     93 ; escape component separator if the field is not consisted
     94 ; of 3 components
     95 S EC(1)=$E(EC,1)
     96 S EC(2)=$E(EC,2)
     97 S EC(3)=$E(EC,3)
     98 S EC(4)=$E(EC,4)
     99 S COMFLAG=1
     100 I $L(SERAPP,$E(EC,1))=3 S COMFLAG=0
     101 I (SERAPP[FS)!(SERAPP[EC(1))!(SERAPP[EC(2))!(SERAPP[EC(3))!(SERAPP[EC(4)) D
     102 . S SERAPP=$$ESCAPE(SERAPP,COMFLAG)
     103 S COMFLAG=1
     104 I $L(CLNTAPP,$E(EC,1))=3 S COMFLAG=0
     105 I (CLNTAPP[FS)!(CLNTAPP[EC(1))!(CLNTAPP[EC(2))!(CLNTAPP[EC(3))!(CLNTAPP[EC(4)) D
     106 . S CLNTAPP=$$ESCAPE(CLNTAPP,COMFLAG)
     107 ; patch HL*1.6*120 end
     108 ;
     109 S HLHDRI=1,HLHDR(1)="BHS"_FS_EC_FS_SERAPP,HLHDRL=$L(HLHDR(1))
     110 F X=SERFAC,CLNTAPP,CLNTFAC,HLDATE,SECURITY,BNAME,BTACK,HLID,ACKMID D MSH(X)
     111 Q
     112VAR ;Check input
     113 N APPPRM,HLPROTS,HLPROT
     114 S IEN=+$G(IEN)
     115 I '$G(^HLMA(IEN,0)) S HLERROR="Valid pointer to Message Administration file (#772) not passed" Q
     116 I '$G(CLIENT) S HLERROR="Could not determine receiving application" Q
     117 ;Get child, text pointer,text entry, and sending app.
     118 S CHILD=$G(^HLMA(IEN,0)),SEND=+$P($G(^(0)),U,11),TXTP=+CHILD,TXTP0=$G(^HL(772,TXTP,0))
     119 I ('SEND) S HLERROR="Could not determine sending application" Q
     120 ;Get info for sending & receiving applications
     121 D APPPRM^HLUTIL2(CLIENT),APPPRM^HLUTIL2(SEND)
     122 ;Get name of sending application, facility, and country
     123 S SERAPP=$P(APPPRM(SEND,0),U),SERFAC=$P(APPPRM(SEND,0),U,2),CNTRY=$P(APPPRM(SEND,0),U,3)
     124 ;Get name of receiving application and facility
     125 S CLNTAPP=$P(APPPRM(CLIENT,0),U),CLNTFAC=$P(APPPRM(CLIENT,0),U,2)
     126 ;
     127 ; patch HL*1.6*120
     128 ; for dynamic addressing, overide the receiving facility from the
     129 ; 3rd component of HLL("LINKS") array
     130 I $G(HLP("REC-FACILITY"))]"" S CLNTFAC=HLP("REC-FACILITY")
     131 ;
     132 ;Get field separator & encoding characters
     133 S FS=APPPRM(SEND,"FS"),EC=APPPRM(SEND,"EC")
     134 S:(EC="") EC="~|\&" S:(FS="") FS="^"
     135 ;Determine if it's a response/ACK to another message
     136 S ACKTO=+$P(CHILD,U,10)
     137 ;subscriber protocol is from child (file 773)
     138 ;If response, get MType from subscriber
     139 S HLPROTS=+$P(CHILD,U,8)
     140 S PROTS=$$TYPE^HLUTIL2(HLPROTS)
     141 I ACKTO S MSGTYPE=$P(PROTS,U,10),EVNTYPE=$P(PROTS,U,3),MSGEVN=$P(PROTS,U,4)
     142 ;Get accept ack & application ack type (based on server protocol) it
     143 ; is always in file 772, TXPT0
     144 ;If original message, get MT from Event Driver Protocol
     145 S HLPROT=+$P(TXTP0,U,10)
     146 S PROT=$$TYPE^HLUTIL2(HLPROT)
     147 S:'ACKTO MSGTYPE=$P(PROT,U,2),EVNTYPE=$P(PROT,U,3),MSGEVN=$P(PROT,U,4)
     148 S ACCACK=$P(PROT,U,7),APPACK=$P(PROT,U,8)
     149PID ;Processing ID
     150 ;I PID not 'debug' get from site params
     151 ;If event driver set to 'debug' get from protocol
     152 ;'production' or 'training' comes from site params
     153 S HLPID=$P(PROT,U,5)
     154 I $G(HLPID)'="D" S HLPID=$P(HLPARAM,U,3)
     155 ;
     156 ; patch HL*1.6*120: to include processing mode
     157 I $G(HLP("PMOD"))]"",($G(HLTYPE)="M") D
     158 . S HLPID=HLPID_$E($G(EC),1)_HLP("PMOD")
     159 ;
     160 I $G(HLPID)="" S HLERROR="Missing processing ID Site parameter."
     161 ;acknowledgements have no application ack, link open no commit ack
     162 I ACKTO S:APPACK]"" APPACK="NE" S:ACCACK]""&$G(HLTCPO) ACCACK="NE"
     163 ;Get date/time, Message ID, and security
     164 S HLDATE=+TXTP0,HLDATE=$$FMTHL7^XLFDT(HLDATE),HLID=$P(CHILD,U,2),SECURITY=$P(CHILD,U,9)
     165HDR23 ;generate extended facility field info based on 'facility required'
     166 ;default format is INSTITUTION_HLCS_DOMAIN_HLCS_'DNS'
     167 ;application parameter entry overrides default
     168 N HLEP773,HLS773
     169 S SERFAC=$G(SERFAC),CLNTFAC=$G(CLNTFAC)
     170 S HLEP773=+$G(^ORD(101,HLPROTS,773))
     171 S HLS773=+$P($G(^ORD(101,HLPROTS,773)),U,2)
     172 Q:'HLEP773&('HLS773)
     173 D GEN^HLCSHDR2
     174 I ACKTO D  Q
     175 .;Find original message
     176 .S X=$G(^HLMA(ACKTO,"MSH",1,0)) ;Find header in TCP nodes
     177 .I X["MSH" D
     178 ..;
     179 ..; patch HL*1.6*120 start
     180 .. N HLEC
     181 ..S HLFS=$E(X,4),HLEC=$E(X,5)
     182 ..S SENDFAC=$P(X,HLFS,4),RECFAC=$P(X,HLFS,6) ;from original msg
     183 ..S CLNTFAC=SENDFAC,SERFAC=RECFAC ;reverse facility info
     184 ..S EC("COMPONENT")=$E($G(EC),1)
     185 ..I $L(EC("COMPONENT"))=1,$L(HLEC)=1,EC("COMPONENT")'=HLEC D
     186 ... ; change the the component separator in the sending and
     187 ... ; receiving facilities for the outgoing message
     188 ... S CLNTFAC=$TR(CLNTFAC,HLEC,EC("COMPONENT"))
     189 ... S SERFAC=$TR(SERFAC,HLEC,EC("COMPONENT"))
     190 ; patch HL*1.6*120 end
     191 ;
     192 I HLEP773,SERFAC="" D EP^HLCSHDR2
     193 I HLS773,CLNTFAC="" D S^HLCSHDR2
     194 Q
     195 ;
     196ESCAPE(INPUT,COMPONET) ;
     197 ; patch HL*1.6*120 - escape delimiters:
     198 ; - field separator
     199 ; - component separator
     200 ; - repetition separator
     201 ; - escape character
     202 ; - subcomponent separator
     203 ;
     204 ; input:
     205 ;     INPUT - string data to be escaped
     206 ;  COMPONET - if 1, escape component separator
     207 ;             if 0, do not escape component separator
     208 ;        FS - field separator character
     209 ;        EC - encoding characters
     210 ; result: return the escaped string
     211 ;
     212 N HLDATA,HLESCAPE,HLI,HLCHAR,HLEN,HLOUT,COMFLAG
     213 S HLDATA=$G(INPUT)
     214 S COMFLAG=$G(COMPONET)
     215 Q:$L($G(FS))'=1 HLDATA
     216 ;
     217 ; patch HL*1.6*133
     218 ; Q:$L($G(EC))'=4 HLDATA
     219 Q:($L($G(EC))<3) HLDATA
     220 Q:HLDATA']"" HLDATA
     221 ;
     222 S HLESCAPE=FS_EC
     223 S HLESCAPE("F")=FS
     224 S HLESCAPE("S")=$E(EC,1)
     225 S HLESCAPE("R")=$E(EC,2)
     226 S HLESCAPE("E")=$E(EC,3)
     227 S HLESCAPE("T")=$E(EC,4)
     228 S HLEN=$L(HLDATA)
     229 S HLOUT=""
     230 F HLI=1:1:HLEN D
     231 . S HLCHAR=$E(HLDATA,HLI)
     232 . I HLESCAPE[HLCHAR D  Q
     233 .. I HLCHAR=HLESCAPE("F") S HLOUT=HLOUT_HLESCAPE("E")_"F"_HLESCAPE("E") Q
     234 .. I HLCHAR=HLESCAPE("S") D  Q
     235 ... I COMFLAG=1 S HLOUT=HLOUT_HLESCAPE("E")_"S"_HLESCAPE("E") Q
     236 ... S HLOUT=HLOUT_HLCHAR
     237 .. I HLCHAR=HLESCAPE("R") S HLOUT=HLOUT_HLESCAPE("E")_"R"_HLESCAPE("E") Q
     238 .. I HLCHAR=HLESCAPE("E") S HLOUT=HLOUT_HLESCAPE("E")_"E"_HLESCAPE("E") Q
     239 .. I HLCHAR=HLESCAPE("T") S HLOUT=HLOUT_HLESCAPE("E")_"T"_HLESCAPE("E") Q
     240 . ;
     241 . S HLOUT=HLOUT_HLCHAR
     242 Q HLOUT
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSHDR4.m

    r613 r623  
    1 HLCSHDR4        ;SFIRMFO/LJA - Reset MSH Segment Fields ;10/09/2007 15:05
    2         ;;1.6;HEALTH LEVEL SEVEN;**93,108,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified
    4         ;
    5 DEBUG(STORE)    ; If HLP set up for debugging, capture VIEW...
    6         ; HLMSH773 -- req
    7         ;
    8         N NOW,NUM,VAR,VARS,X,XTMP
    9         ;
    10         ; 1=some, 2=all
    11         S STORE=$S(STORE=1:1,STORE=2:2,1:0) QUIT:'STORE  ;->
    12         ;
    13         S NOW=$$NOW^XLFDT
    14         ;
    15         S XTMP="HLCSHDR3 "_HLMSH773
    16         S:'$D(^XTMP(XTMP,0)) ^XTMP(XTMP,0)=$$FMADD^XLFDT(NOW,0,4)_U_NOW_U_"Debug data created by DEBUG~HLCSHDR4"
    17         ;
    18         S NUM=$O(^XTMP(XTMP,":"),-1)+1
    19         ;
    20         ; Grab only critical (some) variables?
    21         I STORE=1 D
    22         .
    23         .  ; Sending information...
    24         .  S ^XTMP(XTMP,NUM,"SA")=HLMSHSAO_U_HLSAN_U_HLMSHSAN
    25         .  S ^XTMP(XTMP,NUM,"SF")=HLMSHSFO_U_HLSFN_U_HLMSHSFN
    26         .
    27         .  ; Receiving information...
    28         .  S ^XTMP(XTMP,NUM,"RA")=HLMSHRAO_U_HLRAN_U_HLMSHRAN
    29         .  S ^XTMP(XTMP,NUM,"RF")=HLMSHRFO_U_HLRFN_U_HLMSHRFN
    30         .
    31         .  ; Other information...    (HLMSHPRE and HLMSHPRS hold 2 pieces!)
    32         .  S ^XTMP(XTMP,NUM,0)=NOW_U_HLMSH772_U_HLMSHPRE_U_HLMSHPRS
    33         .  S ^XTMP(XTMP,NUM,1)=HLMSHPRO
    34         ;
    35         ; Grab all variables?
    36         I STORE=2 D
    37         .  S X="^XTMP("""_XTMP_""","_NUM_","
    38         .  D DOLRO^%ZOSV
    39         ;
    40         QUIT
    41         ;
    42 SHOW    N I773
    43         F  R !!,"Enter 773 IEN: ",I773:60 Q:I773'>0  D
    44         .  D SHOW773(I773)
    45         QUIT
    46         ;
    47 SHOW773(I773)   ; Show Dynamic Routing MSH Field Reset Details
    48         N DIV,MSH,N90,N91
    49         ;
    50         S N90=$G(^HLMA(+I773,90)),N91=$G(^HLMA(+I773,91))
    51         I (N90_N91)']"" D  QUIT  ;->
    52         .  W "  no debug data found..."
    53         ;
    54         S MSH=$G(^HLMA(+I773,"MSH",1,0)) QUIT:MSH']""  ;->
    55         S DIV=$E(MSH,4)
    56         ;
    57         W !!,$$CJ^XLFSTR(" 773 # "_I773_" ",IOM,"=")
    58         ;
    59         D HDR(90,N90)
    60         ;
    61         W !
    62         D HDR(91,N91)
    63         ;
    64         W !!,$E(MSH,1,IOM)
    65         ;
    66         S C1=10,C2=30,C3=50
    67         W !!,?C1,"Original (91)",?2,"Array (90)",?3,"MSH-Segment"
    68         W !,$$REPEAT^XLFSTR("-",IOM)
    69         D LINE("snd app",1,2,3)
    70         D LINE("snd fac",3,3,4)
    71         D LINE("rec app",5,4,5)
    72         D LINE("rec fac",7,5,6)
    73         ;
    74         QUIT
    75         ;
    76 LINE(HDR,PCE1,PCE2,PCE3)        ; Print one comparison line...
    77         N P1,P2,P3,P4
    78         S P1=$P(N91,U,PCE1),P2=$P(N90,U,PCE2),P3=$P(MSH,DIV,PCE3),P4=$P(N91,U,PCE1+1)
    79         W !,HDR,":",?C1,P1,?2,P2,?3,P3,$S(P4]"":" ["_P4_"]",1:"")
    80         QUIT
    81         ;
    82 HDR(NUM,DATA)   N TXT
    83         S TXT=$S(NUM=90:"Array (90)",NUM=91:"Original (91)",1:"")
    84         W !,$$CJ^XLFSTR("---------- "_TXT_" ----------",IOM)
    85         W $$CJ^XLFSTR(DATA,IOM)
    86         QUIT
    87         ;
    88 SET(NEW,VAR,PCE)        ; This subroutine performs these actions:
    89         ; (1) Resets variables used in MSH segment
    90         ; (2) Resets SERAPP and CLNTAPP in ^HLMA(#,0)
    91         ; (3) Sets HLMSH91 nodes if overwrite occurs by ARRAY value.
    92         ;     If overwrite occurs by M code, the overwrite has already
    93         ;     been recorded in HLMSH91.  (An overwrite produced by M code
    94         ;     is never overwritten by ARRAY data.)
    95         ;
    96         N IEN771N,IEN771O,HLTCP
    97         ;
    98         ; VAR is the name of the variable, and not it's value...
    99         S PRE=@VAR ; PRE is now the value of the VAR (pre-overwrite) variable...
    100         ;
    101         ; Tests whether anything was changed...
    102         QUIT:NEW']""  ;-> No new value exists to change to...
    103         QUIT:NEW=PRE  ;-> New value = Original value.  Nothing changed...
    104         ;
    105         ; THIS IS THE EPICENTER!!  This is where the variables used in
    106         ; the MSH segment is overwritten.
    107         S @VAR=NEW
    108         ;
    109         ; If PRE exists at this point, it was done by M code...
    110         QUIT:$P(HLMSH91,U,PCE)]""  ;->
    111         ;
    112         ; Change was made, but not by M code.  Must be by array...
    113         S $P(HLMSH91,U,PCE)=PRE,$P(HLMSH91,U,PCE+1)="A"
    114         ;
    115         ; patch HL*1.6*122: for "^" as component separater
    116         S $P(HLMSH91,U,PCE+2,999)=""
    117         ;
    118         ; Upgrade ^HLMA(#,0)...
    119         QUIT:PCE'=1&(PCE'=5)  ;->
    120         ;
    121         ; patch HL*1.6*108 start
    122         ;S IEN771O=$O(^HL(771,"B",PRE,0)) QUIT:IEN771O'>0  ;-> Orig IEN
    123         ;S IEN771N=$O(^HL(771,"B",NEW,0)) QUIT:IEN771N'>0  ;-> New IEN
    124         S IEN771O=$O(^HL(771,"B",$E(PRE,1,30),0)) QUIT:IEN771O'>0  ;-> Orig IEN
    125         S IEN771N=$O(^HL(771,"B",$E(NEW,1,30),0)) QUIT:IEN771N'>0  ;-> New IEN
    126         ; patch HL*1.6*108 end
    127         ;
    128         QUIT:'IEN771O!('IEN771N)!(IEN771O=IEN771N)  ;->
    129         S HLTCP=1 ; So 773 is updated...
    130         I PCE=1 D UPDATE^HLTF0(MTIENS,"","O","","",IEN771N)
    131         I PCE=5 D UPDATE^HLTF0(MTIENS,"","O","",IEN771N)
    132         ;
    133         QUIT
    134         ;
    135 FIELDS  ; Display the Protocol file fields used by the VistA HL7 package,
    136         ; when messages are received, to find the event and subscriber
    137         ; protocols.
    138         N BY,DIC,DIOEND,L
    139         ;
    140         D HD
    141         ;
    142         W !
    143         ;
    144         S L="",DIC="^ORD(101,",BY="[HL PROTOCOL MESSAGING FIELDS]"
    145         S DIOEND="D EXPL^HLCSHDR4"
    146         D EN1^DIP
    147         ;
    148         Q
    149         ;
    150 HD      W @IOF,$$CJ^XLFSTR("HL7 Protocol Messaging Fields",IOM)
    151         W !,$$REPEAT^XLFSTR("=",IOM)
    152         W !,"This 'HL7 Protocol Messaging Fields' report holds information that will help"
    153         W !,"you determine the effects from changes to routing-related fields in the MSH"
    154         W !,"segment when messages are sent between or within VistA HL7 systems."
    155         W !,"Additional explanation is included at the bottom of the report."
    156         Q
    157         ;
    158 EXPL    N I,T QUIT:'$$EXPL1("Press RETURN for 'printout help', or '^' to exit... ")  X "F I=1:1 S T=$T(EXPL+I) QUIT:T'["";;""  W !,$P(T,"";;"",2,99)" S I=$$EXPL1("Press RETURN to exit... ",1)
    159         ;;
    160         ;;When messages are received, their SENDING APPLICATION (MSH-3), MESSAGE
    161         ;;TYPE (MSH-9), EVENT TYPE (MSH-9), and HL7 VERSION (MSH-12) fields are used to
    162         ;;find the event driver protocol to be used in processing the just-received
    163         ;;message. After the event protocol is found, that protocol's subscriber
    164         ;;protocols are evaluated.  The subscriber protocol with a RECEIVING
    165         ;;APPLICATION value that matches the RECEIVING APPLICATION field in the MSH
    166         ;;segment (MSH-5) is used.
    167         ;;
    168         ;;The first line for every "section" in the printout is the event driver
    169         ;;protocol. Lines preceded by dashes, are related subscriber protocols.  An
    170         ;;example is shown below.
    171         ;;
    172         ;;Snd/Rec App's    mTYP   eTYP   Ver        Protocol                     Link
    173         ;;------------------------------------------------------------------------------
    174         ;;AC-VOICERAD      ORU    R01    2.3    |   AC ORU SERVER
    175         ;;-AC-RADIOLOGY    ORU    R01    2.3    |   AC ORU CLIENT                NC  TCP
    176         ;;
    177         ;;In this example, the 'AC-VOICERAD' line holds information for the 'AC ORU
    178         ;;SERVER' event protocol.  And, the '-AC-RADIOLOGY' line holds information for
    179         ;;the 'AC ORU CLIENT' subscriber protocol.
    180         Q
    181         ;
    182 EXPL1(PMT,FF)   ;
    183         N DIR,DIRUT,DTOUT,DUOUT,X,Y
    184         QUIT:$E($G(IOST),1,2)'="C-" 1 ;->
    185         F X=1:1:$G(FF) W !
    186         S DIR(0)="EA",DIR("A")=PMT
    187         D ^DIR
    188         QUIT $S(Y=1:1,1:"")
    189         ;
    190 M       ; Covered by Integration Agreement #3988
    191         ; Application developers may call here when creating new messages,
    192         ; when experimenting with M code to evaluate and conditionally change
    193         ; routing-related fields.
    194         ;
    195         ; This API is called immediately before the MSH segment is created.
    196         N IOINHI,IOINORM,MSHOLD,MSHNEW,MSHPRE,X
    197         ;
    198         S X="IOINHI;IOINORM" D ENDR^%ZISS
    199         ;
    200         S MSHOLD=$$MSHBUILD(0),MSHPRE=$$MSHBUILD(1)
    201         W !!,"The original MSH segment is...",!!,IOINHI,MSHOLD,IOINORM
    202         I MSHPRE'=MSHOLD D
    203         .  W !!,"The MSH segment, after modification by passed-in data, is..."
    204         .  W !!,IOINHI,MSHPRE,IOINORM
    205         ;
    206         D MVAR("SENDING APPLICATION","HLMSHSAN","SERAPP")
    207         D MVAR("SENDING FACILITY","HLMSHSFN","SERFAC")
    208         D MVAR("RECEIVING APPLICATION","HLMSHRAN","CLNTAPP")
    209         D MVAR("RECEIVING FACILITY","HLMSHRFN","CLNTFAC")
    210         ;
    211         S MSHNEW=$$MSHBUILD
    212         I MSHNEW'=MSHPRE D
    213         .  W !!,"Before your changes above, the modified MSH segment was..."
    214         .  W !!,IOINHI,MSHPRE,IOINORM
    215         .  W !!,"After your changes, the MSH segment is..."
    216         .  W !!,IOINHI,MSHNEW,IOINORM
    217         W !!,$$REPEAT^XLFSTR("-",IOM)
    218         W !!,"Message being sent..."
    219         W !
    220         ;
    221         Q
    222         ;
    223 MVAR(FLD,VAR,VARO)      ; Generic resetting of variable...
    224         ;IOINHI,IOINORM -- req
    225         N ANS
    226         W !!,?4,"Protocol-derived value of ",FLD,": "
    227         W IOINHI,@VARO,IOINORM
    228         W !,"Passed-in value of ",FLD," (",VAR,"): "
    229         W IOINHI,@VAR,IOINORM
    230         W !,?10,"Enter new value for ",FLD,": "
    231         R ANS:60 Q:'$T  ;->
    232         I ANS[U!(ANS']"") D
    233         .  W !!,?10,"No changes will be made..."
    234         I ANS'[U&(ANS]"") D
    235         .  S @VAR=ANS
    236         .  W !!,?10,"The variable ",IOINHI,VAR,IOINORM
    237         .  W " will be changed to '",IOINHI,ANS,IOINORM,"'."
    238         .  W !,?10,"This value will be stored in the ",FLD
    239         .  W !,?10,"field in the MSH segment..."
    240         .  W !!,$$REPEAT^XLFSTR("-",IOM)
    241         Q
    242         ;
    243 MSHBUILD(TYPE)  ; Build MSH using current variables...
    244         N MSH,PCE,RAN,RFN,SAN,SFN
    245         S MSH="MSH"_FS_EC
    246         I $G(TYPE)=0 F PCE=SERAPP,SERFAC,CLNTAPP,CLNTFAC,HLDATE,SECURITY,MSGTYPE,HLID,HLPID,$P(PROT,U,9),"",$G(^HL(772,TXTP,1)),ACCACK,APPACK,CNTRY D
    247         .  S MSH=MSH_FS_PCE
    248         I $G(TYPE)'=0 D
    249         .  S SAN=HLMSHSAN,SAN=$S(SAN]"":SAN,1:SERAPP)
    250         .  S SFN=HLMSHSFN,SFN=$S(SFN]"":SFN,1:SERFAC)
    251         .  S RAN=HLMSHRAN,RAN=$S(RAN]"":RAN,1:CLNTAPP)
    252         .  S RFN=HLMSHRFN,RFN=$S(RFN]"":RFN,1:CLNTFAC)
    253         .  F PCE=SAN,SFN,RAN,RFN,HLDATE,SECURITY,MSGTYPE,HLID,HLPID,$P(PROT,U,9),"",$G(^HL(772,TXTP,1)),ACCACK,APPACK,CNTRY D
    254         .  .  S MSH=MSH_FS_PCE
    255         QUIT MSH
    256         ;
    257 EOR     ;HLCSHDR4 - Reset MSH Segment Fields ;9/12/02 11:50
     1HLCSHDR4 ;SFIRMFO/LJA - Reset MSH Segment Fields ;3/24/2004 14:27
     2 ;;1.6;HEALTH LEVEL SEVEN;**93,108**;Oct 13, 1995
     3 ;
     4DEBUG(STORE) ; If HLP set up for debugging, capture VIEW...
     5 ; HLMSH773 -- req
     6 ;
     7 N NOW,NUM,VAR,VARS,X,XTMP
     8 ;
     9 ; 1=some, 2=all
     10 S STORE=$S(STORE=1:1,STORE=2:2,1:0) QUIT:'STORE  ;->
     11 ;
     12 S NOW=$$NOW^XLFDT
     13 ;
     14 S XTMP="HLCSHDR3 "_HLMSH773
     15 S:'$D(^XTMP(XTMP,0)) ^XTMP(XTMP,0)=$$FMADD^XLFDT(NOW,0,4)_U_NOW_U_"Debug data created by DEBUG~HLCSHDR4"
     16 ;
     17 S NUM=$O(^XTMP(XTMP,":"),-1)+1
     18 ;
     19 ; Grab only critical (some) variables?
     20 I STORE=1 D
     21 .
     22 .  ; Sending information...
     23 .  S ^XTMP(XTMP,NUM,"SA")=HLMSHSAO_U_HLSAN_U_HLMSHSAN
     24 .  S ^XTMP(XTMP,NUM,"SF")=HLMSHSFO_U_HLSFN_U_HLMSHSFN
     25 .
     26 .  ; Receiving information...
     27 .  S ^XTMP(XTMP,NUM,"RA")=HLMSHRAO_U_HLRAN_U_HLMSHRAN
     28 .  S ^XTMP(XTMP,NUM,"RF")=HLMSHRFO_U_HLRFN_U_HLMSHRFN
     29 .
     30 .  ; Other information...    (HLMSHPRE and HLMSHPRS hold 2 pieces!)
     31 .  S ^XTMP(XTMP,NUM,0)=NOW_U_HLMSH772_U_HLMSHPRE_U_HLMSHPRS
     32 .  S ^XTMP(XTMP,NUM,1)=HLMSHPRO
     33 ;
     34 ; Grab all variables?
     35 I STORE=2 D
     36 .  S X="^XTMP("""_XTMP_""","_NUM_","
     37 .  D DOLRO^%ZOSV
     38 ;
     39 QUIT
     40 ;
     41SHOW N I773
     42 F  R !!,"Enter 773 IEN: ",I773:60 Q:I773'>0  D
     43 .  D SHOW773(I773)
     44 QUIT
     45 ;
     46SHOW773(I773) ; Show Dynamic Routing MSH Field Reset Details
     47 N DIV,MSH,N90,N91
     48 ;
     49 S N90=$G(^HLMA(+I773,90)),N91=$G(^HLMA(+I773,91))
     50 I (N90_N91)']"" D  QUIT  ;->
     51 .  W "  no debug data found..."
     52 ;
     53 S MSH=$G(^HLMA(+I773,"MSH",1,0)) QUIT:MSH']""  ;->
     54 S DIV=$E(MSH,4)
     55 ;
     56 W !!,$$CJ^XLFSTR(" 773 # "_I773_" ",IOM,"=")
     57 ;
     58 D HDR(90,N90)
     59 ;
     60 W !
     61 D HDR(91,N91)
     62 ;
     63 W !!,$E(MSH,1,IOM)
     64 ;
     65 S C1=10,C2=30,C3=50
     66 W !!,?C1,"Original (91)",?2,"Array (90)",?3,"MSH-Segment"
     67 W !,$$REPEAT^XLFSTR("-",IOM)
     68 D LINE("snd app",1,2,3)
     69 D LINE("snd fac",3,3,4)
     70 D LINE("rec app",5,4,5)
     71 D LINE("rec fac",7,5,6)
     72 ;
     73 QUIT
     74 ;
     75LINE(HDR,PCE1,PCE2,PCE3) ; Print one comparison line...
     76 N P1,P2,P3,P4
     77 S P1=$P(N91,U,PCE1),P2=$P(N90,U,PCE2),P3=$P(MSH,DIV,PCE3),P4=$P(N91,U,PCE1+1)
     78 W !,HDR,":",?C1,P1,?2,P2,?3,P3,$S(P4]"":" ["_P4_"]",1:"")
     79 QUIT
     80 ;
     81HDR(NUM,DATA) N TXT
     82 S TXT=$S(NUM=90:"Array (90)",NUM=91:"Original (91)",1:"")
     83 W !,$$CJ^XLFSTR("---------- "_TXT_" ----------",IOM)
     84 W $$CJ^XLFSTR(DATA,IOM)
     85 QUIT
     86 ;
     87SET(NEW,VAR,PCE) ; This subroutine performs these actions:
     88 ; (1) Resets variables used in MSH segment
     89 ; (2) Resets SERAPP and CLNTAPP in ^HLMA(#,0)
     90 ; (3) Sets HLMSH91 nodes if overwrite occurs by ARRAY value.
     91 ;     If overwrite occurs by M code, the overwrite has already
     92 ;     been recorded in HLMSH91.  (An overwrite produced by M code
     93 ;     is never overwritten by ARRAY data.)
     94 ;
     95 N IEN771N,IEN771O,HLTCP
     96 ;
     97 ; VAR is the name of the variable, and not it's value...
     98 S PRE=@VAR ; PRE is now the value of the VAR (pre-overwrite) variable...
     99 ;
     100 ; Tests whether anything was changed...
     101 QUIT:NEW']""  ;-> No new value exists to change to...
     102 QUIT:NEW=PRE  ;-> New value = Original value.  Nothing changed...
     103 ;
     104 ; THIS IS THE EPICENTER!!  This is where the variables used in
     105 ; the MSH segment is overwritten.
     106 S @VAR=NEW
     107 ;
     108 ; If PRE exists at this point, it was done by M code...
     109 QUIT:$P(HLMSH91,U,PCE)]""  ;->
     110 ;
     111 ; Change was made, but not by M code.  Must be by array...
     112 S $P(HLMSH91,U,PCE)=PRE,$P(HLMSH91,U,PCE+1)="A"
     113 ;
     114 ; Upgrade ^HLMA(#,0)...
     115 QUIT:PCE'=1&(PCE'=5)  ;->
     116 ;
     117 ; patch HL*1.6*108 start
     118 ;S IEN771O=$O(^HL(771,"B",PRE,0)) QUIT:IEN771O'>0  ;-> Orig IEN
     119 ;S IEN771N=$O(^HL(771,"B",NEW,0)) QUIT:IEN771N'>0  ;-> New IEN
     120 S IEN771O=$O(^HL(771,"B",$E(PRE,1,30),0)) QUIT:IEN771O'>0  ;-> Orig IEN
     121 S IEN771N=$O(^HL(771,"B",$E(NEW,1,30),0)) QUIT:IEN771N'>0  ;-> New IEN
     122 ; patch HL*1.6*108 end
     123 ;
     124 QUIT:'IEN771O!('IEN771N)!(IEN771O=IEN771N)  ;->
     125 S HLTCP=1 ; So 773 is updated...
     126 I PCE=1 D UPDATE^HLTF0(MTIENS,"","O","","",IEN771N)
     127 I PCE=5 D UPDATE^HLTF0(MTIENS,"","O","",IEN771N)
     128 ;
     129 QUIT
     130 ;
     131FIELDS ; Display the Protocol file fields used by the VistA HL7 package,
     132 ; when messages are received, to find the event and subscriber
     133 ; protocols.
     134 N BY,DIC,DIOEND,L
     135 ;
     136 D HD
     137 ;
     138 W !
     139 ;
     140 S L="",DIC="^ORD(101,",BY="[HL PROTOCOL MESSAGING FIELDS]"
     141 S DIOEND="D EXPL^HLCSHDR4"
     142 D EN1^DIP
     143 ;
     144 Q
     145 ;
     146HD W @IOF,$$CJ^XLFSTR("HL7 Protocol Messaging Fields",IOM)
     147 W !,$$REPEAT^XLFSTR("=",IOM)
     148 W !,"This 'HL7 Protocol Messaging Fields' report holds information that will help"
     149 W !,"you determine the effects from changes to routing-related fields in the MSH"
     150 W !,"segment when messages are sent between or within VistA HL7 systems."
     151 W !,"Additional explanation is included at the bottom of the report."
     152 Q
     153 ;
     154EXPL N I,T QUIT:'$$EXPL1("Press RETURN for 'printout help', or '^' to exit... ")  X "F I=1:1 S T=$T(EXPL+I) QUIT:T'["";;""  W !,$P(T,"";;"",2,99)" S I=$$EXPL1("Press RETURN to exit... ",1)
     155 ;;
     156 ;;When messages are received, their SENDING APPLICATION (MSH-3), MESSAGE
     157 ;;TYPE (MSH-9), EVENT TYPE (MSH-9), and HL7 VERSION (MSH-12) fields are used to
     158 ;;find the event driver protocol to be used in processing the just-received
     159 ;;message. After the event protocol is found, that protocol's subscriber
     160 ;;protocols are evaluated.  The subscriber protocol with a RECEIVING
     161 ;;APPLICATION value that matches the RECEIVING APPLICATION field in the MSH
     162 ;;segment (MSH-5) is used.
     163 ;;
     164 ;;The first line for every "section" in the printout is the event driver
     165 ;;protocol. Lines preceded by dashes, are related subscriber protocols.  An
     166 ;;example is shown below.
     167 ;;
     168 ;;Snd/Rec App's    mTYP   eTYP   Ver        Protocol                     Link
     169 ;;------------------------------------------------------------------------------
     170 ;;AC-VOICERAD      ORU    R01    2.3    |   AC ORU SERVER
     171 ;;-AC-RADIOLOGY    ORU    R01    2.3    |   AC ORU CLIENT                NC  TCP
     172 ;;
     173 ;;In this example, the 'AC-VOICERAD' line holds information for the 'AC ORU
     174 ;;SERVER' event protocol.  And, the '-AC-RADIOLOGY' line holds information for
     175 ;;the 'AC ORU CLIENT' subscriber protocol.
     176 Q
     177 ;
     178EXPL1(PMT,FF) ;
     179 N DIR,DIRUT,DTOUT,DUOUT,X,Y
     180 QUIT:$E($G(IOST),1,2)'="C-" 1 ;->
     181 F X=1:1:$G(FF) W !
     182 S DIR(0)="EA",DIR("A")=PMT
     183 D ^DIR
     184 QUIT $S(Y=1:1,1:"")
     185 ;
     186M ; Covered by Integration Agreement #3988
     187 ; Application developers may call here when creating new messages,
     188 ; when experimenting with M code to evaluate and conditionally change
     189 ; routing-related fields.
     190 ;
     191 ; This API is called immediately before the MSH segment is created.
     192 N IOINHI,IOINORM,MSHOLD,MSHNEW,MSHPRE,X
     193 ;
     194 S X="IOINHI;IOINORM" D ENDR^%ZISS
     195 ;
     196 S MSHOLD=$$MSHBUILD(0),MSHPRE=$$MSHBUILD(1)
     197 W !!,"The original MSH segment is...",!!,IOINHI,MSHOLD,IOINORM
     198 I MSHPRE'=MSHOLD D
     199 .  W !!,"The MSH segment, after modification by passed-in data, is..."
     200 .  W !!,IOINHI,MSHPRE,IOINORM
     201 ;
     202 D MVAR("SENDING APPLICATION","HLMSHSAN","SERAPP")
     203 D MVAR("SENDING FACILITY","HLMSHSFN","SERFAC")
     204 D MVAR("RECEIVING APPLICATION","HLMSHRAN","CLNTAPP")
     205 D MVAR("RECEIVING FACILITY","HLMSHRFN","CLNTFAC")
     206 ;
     207 S MSHNEW=$$MSHBUILD
     208 I MSHNEW'=MSHPRE D
     209 .  W !!,"Before your changes above, the modified MSH segment was..."
     210 .  W !!,IOINHI,MSHPRE,IOINORM
     211 .  W !!,"After your changes, the MSH segment is..."
     212 .  W !!,IOINHI,MSHNEW,IOINORM
     213 W !!,$$REPEAT^XLFSTR("-",IOM)
     214 W !!,"Message being sent..."
     215 W !
     216 ;
     217 Q
     218 ;
     219MVAR(FLD,VAR,VARO) ; Generic resetting of variable...
     220 ;IOINHI,IOINORM -- req
     221 N ANS
     222 W !!,?4,"Protocol-derived value of ",FLD,": "
     223 W IOINHI,@VARO,IOINORM
     224 W !,"Passed-in value of ",FLD," (",VAR,"): "
     225 W IOINHI,@VAR,IOINORM
     226 W !,?10,"Enter new value for ",FLD,": "
     227 R ANS:60 Q:'$T  ;->
     228 I ANS[U!(ANS']"") D
     229 .  W !!,?10,"No changes will be made..."
     230 I ANS'[U&(ANS]"") D
     231 .  S @VAR=ANS
     232 .  W !!,?10,"The variable ",IOINHI,VAR,IOINORM
     233 .  W " will be changed to '",IOINHI,ANS,IOINORM,"'."
     234 .  W !,?10,"This value will be stored in the ",FLD
     235 .  W !,?10,"field in the MSH segment..."
     236 .  W !!,$$REPEAT^XLFSTR("-",IOM)
     237 Q
     238 ;
     239MSHBUILD(TYPE) ; Build MSH using current variables...
     240 N MSH,PCE,RAN,RFN,SAN,SFN
     241 S MSH="MSH"_FS_EC
     242 I $G(TYPE)=0 F PCE=SERAPP,SERFAC,CLNTAPP,CLNTFAC,HLDATE,SECURITY,MSGTYPE,HLID,HLPID,$P(PROT,U,9),"",$G(^HL(772,TXTP,1)),ACCACK,APPACK,CNTRY D
     243 .  S MSH=MSH_FS_PCE
     244 I $G(TYPE)'=0 D
     245 .  S SAN=HLMSHSAN,SAN=$S(SAN]"":SAN,1:SERAPP)
     246 .  S SFN=HLMSHSFN,SFN=$S(SFN]"":SFN,1:SERFAC)
     247 .  S RAN=HLMSHRAN,RAN=$S(RAN]"":RAN,1:CLNTAPP)
     248 .  S RFN=HLMSHRFN,RFN=$S(RFN]"":RFN,1:CLNTFAC)
     249 .  F PCE=SAN,SFN,RAN,RFN,HLDATE,SECURITY,MSGTYPE,HLID,HLPID,$P(PROT,U,9),"",$G(^HL(772,TXTP,1)),ACCACK,APPACK,CNTRY D
     250 .  .  S MSH=MSH_FS_PCE
     251 QUIT MSH
     252 ;
     253EOR ;HLCSHDR4 - Reset MSH Segment Fields ;9/12/02 11:50
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSIN.m

    r613 r623  
    1 HLCSIN  ;ALB/JRP - INCOMING FILER;01-MAY-95 ;03/17/2008  17:15
    2         ;;1.6;HEALTH LEVEL SEVEN;**2,30,14,19,62,109,115,122,140**;Oct 13, 1995;Build 5
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4 STARTIN ;Main entry point for incoming background filer
    5         ;Create/find entry denoting this filer in the INCOMING FILER TASK
    6         ; NUMBER multiple (field #20) of the HL COMMUNICATION SERVER PARAMETER
    7         ; file (#869.3)
    8         N HLFLG,HLEXIT,HLPTRFLR
    9         ;
    10         ; patch HL*1.6*122
    11         ;; N HLDUZ,DUZ  ; patch HL*1.6*122 TEST v2: DUZ code removed
    12         N HLDUZ
    13         S HLDUZ=+$G(DUZ)
    14         ;
    15         S HLPTRFLR=+$$CRTFLR^HLCSUTL1(ZTSK,"IN")
    16         ;Loop through Logical Links and check for incoming messages
    17         S HLEXIT=0
    18         ; patch HL*1.6*122 TEST v2: DUZ code removed
    19         ; patch HL*1.6*122, set DUZ for application proxy user
    20         ;; D PROXY^HLCSTCP4
    21         S HLPTRFLR("$J")=$J
    22         F  D  Q:HLEXIT
    23         . S HLFLG=0
    24         . D DEFACK(.HLPTRFLR,.HLFLG,.HLEXIT) Q:HLEXIT
    25         . D ACKNOW(.HLPTRFLR,.HLFLG,.HLEXIT) Q:HLEXIT
    26         . Q:HLFLG
    27         . I $$HDIFF^XLFDT($H,$G(HLPTRFLR("LASTDEL")),2)>3600 D  Q
    28         . . S HLPTRFLR("LASTDEL")=$H    ; maintain queue sizes
    29         . . D DELQUE(.HLPTRFLR,.HLEXIT) ; no more than once an hour.
    30         . ; patch HL*1.6*122
    31         . ; H 5
    32         . H 1
    33         . D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
    34         S ZTSTOP=1 ;Asked to stop
    35         D DELFLR^HLCSUTL1(HLPTRFLR,"IN") ;Delete entry denoting this filer
    36         S ZTREQ="@"
    37         Q
    38 DEFACK(HLPTRFLR,HLFLG,HLEXIT)   ; Process TCP links with a deferred response
    39         N HLXX,HLD0,HLPCT
    40         S HLXX=0
    41         F  S HLXX=$O(^HLMA("AC","I",HLXX)) Q:'HLXX  D  Q:HLEXIT
    42         . ; HL*1.6*122, check the in-queue stop flag
    43         . Q:$P($G(^HLCS(870,HLXX,0)),"^",9)
    44         . D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
    45         . ; patch HL*1.6*109: Does another filer have this?
    46         . ; L +^HLMA("AC","I",HLXX):0 Q:'$T
    47         . ; patch HL*1.6*140 - change the lock node, it conflicts with
    48         . ; lock defined in routine, HLCSREP.
    49         . ; L +^HLMA("AC","I",HLXX):2 Q:'$T  ; patch HL*1.6*122
    50         . L +^HLMA("IN-FILER","AC","I",HLXX):2 Q:'$T  ; patch HL*1.6*122
    51         . S HLD0=0,HLFLG=1
    52         . ; HL*1.6*109 changes in for loop below, and post-quit code placed
    53         . ; on following lines.
    54         . S HLPCT=0 ; Counter whether filer should stop every 100th entry.
    55         .;**109 - insure queue last processed at least 2 seconds ago
    56         . ; patch HL*1.6*140
    57         . ; I ($$HDIFF^XLFDT($H,$G(^XTMP("HL7-AC","I",HLXX)),2)<2) L -^HLMA("AC","I",HLXX) Q
    58         . I ($$HDIFF^XLFDT($H,$G(^XTMP("HL7-AC","I",HLXX)),2)<2) L -^HLMA("IN-FILER","AC","I",HLXX) Q
    59         . F  S HLD0=$O(^HLMA("AC","I",HLXX,HLD0)) Q:'HLD0!(HLEXIT)  D
    60         .. ; patch HL*1.6*122 start
    61         .. ; patch HL*1.6*122 TEST v2: DUZ code removed
    62         .. ; DUZ comparison/reset for application proxy user
    63         .. ;; D HLDUZ^HLCSTCP4
    64         .. D HLDUZ2^HLCSTCP4
    65         .. ; protect HLDUZ
    66         .. N HLDUZ
    67         .. S HLPCT=HLPCT+1
    68         .. I '(HLPCT#100) D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
    69         .. ; L +^HLMA(HLD0):0 Q:'$T
    70         .. F  L +^HLMA(HLD0):30 Q:$T  H 1
    71         .. I '$$CHECKAC("I",HLXX,HLD0) L -^HLMA(HLD0) Q  ;-> Quit if not a valid AC xref
    72         .. D DEFACK^HLTP3(HLXX,HLD0)
    73         .. D DEQUE^HLCSREP(HLXX,"I",HLD0)
    74         .. L -^HLMA(HLD0)
    75         . ; patch HL*1.6*122 end
    76         . ;**109 -add dt/tm stamp to time queue last processed
    77         . S ^XTMP("HL7-AC","I",HLXX)=$H
    78         . ;**109 -unlock the queue
    79         . ; patch HL*1.6*140
    80         . ; L -^HLMA("AC","I",HLXX)
    81         . L -^HLMA("IN-FILER","AC","I",HLXX)
    82         Q
    83         ;
    84 CHECKAC(WAY,IEN870,IEN773)      ; If AC xref shouldn't exist, kill it...
    85         ;
    86         ; Check status and if 3 (processed) kill XREF...
    87         I $P($G(^HLMA(+IEN773,"P")),U)=3 D  QUIT "" ;->
    88         .  D DEQUE^HLCSREP(IEN870,WAY,IEN773)
    89         ;
    90         ; Add other checks here in the future...
    91         ;
    92         Q 1
    93         ;
    94 ACKNOW(HLPTRFLR,HLFLG,HLEXIT)   ; Process Logical Link's IN-queue for received message
    95         N HLXX,HLD0,HLD1
    96         S HLXX=0
    97         F  S HLXX=$O(^HLCS(870,"AISTAT","P",HLXX)) Q:'HLXX  D  Q:HLEXIT
    98         . ; HL*1.6*122, check the in-queue stop flag
    99         . Q:$P($G(^HLCS(870,HLXX,0)),"^",9)
    100         . D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
    101         . ; HL*1.6*109: Does another filer have this?
    102         . ; L +^HLCS(870,HLXX,"INFILER"):0 Q:'$T
    103         . L +^HLCS(870,HLXX,"INFILER"):2 Q:'$T  ; patch HL*1.6*122
    104         . F  D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT  S HLD0=$$DEQUEUE^HLCSQUE(HLXX,"IN") Q:+HLD0<0  D
    105         .. ;
    106         .. ; patch HL*1.6*122 start
    107         .. ; clean variables except Kernel related variables
    108         .. D
    109         ... ; protect variables defined in STARTIN^HLCSIN
    110         ... N HLFLG,HLEXIT,HLPTRFLR
    111         ... N HLDUZ
    112         ... ; protect variables defined in ACKNOW^HLCSIN
    113         ... N HLXX,HLD0,HLD1
    114         ... D KILL^XUSCLEAN
    115         .. ;
    116         .. ; patch HL*1.6*122 TEST v2: DUZ code removed
    117         .. ; DUZ comparison/reset for application proxy user
    118         .. ;; D HLDUZ^HLCSTCP4
    119         .. D HLDUZ2^HLCSTCP4
    120         .. ; protect HLDUZ
    121         .. N HLDUZ
    122         .. ;Make sure message is ready to be received
    123         .. S HLFLG=1
    124         .. S HLD1=$P(HLD0,"^",2)
    125         .. S HLD0=+HLD0 ; At this point, HLD0=HLXX
    126         .. I $P($G(^HLCS(870,HLD0,1,HLD1,0)),"^",3)'="A" D  Q
    127         ... D MONITOR^HLCSDR2("D",2,HLD0,HLD1,"IN") ;Set status to DONE
    128         .. D RECEIVE^HLMA0(HLD0,HLD1) ;Process received message
    129         .. D MONITOR^HLCSDR2("D",2,HLD0,HLD1,"IN") ;Set status to DONE
    130         . ; patch HL*1.6*122 end
    131         . I HLD0<0,$D(^HLCS(870,"AISTAT","P",HLXX)) D
    132         . . S HLD1=0 ; Make sure there aren't any loose xrefs hanging around.
    133         . . F  S HLD1=$O(^HLCS(870,"AISTAT","P",HLXX,HLD1)) Q:'HLD1  D
    134         . . . ;I '$D(^HLCS(870,HLXX,1,HLD1,0)) K ^HLCS(870,"AISTAT","P",HLXX,HLD1)
    135         . . . I $P($G(^HLCS(870,HLXX,1,HLD1,0)),U,2)'="P" K ^HLCS(870,"AISTAT","P",HLXX,HLD1)
    136         . L -^HLCS(870,HLXX,"INFILER")
    137         Q
    138 DELQUE(HLPTRFLR,HLEXIT) ; Delete messages outside the 'queue size' window.
    139         N HLDIR,HLXX,HLFRONT
    140         S HLDIR=1,HLXX=0
    141         F  S HLXX=$O(^HLCS(870,HLXX)) Q:'HLXX  D  Q:HLEXIT
    142         . D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
    143         . ; patch HL*1.6*122, comment out, no need to lock
    144         . ; L +^HLCS(870,HLXX,"IN QUEUE FRONT POINTER"):0 Q:'$T
    145         . S HLFRONT=$G(^HLCS(870,HLXX,"IN QUEUE FRONT POINTER"))
    146         . ; patch HL*1.6*122, comment out
    147         . ; L -^HLCS(870,HLXX,"IN QUEUE FRONT POINTER")
    148         . D DELETE^HLCSQUE1(HLXX,HLDIR,HLFRONT)
    149         Q
    150 CHKUPD(HLPTRFLR,HLEXIT) ;
    151         Q:$$HDIFF^XLFDT($H,$G(HLPTRFLR("LASTUP")),2)<15
    152         D SETFLRDH^HLCSUTL1(HLPTRFLR,"IN") ; Update LAST KNOWN $H (field #.03) for filer
    153         S HLPTRFLR("LASTUP")=$H
    154         D CHK4STOP^HLCSUTL2(HLPTRFLR,"IN",.HLEXIT) Q:HLEXIT
    155         Q
     1HLCSIN ;ALB/JRP - INCOMING FILER;01-MAY-95 ;11/15/2000  09:37
     2 ;;1.6;HEALTH LEVEL SEVEN;**2,30,14,19,62,109,115**;Oct 13, 1995
     3STARTIN ;Main entry point for incoming background filer
     4 ;Create/find entry denoting this filer in the INCOMING FILER TASK
     5 ; NUMBER multiple (field #20) of the HL COMMUNICATION SERVER PARAMETER
     6 ; file (#869.3)
     7 ;N HLOGLINK,HLNODE,HLPARENT,HLST1,TMP ; These vbls aren't used!
     8 N HLFLG,HLEXIT,HLPTRFLR
     9 S HLPTRFLR=+$$CRTFLR^HLCSUTL1(ZTSK,"IN")
     10 ;Loop through Logical Links and check for incoming messages
     11 S HLEXIT=0
     12 F  D  Q:HLEXIT
     13 . S HLFLG=0
     14 . D DEFACK(.HLPTRFLR,.HLFLG,.HLEXIT) Q:HLEXIT
     15 . D ACKNOW(.HLPTRFLR,.HLFLG,.HLEXIT) Q:HLEXIT
     16 . Q:HLFLG
     17 . I $$HDIFF^XLFDT($H,$G(HLPTRFLR("LASTDEL")),2)>3600 D  Q
     18 . . S HLPTRFLR("LASTDEL")=$H    ; maintain queue sizes
     19 . . D DELQUE(.HLPTRFLR,.HLEXIT) ; no more than once an hour.
     20 . H 5
     21 . D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
     22 S ZTSTOP=1 ;Asked to stop
     23 D DELFLR^HLCSUTL1(HLPTRFLR,"IN") ;Delete entry denoting this filer
     24 S ZTREQ="@"
     25 Q
     26DEFACK(HLPTRFLR,HLFLG,HLEXIT) ; Process TCP links with a deferred response
     27 N HLXX,HLD0,HLPCT
     28 S HLXX=0
     29 F  S HLXX=$O(^HLMA("AC","I",HLXX)) Q:'HLXX  D  Q:HLEXIT
     30 . D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
     31 . ; HL*1.6*109
     32 . L +^HLMA("AC","I",HLXX):0 Q:'$T  ;*109*Does another filer have this?
     33 . S HLD0=0,HLFLG=1
     34 . ; HL*1.6*109 changes in for loop below, and post-quit code placed
     35 . ; on following lines.
     36 . S HLPCT=0 ; Counter whether filer should stop every 100th entry.
     37 .;**109 - insure queue last processed at least 2 seconds ago
     38 . I ($$HDIFF^XLFDT($H,$G(^XTMP("HL7-AC","I",HLXX)),2)<2) L -^HLMA("AC","I",HLXX) Q
     39 . F  S HLD0=$O(^HLMA("AC","I",HLXX,HLD0)) Q:'HLD0!(HLEXIT)  D
     40 . . S HLPCT=HLPCT+1
     41 . . I '(HLPCT#100) D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
     42 . . L +^HLMA(HLD0):0 Q:'$T
     43 . . I '$$CHECKAC("I",HLXX,HLD0) L -^HLMA(HLD0) Q  ;-> Quit if not a valid AC xref
     44 . . D DEFACK^HLTP3(HLXX,HLD0)
     45 . . D DEQUE^HLCSREP(HLXX,"I",HLD0)
     46 . . L -^HLMA(HLD0)
     47 . ;**109 -add dt/tm stamp to time queue last processed
     48 . S ^XTMP("HL7-AC","I",HLXX)=$H
     49 . ;**109 -unlock the queue
     50 . L -^HLMA("AC","I",HLXX)
     51 Q
     52 ;
     53CHECKAC(WAY,IEN870,IEN773) ; If AC xref shouldn't exist, kill it...
     54 ;
     55 ; Check status and if 3 (processed) kill XREF...
     56 I $P($G(^HLMA(+IEN773,"P")),U)=3 D  QUIT "" ;->
     57 .  D DEQUE^HLCSREP(IEN870,WAY,IEN773)
     58 ;
     59 ; Add other checks here in the future...
     60 ;
     61 Q 1
     62 ;
     63ACKNOW(HLPTRFLR,HLFLG,HLEXIT) ; Process Logical Link's IN-queue for received message
     64 N HLXX,HLD0,HLD1
     65 S HLXX=0
     66 F  S HLXX=$O(^HLCS(870,"AISTAT","P",HLXX)) Q:'HLXX  D  Q:HLEXIT
     67 . D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
     68 .; HL*1.6*109
     69 . L +^HLCS(870,HLXX,"INFILER"):0 Q:'$T  ;Does another filer have this?
     70 . F  D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT  S HLD0=$$DEQUEUE^HLCSQUE(HLXX,"IN") Q:+HLD0<0  D
     71 . . ;Make sure message is ready to be received
     72 . . S HLFLG=1
     73 . . S HLD1=$P(HLD0,"^",2)
     74 . . S HLD0=+HLD0 ; At this point, HLD0=HLXX
     75 . . I $P($G(^HLCS(870,HLD0,1,HLD1,0)),"^",3)'="A" D  Q
     76 . . . D MONITOR^HLCSDR2("D",2,HLD0,HLD1,"IN") ;Set status to DONE
     77 . . D RECEIVE^HLMA0(HLD0,HLD1) ;Process received message
     78 . . D MONITOR^HLCSDR2("D",2,HLD0,HLD1,"IN") ;Set status to DONE
     79 . I HLD0<0,$D(^HLCS(870,"AISTAT","P",HLXX)) D
     80 . . S HLD1=0 ; Make sure there aren't any loose xrefs hanging around.
     81 . . F  S HLD1=$O(^HLCS(870,"AISTAT","P",HLXX,HLD1)) Q:'HLD1  D
     82 . . . ;I '$D(^HLCS(870,HLXX,1,HLD1,0)) K ^HLCS(870,"AISTAT","P",HLXX,HLD1)
     83 . . . I $P($G(^HLCS(870,HLXX,1,HLD1,0)),U,2)'="P" K ^HLCS(870,"AISTAT","P",HLXX,HLD1)
     84 . L -^HLCS(870,HLXX,"INFILER")
     85 Q
     86DELQUE(HLPTRFLR,HLEXIT) ; Delete messages outside the 'queue size' window.
     87 N HLDIR,HLXX,HLFRONT
     88 S HLDIR=1,HLXX=0
     89 F  S HLXX=$O(^HLCS(870,HLXX)) Q:'HLXX  D  Q:HLEXIT
     90 . D CHKUPD(.HLPTRFLR,.HLEXIT) Q:HLEXIT
     91 . L +^HLCS(870,HLXX,"IN QUEUE FRONT POINTER"):0 Q:'$T
     92 . S HLFRONT=$G(^HLCS(870,HLXX,"IN QUEUE FRONT POINTER"))
     93 . L -^HLCS(870,HLXX,"IN QUEUE FRONT POINTER")
     94 . D DELETE^HLCSQUE1(HLXX,HLDIR,HLFRONT)
     95 Q
     96CHKUPD(HLPTRFLR,HLEXIT) ;
     97 Q:$$HDIFF^XLFDT($H,$G(HLPTRFLR("LASTUP")),2)<15
     98 D SETFLRDH^HLCSUTL1(HLPTRFLR,"IN") ; Update LAST KNOWN $H (field #.03) for filer
     99 S HLPTRFLR("LASTUP")=$H
     100 D CHK4STOP^HLCSUTL2(HLPTRFLR,"IN",.HLEXIT) Q:HLEXIT
     101 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSLM.m

    r613 r623  
    1 HLCSLM  ;SFCIOFO/AC - HL7 LINK MANAGER ;03/19/2008  10:01
    2         ;;1.6;HEALTH LEVEL SEVEN;**49,57,109,123,140**;Oct 13, 1995;Build 5
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 EN      ;Entry point for start up task
    6         N %,HLEVLCHK,HLTSKCNT
    7         F %=1:1:10 L +^HLCS("HLCSLM"):2 Q:$T
    8         E  Q
    9         I $G(ZTQUEUED) S Y=$$PSET^%ZTLOAD(ZTQUEUED)
    10         D INIT,SAVDOLRH
    11         D SETNM^%ZOSV($E("HLmgr:"_$G(ZTQUEUED),1,15))
    12         ;
    13 LOOP    ;
    14         D CHKQUE
    15         I $$CKLMSTOP G EXIT
    16         D SAVDOLRH
    17         D CHECKMST^HLEVMST ;HL*1.6*109 - Make sure event monitor current
    18         ; patch HL*1.6*140
    19         ; H 10
    20         H 5
    21         G LOOP
    22         ;
    23 EXIT    N HLJ,X
    24         S X=1
    25         F  L +^HLCS(869.3,X,5):2 Q:$T
    26         ;52=Link Manager task number
    27         S HLJ(869.3,X_",",52)="@"
    28         D FILE^HLDIE("","HLJ","","EXIT","HLCSLM") ;HL*1.6*109
    29         L -^HLCS(869.3,X,5)
    30         L -^HLCS("HLCSLM")
    31         Q
    32         ;
    33 SAVDOLRH        ;Save Last Known $H
    34         N HLJ,X
    35         S X=1
    36         F  L +^HLCS(869.3,X,5):2 Q:$T
    37         ;54=LM LAST KNOWN $H
    38         S HLJ(869.3,X_",",54)=$H
    39         D FILE^HLDIE("","HLJ","","SAVDOLRH","HLCSLM") ;HL*1.6*109
    40         L -^HLCS(869.3,X,5)
    41         Q
    42         ;
    43 CHKQUE  ;Check queues for messages to send
    44         ;HLTSKCNT(logical link)=task #^$H
    45         N HLDA,HLDP,HLMSG,HLTSK,Y
    46         S (HLDA,HLMSG)=""
    47         F HLDP=0:0 S HLDP=+$O(^HLMA("AC","O",HLDP)) Q:HLDP'>0  S HLMSG=+$O(^(HLDP,0)) I HLMSG D  L -^HLCS("HLCSLSM",HLDP)
    48         .;quit if persistent link
    49         .Q:$P($G(^HLCS(870,HLDP,400)),U,4)="Y"
    50         .L +^HLCS("HLCSLSM",HLDP):0 E  K HLTSKCNT(HLDP) Q
    51         .Q:'$$LLOK(+HLDP)
    52         .;get tasknumber from file 870 and HLTSKCNT array
    53         .S Y=$$TASKNUM(HLDP),HLTSK=$G(HLTSKCNT(HLDP))
    54         . ;
    55         . ;patch HL*1.6*123 start
    56         . S HLDP("TASK-ACTIVE")=0
    57         . ;
    58         . I Y D
    59         .. N ZTSK
    60         .. S ZTSK=Y
    61         .. ; Check status of task
    62         .. D STAT^%ZTLOAD
    63         .. I "12"[ZTSK(1) S HLDP("TASK-ACTIVE")=1
    64         . Q:HLDP("TASK-ACTIVE")
    65         . ;
    66         . I HLTSK D
    67         .. N ZTSK
    68         .. S ZTSK=+HLTSK
    69         .. ; Check status of task
    70         .. D STAT^%ZTLOAD
    71         .. I "12"[ZTSK(1) S HLDP("TASK-ACTIVE")=1
    72         . Q:HLDP("TASK-ACTIVE")
    73         . ;
    74         . ;no tasknumber, link not running nor queued, task it
    75         . I 'HLTSK!'Y D TASKLSUB(HLDP),SAVTSK(HLDP) Q
    76         ; comment out the following lines
    77         ; .;link was tasked, check time
    78         ; .S Y=$P(HLTSK,U,2)
    79         ; .;check that time task is less than 30 minutes
    80         ; .Q:$$HDIFF^XLFDT($H,Y,2)<1800
    81         ; .;shutdown and send alert
    82         ; .D SDFLD^HLCSTCP,EXITS^HLCSTCP("Shutdown"),SNDALERT
    83         ; loop through links that have been tasked
    84         ; F HLDP=0:0 S HLDP=$O(HLTSKCNT(HLDP)) Q:HLDP'>0  K:'$D(^HLMA("AC","O",HLDP)) HLTSKCNT(HLDP)
    85         F HLDP=0:0 S HLDP=$O(HLTSKCNT(HLDP)) Q:HLDP'>0  D
    86         . N ZTSK
    87         . S ZTSK=+HLTSKCNT(HLDP)
    88         . ; Check status of task
    89         . D STAT^%ZTLOAD
    90         . ; kill HLTSKCNT(HLDP) if process is not active
    91         . I "12"'[ZTSK(1) K HLTSKCNT(HLDP)
    92         ; patch HL*1.6*123 end
    93         Q
    94         ;
    95 INIT    ;Create Task number and clear Stop flag.
    96         N HLJ,X
    97         S X=1
    98         F  L +^HLCS(869.3,X,5):2 Q:$T
    99         ;52=Link Manager task number,53=Stop Link Manager
    100         S HLJ(869.3,X_",",52)=$G(ZTQUEUED)
    101         S HLJ(869.3,X_",",53)="@"
    102         D FILE^HLDIE("","HLJ","","INIT","HLCSLM") ;HL*1.6*109
    103         L -^HLCS(869.3,X,5)
    104         Q
    105 TASKNUM(X)      ;Look-up task number
    106         N %,DA,Y
    107         S DA=X
    108         ;
    109         ;**109**
    110         ;F  L +^HLCS(870,+DA,0):2 Q:$T
    111         ;
    112         S Y=$$GET1^DIQ(870,DA_",",11)
    113         ;
    114         ;**109
    115         ;L -^HLCS(870,+DA,0)
    116         ;
    117         Q Y
    118 STATUS(X)       ;Status of task
    119         N Y,ZTSK
    120         S ZTSK=X
    121         D STAT^%ZTLOAD
    122         S Y=ZTSK(1)
    123         Q Y
    124         ;
    125 LLOK(X) ;Function to check whether LL ok.
    126         ;return value 1 = ok, 0 = not ok.
    127         Q:'$G(X)
    128         N HLDP,HLDP0,HLPARM4,HLTYPTR
    129         S HLDP=+X,HLDP0=$G(^HLCS(870,HLDP,0)),HLPARM4=$G(^(400)) Q:HLDP0="" 0
    130         ;must be a client
    131         Q:$P(HLPARM4,U,3)'="C" 0
    132         ;
    133         ; patch HL*1.6*123
    134         ;shutdown LLP must be 0
    135         ; Q:$P(HLDP0,U,15)'=0 0
    136         ; change to 1, in case the data is empty
    137         Q:$P(HLDP0,U,15)=1 0
    138         ;
    139         ;must have LLP Type of TCP
    140         S HLTYPTR=+$P(HLDP0,U,3) Q:$P($G(^HLCS(869.1,HLTYPTR,0)),U)'="TCP" 0
    141         Q 1
    142         ;
    143 SAVTSK(X)       ;
    144         N HLDP,HLJ
    145         S HLDP=X
    146         ;
    147         ;**109**
    148         F  L +^HLCS(870,HLDP,0):2 Q:$T
    149         ;
    150         ;4=status,10=Time Stopped,9=Time Started,11=Task Number,3=Online ?
    151         S X=$NA(HLJ(870,HLDP_",")),@X@(11)=$G(ZTSK)
    152         ;S HLJ(870,HLDP_",",11)=$G(ZTSK)
    153         D FILE^HLDIE("","HLJ","","SAVTSK","HLCSLM") ; HL*1.6*109
    154         S HLTSKCNT(HLDP)=$G(ZTSK)_"^"_$H
    155         ;
    156         ;**109**
    157         L -^HLCS(870,HLDP,0)
    158         ;
    159         Q
    160         ;
    161 STRTSTOP        ;ENTRY POINT TO START/STOP TCP LINK MANAGER
    162         N DIR,DIRUT,Y
    163         L +^HLCS("HLCSLM"):3 E  D  Q
    164         .W !,*7,"Link Manager already running!"
    165         .W ! S DIR(0)="YO",DIR("A")="Would you like to stop the Link Manager now",DIR("B")="NO" D ^DIR K DIR
    166         .I $D(DIRUT)!'Y Q
    167         .D STOPLM
    168         W !,*7,"Link Manager is NOT currently running!"
    169         W ! S DIR(0)="YO",DIR("A")="Would you like to start the Link Manager now",DIR("B")="YES" D ^DIR K DIR
    170         I '$D(DIRUT)&Y D TASKLM
    171         L -^HLCS("HLCSLM")
    172         Q
    173         ;
    174 STOPLM  ;ENTRY POINT TO STOP LINK MANAGER
    175         N DIC,X,Y,DTOUT,DUOUT,DLAYGO,DIE,DA,DR
    176         S DIC="^HLCS(869.3,"
    177         S X=1
    178         D ^DIC
    179         S DA=+Y,DIE=DIC
    180         S DR="53////1"
    181         D ^DIE
    182         W !,"Link Manager has been asked to stop"
    183         Q
    184 STAT()  ;Status of LINK MANAGER--up, down or unable to determine.
    185         N %,DA,X,Y
    186         S DA=1
    187         S X=$$GET1^DIQ(869.3,DA_",",52)
    188         Q:X']"" 0
    189         S X=$$GET1^DIQ(869.3,DA_",",54)
    190         Q:X']"" 0
    191         I $$HDIFF^XLFDT($H,X,2)>500 Q 0
    192         Q 1
    193         ;
    194 TASKLSUB(X)     ;Task LINK SUB-MANAGER.
    195         ;This may be a place to log the time which the LINK SUBMANAGER is tasked.
    196         N HLDP,HLDP0,HLDAPP,HLTYPTR,HLBGR,HLENV,HLPARM,HLPARM4,HLQUIT,ZTRTN,ZTDESC,ZTCPU,ZTSAVE
    197         ;ZTSK is not Newed here because it will be needed by SAVTSK.
    198         S HLDP=X,HLDP0=$G(^HLCS(870,HLDP,0)),HLPARM4=$G(^(400))
    199         ; Q:"N"'[$P(HLPARM4,U,4)  ; patch HL*1.6*123: comment out
    200         ;quit if no LLP TYPE
    201         S HLDAPP=$P(HLDP0,U),HLTYPTR=$P(HLDP0,U,3) Q:'HLTYPTR
    202         S HLBGR=$G(^HLCS(869.1,HLTYPTR,100)),HLENV=$G(^(200))
    203         I HLENV'="" K HLQUIT X HLENV Q:$D(HLQUIT)
    204         S ZTRTN="^HLCSLSM",HLBGR=$P(HLBGR," ",2)
    205         S ZTDESC=HLDAPP_" Low Level Protocol",ZTSAVE("HLDP")="",ZTSAVE("HLBGR")=""
    206         S ZTIO="",ZTDTH=$H
    207         ;get startup node
    208         I $P(HLPARM4,U,6),$D(^%ZIS(14.7,+$P(HLPARM4,U,6),0)) S ZTCPU=$P(^(0),U)
    209         D ^%ZTLOAD
    210         D MON^HLCSTCP("Tasked") ;HL*1.6*123
    211         Q
    212         ;
    213 TASKLM  ;Task Link Manager
    214         ;Declare variables
    215         N ZTRTN,ZTDESC,ZTIO,ZTDTH,ZTSK,TMP
    216         S ZTIO=""
    217         S ZTDTH=$H
    218         ;Task Link Manager
    219         S ZTRTN="EN^HLCSLM"
    220         S ZTDESC="HL7 Link Manager"
    221         ;Call TaskMan
    222         D ^%ZTLOAD
    223         I $G(ZTSK) W !,"Link Manager queued as task number ",ZTSK
    224         E  W $C(7),!!,"Unable to start/restart Link Manager"
    225         Q
    226         ;
    227 CKLMSTOP()      ;Check whether Link Manager should stop
    228         N PTRMAIN,NODE5,STOP
    229         S PTRMAIN=+$O(^HLCS(869.3,0))
    230         L +^HLCS(869.3,PTRMAIN,5):1
    231         I $T L -^HLCS(869.3,PTRMAIN,5)
    232         S NODE5=$G(^HLCS(869.3,PTRMAIN,5))
    233         S STOP=+$P(NODE5,"^",3)
    234         Q:STOP STOP
    235         S STOP=$$S^%ZTLOAD
    236         Q STOP
    237         ;
    238 SNDALERT        ;Send Alert
    239         N XQA,XQAMSG,XQAOPT,XQAROU,XQAID,Z
    240         S Z=$P($$PARAM^HLCS2,U,8) Q:Z=""
    241         S XQA("G."_Z)="",XQAMSG="HL7 Logical Link "_$P(^HLCS(870,HLDP,0),U)_" shutdown due to TaskMan unable to process task request"
    242         D SETUP^XQALERT
    243         Q
     1HLCSLM ;SFCIOFO/AC - HL7 LINK MANAGER ;06/14/2005  10:29
     2 ;;1.6;HEALTH LEVEL SEVEN;**49,57,109,123**;Oct 13, 1995
     3 ;
     4EN ;Entry point for start up task
     5 N %,HLEVLCHK,HLTSKCNT
     6 F %=1:1:10 L +^HLCS("HLCSLM"):2 Q:$T
     7 E  Q
     8 I $G(ZTQUEUED) S Y=$$PSET^%ZTLOAD(ZTQUEUED)
     9 D INIT,SAVDOLRH
     10 D SETNM^%ZOSV($E("HLmgr:"_$G(ZTQUEUED),1,15))
     11 ;
     12LOOP ;
     13 D CHKQUE
     14 I $$CKLMSTOP G EXIT
     15 D SAVDOLRH
     16 D CHECKMST^HLEVMST ;HL*1.6*109 - Make sure event monitor current
     17 H 10
     18 G LOOP
     19 ;
     20EXIT N HLJ,X
     21 S X=1
     22 F  L +^HLCS(869.3,X,5):2 Q:$T
     23 ;52=Link Manager task number
     24 S HLJ(869.3,X_",",52)="@"
     25 D FILE^HLDIE("","HLJ","","EXIT","HLCSLM") ;HL*1.6*109
     26 L -^HLCS(869.3,X,5)
     27 L -^HLCS("HLCSLM")
     28 Q
     29 ;
     30SAVDOLRH ;Save Last Known $H
     31 N HLJ,X
     32 S X=1
     33 F  L +^HLCS(869.3,X,5):2 Q:$T
     34 ;54=LM LAST KNOWN $H
     35 S HLJ(869.3,X_",",54)=$H
     36 D FILE^HLDIE("","HLJ","","SAVDOLRH","HLCSLM") ;HL*1.6*109
     37 L -^HLCS(869.3,X,5)
     38 Q
     39 ;
     40CHKQUE ;Check queues for messages to send
     41 ;HLTSKCNT(logical link)=task #^$H
     42 N HLDA,HLDP,HLMSG,HLTSK,Y
     43 S (HLDA,HLMSG)=""
     44 F HLDP=0:0 S HLDP=+$O(^HLMA("AC","O",HLDP)) Q:HLDP'>0  S HLMSG=+$O(^(HLDP,0)) I HLMSG D  L -^HLCS("HLCSLSM",HLDP)
     45 .;quit if persistent link
     46 .Q:$P($G(^HLCS(870,HLDP,400)),U,4)="Y"
     47 .L +^HLCS("HLCSLSM",HLDP):0 E  K HLTSKCNT(HLDP) Q
     48 .Q:'$$LLOK(+HLDP)
     49 .;get tasknumber from file 870 and HLTSKCNT array
     50 .S Y=$$TASKNUM(HLDP),HLTSK=$G(HLTSKCNT(HLDP))
     51 . ;
     52 . ;patch HL*1.6*123 start
     53 . S HLDP("TASK-ACTIVE")=0
     54 . ;
     55 . I Y D
     56 .. N ZTSK
     57 .. S ZTSK=Y
     58 .. ; Check status of task
     59 .. D STAT^%ZTLOAD
     60 .. I "12"[ZTSK(1) S HLDP("TASK-ACTIVE")=1
     61 . Q:HLDP("TASK-ACTIVE")
     62 . ;
     63 . I HLTSK D
     64 .. N ZTSK
     65 .. S ZTSK=+HLTSK
     66 .. ; Check status of task
     67 .. D STAT^%ZTLOAD
     68 .. I "12"[ZTSK(1) S HLDP("TASK-ACTIVE")=1
     69 . Q:HLDP("TASK-ACTIVE")
     70 . ;
     71 . ;no tasknumber, link not running nor queued, task it
     72 . I 'HLTSK!'Y D TASKLSUB(HLDP),SAVTSK(HLDP) Q
     73 ; comment out the following lines
     74 ; .;link was tasked, check time
     75 ; .S Y=$P(HLTSK,U,2)
     76 ; .;check that time task is less than 30 minutes
     77 ; .Q:$$HDIFF^XLFDT($H,Y,2)<1800
     78 ; .;shutdown and send alert
     79 ; .D SDFLD^HLCSTCP,EXITS^HLCSTCP("Shutdown"),SNDALERT
     80 ; loop through links that have been tasked
     81 ; F HLDP=0:0 S HLDP=$O(HLTSKCNT(HLDP)) Q:HLDP'>0  K:'$D(^HLMA("AC","O",HLDP)) HLTSKCNT(HLDP)
     82 F HLDP=0:0 S HLDP=$O(HLTSKCNT(HLDP)) Q:HLDP'>0  D
     83 . N ZTSK
     84 . S ZTSK=+HLTSKCNT(HLDP)
     85 . ; Check status of task
     86 . D STAT^%ZTLOAD
     87 . ; kill HLTSKCNT(HLDP) if process is not active
     88 . I "12"'[ZTSK(1) K HLTSKCNT(HLDP)
     89 ; patch HL*1.6*123 end
     90 Q
     91 ;
     92INIT ;Create Task number and clear Stop flag.
     93 N HLJ,X
     94 S X=1
     95 F  L +^HLCS(869.3,X,5):2 Q:$T
     96 ;52=Link Manager task number,53=Stop Link Manager
     97 S HLJ(869.3,X_",",52)=$G(ZTQUEUED)
     98 S HLJ(869.3,X_",",53)="@"
     99 D FILE^HLDIE("","HLJ","","INIT","HLCSLM") ;HL*1.6*109
     100 L -^HLCS(869.3,X,5)
     101 Q
     102TASKNUM(X) ;Look-up task number
     103 N %,DA,Y
     104 S DA=X
     105 ;
     106 ;**109**
     107 ;F  L +^HLCS(870,+DA,0):2 Q:$T
     108 ;
     109 S Y=$$GET1^DIQ(870,DA_",",11)
     110 ;
     111 ;**109
     112 ;L -^HLCS(870,+DA,0)
     113 ;
     114 Q Y
     115STATUS(X) ;Status of task
     116 N Y,ZTSK
     117 S ZTSK=X
     118 D STAT^%ZTLOAD
     119 S Y=ZTSK(1)
     120 Q Y
     121 ;
     122LLOK(X) ;Function to check whether LL ok.
     123 ;return value 1 = ok, 0 = not ok.
     124 Q:'$G(X)
     125 N HLDP,HLDP0,HLPARM4,HLTYPTR
     126 S HLDP=+X,HLDP0=$G(^HLCS(870,HLDP,0)),HLPARM4=$G(^(400)) Q:HLDP0="" 0
     127 ;must be a client
     128 Q:$P(HLPARM4,U,3)'="C" 0
     129 ;
     130 ; patch HL*1.6*123
     131 ;shutdown LLP must be 0
     132 ; Q:$P(HLDP0,U,15)'=0 0
     133 ; change to 1, in case the data is empty
     134 Q:$P(HLDP0,U,15)=1 0
     135 ;
     136 ;must have LLP Type of TCP
     137 S HLTYPTR=+$P(HLDP0,U,3) Q:$P($G(^HLCS(869.1,HLTYPTR,0)),U)'="TCP" 0
     138 Q 1
     139 ;
     140SAVTSK(X) ;
     141 N HLDP,HLJ
     142 S HLDP=X
     143 ;
     144 ;**109**
     145 F  L +^HLCS(870,HLDP,0):2 Q:$T
     146 ;
     147 ;4=status,10=Time Stopped,9=Time Started,11=Task Number,3=Online ?
     148 S X=$NA(HLJ(870,HLDP_",")),@X@(11)=$G(ZTSK)
     149 ;S HLJ(870,HLDP_",",11)=$G(ZTSK)
     150 D FILE^HLDIE("","HLJ","","SAVTSK","HLCSLM") ; HL*1.6*109
     151 S HLTSKCNT(HLDP)=$G(ZTSK)_"^"_$H
     152 ;
     153 ;**109**
     154 L -^HLCS(870,HLDP,0)
     155 ;
     156 Q
     157 ;
     158STRTSTOP ;ENTRY POINT TO START/STOP TCP LINK MANAGER
     159 N DIR,DIRUT,Y
     160 L +^HLCS("HLCSLM"):3 E  D  Q
     161 .W !,*7,"Link Manager already running!"
     162 .W ! S DIR(0)="YO",DIR("A")="Would you like to stop the Link Manager now",DIR("B")="NO" D ^DIR K DIR
     163 .I $D(DIRUT)!'Y Q
     164 .D STOPLM
     165 W !,*7,"Link Manager is NOT currently running!"
     166 W ! S DIR(0)="YO",DIR("A")="Would you like to start the Link Manager now",DIR("B")="YES" D ^DIR K DIR
     167 I '$D(DIRUT)&Y D TASKLM
     168 L -^HLCS("HLCSLM")
     169 Q
     170 ;
     171STOPLM ;ENTRY POINT TO STOP LINK MANAGER
     172 N DIC,X,Y,DTOUT,DUOUT,DLAYGO,DIE,DA,DR
     173 S DIC="^HLCS(869.3,"
     174 S X=1
     175 D ^DIC
     176 S DA=+Y,DIE=DIC
     177 S DR="53////1"
     178 D ^DIE
     179 W !,"Link Manager has been asked to stop"
     180 Q
     181STAT() ;Status of LINK MANAGER--up, down or unable to determine.
     182 N %,DA,X,Y
     183 S DA=1
     184 S X=$$GET1^DIQ(869.3,DA_",",52)
     185 Q:X']"" 0
     186 S X=$$GET1^DIQ(869.3,DA_",",54)
     187 Q:X']"" 0
     188 I $$HDIFF^XLFDT($H,X,2)>500 Q 0
     189 Q 1
     190 ;
     191TASKLSUB(X) ;Task LINK SUB-MANAGER.
     192 ;This may be a place to log the time which the LINK SUBMANAGER is tasked.
     193 N HLDP,HLDP0,HLDAPP,HLTYPTR,HLBGR,HLENV,HLPARM,HLPARM4,HLQUIT,ZTRTN,ZTDESC,ZTCPU,ZTSAVE
     194 ;ZTSK is not Newed here because it will be needed by SAVTSK.
     195 S HLDP=X,HLDP0=$G(^HLCS(870,HLDP,0)),HLPARM4=$G(^(400))
     196 ; Q:"N"'[$P(HLPARM4,U,4)  ; patch HL*1.6*123: comment out
     197 ;quit if no LLP TYPE
     198 S HLDAPP=$P(HLDP0,U),HLTYPTR=$P(HLDP0,U,3) Q:'HLTYPTR
     199 S HLBGR=$G(^HLCS(869.1,HLTYPTR,100)),HLENV=$G(^(200))
     200 I HLENV'="" K HLQUIT X HLENV Q:$D(HLQUIT)
     201 S ZTRTN="^HLCSLSM",HLBGR=$P(HLBGR," ",2)
     202 S ZTDESC=HLDAPP_" Low Level Protocol",ZTSAVE("HLDP")="",ZTSAVE("HLBGR")=""
     203 S ZTIO="",ZTDTH=$H
     204 ;get startup node
     205 I $P(HLPARM4,U,6),$D(^%ZIS(14.7,+$P(HLPARM4,U,6),0)) S ZTCPU=$P(^(0),U)
     206 D ^%ZTLOAD
     207 D MON^HLCSTCP("Tasked") ;HL*1.6*123
     208 Q
     209 ;
     210TASKLM ;Task Link Manager
     211 ;Declare variables
     212 N ZTRTN,ZTDESC,ZTIO,ZTDTH,ZTSK,TMP
     213 S ZTIO=""
     214 S ZTDTH=$H
     215 ;Task Link Manager
     216 S ZTRTN="EN^HLCSLM"
     217 S ZTDESC="HL7 Link Manager"
     218 ;Call TaskMan
     219 D ^%ZTLOAD
     220 I $G(ZTSK) W !,"Link Manager queued as task number ",ZTSK
     221 E  W $C(7),!!,"Unable to start/restart Link Manager"
     222 Q
     223 ;
     224CKLMSTOP() ;Check whether Link Manager should stop
     225 N PTRMAIN,NODE5,STOP
     226 S PTRMAIN=+$O(^HLCS(869.3,0))
     227 L +^HLCS(869.3,PTRMAIN,5):1
     228 I $T L -^HLCS(869.3,PTRMAIN,5)
     229 S NODE5=$G(^HLCS(869.3,PTRMAIN,5))
     230 S STOP=+$P(NODE5,"^",3)
     231 Q:STOP STOP
     232 S STOP=$$S^%ZTLOAD
     233 Q STOP
     234 ;
     235SNDALERT ;Send Alert
     236 N XQA,XQAMSG,XQAOPT,XQAROU,XQAID,Z
     237 S Z=$P($$PARAM^HLCS2,U,8) Q:Z=""
     238 S XQA("G."_Z)="",XQAMSG="HL7 Logical Link "_$P(^HLCS(870,HLDP,0),U)_" shutdown due to TaskMan unable to process task request"
     239 D SETUP^XQALERT
     240 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSLNCH.m

    r613 r623  
    1 HLCSLNCH        ;ALB/MTC/JC - START AND STOP THE LLP ;07/26/2007  17:10
    2         ;;1.6;HEALTH LEVEL SEVEN;**6,19,43,49,57,75,84,109,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;This program is callable from a menu
    6         ;It allows the user to Start and Stop the Lower Layer
    7         ;Protocol in the Background or in the foreground
    8         ;
    9         ;Required or Optional INPUT PARAMETERS
    10         ;             None
    11         ;
    12         ;
    13         ;Output variables
    14         ;             HLDP=IEN of Logical Link in file #870
    15         ;(optional)HLTRACE=if SET it launches the LLP in the Foreground
    16         ;(optional)   ZTSK=if defined LLP was launched in the
    17         ;background
    18         ;
    19         ;
    20 START   ; Start up the lower level protocol
    21         N DIC,DIRUT,DTOUT,DUOUT,HLDP,HLDAPP,HLJ,HLQUIT,HLTRACE
    22         N HLPARM0,HLPARM4,HLTYPTR,HLBGR,X,Y,ZTCPU,ZTSK,ZTRTN,ZTDESC
    23         W !!,"This option is used to launch the lower level protocol for the"
    24         W !,"appropriate device.  Please select the node with which you want"
    25         W !,"to communicate",!
    26         ; patch HL*1.6*122
    27         S POP=0
    28         S DIC="^HLCS(870,",DIC(0)="QEAMZ" D ^DIC G:Y<0 STARTQ
    29         S HLDP=+Y,HLDAPP=Y(0,0),HLTYPTR=+$P(Y(0),U,3),HLPARM0=Y(0)
    30         ;-- check if parameter have been setup
    31         ;-- check for LLP type
    32         I 'HLTYPTR W !!,$C(7),"A Lower Layer Protocol must be selected before start-up can occur." G STARTQ
    33         ;-- get TCP information
    34         S HLPARM4=$G(^HLCS(870,HLDP,400))
    35         ;-- get routine (background job for LLP)
    36         S HLBGR=$G(^HLCS(869.1,HLTYPTR,100))
    37         ;-- get environment check routine (HLQUIT should be defined in fails)
    38         S HLENV=$G(^HLCS(869.1,HLTYPTR,200))
    39         ;
    40         I HLBGR="" W !!,$C(7),"No routine has been specified for this LLP." G STARTQ
    41         ;
    42         ;-- execute environment check routine if HLQUIT is defined then terminate
    43         I HLENV'="" X HLENV G:$D(HLQUIT) STARTQ
    44         ; patch HL*1.6*122 start
    45         ; Multi-Servers: TCP service (GT.M, DSM, and Cache/VMS) is controlled
    46         ; by the external service
    47         I $P(HLPARM4,U,3)="M",$S(^%ZOSF("OS")'["OpenM":1,1:$$OS^%ZOSV["VMS") D  G STARTQ
    48         . W !,$C(7),"This LLP is a multi-threaded server. It is controlled by external service, i.e. TCPIP/UCX. You must use the external service to start this LLP."
    49         . Q
    50         ; patch HL*1.6*122 end
    51         ;
    52         I $P(HLPARM0,U,10) W !,$C(7),"The LLP was last started on ",$$DAT2^HLUTIL1($P(HLPARM0,U,10)),"." G STP1:$P(HLPARM0,U,5)'="Error"
    53         I $P(HLPARM0,U,11) W !,"The LLP was last shutdown on ",$$DAT2^HLUTIL1($P(HLPARM0,U,11)),"."
    54         ; patch HL*1.6*122 start
    55         ; comment out-should be taken care of by the code 2 line above
    56         ; I $P(HLPARM0,U,5)'="Error",'($P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4))),$P(HLPARM0,U,10)]""&($P(HLPARM0,U,11)=""),$P(HLPARM0,U,12) W !,"The LLP appears to be online already !"
    57         ; I $$TASK^HLUTIL1($P(HLPARM0,U,12)) D  G STARTQ
    58         ; . W !,$C(7),"NOTE: The lower level protocol for this application is already running."
    59         N HLTEMP
    60         S HLTEMP=0
    61         I $P(HLPARM0,U,12) D  G:HLTEMP STARTQ
    62         . N ZTSK
    63         . S ZTSK=$P(HLPARM0,U,12)
    64         . D STAT^%ZTLOAD
    65         . I "12"[ZTSK(1) D
    66         .. W !,$C(7),"NOTE: The lower level protocol for this application is already running."
    67         .. I '$P(^HLCS(870,HLDP,0),"^",10) S $P(^HLCS(870,HLDP,0),"^",10)=$$NOW^XLFDT
    68         .. S HLTEMP=1
    69         ; patch HL*1.6*122 end
    70         I $P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4)) D  G STARTQ
    71         .;4=status 9=Time Started, 10=Time Stopped, 11=Task Number
    72         .;14=Shutdown LLP, 3=Device Type, 18=Gross Errors
    73         .N HLJ,X
    74         . ; patch HL*1.6*122-comment out
    75         . ; I $P(HLPARM0,U,15)=0 W !,"This LLP is already enabled!" Q
    76         .L +^HLCS(870,HLDP,0):2
    77         .E  W !,$C(7),"Unable to enable this LLP !" Q
    78         .S X="HLJ(870,"""_HLDP_","")"
    79         .S @X@(4)="Enabled",@X@(9)=$$NOW^XLFDT,@X@(14)=0
    80         .D FILE^HLDIE("","HLJ","","START","HLCSLNCH") ;HL*1.6*109
    81         .L -^HLCS(870,HLDP,0)
    82         .W !,"This LLP has been enabled!"
    83         .Q
    84         I $P(HLPARM4,U,6),$D(^%ZIS(14.7,+$P(HLPARM4,U,6),0)) S ZTCPU=$P(^(0),U) W !,"This LLP will start on node ",ZTCPU," if it is run in the Background.",!
    85         ;
    86         ; patch HL*1.6*122 start, for tcp link
    87         I HLTYPTR=4 D  Q
    88         . S Y="B"
    89         . D STARTJOB
    90         ; patch HL*1.6*122 end
    91         ;
    92         W ! S DIR(0)="SM^F:FOREGROUND;B:BACKGROUND;Q:QUIT"
    93         S DIR("A")="Method for running the receiver"
    94         S DIR("B")="B"
    95         S DIR("?",1)="Enter F for Foreground (and trace)"
    96         S DIR("?",2)="      B for Background (normal) or"
    97         S DIR("?")="      Q to quit without starting the receiver"
    98         D ^DIR K DIR
    99         Q:(Y=U)!(Y="Q")
    100         ;
    101 STARTJOB        ;
    102         S HLX=$G(^HLCS(870,HLDP,0))
    103         ;-- foreground
    104         I Y="F" S HLTRACE=1 D  G STARTQ
    105         . S $P(^HLCS(870,HLDP,0),"^",10)=$$NOW^XLFDT
    106         . D MON^HLCSTCP("Start")
    107         . X HLBGR
    108         ;-- background
    109         I Y="B" D  G STARTQ
    110         . S ZTRTN=$P(HLBGR," ",2),HLTRACE="",ZTIO="",ZTDTH=$H
    111         . S ZTDESC=HLDAPP_" Low Level Protocol",ZTSAVE("HLDP")=""
    112         . D ^%ZTLOAD
    113         . ; patch HL*1.6*122 start
    114         . I $D(ZTSK) D
    115         .. K HLTRACE
    116         .. D MON^HLCSTCP("Tasked")
    117         .. S $P(^HLCS(870,HLDP,0),"^",10)=$$NOW^XLFDT
    118         . ; patch HL*1.6*122 end
    119         . W !,$S($D(ZTSK):"Job was queued as "_ZTSK_".",1:"Unable to queue job.")
    120         ;
    121         Q
    122         ;
    123 STARTQ  ;
    124         I $G(POP) W !,?5,"-Unable to Open the Device !",!,!,?6,"Check that Port is Logged Out, and that the",!,?6,"Lower Level Protocol is not Already Running."
    125         Q
    126         ;
    127 STOP    ; Shut down a lower level protocol..
    128         N DIC,DIRUT,DTOUT,DUOUT,HLDP,HLDAPP,HLJ,HLPARM0,HLPARM4,X,Y
    129         W !!,"This option is used to shut down the lower level protocol for the"
    130         W !,"appropriate device.  Please select the link which you would"
    131         W !,"like to shutdown.",!
    132         S DIC="^HLCS(870,",DIC(0)="QEAMZ" D ^DIC K DIC Q:Y<0
    133         S HLDP=+Y,HLDAPP=Y(0,0),HLPARM0=Y(0),HLPARM4=$G(^HLCS(870,HLDP,400))
    134         ; patch HL*1.6*122
    135         ; Multi-Servers: TCP service (GT.M, DSM, and Cache/VMS) is controlled
    136         ; by the external service
    137         I $P(HLPARM4,U,3)="M",$S(^%ZOSF("OS")'["OpenM":1,1:$$OS^%ZOSV["VMS") D  Q
    138         . W !,$C(7),"This LLP is a multi-threaded server. It is controlled by external service, i.e. TCPIP/UCX. You must use the external service to disable this LLP."
    139         . Q
    140         ;
    141         I $P(HLPARM0,U,15) W !,$C(7),"The lower level protocol is already ",$P(HLPARM0,U,5),"." Q
    142         I $P(HLPARM0,U,10) W !,$C(7),"The lower level protocol was started on ",$$DAT2^HLUTIL1($P(HLPARM0,U,10)),"."
    143 STP1    ;
    144         W ! S DIR(0)="Y",DIR("A")="Okay to shut down this job" D ^DIR K DIR
    145         I 'Y!($D(DIRUT))!($D(DUOUT)) W !!,"The job will not be shut down." Q
    146 S       ;
    147         F  L +^HLCS(870,HLDP,0):2 Q:$T
    148         ;4=status,10=Time Stopped,9=Time Started,11=Task Number,3=Device Type,14=shutdown
    149         S X="HLJ(870,"""_HLDP_","")",@X@(4)="Halting",@X@(10)=$$NOW^XLFDT,(@X@(11),@X@(9))="@",@X@(14)=1
    150         I $P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4)),'$P(HLPARM0,U,12) S @X@(4)="Shutdown"
    151         D FILE^HLDIE("","HLJ","","STOP","HLCSLNCH") ; HL*1.6*109
    152         ; patch HL*1.6*122 start
    153         ; I ^%ZOSF("OS")["OpenM",(($P(HLPARM4,U,3)="M"&($$OS^%ZOSV'["VMS"))!($P(HLPARM4,U,3)="S")) D
    154         ; I ^%ZOSF("OS")'["DSM",(($P(HLPARM4,U,3)="M"&($$OS^%ZOSV'["VMS"))!($P(HLPARM4,U,3)="S")) D
    155         I ($P(HLPARM4,U,3)="S")!(($P(HLPARM4,U,3)="M")&($S(^%ZOSF("OS")'["OpenM":0,1:$$OS^%ZOSV'["VMS"))) D
    156         . ;pass task number to stop listener
    157         . S:$P(HLPARM0,U,12) X=$$ASKSTOP^%ZTLOAD(+$P(HLPARM0,U,12))
    158         . ; D CALL^%ZISTCP($P(HLPARM4,U),$P(HLPARM4,U,2),10)
    159         . ; I POP D HOME^%ZIS U IO W !,"Unable to shutdown logical link!!!",$C(7),$C(7) Q
    160         . ; U IO W "**STOP**"
    161         . ; W !
    162         . ; D CLOSE^%ZISTCP
    163         . ; patch HL*1.6*122 end
    164         L -^HLCS(870,HLDP,0)
    165         W !,"The job for the "_HLDAPP_" Lower Level Protocol will be shut down."
    166         Q
    167         ;
    168 STOPQ   Q
     1HLCSLNCH ;ALB/MTC/JC - START AND STOP THE LLP ;12/31/2003  17:37
     2 ;;1.6;HEALTH LEVEL SEVEN;**6,19,43,49,57,75,84,109**;Oct 13, 1995
     3 ;
     4 ;This program is callable from a menu
     5 ;It allows the user to Start and Stop the Lower Layer
     6 ;Protocol in the Background or in the foreground
     7 ;
     8 ;Required or Optional INPUT PARAMETERS
     9 ;             None
     10 ;
     11 ;
     12 ;Output variables
     13 ;             HLDP=IEN of Logical Link in file #870
     14 ;(optional)HLTRACE=if SET it launches the LLP in the Foreground
     15 ;(optional)   ZTSK=if defined LLP was launched in the
     16 ;background
     17 ;
     18 ;
     19START ; Start up the lower level protocol
     20 N DIC,DIRUT,DTOUT,DUOUT,HLDP,HLDAPP,HLJ,HLQUIT,HLTRACE
     21 N HLPARM0,HLPARM4,HLTYPTR,HLBGR,X,Y,ZTCPU,ZTSK,ZTRTN,ZTDESC
     22 W !!,"This option is used to launch the lower level protocol for the"
     23 W !,"appropriate device.  Please select the node with which you want"
     24 W !,"to communicate",!
     25 S DIC="^HLCS(870,",DIC(0)="QEAMZ" D ^DIC G:Y<0 STARTQ
     26 S HLDP=+Y,HLDAPP=Y(0,0),HLTYPTR=+$P(Y(0),U,3),HLPARM0=Y(0)
     27 ;-- check if parameter have been setup
     28 ;-- check for LLP type
     29 I 'HLTYPTR W !,$C(7),"A Lower Layer Protocol must be selected before start-up can occur." G STARTQ
     30 ;-- get TCP information
     31 S HLPARM4=$G(^HLCS(870,HLDP,400))
     32 ;-- get routine (background job for LLP)
     33 S HLBGR=$G(^HLCS(869.1,HLTYPTR,100))
     34 ;-- get environment check routine (HLQUIT should be defined in fails)
     35 S HLENV=$G(^HLCS(869.1,HLTYPTR,200))
     36 ;
     37 I HLBGR="" W !,$C(7),"No routine has been specified for this LLP." G STARTQ
     38 ;
     39 ;-- execute environment check routine if HLQUIT is defined then terminate
     40 I HLENV'="" X HLENV G:$D(HLQUIT) STARTQ
     41 ;Multi-Servers, only enable the link if not OpenM
     42 I $P(HLPARM4,U,3)="M",$S(^%ZOSF("OS")'["OpenM":1,1:$$OS^%ZOSV["VMS") D  G STARTQ
     43 . W !,$C(7),"This LLP is a multi-threaded server. It is controlled by external service, i.e. TCPIP/UCX. You must use the external service to start this LLP."
     44 . Q
     45 ;
     46 I $P(HLPARM0,U,10) W !,$C(7),"The LLP was last started on ",$$DAT2^HLUTIL1($P(HLPARM0,U,10)),"." G STP1:$P(HLPARM0,U,5)'="Error"
     47 I $P(HLPARM0,U,11) W !,"The LLP was last shutdown on ",$$DAT2^HLUTIL1($P(HLPARM0,U,11)),"."
     48 I $P(HLPARM0,U,5)'="Error",'($P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4))),$P(HLPARM0,U,10)]""&($P(HLPARM0,U,11)=""),$P(HLPARM0,U,12) W !,"The LLP appears to be online already !"
     49 I $$TASK^HLUTIL1($P(HLPARM0,U,12)) D  G STARTQ
     50 . W !,$C(7),"NOTE: The lower level protocol for this application is already running."
     51 I $P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4)) D  G STARTQ
     52 .;4=status 9=Time Started, 10=Time Stopped, 11=Task Number
     53 .;14=Shutdown LLP, 3=Device Type, 18=Gross Errors
     54 .N HLJ,X
     55 .I $P(HLPARM0,U,15)=0 W !,"This LLP is already enabled!" Q
     56 .L +^HLCS(870,HLDP,0):2
     57 .E  W !,$C(7),"Unable to enable this LLP !" Q
     58 .S X="HLJ(870,"""_HLDP_","")"
     59 .S @X@(4)="Enabled",@X@(9)=$$NOW^XLFDT,@X@(14)=0
     60 .D FILE^HLDIE("","HLJ","","START","HLCSLNCH") ;HL*1.6*109
     61 .L -^HLCS(870,HLDP,0)
     62 .W !,"This LLP has been enabled!"
     63 .Q
     64 I $P(HLPARM4,U,6),$D(^%ZIS(14.7,+$P(HLPARM4,U,6),0)) S ZTCPU=$P(^(0),U) W !,"This LLP will start on node ",ZTCPU," if it is run in the Background.",!
     65 ;
     66 W ! S DIR(0)="SM^F:FOREGROUND;B:BACKGROUND;Q:QUIT"
     67 S DIR("A")="Method for running the receiver"
     68 S DIR("B")="B"
     69 S DIR("?",1)="Enter F for Foreground (and trace)"
     70 S DIR("?",2)="      B for Background (normal) or"
     71 S DIR("?")="      Q to quit without starting the receiver"
     72 D ^DIR K DIR
     73 Q:(Y=U)!(Y="Q")
     74 ;
     75 S HLX=$G(^HLCS(870,HLDP,0))
     76 ;-- foreground
     77 I Y="F" S HLTRACE=1 D  G STARTQ
     78 . X HLBGR
     79 ;-- background
     80 I Y="B" D  G STARTQ
     81 . S ZTRTN=$P(HLBGR," ",2),HLTRACE="",ZTIO="",ZTDTH=$H
     82 . S ZTDESC=HLDAPP_" Low Level Protocol",ZTSAVE("HLDP")=""
     83 . D ^%ZTLOAD
     84 . W !,$S($D(ZTSK):"Job was queued as "_ZTSK_".",1:"Unable to queue job.")
     85 ;
     86 Q
     87 ;
     88 ;
     89STARTQ ;
     90 I $G(POP) W !,?5,"-Unable to Open the Device !",!,!,?6,"Check that Port is Logged Out, and that the",!,?6,"Lower Level Protocol is not Already Running."
     91 Q
     92 ;
     93STOP ; Shut down a lower level protocol..
     94 N DIC,DIRUT,DTOUT,DUOUT,HLDP,HLDAPP,HLJ,HLPARM0,HLPARM4,X,Y
     95 W !!,"This option is used to shut down the lower level protocol for the"
     96 W !,"appropriate device.  Please select the link which you would"
     97 W !,"like to shutdown.",!
     98 S DIC="^HLCS(870,",DIC(0)="QEAMZ" D ^DIC K DIC Q:Y<0
     99 S HLDP=+Y,HLDAPP=Y(0,0),HLPARM0=Y(0),HLPARM4=$G(^HLCS(870,HLDP,400))
     100 I $P(HLPARM4,U,3)="M",$S(^%ZOSF("OS")'["OpenM":1,1:$$OS^%ZOSV["VMS") D  Q
     101 . W !,$C(7),"This LLP is a multi-threaded server. It is controlled by external service, i.e. UCX. You must use the external service to disable this LLP."
     102 . Q
     103 ;
     104 I $P(HLPARM0,U,15) W !,$C(7),"The lower level protocol is already ",$P(HLPARM0,U,5),"." Q
     105 I $P(HLPARM0,U,10) W !,$C(7),"The lower level protocol was started on ",$$DAT2^HLUTIL1($P(HLPARM0,U,10)),"."
     106STP1 ;
     107 W ! S DIR(0)="Y",DIR("A")="Okay to shut down this job" D ^DIR K DIR
     108 I 'Y!($D(DIRUT))!($D(DUOUT)) W !!,"The job will not be shut down." Q
     109S ;
     110 F  L +^HLCS(870,HLDP,0):2 Q:$T
     111 ;4=status,10=Time Stopped,9=Time Started,11=Task Number,3=Device Type,14=shutdown
     112 S X="HLJ(870,"""_HLDP_","")",@X@(4)="Halting",@X@(10)=$$NOW^XLFDT,(@X@(11),@X@(9))="@",@X@(14)=1
     113 I $P(HLPARM4,U,3)="C"&("N"[$P(HLPARM4,U,4)),'$P(HLPARM0,U,12) S @X@(4)="Shutdown"
     114 D FILE^HLDIE("","HLJ","","STOP","HLCSLNCH") ; HL*1.6*109
     115 I ^%ZOSF("OS")["OpenM",(($P(HLPARM4,U,3)="M"&($$OS^%ZOSV'["VMS"))!($P(HLPARM4,U,3)="S")) D
     116 . ;pass task number to stop listener
     117 . S:$P(HLPARM0,U,12) X=$$ASKSTOP^%ZTLOAD(+$P(HLPARM0,U,12))
     118 . D CALL^%ZISTCP($P(HLPARM4,U),$P(HLPARM4,U,2),10)
     119 . I POP D HOME^%ZIS U IO W !,"Unable to shutdown logical link!!!",$C(7),$C(7) Q
     120 . U IO W "**STOP**"
     121 . W !
     122 . D CLOSE^%ZISTCP
     123 L -^HLCS(870,HLDP,0)
     124 W !,"The job for the "_HLDAPP_" Lower Level Protocol will be shut down."
     125 Q
     126 ;
     127STOPQ Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSMON.m

    r613 r623  
    1 HLCSMON ;SF-DISPLAY DRIVER PROGRAM  ;12/11/2007  17:07
    2         ;;1.6;HEALTH LEVEL SEVEN;**34,40,48,49,65,66,73,109,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;This Program drives a real-time display monitor for the HL7
    6         ;Package. All the data used by this display is stored in file
    7         ;# 870. Several callable entry points were broken
    8         ;out of this routine and placed into HLCSMON1
    9         ;
    10         ;This routine has no required input parameters other than require that
    11         ;U be defined, it does not instantiate any parameters either.
    12         ;
    13         ;
    14         ;HLARY=array of all,HLARYD=array of display,HLARYO=array of old values
    15         ;HLPTR1=top of display,HLPTR2=bottom of display,HLPTR3=last in HLVARY
    16 INIT    N HLARY,HLARYD,HLARYO,HLCOFF,HLCON,HLDISP,HLPTR1,HLPTR2,HLPTR3,HLRESP
    17         N HLDEV,HLERR,HLEVL,HLHDR,HLNODE,HLOCK
    18         N HLPARAM,HLPROC,HLPROD,HLSEND,HLSENT,HLSITE
    19         N HLI,HLREC,HLRUNCNT,HLSTAT,HLTMSTAT,HLLMSTAT,HLVIEW,HLXX,HLYY,X,Y,DX,DY
    20         ;
    21         ; patch HL*1.6*122 start
    22         D HOME^%ZIS
    23         W @IOF
    24         ; patch HL*1.6*122 end
    25         ;
    26         D ^HLCSTERM ;Sets up variables to control display attributes
    27 INIT1   ;
    28         ; Next 4 lines copied here from top of START by patch 73...
    29         ;HLRUNCNT=number of in filers^out filers, HLDISP=display mode
    30         S HLRUNCNT="-1^-1",HLPTR1=1 S:'$D(HLDISP) HLDISP="S"
    31         D BUILDARY ;Build an array for display
    32         QUIT:$$LOCKED(.HLOCK)  ;-> Anything locked?
    33         ;
    34         W HLCOFF ;Shut Cursor off
    35         D HEADER^HLCSTERM ;Write header
    36         D WDATA^HLCSMON1(5,17,"","","Incoming filers running => ")
    37         D WDATA^HLCSMON1(5,18,"","","Outgoing filers running => ")
    38         D WDATA^HLCSMON1(5,20,"","","Select a Command:")
    39         D WDATA^HLCSMON1(1,21,"","","(N)EXT  (B)ACKUP  (A)LL LINKS  (S)CREENED  (V)IEWS  (Q)UIT  (?) HELP: ")
    40         ;HLRUNCNT=number of in filers^out filers, HLDISP=display mode
    41         S HLRUNCNT="-1^-1",HLPTR1=1 S:'$D(HLDISP) HLDISP="S"
    42 START   ;
    43         D BUILDARY ;Build an array for display
    44         D DISPLAY^HLCSMON1 ;Display the array just built
    45         D READ
    46         ;HLRESP=user response
    47         I '$L(HLRESP) G START
    48         G:HLRESP="Q" EXIT
    49         ;any of following commands, kill old values
    50         K HLARYO,HLTMSTAT,HLLMSTAT
    51         I HLRESP="?" D HELP G INIT1
    52         I HLRESP="V" D VIEW G INIT1
    53         I "AS"[HLRESP K HLARY,HLEVL S HLDISP=HLRESP G INIT1
    54         I "NB"[HLRESP D NEXT
    55         G START
    56         ;
    57 READ    ;Prompt the user for the next action
    58         D WDATA^HLCSMON1(71,21,"","","",1)
    59         W HLCON
    60         R X#1:3
    61         W HLCOFF
    62         S HLRESP=$S(X="":X,"Qq^"[X:"Q","Bb"[X:"B","Nn"[X:"N","Aa"[X:"A","Vv"[X:"V",X="?":"?","Ss"[X:"S",1:"")
    63         Q
    64         ;
    65 VIEW    ;select new view
    66         W HLCON,!!
    67         N DIC
    68         S DIC="^HLCS(869.3,1,6,",DIC(0)="QEA"
    69         D ^DIC Q:Y<0
    70         S HLVIEW=+Y,HLDISP="V"
    71         W HLCOFF
    72         Q
    73         ;
    74 NEXT    ;
    75         ;Next page
    76         I HLRESP="N" D
    77         . ;no more
    78         . I HLPTR2=HLPTR3 D EOB Q
    79         . S Y=HLPTR2+10,HLEVL(HLPTR1)=""
    80         . ;exceed list, get last 10
    81         . I Y>HLPTR3 S HLPTR2=HLPTR3,HLPTR1=HLPTR2-9 Q
    82         . S HLPTR1=HLPTR2,HLPTR2=Y
    83         ;
    84         ;Backup a page
    85         I HLRESP="B" D
    86         . ;top of list
    87         . I HLPTR1=1 D EOB Q
    88         . I HLDISP="S" S HLPTR1=$O(HLEVL(HLPTR1),-1) Q
    89         . S Y=HLPTR1-9
    90         . ;can't go back 10, reset to top
    91         . I Y'>0 S HLPTR1=1,HLPTR2=10 Q
    92         . S HLPTR2=HLPTR1,HLPTR1=Y
    93         ;
    94         ;Erase what might be displayed on line 22
    95         D WDATA^HLCSMON1(1,22,IOELALL,"","")
    96         Q
    97 EOB     D WDATA^HLCSMON1(5,22,IORVON,IORVOFF,"CANNOT "_$S(HLRESP="N":"ADVANCE",1:"BACKUP")_" BEYOND END OF BUFFER")
    98         W $C(7) H 2
    99         Q
    100         ;
    101 BUILDARY        ;
    102         K HLARYD
    103         ;
    104         ;if view is defined, get links
    105         I $G(HLVIEW) D  S HLVIEW=0,HLDISP="V"
    106         . N HLTMP
    107         . K HLARY,HLEVL S HLI=0
    108         . F  S HLI=$O(^HLCS(869.3,1,6,HLVIEW,1,HLI)) Q:'HLI  S HLYY=+$P($G(^(HLI,0)),U,2) D
    109         .. S Y=$P($G(^HLCS(870,HLI,0)),U) Q:Y=""
    110         .. ;build array by DISPLAY ORDER and then by NAME
    111         .. I HLYY S HLTMP(HLYY,HLI)="" Q
    112         .. S HLTMP(Y,HLI)=""
    113         . S (HLI,HLYY)=0
    114         . ;rebuild array to put in proper order
    115         . F  S HLI=$O(HLTMP(HLI)),HLXX=0 Q:HLI=""  D
    116         .. F  S HLXX=$O(HLTMP(HLI,HLXX)) Q:'HLXX  S HLYY=HLYY+1,HLARY(HLYY,HLXX)=""
    117         . S HLPTR3=HLYY
    118         ;
    119         I '$D(HLARY)  S HLYY=0,HLXX="" D
    120         . ;build array in alphabetical order
    121         . F  S HLXX=$O(^HLCS(870,"B",HLXX)) Q:HLXX=""  S Y=$O(^(HLXX,0)),HLYY=HLYY+1,HLARY(HLYY,Y)=""
    122         . S HLPTR3=HLYY
    123         ;
    124         S HLI=HLPTR1,HLYY=6 ;HLYY=6TH Line of display
    125         ;HLARYD(6) through HLARYD(15) with 6 through 15 also representing line
    126         ;numbers on the display
    127         F HLI=HLI:1 S HLXX=$O(HLARY(HLI,0)) Q:HLYY=16!'HLXX  D COPY
    128         S HLPTR2=HLI-1
    129         ;Set all HLARY elements not defined on this pass to null
    130         F HLYY=HLYY:1:15 S HLARYD(HLYY)=""
    131         Q
    132 COPY    ;
    133         Q:'$D(^HLCS(870,HLXX))
    134         ;
    135         ;These lock tags lock nodes in the global so that the screen is
    136         ;refreshed in real-time. The lock forces the buffer to be refreshed,
    137         ;so that the display is up to date.
    138         ;
    139         ;**109**
    140         ;L +^HLCS(870,HLXX,0):0 L -^HLCS(870,HLXX,0) D CHKLOCK
    141         ;
    142         ; Set, even if not able to lock...
    143         S Y=$G(^HLCS(870,HLXX,0))
    144         ;
    145         ;name^rec^proc^send^sent^device^state^error
    146         S HLARYD(HLYY)=$P(Y,U)_"^^^^^"_$P(Y,U,4)_"^"_$P(Y,U,5)_"^"_$P(Y,U,19)
    147         ;
    148         ;**109**
    149         ;L +^HLCS(870,HLXX,"IN QUEUE BACK POINTER"):0 D CHKLOCK
    150         ;L -^HLCS(870,HLXX,"IN QUEUE BACK POINTER")
    151         ;
    152         S $P(HLARYD(HLYY),U,2)=$G(^HLCS(870,HLXX,"IN QUEUE BACK POINTER"))
    153         ;
    154         ;**109**
    155         ;L +^HLCS(870,HLXX,"IN QUEUE FRONT POINTER"):0 D CHKLOCK
    156         ;L -^HLCS(870,HLXX,"IN QUEUE FRONT POINTER")
    157         ;
    158         S $P(HLARYD(HLYY),U,3)=$G(^HLCS(870,HLXX,"IN QUEUE FRONT POINTER"))
    159         ;
    160         ;**109**
    161         ;L +^HLCS(870,HLXX,"OUT QUEUE BACK POINTER"):0 D CHKLOCK
    162         ;L -^HLCS(870,HLXX,"OUT QUEUE BACK POINTER")
    163         ;
    164         S $P(HLARYD(HLYY),U,4)=$G(^HLCS(870,HLXX,"OUT QUEUE BACK POINTER"))
    165         ;
    166         ;**109**
    167         ;L +^HLCS(870,HLXX,"OUT QUEUE FRONT POINTER"):0 D CHKLOCK
    168         ;L -^HLCS(870,HLXX,"OUT QUEUE FRONT POINTER")
    169         ;
    170         S $P(HLARYD(HLYY),U,5)=$G(^HLCS(870,HLXX,"OUT QUEUE FRONT POINTER"))
    171         ;
    172         S X=HLARYD(HLYY),Y=$P(X,U,2)+$P(X,U,3)+$P(X,U,4)+$P(X,U,5)
    173         ;if Select and the Y=0, nothing to report
    174         I 'Y,HLDISP="S" S HLARYD(HLYY)="" Q
    175         S HLYY=HLYY+1
    176         Q
    177         ;
    178 CHKLOCK ; Call here immediately after trying to lock.  And, BE SURE that
    179         ; nothing might occur that would change $T after the lock attempt!!
    180         ; $T,HLXX -- req
    181         N NM870
    182         QUIT:$T  ;-> Lock obtained...
    183         S NM870=$P($G(^HLCS(870,+HLXX,0)),U)
    184         S NM870=$S(NM870]"":NM870_" (IEN #"_HLXX_")",1:"IEN #"_HLXX)
    185         S HLOCK(NM870)=""
    186         QUIT
    187         ;
    188 HELP    ;
    189         W HLCON,@IOF
    190         W !,"You have the following options when monitoring the Messaging System:"
    191         W !,"Enter the command letter parentheses: N,B,Q,A,S,V or ?"
    192         W !!,"(N) takes you to the next page of the display of Logical Links."
    193         W !!,"(B) takes you back one page."
    194         W !!,"(Q) terminates the monitor."
    195         W !!,"(A) provides a display of all links defined on your system."
    196         W !!,"(S) displays only those links that have had message traffic."
    197         W !!,"(V) prompts for a view name and displays links defined in view."
    198         W !!,"    Note that (S) is the default display at startup."
    199         W !!,"**PRESS <RET> TO CONTINUE**"
    200         R X:DTIME
    201         W @IOF
    202         W !,?25,"Device Types and corresponding prefixes:"
    203         W !!,?30,"PC -- Persistent TCP/IP Client"
    204         W !!,?30,"NC -- Non-Persistent TCP/IP Client"
    205         W !!,?30,"SS -- Single-threaded TCP/IP Server"
    206         W !!,?30,"MS -- Multi-threaded TCP/IP Server"
    207         W !!,?30,"SH -- Serial HLLP"
    208         W !!,?30,"SX -- Serial X3.28"
    209         W !!,?30,"MM -- MailMan"
    210         W !!,"**PRESS <RET> TO CONTINUE**"
    211         R X:DTIME
    212         W HLCOFF
    213         Q
    214 EXIT    ;
    215         ;Turn Cursor back on
    216         W HLCON
    217         D KVAR^HLCSTERM
    218         Q
    219         ;
    220 LOCKED(HLOCK)   ; Anything locked?
    221         ;
    222         ;
    223         ; Nothing locked...
    224         I '$D(HLOCK) QUIT "" ;->
    225         ;
    226         W !!,"Editing of logical link data is occurring right now.  For this reason, some of"
    227         W !,"the information on the 'System Link Monitor' report might not be accurate for"
    228         W !,"the following node(s)..."
    229         W !
    230         ;
    231         S HLOCK=""
    232         F  S HLOCK=$O(HLOCK(HLOCK)) Q:HLOCK']""  D
    233         .  W !,?5,HLOCK
    234         ;
    235         S ACTION=$$BTE("Press RETURN to print report or '^' to exit... ",1)
    236         ;
    237         QUIT $S(ACTION=1:1,1:"")
    238         ;
    239 BTE(PMT,FF)     ;
    240         N DIR,DIRUT,DTOUT,DUOUT,X,Y
    241         F X=1:1:$G(FF) W !
    242         S DIR(0)="EA",DIR("A")=PMT
    243         D ^DIR
    244         QUIT $S(Y=1:"",1:1)
    245         ;
     1HLCSMON ;SF-DISPLAY DRIVER PROGRAM  ;07/10/2000  12:18
     2 ;;1.6;HEALTH LEVEL SEVEN;**34,40,48,49,65,66,73,109**;Oct 13, 1995
     3 ;
     4 ;This Program drives a real-time display monitor for the HL7
     5 ;Package. All the data used by this display is stored in file
     6 ;# 870. Several callable entry points were broken
     7 ;out of this routine and placed into HLCSMON1
     8 ;
     9 ;This routine has no required input parameters other than require that
     10 ;U be defined, it does not instantiate any parameters either.
     11 ;
     12 ;
     13 ;HLARY=array of all,HLARYD=array of display,HLARYO=array of old values
     14 ;HLPTR1=top of display,HLPTR2=bottom of display,HLPTR3=last in HLVARY
     15INIT N HLARY,HLARYD,HLARYO,HLCOFF,HLCON,HLDISP,HLPTR1,HLPTR2,HLPTR3,HLRESP
     16 N HLDEV,HLERR,HLEVL,HLHDR,HLNODE,HLOCK
     17 N HLPARAM,HLPROC,HLPROD,HLSEND,HLSENT,HLSITE
     18 N HLI,HLREC,HLRUNCNT,HLSTAT,HLTMSTAT,HLLMSTAT,HLVIEW,HLXX,HLYY,X,Y,DX,DY
     19 ;
     20 D ^HLCSTERM ;Sets up variables to control display attributes
     21INIT1 ;
     22 ; Next 4 lines copied here from top of START by patch 73...
     23 ;HLRUNCNT=number of in filers^out filers, HLDISP=display mode
     24 S HLRUNCNT="-1^-1",HLPTR1=1 S:'$D(HLDISP) HLDISP="S"
     25 D BUILDARY ;Build an array for display
     26 QUIT:$$LOCKED(.HLOCK)  ;-> Anything locked?
     27 ;
     28 W HLCOFF ;Shut Cursor off
     29 D HEADER^HLCSTERM ;Write header
     30 D WDATA^HLCSMON1(5,17,"","","Incoming filers running => ")
     31 D WDATA^HLCSMON1(5,18,"","","Outgoing filers running => ")
     32 D WDATA^HLCSMON1(5,20,"","","Select a Command:")
     33 D WDATA^HLCSMON1(1,21,"","","(N)EXT  (B)ACKUP  (A)LL LINKS  (S)CREENED  (V)IEWS  (Q)UIT  (?) HELP: ")
     34 ;HLRUNCNT=number of in filers^out filers, HLDISP=display mode
     35 S HLRUNCNT="-1^-1",HLPTR1=1 S:'$D(HLDISP) HLDISP="S"
     36START ;
     37 D BUILDARY ;Build an array for display
     38 D DISPLAY^HLCSMON1 ;Display the array just built
     39 D READ
     40 ;HLRESP=user response
     41 I '$L(HLRESP) G START
     42 G:HLRESP="Q" EXIT
     43 ;any of following commands, kill old values
     44 K HLARYO,HLTMSTAT,HLLMSTAT
     45 I HLRESP="?" D HELP G INIT1
     46 I HLRESP="V" D VIEW G INIT1
     47 I "AS"[HLRESP K HLARY,HLEVL S HLDISP=HLRESP G INIT1
     48 I "NB"[HLRESP D NEXT
     49 G START
     50 ;
     51READ ;Prompt the user for the next action
     52 D WDATA^HLCSMON1(71,21,"","","",1)
     53 W HLCON
     54 R X#1:3
     55 W HLCOFF
     56 S HLRESP=$S(X="":X,"Qq^"[X:"Q","Bb"[X:"B","Nn"[X:"N","Aa"[X:"A","Vv"[X:"V",X="?":"?","Ss"[X:"S",1:"")
     57 Q
     58 ;
     59VIEW ;select new view
     60 W HLCON,!!
     61 N DIC
     62 S DIC="^HLCS(869.3,1,6,",DIC(0)="QEA"
     63 D ^DIC Q:Y<0
     64 S HLVIEW=+Y,HLDISP="V"
     65 W HLCOFF
     66 Q
     67 ;
     68NEXT ;
     69 ;Next page
     70 I HLRESP="N" D
     71 . ;no more
     72 . I HLPTR2=HLPTR3 D EOB Q
     73 . S Y=HLPTR2+10,HLEVL(HLPTR1)=""
     74 . ;exceed list, get last 10
     75 . I Y>HLPTR3 S HLPTR2=HLPTR3,HLPTR1=HLPTR2-9 Q
     76 . S HLPTR1=HLPTR2,HLPTR2=Y
     77 ;
     78 ;Backup a page
     79 I HLRESP="B" D
     80 . ;top of list
     81 . I HLPTR1=1 D EOB Q
     82 . I HLDISP="S" S HLPTR1=$O(HLEVL(HLPTR1),-1) Q
     83 . S Y=HLPTR1-9
     84 . ;can't go back 10, reset to top
     85 . I Y'>0 S HLPTR1=1,HLPTR2=10 Q
     86 . S HLPTR2=HLPTR1,HLPTR1=Y
     87 ;
     88 ;Erase what might be displayed on line 22
     89 D WDATA^HLCSMON1(1,22,IOELALL,"","")
     90 Q
     91EOB D WDATA^HLCSMON1(5,22,IORVON,IORVOFF,"CANNOT "_$S(HLRESP="N":"ADVANCE",1:"BACKUP")_" BEYOND END OF BUFFER")
     92 W $C(7) H 2
     93 Q
     94 ;
     95BUILDARY ;
     96 K HLARYD
     97 ;
     98 ;if view is defined, get links
     99 I $G(HLVIEW) D  S HLVIEW=0,HLDISP="V"
     100 . N HLTMP
     101 . K HLARY,HLEVL S HLI=0
     102 . F  S HLI=$O(^HLCS(869.3,1,6,HLVIEW,1,HLI)) Q:'HLI  S HLYY=+$P($G(^(HLI,0)),U,2) D
     103 .. S Y=$P($G(^HLCS(870,HLI,0)),U) Q:Y=""
     104 .. ;build array by DISPLAY ORDER and then by NAME
     105 .. I HLYY S HLTMP(HLYY,HLI)="" Q
     106 .. S HLTMP(Y,HLI)=""
     107 . S (HLI,HLYY)=0
     108 . ;rebuild array to put in proper order
     109 . F  S HLI=$O(HLTMP(HLI)),HLXX=0 Q:HLI=""  D
     110 .. F  S HLXX=$O(HLTMP(HLI,HLXX)) Q:'HLXX  S HLYY=HLYY+1,HLARY(HLYY,HLXX)=""
     111 . S HLPTR3=HLYY
     112 ;
     113 I '$D(HLARY)  S HLYY=0,HLXX="" D
     114 . ;build array in alphabetical order
     115 . F  S HLXX=$O(^HLCS(870,"B",HLXX)) Q:HLXX=""  S Y=$O(^(HLXX,0)),HLYY=HLYY+1,HLARY(HLYY,Y)=""
     116 . S HLPTR3=HLYY
     117 ;
     118 S HLI=HLPTR1,HLYY=6 ;HLYY=6TH Line of display
     119 ;HLARYD(6) through HLARYD(15) with 6 through 15 also representing line
     120 ;numbers on the display
     121 F HLI=HLI:1 S HLXX=$O(HLARY(HLI,0)) Q:HLYY=16!'HLXX  D COPY
     122 S HLPTR2=HLI-1
     123 ;Set all HLARY elements not defined on this pass to null
     124 F HLYY=HLYY:1:15 S HLARYD(HLYY)=""
     125 Q
     126COPY ;
     127 Q:'$D(^HLCS(870,HLXX))
     128 ;
     129 ;These lock tags lock nodes in the global so that the screen is
     130 ;refreshed in real-time. The lock forces the buffer to be refreshed,
     131 ;so that the display is up to date.
     132 ;
     133 ;**109**
     134 ;L +^HLCS(870,HLXX,0):0 L -^HLCS(870,HLXX,0) D CHKLOCK
     135 ;
     136 ; Set, even if not able to lock...
     137 S Y=$G(^HLCS(870,HLXX,0))
     138 ;
     139 ;name^rec^proc^send^sent^device^state^error
     140 S HLARYD(HLYY)=$P(Y,U)_"^^^^^"_$P(Y,U,4)_"^"_$P(Y,U,5)_"^"_$P(Y,U,19)
     141 ;
     142 ;**109**
     143 ;L +^HLCS(870,HLXX,"IN QUEUE BACK POINTER"):0 D CHKLOCK
     144 ;L -^HLCS(870,HLXX,"IN QUEUE BACK POINTER")
     145 ;
     146 S $P(HLARYD(HLYY),U,2)=$G(^HLCS(870,HLXX,"IN QUEUE BACK POINTER"))
     147 ;
     148 ;**109**
     149 ;L +^HLCS(870,HLXX,"IN QUEUE FRONT POINTER"):0 D CHKLOCK
     150 ;L -^HLCS(870,HLXX,"IN QUEUE FRONT POINTER")
     151 ;
     152 S $P(HLARYD(HLYY),U,3)=$G(^HLCS(870,HLXX,"IN QUEUE FRONT POINTER"))
     153 ;
     154 ;**109**
     155 ;L +^HLCS(870,HLXX,"OUT QUEUE BACK POINTER"):0 D CHKLOCK
     156 ;L -^HLCS(870,HLXX,"OUT QUEUE BACK POINTER")
     157 ;
     158 S $P(HLARYD(HLYY),U,4)=$G(^HLCS(870,HLXX,"OUT QUEUE BACK POINTER"))
     159 ;
     160 ;**109**
     161 ;L +^HLCS(870,HLXX,"OUT QUEUE FRONT POINTER"):0 D CHKLOCK
     162 ;L -^HLCS(870,HLXX,"OUT QUEUE FRONT POINTER")
     163 ;
     164 S $P(HLARYD(HLYY),U,5)=$G(^HLCS(870,HLXX,"OUT QUEUE FRONT POINTER"))
     165 ;
     166 S X=HLARYD(HLYY),Y=$P(X,U,2)+$P(X,U,3)+$P(X,U,4)+$P(X,U,5)
     167 ;if Select and the Y=0, nothing to report
     168 I 'Y,HLDISP="S" S HLARYD(HLYY)="" Q
     169 S HLYY=HLYY+1
     170 Q
     171 ;
     172CHKLOCK ; Call here immediately after trying to lock.  And, BE SURE that
     173 ; nothing might occur that would change $T after the lock attempt!!
     174 ; $T,HLXX -- req
     175 N NM870
     176 QUIT:$T  ;-> Lock obtained...
     177 S NM870=$P($G(^HLCS(870,+HLXX,0)),U)
     178 S NM870=$S(NM870]"":NM870_" (IEN #"_HLXX_")",1:"IEN #"_HLXX)
     179 S HLOCK(NM870)=""
     180 QUIT
     181 ;
     182HELP ;
     183 W HLCON,@IOF
     184 W !,"You have the following options when monitoring the Messaging System:"
     185 W !,"Enter the command letter parentheses: N,B,Q,A,S,V or ?"
     186 W !!,"(N) takes you to the next page of the display of Logical Links."
     187 W !!,"(B) takes you back one page."
     188 W !!,"(Q) terminates the monitor."
     189 W !!,"(A) provides a display of all links defined on your system."
     190 W !!,"(S) displays only those links that have had message traffic."
     191 W !!,"(V) prompts for a view name and displays links defined in view."
     192 W !!,"    Note that (S) is the default display at startup."
     193 W !!,"**PRESS <RET> TO CONTINUE**"
     194 R X:DTIME
     195 W @IOF
     196 W !,?25,"Device Types and corresponding prefixes:"
     197 W !!,?30,"PC -- Persistent TCP/IP Client"
     198 W !!,?30,"NC -- Non-Persistent TCP/IP Client"
     199 W !!,?30,"SS -- Single-threaded TCP/IP Server"
     200 W !!,?30,"MS -- Multi-threaded TCP/IP Server"
     201 W !!,?30,"SH -- Serial HLLP"
     202 W !!,?30,"SX -- Serial X3.28"
     203 W !!,?30,"MM -- MailMan"
     204 W !!,"**PRESS <RET> TO CONTINUE**"
     205 R X:DTIME
     206 W HLCOFF
     207 Q
     208EXIT ;
     209 ;Turn Cursor back on
     210 W HLCON
     211 D KVAR^HLCSTERM
     212 Q
     213 ;
     214LOCKED(HLOCK) ; Anything locked?
     215 ;
     216 ;
     217 ; Nothing locked...
     218 I '$D(HLOCK) QUIT "" ;->
     219 ;
     220 W !!,"Editing of logical link data is occurring right now.  For this reason, some of"
     221 W !,"the information on the 'System Link Monitor' report might not be accurate for"
     222 W !,"the following node(s)..."
     223 W !
     224 ;
     225 S HLOCK=""
     226 F  S HLOCK=$O(HLOCK(HLOCK)) Q:HLOCK']""  D
     227 .  W !,?5,HLOCK
     228 ;
     229 S ACTION=$$BTE("Press RETURN to print report or '^' to exit... ",1)
     230 ;
     231 QUIT $S(ACTION=1:1,1:"")
     232 ;
     233BTE(PMT,FF) ;
     234 N DIR,DIRUT,DTOUT,DUOUT,X,Y
     235 F X=1:1:$G(FF) W !
     236 S DIR(0)="EA",DIR("A")=PMT
     237 D ^DIR
     238 QUIT $S(Y=1:"",1:1)
     239 ;
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSMON1.m

    r613 r623  
    1 HLCSMON1        ;SF-Utilities for Driver Program  ;07/17/2007  17:05
    2         ;;1.6;HEALTH LEVEL SEVEN;**15,40,49,65,109,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;This routine contains several entry points called from HLCSMON
    6         ;no input parameters are required. All variables used which are
    7         ;not newed here are newed in HLCSMON
    8         ;
    9 DISPLAY ;display link info
    10         ;turn of line wrap
    11         S HLXX=0,X=0 X ^%ZOSF("RM")
    12         F  S HLXX=$O(HLARYD(HLXX)) Q:(HLXX'>0)  D WLINE(HLXX)
    13         ;DISPLAY INCOMING FILER STATUS
    14         ; patch HL*1.6*122
    15         S HLXX=$P(HLRUNCNT,"^",1)
    16         ; S HLXX=$$CNTFLR^HLCSUTL2("IN")
    17         I (+HLXX)=-1 S HLXX=$$CNTFLR^HLCSUTL2("IN")
    18         ;
    19         ;ONLY UPDATE SCREEN IF COUNT HAS CHANGED
    20         I (HLXX'=+HLRUNCNT) D
    21         .D WDATA(5,17,"","",$J(" ",31)),WDATA^HLCSMON1(5,17,"","","Incoming filers running => ",35)
    22         .I (HLXX) D WDATA(32,17,"","",HLXX)
    23         .I ('HLXX) D WDATA(32,17,IOINHI,IOINORM,"Zero")
    24         .S $P(HLRUNCNT,"^",1)=HLXX
    25         ;DISPLAY OUTGOING FILER STATUS
    26         ; patch HL*1.6*122
    27         S HLXX=$P(HLRUNCNT,"^",2)
    28         ; S HLXX=$$CNTFLR^HLCSUTL2("OUT")
    29         I (+HLXX)=-1 S HLXX=$$CNTFLR^HLCSUTL2("OUT")
    30         ;
    31         ;ONLY UPDATE SCREEN IF COUNT HAS CHANGED
    32         I (HLXX'=+$P(HLRUNCNT,"^",2)) D
    33         .D WDATA(5,18,"","",$J(" ",31)),WDATA^HLCSMON1(5,18,"","","Outgoing filers running => ",35)
    34         .I (HLXX) D WDATA(32,18,"","",HLXX)
    35         .I ('HLXX) D WDATA(32,18,IOINHI,IOINORM,"Zero")
    36         .S $P(HLRUNCNT,"^",2)=HLXX
    37         S X=$$TM^%ZTLOAD
    38         I X'=$G(HLTMSTAT) D
    39         .S HLTMSTAT=X
    40         .S HLXX=$S('HLTMSTAT:"***TASKMAN NOT RUNNING!!!***",1:"")
    41         .I 'HLTMSTAT D WDATA^HLCSMON1(45,17,IOELEOL_IOBON_IORVON,IOBOFF_IORVOFF,HLXX) I 1
    42         .E  D WDATA(45,17,IOELEOL,"",$J("TaskMan running ",16)) ;D WDATA(5,19,IOELALL,"","")
    43         S X=$$STAT^HLCSLM
    44         I X'=$G(HLLMSTAT) D
    45         .S HLLMSTAT=X Q:HLLMSTAT=3
    46         .S HLXX=$S('HLLMSTAT:"***LINK MANAGER NOT RUNNING!!!***",1:"")
    47         .I 'HLLMSTAT D WDATA^HLCSMON1(45,18,IOELEOL_IOBON_IORVON,IOBOFF_IORVOFF,HLXX) I 1
    48         .E  D WDATA^HLCSMON1(45,18,IOELEOL,"",$J("Link Manager running",18))
    49         ;Turn terminal line wrap back on
    50         D WDATA(45,19,IOELEOL,"",$$SLM^HLEVUTIL) ; HL*1.6*109
    51         S X=IOM X ^%ZOSF("RM")
    52         Q
    53         ;
    54 WLINE(HLXX)     ;write line from HLARYD=current values, HLARYO=old values
    55         ;if values haven't changed, don't do anything
    56         I HLARYD(HLXX)]"",HLARYD(HLXX)=$G(HLARYO(HLXX)) Q
    57         S HLARYO(HLXX)=HLARYD(HLXX),HLERR=$P(HLARYD(HLXX),U,8),DX=1
    58         ; patch HL*1.6*122
    59         ; F X=1:1:7 S @$P("HLNODE^HLREC^HLPROC^HLSEND^HLSENT^HLDEV^HLSTAT",U,X)=$E($P(HLARYD(HLXX),U,X)_"        ",1,8)
    60         F X=1,7 S @$P("HLNODE^HLREC^HLPROC^HLSEND^HLSENT^HLDEV^HLSTAT",U,X)=$E($P(HLARYD(HLXX),U,X)_"        ",1,10)
    61         F X=2:1:5 S @$P("HLNODE^HLREC^HLPROC^HLSEND^HLSENT^HLDEV^HLSTAT",U,X)=$E($P(HLARYD(HLXX),U,X)_"        ",1,8)
    62         S X=6,@$P("HLNODE^HLREC^HLPROC^HLSEND^HLSENT^HLDEV^HLSTAT",U,X)=$E($P(HLARYD(HLXX),U,X)_"        ",1,7)
    63         ;
    64         ;if link is in error, write node in rev. video
    65         I HLERR]"" D WDATA(5,HLXX,IOBON_IORVON,IOBOFF_IORVOFF,HLNODE,8) S DX=14
    66         ;Turn off terminal line wrap & inform O/S where cursor is located
    67         S DY=HLXX X IOXY,^%ZOSF("XY")
    68         ; patch HL*1.6*122
    69         W:HLERR="" ?4,HLNODE
    70         W ?16,HLREC,?26,HLPROC,?37,HLSEND,?47,HLSENT,?58,HLDEV,?63,HLSTAT
    71         ;
    72         Q
    73         ;
    74 WDATA(DX,DY,IO1,IO2,HLDATA,HLENGTH)     ;
    75         ;
    76         ;First erase the data block then write to it. Attributes are
    77         ;contained in IO1 & IO2
    78         ;
    79         N X S X=0 X ^%ZOSF("RM") X ^%ZOSF("XY")
    80         ;Turn off terminal line wrap & inform O/S where cursor is located
    81         I '$D(HLENGTH) S HLENGTH=$L(HLDATA)
    82         X IOXY W IOSC,$E($J(" ",79),1,HLENGTH),IORC W IO1,$E(HLDATA,1,HLENGTH),IO2
    83         S X=IOM X ^%ZOSF("RM")
    84         ;Turn terminal line wrap back on
    85         Q
     1HLCSMON1 ;SF-Utilities for Driver Program  ;02/04/2004  10:25
     2 ;;1.6;HEALTH LEVEL SEVEN;**15,40,49,65,109**;Oct 13, 1995
     3 ;
     4 ;This routine contains several entry points called from HLCSMON
     5 ;no input parameters are required. All variables used which are
     6 ;not newed here are newed in HLCSMON
     7 ;
     8DISPLAY ;display link info
     9 ;turn of line wrap
     10 S HLXX=0,X=0 X ^%ZOSF("RM")
     11 F  S HLXX=$O(HLARYD(HLXX)) Q:(HLXX'>0)  D WLINE(HLXX)
     12 ;DISPLAY INCOMING FILER STATUS
     13 S HLXX=$$CNTFLR^HLCSUTL2("IN")
     14 ;ONLY UPDATE SCREEN IF COUNT HAS CHANGED
     15 I (HLXX'=+HLRUNCNT) D
     16 .D WDATA(5,17,"","",$J(" ",31)),WDATA^HLCSMON1(5,17,"","","Incoming filers running => ",35)
     17 .I (HLXX) D WDATA(32,17,"","",HLXX)
     18 .I ('HLXX) D WDATA(32,17,IOINHI,IOINORM,"Zero")
     19 .S $P(HLRUNCNT,"^",1)=HLXX
     20 ;DISPLAY OUTGOING FILER STATUS
     21 S HLXX=$$CNTFLR^HLCSUTL2("OUT")
     22 ;ONLY UPDATE SCREEN IF COUNT HAS CHANGED
     23 I (HLXX'=+$P(HLRUNCNT,"^",2)) D
     24 .D WDATA(5,18,"","",$J(" ",31)),WDATA^HLCSMON1(5,18,"","","Outgoing filers running => ",35)
     25 .I (HLXX) D WDATA(32,18,"","",HLXX)
     26 .I ('HLXX) D WDATA(32,18,IOINHI,IOINORM,"Zero")
     27 .S $P(HLRUNCNT,"^",2)=HLXX
     28 S X=$$TM^%ZTLOAD
     29 I X'=$G(HLTMSTAT) D
     30 .S HLTMSTAT=X
     31 .S HLXX=$S('HLTMSTAT:"***TASKMAN NOT RUNNING!!!***",1:"")
     32 .I 'HLTMSTAT D WDATA^HLCSMON1(45,17,IOELEOL_IOBON_IORVON,IOBOFF_IORVOFF,HLXX) I 1
     33 .E  D WDATA(45,17,IOELEOL,"",$J("TaskMan running ",16)) ;D WDATA(5,19,IOELALL,"","")
     34 S X=$$STAT^HLCSLM
     35 I X'=$G(HLLMSTAT) D
     36 .S HLLMSTAT=X Q:HLLMSTAT=3
     37 .S HLXX=$S('HLLMSTAT:"***LINK MANAGER NOT RUNNING!!!***",1:"")
     38 .I 'HLLMSTAT D WDATA^HLCSMON1(45,18,IOELEOL_IOBON_IORVON,IOBOFF_IORVOFF,HLXX) I 1
     39 .E  D WDATA^HLCSMON1(45,18,IOELEOL,"",$J("Link Manager running",18))
     40 ;Turn terminal line wrap back on
     41 D WDATA(45,19,IOELEOL,"",$$SLM^HLEVUTIL) ; HL*1.6*109
     42 S X=IOM X ^%ZOSF("RM")
     43 Q
     44 ;
     45WLINE(HLXX) ;write line from HLARYD=current values, HLARYO=old values
     46 ;if values haven't changed, don't do anything
     47 I HLARYD(HLXX)]"",HLARYD(HLXX)=$G(HLARYO(HLXX)) Q
     48 S HLARYO(HLXX)=HLARYD(HLXX),HLERR=$P(HLARYD(HLXX),U,8),DX=1
     49 F X=1:1:7 S @$P("HLNODE^HLREC^HLPROC^HLSEND^HLSENT^HLDEV^HLSTAT",U,X)=$E($P(HLARYD(HLXX),U,X)_"        ",1,8)
     50 ;if link is in error, write node in rev. video
     51 I HLERR]"" D WDATA(5,HLXX,IOBON_IORVON,IOBOFF_IORVOFF,HLNODE,8) S DX=14
     52 ;Turn off terminal line wrap & inform O/S where cursor is located
     53 S DY=HLXX X IOXY,^%ZOSF("XY")
     54 W:HLERR="" ?5,HLNODE
     55 W ?16,HLREC,?26,HLPROC,?37,HLSEND,?47,HLSENT,?58,HLDEV,?64,HLSTAT
     56 Q
     57 ;
     58WDATA(DX,DY,IO1,IO2,HLDATA,HLENGTH) ;
     59 ;
     60 ;First erase the data block then write to it. Attributes are
     61 ;contained in IO1 & IO2
     62 ;
     63 N X S X=0 X ^%ZOSF("RM") X ^%ZOSF("XY")
     64 ;Turn off terminal line wrap & inform O/S where cursor is located
     65 I '$D(HLENGTH) S HLENGTH=$L(HLDATA)
     66 X IOXY W IOSC,$E($J(" ",79),1,HLENGTH),IORC W IO1,$E(HLDATA,1,HLENGTH),IO2
     67 S X=IOM X ^%ZOSF("RM")
     68 ;Turn terminal line wrap back on
     69 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSREP.m

    r613 r623  
    1 HLCSREP ;ALB/MFK - HL7 QUEUE MANAGEMENT ;10/17/2007  08:56
    2         ;;1.6;HEALTH LEVEL SEVEN;**109,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 REPMSG  ;Duplicate messages on a queue
    6         ; INPUT:  MSG   - Array which contains the queue and the
    7         ;                 message numbers for msgs to be re-queued
    8         ;                 MSG(QUEUE,NUMBER)
    9         ; OUTPUT: NONE
    10         N DIC,LLE,X,Y,DA,ERROR,FROMID,MSGID
    11         N TOID,ENTRY,LLE
    12         Q:('$D(MSG))
    13         ;  create new entries
    14         S (LLE,ERROR)=""
    15         F  S LLE=$O(MSG(LLE)) Q:(LLE="")!(ERROR)  D
    16         .S ENTRY=""
    17         .F  S ENTRY=$O(MSG(LLE,ENTRY)) Q:(ENTRY="")!(ERROR)  D
    18         ..S MSGID=$$ENQUEUE^HLCSQUE(LLE,"OUT")
    19         ..I +MSGID'>0 S ERROR=1 Q
    20         ..S TOID=$P(MSGID,"^",2)
    21         ..M ^HLCS(870,LLE,2,TOID)=^HLCS(870,LLE,2,ENTRY)
    22         ..;  Change .01 of new record to be IEN
    23         ..S $P(^HLCS(870,LLE,2,TOID,0),"^",1)=TOID
    24         ..S $P(^HLCS(870,LLE,2,TOID,0),"^",2)="P"
    25 EXIT    ;
    26         Q
    27         ;
    28 ENQUE(LINK,DIR,IEN773)  ;
    29         ;This routine will place the message=IEN773 on the "AC" xref of file 773.
    30         ;Input:
    31         ;  DIR = "I" or "O", denoting the direction that the message is going in
    32         ;  LINK = the ien of the logical link
    33         ;  IEN773 = ien of the message in file 773
    34         ;
    35         Q:'$G(LINK)
    36         I DIR'="I",DIR'="O" Q
    37         Q:'$G(IEN773)
    38         ;
    39         ; patch HL*1.6*122: MPI-client/server
    40         F  L +^HLMA("AC",DIR,LINK,IEN773):10 Q:$T  H 1
    41         S ^HLMA("AC",DIR,LINK,IEN773)=""
    42         L -^HLMA("AC",DIR,LINK,IEN773)
    43         ;
    44         S $P(^HLMA(+IEN773,0),U,17)=+LINK ; HL*1.6*109 - lja
    45         I DIR="O" D LLCNT^HLCSTCP(LINK,3)
    46         Q
    47         ;
    48 DEQUE(LINK,DIR,IEN773)  ;
    49         ;This routine will remove the message=IEN773 on the "AC" xref of file 773.
    50         ;Input:
    51         ;  DIR = "I" or "O", denoting the direction that the message is going in
    52         ;  LINK = the ien of the logical link
    53         ;  IEN773 = ien of the message in file 773
    54         ;
    55         Q:'$G(LINK)
    56         I DIR'="I",DIR'="O" Q
    57         Q:'$G(IEN773)
    58         ;
    59         ; patch HL*1.6*122: MPI-client/server
    60         F  L +^HLMA("AC",DIR,LINK,IEN773):10 Q:$T  H 1
    61         K ^HLMA("AC",DIR,LINK,IEN773)
    62         L -^HLMA("AC",DIR,LINK,IEN773)
    63         ;
    64         Q
     1HLCSREP ;ALB/MFK - HL7 QUEUE MANAGEMENT - 10/4/94 1pm
     2 ;;1.6;HEALTH LEVEL SEVEN;**109**;Oct 13, 1995
     3REPMSG ;Duplicate messages on a queue
     4 ; INPUT:  MSG   - Array which contains the queue and the
     5 ;                 message numbers for msgs to be re-queued
     6 ;                 MSG(QUEUE,NUMBER)
     7 ; OUTPUT: NONE
     8 N DIC,LLE,X,Y,DA,ERROR,FROMID,MSGID
     9 N TOID,ENTRY,LLE
     10 Q:('$D(MSG))
     11 ;  create new entries
     12 S (LLE,ERROR)=""
     13 F  S LLE=$O(MSG(LLE)) Q:(LLE="")!(ERROR)  D
     14 .S ENTRY=""
     15 .F  S ENTRY=$O(MSG(LLE,ENTRY)) Q:(ENTRY="")!(ERROR)  D
     16 ..S MSGID=$$ENQUEUE^HLCSQUE(LLE,"OUT")
     17 ..I +MSGID'>0 S ERROR=1 Q
     18 ..S TOID=$P(MSGID,"^",2)
     19 ..M ^HLCS(870,LLE,2,TOID)=^HLCS(870,LLE,2,ENTRY)
     20 ..;  Change .01 of new record to be IEN
     21 ..S $P(^HLCS(870,LLE,2,TOID,0),"^",1)=TOID
     22 ..S $P(^HLCS(870,LLE,2,TOID,0),"^",2)="P"
     23EXIT ;
     24 Q
     25 ;
     26ENQUE(LINK,DIR,IEN773) ;
     27 ;This routine will place the message=IEN773 on the "AC" xref of file 773.
     28 ;Input:
     29 ;  DIR = "I" or "O", denoting the direction that the message is going in
     30 ;  LINK = the ien of the logical link
     31 ;  IEN773 = ien of the message in file 773
     32 ;
     33 Q:'$G(LINK)
     34 I DIR'="I",DIR'="O" Q
     35 Q:'$G(IEN773)
     36 S ^HLMA("AC",DIR,LINK,IEN773)=""
     37 S $P(^HLMA(+IEN773,0),U,17)=+LINK ; HL*1.6*109 - lja
     38 I DIR="O" D LLCNT^HLCSTCP(LINK,3)
     39 Q
     40 ;
     41DEQUE(LINK,DIR,IEN773) ;
     42 ;This routine will remove the message=IEN773 on the "AC" xref of file 773.
     43 ;Input:
     44 ;  DIR = "I" or "O", denoting the direction that the message is going in
     45 ;  LINK = the ien of the logical link
     46 ;  IEN773 = ien of the message in file 773
     47 ;
     48 Q:'$G(LINK)
     49 I DIR'="I",DIR'="O" Q
     50 Q:'$G(IEN773)
     51 K ^HLMA("AC",DIR,LINK,IEN773)
     52 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSTCP.m

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

    r613 r623  
    1 HLCSTCP1        ;SFIRMFO/RSD - BI-DIRECTIONAL TCP ;04/15/08  11:11
    2         ;;1.6;HEALTH LEVEL SEVEN;**19,43,57,64,71,133,132,122,140**;OCT 13,1995;Build 5
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;Receiver
    5         ;connection is initiated by sender and listener accepts connection
    6         ;and calls this routine
    7         ;
    8         N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP1"
    9         N HLMIEN,HLASTMSG
    10         ;
    11         ; patch HL*1.6*140, save IO
    12         S HLTCPORT("IO")=IO ;RWF
    13         ; patch HL*1.6*122 start
    14         ; variable to replace ^TMP
    15         N HLTMBUF
    16         ;
    17         ; for HL7 application proxy user
    18         ;; N HLDUZ,DUZ  ; patch HL*1.6*122 TEST v2: DUZ code removed
    19         N HLDUZ
    20         S HLDUZ=+$G(DUZ)
    21         ;
    22         D MON^HLCSTCP("Open")
    23         ; K ^TMP("HLCSTCP",$J,0)
    24         S HLMIEN=0,HLASTMSG=""
    25         ;
    26         ; patch HL*1.6*122 TEST v2: DUZ code removed
    27         ; set DUZ for application proxy user
    28         ;; D PROXY^HLCSTCP4
    29         ;
    30         F  D  Q:$$STOP^HLCSTCP  I 'HLMIEN D MON^HLCSTCP("Idle") H 3
    31         . ; clean variables
    32         . D CLEANVAR^HLCSTCP4
    33         . ; patch HL*1.6*140, restore the saved IO
    34         . S IO=HLTCPORT("IO") ;RWF
    35         . S HLMIEN=$$READ
    36         . Q:'HLMIEN
    37         . ;
    38         . ; patch HL*1.6*122 TEST v2: DUZ code removed
    39         . ; DUZ comparison/reset for application proxy user
    40         . ;; D HLDUZ^HLCSTCP4
    41         . D HLDUZ2^HLCSTCP4
    42         . ; protect HLDUZ
    43         . N HLDUZ
    44         . D PROCESS
    45         ; patch HL*1.6*122 end
    46         Q
    47         ;
    48 PROCESS ;check message and reply
    49         ;HLDP=LL in 870
    50         N HLTCP,HLTCPI,HLTCPO
    51         S HLTCP="",HLTCPO=HLDP,HLTCPI=+HLMIEN
    52         ;update monitor, msg. received
    53         D LLCNT^HLCSTCP(HLDP,1)
    54         D NEW^HLTP3(HLMIEN)
    55         ;I IO'=HLTCPORT("IO") D ^%ZTER ;RWF
    56         ;update monitor, msg. processed
    57         D LLCNT^HLCSTCP(HLDP,2)
    58         Q
    59         ;
    60 READ()  ;read 1 message, returns ien in 773^ien in 772 for message
    61         D MON^HLCSTCP("Reading")
    62         N HLDB,HLDT,HLDEND,HLACKWT,HLDSTRT,HLHDR,HLIND1,HLINE,HLMSG,HLRDOUT,HLRS,HLX,X
    63         ;HLDSTRT=start char., HLDEND=end char., HLRS=record separator
    64         S HLDSTRT=$C(11),HLDEND=$C(28),HLRS=$C(13)
    65         ;HLRDOUT=exit read loop, HLINE=line count, HLIND1=ien 773^ien 772
    66         ;HLHDR=have a header, HLTMBUF()=excess from last read, HLACKWT=wait for ack
    67         ; HL*1.6*122 start
    68         ; S (HLRDOUT,HLINE,HLIND1,HLHDR)=0,HLX=$G(^TMP("HLCSTCP",$J,0)),HLACKWT=HLDBACK
    69         S (HLRDOUT,HLINE,HLIND1,HLHDR)=0,HLX=$G(HLTMBUF(0)),HLACKWT=HLDBACK
    70         N HLBUFF,HLXX,MAXWAIT
    71         ; based on patch 132 for readtime
    72         S MAXWAIT=$S((HLACKWT>HLDREAD):HLACKWT,1:HLDREAD)
    73         S HLRS("START-FLAG")=0
    74         S HLTMBUF(0)=""
    75         ; variable used to store data in HLBUFF
    76         S HLX(1)=$G(HLTMBUF(1))
    77         S HLTMBUF(1)=""
    78         S HLBUFF("START")=0
    79         S HLBUFF("END")=0
    80         I (HLX]"")!(HLX(1)]"") D
    81         . I (HLX[HLDSTRT)!(HLX(1)[HLDSTRT) D
    82         .. S HLBUFF("START")=1
    83         . I (HLX[HLDEND)!(HLX(1)[HLDEND) D
    84         .. S HLBUFF("END")=1
    85         F  D RDBLK Q:HLRDOUT
    86         ;**132**
    87         ;switch to null device if opened to prevent 'leakage'
    88         I $G(IO(0))]"",IO(0)'=IO U IO(0)
    89         ;
    90         ;save any excess for next time
    91         S:HLX]"" HLTMBUF(0)=HLX
    92         S:HLX(1)]"" HLTMBUF(1)=HLX(1)
    93         I +HLIND1,'$P(HLIND1,U,3) D DELMSG(HLIND1) S HLIND1=0
    94         Q HLIND1
    95         ;
    96 RDBLK   ;
    97         ; initialize
    98         S HLBUFF=""
    99         ;
    100         ;S HLDB=HLDBSIZE-$L(HLX)
    101         ; store the total length of HLX and HLX(1) in HLDB(1)
    102         S HLDB(1)=$L(HLX)+$L(HLX(1))
    103         ;
    104         ;**132 **
    105         ;U IO R X#HLDB:HLDREAD
    106         ; U IO R X#HLDB:MAXWAIT
    107         ;
    108         ; remove the readcount to speedup GT.M
    109         U IO
    110         R:(HLDB(1)<HLDBSIZE) HLBUFF:MAXWAIT
    111         ;
    112         I HLBUFF]"" D
    113         . I HLBUFF[HLDSTRT,(HLBUFF("START")=0) D
    114         .. ; remove the extraneous text prefixing the "START" char
    115         .. I $P(HLBUFF,HLDSTRT)]"" S HLBUFF=HLDSTRT_$P(HLBUFF,HLDSTRT,2,99)
    116         .. S HLBUFF("START")=1
    117         . ;
    118         . I HLBUFF[HLDEND,(HLBUFF("END")=0) S HLBUFF("END")=1
    119         ; detect disconnect for GT.M
    120         I $G(^%ZOSF("OS"))["GT.M",$DEVICE S $ECODE=",UREAD,"
    121         ; timedout, <clean up>, quit
    122         ;I '$T,X="",HLX="" S HLACKWT=HLACKWT-HLDREAD D:HLACKWT<0&'HLHDR CLEAN Q
    123         ;I '$T,X="",HLX="" D:'HLHDR CLEAN Q
    124         ; patch HL*1.6*140
    125         ; I '$T,HLBUFF="",HLX="",HLX(1)="" D  Q
    126         I HLBUFF="",HLX="",HLX(1)="" D  Q
    127         . D:('HLHDR)&('HLIND1) CLEAN
    128         ;add incoming line to what wasn't processed in last read
    129         ;S HLX=$G(HLX)_X
    130         ; get block of characters from read buffer HLBUFF
    131         ; every 'for-loop' deal with one read at most, and one message at most
    132         ; if HLX is not empty, loop continues even no data is read
    133         ; quit, if both HLDBUFF and HLX(1) are empty, means one read is done
    134         ; quit, when HLRDOUT is set to 1, means one message is encountered
    135         ; an "end"
    136         ; F  D  Q:HLXX=""!(HLRDOUT)
    137         F  D  Q:(HLRDOUT)!(HLBUFF=""&(HLX(1)=""))
    138         . ;
    139         . ; if HLX(1) is not empty
    140         . I HLX(1)]"" D
    141         .. ; hldb(2) is the number of characters extracted from hlx(1)
    142         .. ; to be concatenated with hlx
    143         .. S HLDB(2)=HLDBSIZE-$L(HLX)
    144         .. ; hlx(2) stores the first hldb(2) characters extracted
    145         .. ; from hlx(1)
    146         .. S HLX(2)=$E(HLX(1),1,HLDB(2))
    147         .. S HLX(1)=$E(HLX(1),HLDB(2)+1,$L(HLX(1)))
    148         .. S HLX=$G(HLX)_HLX(2)
    149         . ;
    150         . ; if HLX(1) is empty, and HLBUFF contains data
    151         . ; all the data in hlx(1) need to be extracted first
    152         . I HLX(1)="",HLBUFF]"" D
    153         .. S HLDB=HLDBSIZE-$L(HLX)
    154         .. S HLXX=$E(HLBUFF,1,HLDB)
    155         .. S HLBUFF=$E(HLBUFF,HLDB+1,$L(HLBUFF))
    156         .. S HLX=$G(HLX)_HLXX
    157         . ; quit when HLX is empty
    158         . Q:(HLX="")
    159         . ; ** 132 **
    160         . ; if no segment end, HLX not full, go back for more
    161         . I $L(HLX)<HLDBSIZE,HLX'[HLRS,HLX'[HLDEND Q
    162         . ;add incoming line to what wasn't processed
    163         . D RDBLK2
    164         ;
    165         ; it is possible one message is encountered an "end" and other
    166         ; messages left in buffer,HLBUFF, save it in HLX for next run
    167         I HLBUFF]"" D
    168         . ; variable HLBUFF may remain data with size more than HLDBSIZE
    169         . ; variable HLBUFF is not empty, only if the total length of
    170         . ; HLX and HLX(1) is less than HLDBSIZE and HLX(1) should be
    171         . ; empty when the command s hlx(1)=$g(hlx(1))_hlbuff is executed
    172         . ; use hlx(1) to store the data of hlbuff to avoid "MAXTRING" error
    173         . S HLX(1)=$G(HLX(1))_HLBUFF
    174         . S HLBUFF=""
    175         Q
    176         ;
    177 RDBLK2  ;data stream: <sb>dddd<cr><eb><cr>
    178         ; HL*1.6*122 end
    179         ; look for segment= <CR>
    180         F  Q:HLX'[HLRS  D  Q:HLRDOUT
    181         . ; Get the first piece, save the rest of the line
    182         . S HLINE=HLINE+1,HLMSG(HLINE,0)=$P(HLX,HLRS),HLX=$P(HLX,HLRS,2,999)
    183         . ; check for start block, Quit if no ien
    184         . I HLMSG(HLINE,0)[HLDSTRT!HLHDR D  Q
    185         .. S HLRS("START-FLAG")=1 ; HL*1.6*122
    186         .. D:HLMSG(HLINE,0)[HLDSTRT
    187         ... S X=$L(HLMSG(HLINE,0),HLDSTRT)
    188         ... S:X>2 HLMSG(HLINE,0)=HLDSTRT_$P(HLMSG(HLINE,0),HLDSTRT,X)
    189         ... S HLMSG(HLINE,0)=$P(HLMSG(HLINE,0),HLDSTRT,2)
    190         ... D RESET:(HLINE>1)
    191         .. ;
    192         .. ; patch HL*1.6*122
    193         .. ; if the first line less than 10 characters
    194         .. I HLHDR,$L(HLMSG(1,0))<10,$D(HLMSG(2,0)) D
    195         ... S HLMSG(1,0)=HLMSG(1,0)_$E(HLMSG(2,0),1,10)
    196         ... S HLMSG(2,0)=$E(HLMSG(2,0),11,9999999)
    197         .. ;
    198         .. ;ping message
    199         .. I $E(HLMSG(1,0),1,9)="MSH^PING^" D PING Q
    200         .. ; get next ien to store
    201         .. D MIEN^HLCSTCP4
    202         .. K HLMSG
    203         .. S (HLINE,HLHDR)=0
    204         . ; check for end block; <eb><cr>
    205         . I HLMSG(HLINE,0)[HLDEND D
    206         .. ; patch HL*1.6*122 start
    207         .. ;no msg. ien
    208         .. ; Q:'HLIND1
    209         .. I 'HLIND1 D CLEAN Q
    210         .. ; Kill just the last line if no data before HLDEND
    211         .. I $P(HLMSG(HLINE,0),HLDEND)']"" D
    212         ... K HLMSG(HLINE,0) S HLINE=HLINE-1
    213         .. E  S HLMSG(HLINE,0)=$P(HLMSG(HLINE,0),HLDEND)
    214         .. ; patch HL*1.6*122 end
    215         .. ;
    216         .. ; move into 772
    217         .. D SAVE(.HLMSG,"^HL(772,"_+$P(HLIND1,U,2)_",""IN"")")
    218         .. ;mark that end block has been received
    219         .. ;HLIND1=ien in 773^ien in 772^1 if end block was received
    220         .. S $P(HLIND1,U,3)=1
    221         .. S HLBUFF("HLIND1")=HLIND1
    222         .. ;reset variables for next message
    223         .. D CLEAN
    224         . ;add blank line for carriage return
    225         . I HLINE'=0,HLMSG(HLINE,0)]"" S HLINE=HLINE+1,HLMSG(HLINE,0)=""
    226         Q:HLRDOUT
    227         ;If the line is long and no <CR> move it into the array.
    228         I ($L(HLX)=HLDBSIZE),(HLX'[HLRS),(HLX'[HLDEND),(HLX'[HLDSTRT) D  Q
    229         . S HLINE=HLINE+1,HLMSG(HLINE,0)=HLX,HLX=""
    230         ;have start block but no record separator
    231         I HLX[HLDSTRT D  Q
    232         . ;check for more than 1 start block
    233         . S X=$L(HLX,HLDSTRT) S:X>2 HLX=HLDSTRT_$P(HLX,HLDSTRT,X)
    234         . ;
    235         . ; patch HL*1.6*122
    236         . ; S:$L($P(HLX,HLDSTRT,2))>8 HLINE=HLINE+1,HLMSG(HLINE,0)=$P(HLX,HLDSTRT,2),HLX="",HLHDR=1
    237         . S HLINE=HLINE+1,HLMSG(HLINE,0)=$P(HLX,HLDSTRT,2),HLX="",HLHDR=1
    238         . ;
    239         . D RESET:(HLHDR&(HLINE>1))
    240         ;if no ien, reset
    241         ; patch HL*1.6*122
    242         ; I 'HLIND1 D CLEAN Q
    243         I (HLRS("START-FLAG")=1),'HLIND1 D CLEAN Q
    244         ; big message-merge from local to global every 100 lines
    245         I (HLINE-$O(HLMSG(0)))>100 D
    246         . M ^HL(772,+$P(HLIND1,U,2),"IN")=HLMSG
    247         . ; reset working array
    248         . K HLMSG
    249         Q
    250         ;
    251 SAVE(SRC,DEST)  ;save into global & set top node
    252         ;SRC=source array (passed by ref.), DEST=destination global
    253         ;
    254         ; patch HL*1.6*122: MPI-client/server
    255         I DEST["HLMA" D
    256         . F  L +^HLMA(+HLIND1):10 Q:$T  H 1
    257         E  D
    258         . F  L +^HL(772,+$P(HLIND1,U,2)):10 Q:$T  H 1
    259         ;
    260         M @DEST=SRC
    261         S @DEST@(0)="^^"_HLINE_"^"_HLINE_"^"_DT_"^"
    262         ;
    263         I DEST["HLMA" L -^HLMA(+HLIND1)
    264         E  L -^HL(772,+$P(HLIND1,U,2))
    265         ;
    266         Q
    267         ;
    268 DELMSG(HLMAMT)  ;delete message from Message Administration/Message Text files.
    269         N DIK,DA
    270         S DA=+HLMAMT,DIK="^HLMA("
    271         D ^DIK
    272         S DA=$P(HLMAMT,U,2),DIK="^HL(772,"
    273         D ^DIK
    274         Q
    275 PING    ;process PING message
    276         S X=HLMSG(1,0)
    277         ; patch HL*1.6*140, flush character- HLTCPLNK("IOF")
    278         ; I X[HLDEND U IO W X,! D
    279         I X[HLDEND U IO W X,HLTCPLNK("IOF") D
    280         . ; switch to null device if opened to prevent 'leakage'
    281         . I $G(IO(0))]"",$G(IO(0))'=IO U IO(0)
    282 CLEAN   ;reset var. for next message
    283         K HLMSG
    284         S HLINE=0,HLRDOUT=1
    285         Q
    286         ;
    287 ERROR   ; Error trap for disconnect error and return back to the read loop.
    288         ; patch HL*1.6*122
    289         ; move to routine HLCSTCP4 (splitted-size over 10000)
    290         D ERROR1^HLCSTCP4
    291         Q
    292         ;
    293 CC(X)   ;cleanup and close
    294         D MON^HLCSTCP(X)
    295         H 2
    296         Q
    297 RESET   ;reset info as a result of no end block
    298         N %
    299         S HLMSG(1,0)=HLMSG(HLINE,0)
    300         F %=2:1:HLINE K HLMSG(%,0)
    301         S HLINE=1
    302         Q
     1HLCSTCP1 ;SFIRMFO/RSD - BI-DIRECTIONAL TCP ;7/28/07  08:58
     2 ;;1.6;HEALTH LEVEL SEVEN;**19,43,57,64,71,133,132,122**;OCT 13,1995;Build 4
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;Receiver
     5 ;connection is initiated by sender and listener accepts connection
     6 ;and calls this routine
     7 ;
     8 N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP1"
     9 N HLMIEN,HLASTMSG
     10 ;
     11 ; patch HL*1.6*122 start
     12 ; variable to replace ^TMP
     13 N HLTMBUF
     14 ; for HL7 application proxy user
     15 N HLDUZ,DUZ
     16 D MON^HLCSTCP("Open")
     17 ; K ^TMP("HLCSTCP",$J,0)
     18 S HLMIEN=0,HLASTMSG=""
     19 ; set DUZ for application proxy user
     20 D PROXY^HLCSTCP4
     21 F  D  Q:$$STOP^HLCSTCP  I 'HLMIEN D MON^HLCSTCP("Idle") H 3
     22 . ; clean variables
     23 . D CLEANVAR^HLCSTCP4
     24 . S HLMIEN=$$READ
     25 . Q:'HLMIEN
     26 . ; DUZ comparison/reset for application proxy user
     27 . D HLDUZ^HLCSTCP4
     28 . ; protect HLDUZ
     29 . N HLDUZ
     30 . D PROCESS
     31 ; patch HL*1.6*122 end
     32 Q
     33 ;
     34PROCESS ;check message and reply
     35 ;HLDP=LL in 870
     36 N HLTCP,HLTCPI,HLTCPO
     37 S HLTCP="",HLTCPO=HLDP,HLTCPI=+HLMIEN
     38 ;update monitor, msg. received
     39 D LLCNT^HLCSTCP(HLDP,1)
     40 D NEW^HLTP3(HLMIEN)
     41 ;update monitor, msg. processed
     42 D LLCNT^HLCSTCP(HLDP,2)
     43 Q
     44 ;
     45READ() ;read 1 message, returns ien in 773^ien in 772 for message
     46 D MON^HLCSTCP("Reading")
     47 N HLDB,HLDT,HLDEND,HLACKWT,HLDSTRT,HLHDR,HLIND1,HLINE,HLMSG,HLRDOUT,HLRS,HLX,X
     48 ;HLDSTRT=start char., HLDEND=end char., HLRS=record seperator
     49 S HLDSTRT=$C(11),HLDEND=$C(28),HLRS=$C(13)
     50 ;HLRDOUT=exit read loop, HLINE=line count, HLIND1=ien 773^ien 772
     51 ;HLHDR=have a header, HLTMBUF()=excess from last read, HLACKWT=wait for ack
     52 ; HL*1.6*122 start
     53 ; S (HLRDOUT,HLINE,HLIND1,HLHDR)=0,HLX=$G(^TMP("HLCSTCP",$J,0)),HLACKWT=HLDBACK
     54 S (HLRDOUT,HLINE,HLIND1,HLHDR)=0,HLX=$G(HLTMBUF(0)),HLACKWT=HLDBACK
     55 N HLBUFF,HLXX,MAXWAIT
     56 ; based on patch 132 for readtime
     57 S MAXWAIT=$S((HLACKWT>HLDREAD):HLACKWT,1:HLDREAD)
     58 S HLRS("START-FLAG")=0
     59 S HLTMBUF(0)=""
     60 ; variable used to store data in HLBUFF
     61 S HLX(1)=$G(HLTMBUF(1))
     62 S HLTMBUF(1)=""
     63 S HLBUFF("START")=0
     64 S HLBUFF("END")=0
     65 I (HLX]"")!(HLX(1)]"") D
     66 . I (HLX[HLDSTRT)!(HLX(1)[HLDSTRT) D
     67 .. S HLBUFF("START")=1
     68 . I (HLX[HLDEND)!(HLX(1)[HLDEND) D
     69 .. S HLBUFF("END")=1
     70 F  D RDBLK Q:HLRDOUT
     71 ;**132**
     72 ;switch to null device if opened to prevent 'leakage'
     73 I $G(IO(0))]"",IO(0)'=IO U IO(0)
     74 ;
     75 ;save any excess for next time
     76 S:HLX]"" HLTMBUF(0)=HLX
     77 S:HLX(1)]"" HLTMBUF(1)=HLX(1)
     78 I +HLIND1,'$P(HLIND1,U,3) D DELMSG(HLIND1) S HLIND1=0
     79 Q HLIND1
     80 ;
     81RDBLK ;
     82 ; initialize
     83 S HLBUFF=""
     84 ;
     85 ;S HLDB=HLDBSIZE-$L(HLX)
     86 ; store the total length of HLX and HLX(1) in HLDB(1)
     87 S HLDB(1)=$L(HLX)+$L(HLX(1))
     88 ;
     89 ;**132 **
     90 ;U IO R X#HLDB:HLDREAD
     91 ; U IO R X#HLDB:MAXWAIT
     92 ;
     93 ; remove the readcount to speedup GT.M
     94 U IO
     95 R:(HLDB(1)<HLDBSIZE) HLBUFF:MAXWAIT
     96 I HLBUFF]"" D
     97 . I HLBUFF[HLDSTRT,(HLBUFF("START")=0) D
     98 .. ; remove the extraneous text prefixing the "START" char
     99 .. I $P(HLBUFF,HLDSTRT)]"" S HLBUFF=HLDSTRT_$P(HLBUFF,HLDSTRT,2,99)
     100 .. S HLBUFF("START")=1
     101 . ;
     102 . I HLBUFF[HLDEND,(HLBUFF("END")=0) S HLBUFF("END")=1
     103 ; detect disconnect for GT.M
     104 I $G(^%ZOSF("OS"))["GT.M",$DEVICE S $ECODE=""
     105 ; timedout, <clean up>, quit
     106 ;I '$T,X="",HLX="" S HLACKWT=HLACKWT-HLDREAD D:HLACKWT<0&'HLHDR CLEAN Q
     107 ;I '$T,X="",HLX="" D:'HLHDR CLEAN Q
     108 I '$T,HLBUFF="",HLX="",HLX(1)="" D  Q
     109 . D:('HLHDR)&('HLIND1) CLEAN
     110 ;add incoming line to what wasn't processed in last read
     111 ;S HLX=$G(HLX)_X
     112 ;
     113 ; get block of characters from read buffer HLBUFF
     114 ; every 'for-loop' deal with one read at most, and one message at most
     115 ; if HLX is not empty, loop continues even no data is read
     116 ; quit, if both HLDBUFF and HLX(1) are empty, means one read is done
     117 ; quit, when HLRDOUT is set to 1, means one message is encountered
     118 ; an "end"
     119 ; F  D  Q:HLXX=""!(HLRDOUT)
     120 F  D  Q:(HLRDOUT)!(HLBUFF=""&(HLX(1)=""))
     121 . ;
     122 . ; if HLX(1) is not empty
     123 . I HLX(1)]"" D
     124 .. ; hldb(2) is the number of characters extracted from hlx(1)
     125 .. ; to be concatenated with hlx
     126 .. S HLDB(2)=HLDBSIZE-$L(HLX)
     127 .. ; hlx(2) stores the first hldb(2) characters extracted
     128 .. ; from hlx(1)
     129 .. S HLX(2)=$E(HLX(1),1,HLDB(2))
     130 .. S HLX(1)=$E(HLX(1),HLDB(2)+1,$L(HLX(1)))
     131 .. S HLX=$G(HLX)_HLX(2)
     132 . ;
     133 . ; if HLX(1) is empty, and HLBUFF contains data
     134 . ; all the data in hlx(1) need to be extracted first
     135 . I HLX(1)="",HLBUFF]"" D
     136 .. S HLDB=HLDBSIZE-$L(HLX)
     137 .. S HLXX=$E(HLBUFF,1,HLDB)
     138 .. S HLBUFF=$E(HLBUFF,HLDB+1,$L(HLBUFF))
     139 .. S HLX=$G(HLX)_HLXX
     140 . ; quit when HLX is empty
     141 . Q:(HLX="")
     142 . ; ** 132 **
     143 . ; if no segment end, HLX not full, go back for more
     144 . I $L(HLX)<HLDBSIZE,HLX'[HLRS,HLX'[HLDEND Q
     145 . ;add incoming line to what wasn't processed
     146 . D RDBLK2
     147 ;
     148 ; it is possible one message is encountered an "end" and other
     149 ; messages left in buffer,HLBUFF, save it in HLX for next run
     150 I HLBUFF]"" D
     151 . ; variable HLBUFF may remain data with size more than HLDBSIZE
     152 . ; variable HLBUFF is not empty, only if the total length of
     153 . ; HLX and HLX(1) is less than HLDBSIZE and HLX(1) should be
     154 . ; empty when the command s hlx(1)=$g(hlx(1))_hlbuff is executed
     155 . ; use hlx(1) to store the data of hlbuff to avoid "MAXTRING" error
     156 . S HLX(1)=$G(HLX(1))_HLBUFF
     157 . S HLBUFF=""
     158 Q
     159 ;
     160RDBLK2 ;data stream: <sb>dddd<cr><eb><cr>
     161 ; HL*1.6*122 end
     162 ; look for segment= <CR>
     163 F  Q:HLX'[HLRS  D  Q:HLRDOUT
     164 . ; Get the first piece, save the rest of the line
     165 . S HLINE=HLINE+1,HLMSG(HLINE,0)=$P(HLX,HLRS),HLX=$P(HLX,HLRS,2,999)
     166 . ; check for start block, Quit if no ien
     167 . I HLMSG(HLINE,0)[HLDSTRT!HLHDR D  Q
     168 .. S HLRS("START-FLAG")=1 ; HL*1.6*122
     169 .. D:HLMSG(HLINE,0)[HLDSTRT
     170 ... S X=$L(HLMSG(HLINE,0),HLDSTRT)
     171 ... S:X>2 HLMSG(HLINE,0)=HLDSTRT_$P(HLMSG(HLINE,0),HLDSTRT,X)
     172 ... S HLMSG(HLINE,0)=$P(HLMSG(HLINE,0),HLDSTRT,2)
     173 ... D RESET:(HLINE>1)
     174 .. ;
     175 .. ; patch HL*1.6*122
     176 .. ; if the first line less than 10 characters
     177 .. I HLHDR,$L(HLMSG(1,0))<10,$D(HLMSG(2,0)) D
     178 ... S HLMSG(1,0)=HLMSG(1,0)_$E(HLMSG(2,0),1,10)
     179 ... S HLMSG(2,0)=$E(HLMSG(2,0),11,9999999)
     180 .. ;
     181 .. ;ping message
     182 .. I $E(HLMSG(1,0),1,9)="MSH^PING^" D PING Q
     183 .. ; get next ien to store
     184 .. D MIEN^HLCSTCP4
     185 .. K HLMSG
     186 .. S (HLINE,HLHDR)=0
     187 . ; check for end block; <eb><cr>
     188 . I HLMSG(HLINE,0)[HLDEND D
     189 .. ; patch HL*1.6*122 start
     190 .. ;no msg. ien
     191 .. ; Q:'HLIND1
     192 .. I 'HLIND1 D CLEAN Q
     193 .. ; Kill just the last line if no data before HLDEND
     194 .. I $P(HLMSG(HLINE,0),HLDEND)']"" D
     195 ... K HLMSG(HLINE,0) S HLINE=HLINE-1
     196 .. E  S HLMSG(HLINE,0)=$P(HLMSG(HLINE,0),HLDEND)
     197 .. ; patch HL*1.6*122 end
     198 .. ;
     199 .. ; move into 772
     200 .. D SAVE(.HLMSG,"^HL(772,"_+$P(HLIND1,U,2)_",""IN"")")
     201 .. ;mark that end block has been received
     202 .. ;HLIND1=ien in 773^ien in 772^1 if end block was received
     203 .. S $P(HLIND1,U,3)=1
     204 .. S HLBUFF("HLIND1")=HLIND1
     205 .. ;reset variables for next message
     206 .. D CLEAN
     207 . ;add blank line for carriage return
     208 . I HLINE'=0,HLMSG(HLINE,0)]"" S HLINE=HLINE+1,HLMSG(HLINE,0)=""
     209 Q:HLRDOUT
     210 ;If the line is long and no <CR> move it into the array.
     211 I ($L(HLX)=HLDBSIZE),(HLX'[HLRS),(HLX'[HLDEND),(HLX'[HLDSTRT) D  Q
     212 . S HLINE=HLINE+1,HLMSG(HLINE,0)=HLX,HLX=""
     213 ;have start block but no record seperator
     214 I HLX[HLDSTRT D  Q
     215 . ;check for more than 1 start block
     216 . S X=$L(HLX,HLDSTRT) S:X>2 HLX=HLDSTRT_$P(HLX,HLDSTRT,X)
     217 . ;
     218 . ; patch HL*1.6*122
     219 . ; S:$L($P(HLX,HLDSTRT,2))>8 HLINE=HLINE+1,HLMSG(HLINE,0)=$P(HLX,HLDSTRT,2),HLX="",HLHDR=1
     220 . S HLINE=HLINE+1,HLMSG(HLINE,0)=$P(HLX,HLDSTRT,2),HLX="",HLHDR=1
     221 . ;
     222 . D RESET:(HLHDR&(HLINE>1))
     223 ;if no ien, reset
     224 ; patch HL*1.6*122
     225 ; I 'HLIND1 D CLEAN Q
     226 I (HLRS("START-FLAG")=1),'HLIND1 D CLEAN Q
     227 ; big message-merge from local to global every 100 lines
     228 I (HLINE-$O(HLMSG(0)))>100 D
     229 . M ^HL(772,+$P(HLIND1,U,2),"IN")=HLMSG
     230 . ; reset working array
     231 . K HLMSG
     232 Q
     233 ;
     234SAVE(SRC,DEST) ;save into global & set top node
     235 ;SRC=source array (passed by ref.), DEST=destination global
     236 M @DEST=SRC
     237 S @DEST@(0)="^^"_HLINE_"^"_HLINE_"^"_DT_"^"
     238 Q
     239 ;
     240DELMSG(HLMAMT) ;delete message from Message Administration/Message Text files.
     241 N DIK,DA
     242 S DA=+HLMAMT,DIK="^HLMA("
     243 D ^DIK
     244 S DA=$P(HLMAMT,U,2),DIK="^HL(772,"
     245 D ^DIK
     246 Q
     247PING ;process PING message
     248 S X=HLMSG(1,0)
     249 I X[HLDEND U IO W X,! D
     250 . ; switch to null device if opened to prevent 'leakage'
     251 . I $G(IO(0))]"",$G(IO(0))'=IO U IO(0)
     252CLEAN ;reset var. for next message
     253 K HLMSG
     254 S HLINE=0,HLRDOUT=1
     255 Q
     256 ;
     257ERROR ; Error trap for disconnect error and return back to the read loop.
     258 S $ETRAP="D UNWIND^%ZTER"
     259 I $$EC^%ZOSV["IOEOF" D UNWIND^%ZTER Q  ;VOE change for GT.M
     260 I $$EC^%ZOSV["READ"!($$EC^%ZOSV["NOTOPEN")!($$EC^%ZOSV["DEVNOTOPN") D UNWIND^%ZTER Q
     261 I $$EC^%ZOSV["WRITE" D CC("Wr-err") D UNWIND^%ZTER Q
     262 I $ECODE["UREAD" D UNWIND^%ZTER Q  ; HL*1.6*122 GT.M
     263 S HLCSOUT=1 D ^%ZTER,CC("Error")
     264 D UNWIND^%ZTER
     265 Q
     266 ;
     267CC(X) ;cleanup and close
     268 D MON^HLCSTCP(X)
     269 H 2
     270 Q
     271RESET ;reset info as a result of no end block
     272 N %
     273 S HLMSG(1,0)=HLMSG(HLINE,0)
     274 F %=2:1:HLINE K HLMSG(%,0)
     275 S HLINE=1
     276 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSTCP2.m

    r613 r623  
    1 HLCSTCP2        ;SFIRMFO/RSD - BI-DIRECTIONAL TCP ;04/16/2008  16:20
    2         ;;1.6;HEALTH LEVEL SEVEN;**19,43,49,57,63,64,66,67,76,77,87,109,133,122,140**;Oct 13,1995;Build 5
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;Sender
    5         ;Request connection, send outbound message(s) delimited by MLLP
    6         ;Input : HLDP=Logical Link to use
    7         ; Set up error trap
    8         N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP2"
    9         N HLMSG,HLPORT,HLRETRY,HLRETMG,HLTCPO,POP
    10         ;HLRETRY=number of retranmission for this link,HLRETMG=alert sent
    11         S HLTCPO=HLDP,HLMSG="",(HLRETRY,HLRETMG)=0
    12         ;
    13         ; patch 122
    14         ; patch 133
    15         ; set IO(0) to the null device
    16         I $G(^%ZOSF("OS"))]"",^%ZOSF("OS")'["GT.M" D
    17         . S IO(0)=$S(^%ZOSF("OS")["OpenM":$S($$OS^%ZOSV()["VMS":"_NLA0:",$$OS^%ZOSV()["UNIX":"/dev/null",1:$P),^%ZOSF("OS")["DSM":"_NLA0:",1:$P)
    18         . O IO(0) U IO(0)
    19         ;
    20         ;persistent conection, open connection first, HLPORT=open port
    21         I $G(HLTCPLNK)["Y" F  Q:$$OPEN  G EXIT:$$STOP^HLCSTCP H 1
    22         F  D QUE Q:$$STOP^HLCSTCP  D:'HLMSG  Q:$G(HLCSOUT)
    23         . ;no messages to send
    24         . D MON^HLCSTCP("Idle") H 3
    25         . ;persistent connection, no retention
    26         . Q:$G(HLTCPLNK)["Y"
    27         . D MON^HLCSTCP("Retention")
    28         . N % I 0
    29         . ;if message comes in or ask to stop
    30         . F %=1:1:HLTCPRET H 1 I $$STOP^HLCSTCP!$O(^HLMA("AC","O",HLDP,0)) Q
    31         . E  S HLCSOUT=2 Q
    32         . Q:$$STOP^HLCSTCP
    33         . D MON^HLCSTCP("Idle")
    34         ;Close port
    35         I $D(HLPORT) D CLOSE^%ZISTCP K HLPORT
    36 EXIT    Q
    37         ;
    38 QUE     ; -- Check "OUT" queue for processing IF there is a message do it
    39         ; and then check the link if it open or not
    40         N HL,HLN,HLARR,HLHDR,HLI,HLJ,HLMSA,HLRESP,HLRESLT,HLRETRM,HLTCP,HLTCPI,X,Z,HLREREAD
    41         N HLTMBUF
    42         D MON^HLCSTCP("CheckOut")
    43         ;HLMSG=next msg, set at tag DONE
    44         I 'HLMSG S HLMSG=+$O(^HLMA("AC","O",HLDP,0)),HLRETRY=0 Q:'HLMSG
    45         ;
    46         S HLI=+$G(^HLMA(HLMSG,0)),HLJ=$O(^("MSH",0)),HLTCP=""
    47         ;don't have message text or MSH, kill x-ref and decrement 'to send'
    48         ;
    49         ; patch HL*1.6*122: MPI-client/server
    50         ; I 'HLI!'HLJ K ^HLMA("AC","O",HLDP,HLMSG) D LLCNT^HLCSTCP(HLDP,3,1) S HLMSG=0 Q
    51         I 'HLI!'HLJ D  Q
    52         . F  L +^HLMA("AC","O",HLDP,HLMSG):10 Q:$T  H 1
    53         . K ^HLMA("AC","O",HLDP,HLMSG)
    54         . L -^HLMA("AC","O",HLDP,HLMSG)
    55         . D LLCNT^HLCSTCP(HLDP,3,1)
    56         . S HLMSG=0
    57         ;
    58         ;update msg status to 'being transmitted'; if cancelled decrement link and quit
    59         I '$$CHKMSG(1.5) D LLCNT^HLCSTCP(HLDP,3,1) S HLMSG=0 Q
    60         ;number of retransmissions for message
    61         S HLRETRM=+$P(^HLMA(HLMSG,"P"),U,5)
    62         ;retries exceeded, HLRETRA:action i=ignore, r=restart, s=shutdown
    63         ;quit if restart or shutdown, link is going down
    64         I HLRETRY>HLDRETR D  Q:"I"'[HLRETRA
    65         . D MON^HLCSTCP("Error")
    66         . ;only 1 alert per link up time, don't send if restart
    67         . D:'HLRETMG&(HLRETRA'="R")
    68         .. ;send alert
    69         .. N XQA,XQAMSG,XQAOPT,XQAROU,XQAID,Z
    70         .. ;get mailgroup from file 869.3
    71         .. S HLRETMG=1,Z=$P($$PARAM^HLCS2,U,8) Q:Z=""
    72         .. S XQA("G."_Z)="",XQAMSG=$$HTE^XLFDT($H,2)_" HL7 LL "_$P(^HLCS(870,HLDP,0),U)_" exceeded retries. LL will "_$S(HLRETRA="S":"shutdown.",HLRETRA="R":"restart.",1:"keep trying.")
    73         .. D SETUP^XQALERT
    74         . ;quit if action is ignore
    75         . Q:"I"[HLRETRA
    76         . ;this will shutdown this link
    77         . S HLCSOUT=1
    78         . ;action is shutdown, set shutdown flag so LM won't restart
    79         . S:HLRETRA="S" $P(^HLCS(870,HLDP,0),U,15)=1
    80         . D STATUS^HLTF0(HLMSG,4,103,"LLP Exceeded Retry Param")
    81         I '$$OPEN Q
    82         D MON^HLCSTCP("Send")
    83         ; -- data passed in global array, success=1
    84         I $$WRITE(HLMSG)<0 Q
    85         S (HLTCP,HLTCPI)=HLMSG,HLRETRY=HLRETRY+1,HLRETRM=HLRETRM+1
    86         ;update status to awaiting response, decrement link if cancelled
    87         I '$$CHKMSG(1.7) D LLCNT^HLCSTCP(HLDP,3,1) S HLMSG=0 Q
    88         ;set transmission count, get ACKTIMEOUT override
    89         S $P(^HLMA(HLMSG,"P"),U,5)=HLRETRM I $P(^("P"),U,7) S HLN("ACKTIME")=+$P(^("P"),U,7)
    90         ;get header of message just sent
    91         K HLJ M HLJ=^HLMA(HLMSG,"MSH")
    92         ;first component of sending app.
    93         S HLN("ECH")=$$P^HLTPCK2(.HLJ,2),HLN("SAN")=$P($$P^HLTPCK2(.HLJ,3),$E(HLN("ECH")))
    94         ;msg type, msg. id, commit ack, and app. ack parameter
    95         S HLN("TYPE")=$$P^HLTPCK2(.HLJ,1),HLN("MID")=$$P^HLTPCK2(.HLJ,10),HLN("ACAT")=$$P^HLTPCK2(.HLJ,15),HLN("APAT")=$$P^HLTPCK2(.HLJ,16)
    96         ;MSA segment, message is a response, can't have an a. ack.
    97         S Z=$$MSA^HLTP3(+^HLMA(HLMSG,0)) I Z]"" S:HLN("ACAT")="" HLN("ACAT")="NE" S HLN("APAT")="NE"
    98         ;for batch/file with commit ack, reset c. ack and a. ack variables
    99         I "BHS,FHS"[HLN("TYPE") S Z=$E(HLJ(1,0),5),X=$$P^HLTPCK2(.HLJ,9),HLN("ACAT")=$P(X,Z,5),HLN("APAT")=$P(X,Z,6),HLN("MID")=$$P^HLTPCK2(.HLJ,11)
    100         ;get event protocol
    101         S HLN("EID")=+$P(^HLMA(HLMSG,0),U,8),X=$G(^ORD(101,HLN("EID"),770))
    102         ;set link counter to msg sent
    103         D LLCNT^HLCSTCP(HLDP,4)
    104         ;commit and app. ack is never, update status to complete and hang UNI-DIRECTIONAL WAIT
    105         I HLN("ACAT")="NE",HLN("APAT")="NE" D  Q
    106         .D DONE(3)
    107         .;
    108         .;
    109         .H $G(HLDWAIT)
    110         ;
    111         ;do structure is to stack error
    112         D
    113         . N $ETRAP,$ESTACK S $ETRAP="D RDERR^HLCSTCP2"
    114         . ;HL*1.6*87: Read acknowledgement. 
    115         . ;Loop to re-read from buffer when receiving incorrect ack.
    116         . F  D  Q:'+$G(HLREREAD)
    117         .. S HLREREAD=1
    118         .. ;override ack timeout
    119         .. I $G(HLN("ACKTIME")) N HLDBACK S HLDBACK=HLN("ACKTIME")
    120         .. ;check for response, quit if no-response, msg will be resent
    121         .. ;HLRESP=ien 773^ien 772 for response message
    122         .. S HLRESP=$$READ^HLCSTCP1()
    123         .. ;if no response, decrement counter and quit
    124         .. I 'HLRESP D  Q
    125         ...D LLCNT^HLCSTCP(HLDP,4,1)
    126         ...S HLREREAD="0^No Response"
    127         ...;check if the port needs to be closed and re-opened before the next re-transmission attempt
    128         ...I $G(HLDRETRY("CLOSE")) D CLOSE^%ZISTCP K HLPORT
    129         .. ;X 0=re-read msg, 1=commit ack, 3=app ack success, 4=error
    130         .. S X=$$RSP^HLTP31(HLRESP,.HLN)
    131         .. ;X=0, re-read msg. Incorrect ack (bad MSH,MSA,msg id,or sending app)
    132         .. Q:'X
    133         .. ;commit ack - done
    134         .. I X=1 D  S HLREREAD="0^Commit Ack" Q
    135         ... ;don't need app. ack, set status to complete
    136         ... I "NE"[HLN("APAT") D  Q
    137         ....D DONE(3)
    138         ....;
    139         ... ;response is deferred, set status to awaiting ack
    140         ... D DONE(2)
    141         ...;
    142         .. ;Error, HLRESLT=error number^error message from HLTP3
    143         .. I X=4 D  Q
    144         ... D DONE(4,+$G(HLRESLT),$P($G(HLRESLT),U,2))
    145         ...;
    146         ... S HLREREAD="0^Error"
    147         .. ;app ack was successful
    148         .. D DONE(3) S HLREREAD="0^App Ack"
    149         ..;
    150         Q
    151         ;
    152 DCSEND  ;direct connect
    153         ; Set up error trap
    154         N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP2"
    155         ; patch HL*1.6*122
    156         N HLTMBUF
    157         ;override ack timeout
    158         I $G(HLP("ACKTIME")) N HLDBACK S HLDBACK=HLP("ACKTIME")
    159         I $$WRITE(HLMSG)<0 D:$G(HLERROR)]""  Q  ;HL*1.6*77
    160         .  D STATUS^HLTF0(HLMSG,4,$P(HLERROR,"^"),$P(HLERROR,"^",2),1) ;HL*1.6*77
    161         .  D LLCNT^HLCSTCP(HLDP,3,1)
    162         D LLCNT^HLCSTCP(HLDP,4)
    163         ;do structure is to stack error
    164         D
    165         . N $ETRAP,$ESTACK S $ETRAP="D RDERR^HLCSTCP2"
    166         . ;HLRESP=ien 773^ien 772 for response message
    167         . S HLRESP=$$READ^HLCSTCP1()
    168         ;
    169         D DONE(3):$G(HLRESP),DONE(4,108,$S($G(HLERROR)]"":$P(HLERROR,"^",2),1:"No response")):'$G(HLRESP)
    170         I $G(HLERROR)']"" D
    171         .D MON^HLCSTCP("Idle")
    172         .I '$G(HLRESP) S HLERROR="108^No response"
    173         ;Close port
    174         I $D(HLPORT) D CLOSE^%ZISTCP K HLPORT
    175         Q
    176         ;
    177 DONE(ST,ERR,ERRMSG)     ;set status to complete
    178         ;ST=status, ERR=error ien, ERRMSG=error msg
    179         D STATUS^HLTF0(HLMSG,ST,$G(ERR),$G(ERRMSG),1)
    180         ;
    181         D DEQUE^HLCSREP(HLDP,"O",HLMSG)
    182         ;
    183         ;check for more msg.
    184         I $G(HLPRIO)'="I" S HLMSG=+$O(^HLMA("AC","O",HLDP,0)),HLRETRY=0
    185         Q
    186         ;
    187 CHKMSG(HLI)     ;check status of message and update if not cancelled
    188         ;input: HLI=new status, HLMSG=ien of msg in 773
    189         ;returns 1=msg was updated, 0=msg has been canceled
    190         N X
    191         ;
    192         ; New HL*1.6*77 code starting here...
    193         I '$D(^HLMA(HLMSG,"P")) D  Q 0
    194         .  S HLERROR="2^Missing status field"
    195         .  D STATUS^HLTF0(HLMSG,4,$P(HLERROR,U),$P(HLERROR,U,2),1)
    196         .;
    197         . D DEQUE^HLCSREP(HLDP,"O",HLMSG)
    198         ;
    199         ; End of HL*1.6*77
    200         ;
    201         ;get status, quit if msg was cancelled
    202         ;
    203         S X=+^HLMA(HLMSG,"P") Q:X=3 0
    204         ;
    205         ;update status if it is different
    206         I $G(HLI),HLI'=X D STATUS^HLTF0(HLMSG,HLI)
    207         ;
    208         Q 1
    209         ;
    210 WRITE(HLDA)     ; write message in HL7 format
    211         ;  HLDA       - ien of message in 773
    212         ;             - start block $C(11)
    213         ;             - end block $C(28)
    214         ;             - record separator $C(13)
    215         ;Output(s): 1 - Successful
    216         ;           -1 - Unsuccessful
    217         ;
    218         N HLDA2,HLAR,HLI,LINENO,X,CRCOUNT
    219         S CRCOUNT=0
    220         ;set error trap, used when called from HLTP3
    221         ;
    222         ; New HL*1.6*77 code starts here...
    223         N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP2"
    224         I $G(^HLMA(HLDA,0))'>0 D  Q -1
    225         .  S HLERROR="2^Message Text pointer missing"
    226         S HLDA2=+$G(^HLMA(HLDA,0))
    227         ; End of HL*1.6*77 modifications...
    228         ;
    229         Q:'$G(^HLMA(HLDA,0)) -1 ;HL*1.6*77
    230         ; header is in ^HLMA(, message is in ^HL(772,
    231         S LINENO=1,HLI=0,HLAR="^HLMA(HLDA,""MSH"")"
    232         U IO
    233         D  W $C(13) S HLAR="^HL(772,HLDA2,""IN"")",HLI=0 D
    234         . F  S HLI=$O(@HLAR@(HLI)) Q:'HLI  S X=$G(^(HLI,0)) D
    235         .. ;first line, need start block char.
    236         .. S:LINENO=1 X=$C(11)_X
    237         .. ; HL*1.6*122
    238         .. ; I X]"" W X,!
    239         .. N LENGTH
    240         .. S LENGTH=$L(X)
    241         .. ; buffer should be limited to 512
    242         .. I LENGTH>512 D
    243         ... N X1
    244         ... F  Q:LENGTH<512  D
    245         .... S X1=$E(X,1,512),X=$E(X,513,999999)
    246         .... S LENGTH=$L(X)
    247         .... ; patch HL*1.6*140
    248         .... ; W X1,@IOF
    249         .... W X1,@HLTCPLNK("IOF")
    250         .. ;
    251         .. ; @HLTCPLNK("IOF") (! or #) for flush character
    252         .. I X]"" W X,@HLTCPLNK("IOF") S CRCOUNT=0
    253         .. ;send CR
    254         .. I X="" W $C(13) S CRCOUNT=CRCOUNT+1
    255         .. ; prevent from maxstring error
    256         .. I CRCOUNT>200 W @HLTCPLNK("IOF") S CRCOUNT=0
    257         .. S LINENO=LINENO+1
    258         ; Sends end block for this message
    259         S X=$C(28)_$C(13)
    260         ; U IO W X,!
    261         U IO W X,@HLTCPLNK("IOF")
    262         ;switch to null device
    263         I $G(IO(0))'="",$G(IO(0))'=IO U IO(0)
    264         Q 1
    265         ;
    266 OPEN()  ; -- Open TCP/IP device (Client)
    267         ;HLPORT=port, defined only if port is open
    268         ;HLPORTA=number of attempted opens
    269         I $D(HLPORT) S IO=HLPORT D  Q 1
    270         . U IO
    271         . I HLOS["OpenM" X "U IO:(::""-M"")" ;use packet mode on Cache'
    272         N HLDOM,HLI,HLIP,HLPORTA
    273         G OPENA^HLCSTCP3
    274         ;
    275 RDERR   D RDERR^HLCSTCP4 Q
    276 ERROR   D ERROR^HLCSTCP4 Q
    277         ;
    278 CC(X)   ;cleanup and close
    279         D MON^HLCSTCP(X)
    280         I $D(HLPORT) D CLOSE^%ZISTCP K HLPORT
    281         ; patch HL*1.6*140
    282         ; H 2
    283         H 1
    284         Q
     1HLCSTCP2 ;SFIRMFO/RSD - BI-DIRECTIONAL TCP ;09/13/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**19,43,49,57,63,64,66,67,76,77,87,109,133**;Oct 13,1995;Build 13
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;Sender
     5 ;Request connection, send outbound message(s) delimited by MLLP
     6 ;Input : HLDP=Logical Link to use
     7 ; Set up error trap
     8 N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP2"
     9 N HLMSG,HLPORT,HLRETRY,HLRETMG,HLTCPO,POP
     10 ;HLRETRY=number of retranmission for this link,HLRETMG=alert sent
     11 S HLTCPO=HLDP,HLMSG="",(HLRETRY,HLRETMG)=0
     12 ;
     13 ;set IO(0) to the null device
     14 S IO(0)=$S(^%ZOSF("OS")["OpenM":$S($$OS^%ZOSV()["VMS":"_NLA0:",$$OS^%ZOSV()["UNIX":"/dev/null",1:$P),^%ZOSF("OS")["DSM":"_NLA0:",1:$P)
     15 O IO(0) U IO(0)
     16 ;
     17 ;persistent conection, open connection first, HLPORT=open port
     18 I $G(HLTCPLNK)["Y" F  Q:$$OPEN  G EXIT:$$STOP^HLCSTCP H 1
     19 F  D QUE Q:$$STOP^HLCSTCP  D:'HLMSG  Q:$G(HLCSOUT)
     20 . ;no messages to send
     21 . D MON^HLCSTCP("Idle") H 3
     22 . ;persistent connection, no retention
     23 . Q:$G(HLTCPLNK)["Y"
     24 . D MON^HLCSTCP("Retention")
     25 . N % I 0
     26 . ;if message comes in or ask to stop
     27 . F %=1:1:HLTCPRET H 1 I $$STOP^HLCSTCP!$O(^HLMA("AC","O",HLDP,0)) Q
     28 . E  S HLCSOUT=2 Q
     29 . Q:$$STOP^HLCSTCP
     30 . D MON^HLCSTCP("Idle")
     31 ;Close port
     32 I $D(HLPORT) D CLOSE^%ZISTCP K HLPORT
     33EXIT Q
     34 ;
     35QUE ; -- Check "OUT" queue for processing IF there is a message do it
     36 ; and then check the link if it open or not
     37 N HL,HLN,HLARR,HLHDR,HLI,HLJ,HLMSA,HLRESP,HLRESLT,HLRETRM,HLTCP,HLTCPI,X,Z,HLREREAD
     38 D MON^HLCSTCP("Check out")
     39 ;HLMSG=next msg, set at tag DONE
     40 I 'HLMSG S HLMSG=+$O(^HLMA("AC","O",HLDP,0)),HLRETRY=0 Q:'HLMSG
     41 ;
     42 ;**109**
     43 ;Temporarily lock ^HLMA to flush buffer and ensure edits are complete
     44 ;L +^HLMA(HLMSG):1 I '$T S HLMSG=0 Q
     45 ;L -^HLMA(HLMSG)
     46 ;
     47 S HLI=+$G(^HLMA(HLMSG,0)),HLJ=$O(^("MSH",0)),HLTCP=""
     48 ;don't have message text or MSH, kill x-ref and decrement 'to send'
     49 I 'HLI!'HLJ K ^HLMA("AC","O",HLDP,HLMSG) D LLCNT^HLCSTCP(HLDP,3,1) S HLMSG=0 Q
     50 ;update msg status to 'being transmitted'; if cancelled decrement link and quit
     51 I '$$CHKMSG(1.5) D LLCNT^HLCSTCP(HLDP,3,1) S HLMSG=0 Q
     52 ;number of retransmissions for message
     53 S HLRETRM=+$P(^HLMA(HLMSG,"P"),U,5)
     54 ;retries exceeded, HLRETRA:action i=ignore, r=restart, s=shutdown
     55 ;quit if restart or shutdown, link is going down
     56 I HLRETRY>HLDRETR D  Q:"I"'[HLRETRA
     57 . D MON^HLCSTCP("Error")
     58 . ;only 1 alert per link up time, don't send if restart
     59 . D:'HLRETMG&(HLRETRA'="R")
     60 .. ;send alert
     61 .. N XQA,XQAMSG,XQAOPT,XQAROU,XQAID,Z
     62 .. ;get mailgroup from file 869.3
     63 .. S HLRETMG=1,Z=$P($$PARAM^HLCS2,U,8) Q:Z=""
     64 .. S XQA("G."_Z)="",XQAMSG=$$HTE^XLFDT($H,2)_" HL7 LL "_$P(^HLCS(870,HLDP,0),U)_" exceeded retries. LL will "_$S(HLRETRA="S":"shutdown.",HLRETRA="R":"restart.",1:"keep trying.")
     65 .. D SETUP^XQALERT
     66 . ;quit if action is ignore
     67 . Q:"I"[HLRETRA
     68 . ;this will shutdown this link
     69 . S HLCSOUT=1
     70 . ;action is shutdown, set shutdown flag so LM won't restart
     71 . S:HLRETRA="S" $P(^HLCS(870,HLDP,0),U,15)=1
     72 . D STATUS^HLTF0(HLMSG,4,103,"LLP Exceeded Retry Param")
     73 I '$$OPEN Q
     74 D MON^HLCSTCP("Send")
     75 ; -- data passed in global array, success=1
     76 I $$WRITE(HLMSG)<0 Q
     77 S (HLTCP,HLTCPI)=HLMSG,HLRETRY=HLRETRY+1,HLRETRM=HLRETRM+1
     78 ;update status to awaiting response, decrement link if cancelled
     79 I '$$CHKMSG(1.7) D LLCNT^HLCSTCP(HLDP,3,1) S HLMSG=0 Q
     80 ;set transmission count, get ACKTIMEOUT override
     81 S $P(^HLMA(HLMSG,"P"),U,5)=HLRETRM I $P(^("P"),U,7) S HLN("ACKTIME")=+$P(^("P"),U,7)
     82 ;get header of message just sent
     83 K HLJ M HLJ=^HLMA(HLMSG,"MSH")
     84 ;first component of sending app.
     85 S HLN("ECH")=$$P^HLTPCK2(.HLJ,2),HLN("SAN")=$P($$P^HLTPCK2(.HLJ,3),$E(HLN("ECH")))
     86 ;msg type, msg. id, commit ack, and app. ack parameter
     87 S HLN("TYPE")=$$P^HLTPCK2(.HLJ,1),HLN("MID")=$$P^HLTPCK2(.HLJ,10),HLN("ACAT")=$$P^HLTPCK2(.HLJ,15),HLN("APAT")=$$P^HLTPCK2(.HLJ,16)
     88 ;MSA segment, message is a response, can't have an a. ack.
     89 S Z=$$MSA^HLTP3(+^HLMA(HLMSG,0)) I Z]"" S:HLN("ACAT")="" HLN("ACAT")="NE" S HLN("APAT")="NE"
     90 ;for batch/file with commit ack, reset c. ack and a. ack variables
     91 I "BHS,FHS"[HLN("TYPE") S Z=$E(HLJ(1,0),5),X=$$P^HLTPCK2(.HLJ,9),HLN("ACAT")=$P(X,Z,5),HLN("APAT")=$P(X,Z,6),HLN("MID")=$$P^HLTPCK2(.HLJ,11)
     92 ;get event protocol
     93 S HLN("EID")=+$P(^HLMA(HLMSG,0),U,8),X=$G(^ORD(101,HLN("EID"),770))
     94 ;set link counter to msg sent
     95 D LLCNT^HLCSTCP(HLDP,4)
     96 ;commit and app. ack is never, update status to complete and hang UNI-DIRECTIONAL WAIT
     97 I HLN("ACAT")="NE",HLN("APAT")="NE" D  Q
     98 .D DONE(3)
     99 .;
     100 .;
     101 .H $G(HLDWAIT)
     102 ;
     103 ;do structure is to stack error
     104 D
     105 . N $ETRAP,$ESTACK S $ETRAP="D RDERR^HLCSTCP2"
     106 . ;HL*1.6*87: Read acknowledgement. 
     107 . ;Loop to re-read from buffer when receiving incorrect ack.
     108 . F  D  Q:'+$G(HLREREAD)
     109 .. S HLREREAD=1
     110 .. ;override ack timeout
     111 .. I $G(HLN("ACKTIME")) N HLDBACK S HLDBACK=HLN("ACKTIME")
     112 .. ;check for response, quit if no-response, msg will be resent
     113 .. ;HLRESP=ien 773^ien 772 for response message
     114 .. S HLRESP=$$READ^HLCSTCP1()
     115 .. ;if no response, decrement counter and quit
     116 .. I 'HLRESP D  Q
     117 ...D LLCNT^HLCSTCP(HLDP,4,1)
     118 ...S HLREREAD="0^No Response"
     119 ...;check if the port needs to be closed and re-opened before the next re-transmission attempt
     120 ...I $G(HLDRETRY("CLOSE")) D CLOSE^%ZISTCP K HLPORT
     121 .. ;X 0=re-read msg, 1=commit ack, 3=app ack success, 4=error
     122 .. S X=$$RSP^HLTP31(HLRESP,.HLN)
     123 .. ;X=0, re-read msg. Incorrect ack (bad MSH,MSA,msg id,or sending app)
     124 .. Q:'X
     125 .. ;commit ack - done
     126 .. I X=1 D  S HLREREAD="0^Commit Ack" Q
     127 ... ;don't need app. ack, set status to complete
     128 ... I "NE"[HLN("APAT") D  Q
     129 ....D DONE(3)
     130 ....;
     131 ... ;response is deferred, set status to awaiting ack
     132 ... D DONE(2)
     133 ...;
     134 .. ;Error, HLRESLT=error number^error message from HLTP3
     135 .. I X=4 D  Q
     136 ... D DONE(4,+$G(HLRESLT),$P($G(HLRESLT),U,2))
     137 ...;
     138 ... S HLREREAD="0^Error"
     139 .. ;app ack was successful
     140 .. D DONE(3) S HLREREAD="0^App Ack"
     141 ..;
     142 Q
     143 ;
     144DCSEND ;direct connect
     145 ; Set up error trap
     146 N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP2"
     147 ;override ack timeout
     148 I $G(HLP("ACKTIME")) N HLDBACK S HLDBACK=HLP("ACKTIME")
     149 I $$WRITE(HLMSG)<0 D:$G(HLERROR)]""  Q  ;HL*1.6*77
     150 .  D STATUS^HLTF0(HLMSG,4,$P(HLERROR,"^"),$P(HLERROR,"^",2),1) ;HL*1.6*77
     151 .  D LLCNT^HLCSTCP(HLDP,3,1)
     152 D LLCNT^HLCSTCP(HLDP,4)
     153 ;do structure is to stack error
     154 D
     155 . N $ETRAP,$ESTACK S $ETRAP="D RDERR^HLCSTCP2"
     156 . ;HLRESP=ien 773^ien 772 for response message
     157 . S HLRESP=$$READ^HLCSTCP1()
     158 ;
     159 D DONE(3):$G(HLRESP),DONE(4,108,$S($G(HLERROR)]"":$P(HLERROR,"^",2),1:"No response")):'$G(HLRESP)
     160 I $G(HLERROR)']"" D
     161 .D MON^HLCSTCP("Idle")
     162 .I '$G(HLRESP) S HLERROR="108^No response"
     163 ;Close port
     164 I $D(HLPORT) D CLOSE^%ZISTCP K HLPORT
     165 Q
     166 ;
     167DONE(ST,ERR,ERRMSG) ;set status to complete
     168 ;ST=status, ERR=error ien, ERRMSG=error msg
     169 D STATUS^HLTF0(HLMSG,ST,$G(ERR),$G(ERRMSG),1)
     170 ;
     171 ;**109**
     172 D DEQUE^HLCSREP(HLDP,"O",HLMSG)
     173 ;
     174 ;check for more msg.
     175 I $G(HLPRIO)'="I" S HLMSG=+$O(^HLMA("AC","O",HLDP,0)),HLRETRY=0
     176 Q
     177 ;
     178CHKMSG(HLI) ;check status of message and update if not cancelled
     179 ;input: HLI=new status, HLMSG=ien of msg in 773
     180 ;returns 1=msg was updated, 0=msg has been canceled
     181 N X
     182 ;
     183 ;**109**
     184 ;F  L +^HLMA(HLMSG,"P"):1 Q:$T  H 1
     185 ;
     186 ;
     187 ; New HL*1.6*77 code starting here...
     188 I '$D(^HLMA(HLMSG,"P")) D  Q 0
     189 .  S HLERROR="2^Missing status field"
     190 .  D STATUS^HLTF0(HLMSG,4,$P(HLERROR,U),$P(HLERROR,U,2),1)
     191 .;
     192 .;**109**
     193 . D DEQUE^HLCSREP(HLDP,"O",HLMSG)
     194 .;L -^HLMA(HLMSG,"P")
     195 ;**end 109**
     196 ;
     197 ; End of HL*1.6*77 modifications
     198 ;
     199 ;get status, quit if msg was cancelled
     200 ;
     201 ;**109**
     202 ;S X=+^HLMA(HLMSG,"P") I X=3 L -^HLMA(HLMSG,"P") Q 0
     203 S X=+^HLMA(HLMSG,"P") Q:X=3 0
     204 ;
     205 ;update status if it is different
     206 I $G(HLI),HLI'=X D STATUS^HLTF0(HLMSG,HLI)
     207 ;
     208 ;**109**
     209 ;L -^HLMA(HLMSG,"P")
     210 ;
     211 Q 1
     212 ;
     213WRITE(HLDA) ; write message in HL7 format
     214 ;  HLDA       - ien of message in 773
     215 ;             - start block $C(11)
     216 ;             - end block $C(28)
     217 ;             - record separator $C(13)
     218 ;Output(s): 1 - Successful
     219 ;           -1 - Unsuccessful
     220 ;
     221 N HLDA2,HLAR,HLI,LINENO,X
     222 ;set error trap, used when called from HLTP3
     223 ;
     224 ; New HL*1.6*77 code starts here...
     225 N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP2"
     226 I $G(^HLMA(HLDA,0))'>0 D  Q -1
     227 .  S HLERROR="2^Message Text pointer missing"
     228 S HLDA2=+$G(^HLMA(HLDA,0))
     229 ; End of HL*1.6*77 modifications...
     230 ;
     231 Q:'$G(^HLMA(HLDA,0)) -1 ;HL*1.6*77
     232 ; header is in ^HLMA(, message is in ^HL(772,
     233 S LINENO=1,HLI=0,HLAR="^HLMA(HLDA,""MSH"")"
     234 U IO
     235 D  W $C(13) S HLAR="^HL(772,HLDA2,""IN"")",HLI=0 D
     236 . F  S HLI=$O(@HLAR@(HLI)) Q:'HLI  S X=$G(^(HLI,0)) D
     237 .. ;first line, need start block char.
     238 .. S:LINENO=1 X=$C(11)_X
     239 .. I X]"" W X,!
     240 .. ;send CR for blank lines
     241 .. I X="" W $C(13)
     242 .. S LINENO=LINENO+1
     243 ; Sends end block for this message
     244 S X=$C(28)_$C(13)
     245 U IO W X,!
     246 I $G(IO(0))'="",$G(IO(0))'=IO U IO(0) ;switch to null device if opened to prevent 'leakage'
     247 Q 1
     248 ;
     249OPEN() ; -- Open TCP/IP device (Client)
     250 ;HLPORT=port, defined only if port is open
     251 ;HLPORTA=number of attempted opens
     252 I $D(HLPORT) S IO=HLPORT D  Q 1
     253 . U IO
     254 . I HLOS["OpenM" X "U IO:(::""-M"")" ;use packet mode on Cache'
     255 N HLDOM,HLI,HLIP,HLPORTA
     256 G OPENA^HLCSTCP3
     257 ;
     258RDERR D RDERR^HLCSTCP4 Q  ; Exceeded 10,000 bytes, so split on 12/2/03-LJA
     259ERROR D ERROR^HLCSTCP4 Q  ; Exceeded 10,000 bytes, so split on 12/2/03-LJA
     260 ;
     261CC(X) ;cleanup and close
     262 D MON^HLCSTCP(X)
     263 I $D(HLPORT) D CLOSE^%ZISTCP K HLPORT
     264 H 2
     265 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSTCP3.m

    r613 r623  
    1 HLCSTCP3        ;SFIRMFO/RSD - BI-DIRECTIONAL TCP ; 09/13/2006  15:36
    2         ;;1.6;HEALTH LEVEL SEVEN;**76,77,133,122**;OCT 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 OPENA   ;
    6         ; called from $$OPEN^HLCSTCP2 and this sub-routine OPENA
    7         ;
    8         I $G(HLMSG),$D(^HLMA(HLMSG,"P")) S HLPORTA=+$P(^("P"),U,6)
    9         S POP=1
    10         ;
    11         ; patch HL*1.6*122 start
    12         ; variable HLDRETR=re-transmit attemps (#870,200.02)
    13         ; variable HLTCPLNK("TIMEOUT")=timeout for 3rd parameter of CALL^%ZISTCP()
    14         ; defined in HLCSTCP routine
    15         ;
    16         I '$G(HLDRETR("COUNT")) S HLDRETR("COUNT")=1
    17         I '$G(HLTCPLNK("TIMEOUT")) S HLTCPLNK("TIMEOUT")=5
    18         S HLDRETR("COUNT-2")=HLDRETR("COUNT")+HLDRETR
    19         ; patch 133
    20         ; I $G(HLDIRECT("OPEN TIMEOUT")) D
    21         ; .S HLI=1
    22         ; .D CALL^%ZISTCP(HLTCPADD,HLTCPORT,HLDIRECT("OPEN TIMEOUT"))
    23         ; E  D
    24         ; .F HLI=1:1:HLDRETR D CALL^%ZISTCP(HLTCPADD,HLTCPORT) Q:'POP
    25         I $G(HLDIRECT("OPEN TIMEOUT")) D
    26         . D MON^HLCSTCP("Open")
    27         . D CALL^%ZISTCP(HLTCPADD,HLTCPORT,HLDIRECT("OPEN TIMEOUT"))
    28         . ; give site one more chance to override the application setup
    29         . I $G(POP),(HLTCPLNK("TIMEOUT")>HLDIRECT("OPEN TIMEOUT")) D
    30         .. D CALL^%ZISTCP(HLTCPADD,HLTCPORT,HLTCPLNK("TIMEOUT"))
    31         E  D
    32         . N COUNT
    33         . ; try to connect HLDRETR times
    34         . F HLDRETR("COUNT")=HLDRETR("COUNT"):1:HLDRETR("COUNT-2") D  Q:('POP)!($$STOP^HLCSTCP)
    35         .. D MON^HLCSTCP("Open")
    36         .. ; D CALL^%ZISTCP(HLTCPADD,HLTCPORT)
    37         .. D CALL^%ZISTCP(HLTCPADD,HLTCPORT,HLTCPLNK("TIMEOUT"))
    38         .. ;open error
    39         .. I POP D
    40         ... D CC^HLCSTCP2("Openfail")
    41         ... H $S(HLDRETR("COUNT")=1:0,HLDRETR("COUNT")<10:1,1:8)
    42         ... I '$D(^XTMP("HL7-Openfail",$J)) D
    43         .... S ^XTMP("HL7-Openfail",0)=$$FMADD^XLFDT($$NOW^XLFDT,3)_"^"_$$NOW^XLFDT
    44         .... S ^XTMP("HL7-Openfail",$J,"COUNT","FIRST")=HLDRETR("COUNT")_"^"_$$NOW^XLFDT
    45         ... S COUNT=$P($G(^XTMP("HL7-Openfail",$J,"COUNT","LAST")),"^")+1
    46         ... S ^XTMP("HL7-Openfail",$J,"COUNT","LAST")=COUNT_"^"_$$NOW^XLFDT
    47         ;
    48         ;set # of opens back in msg
    49         ; I $G(HLMSG),$D(^HLMA(HLMSG,"P")) S $P(^("P"),U,6)=HLPORTA+HLI
    50         I $G(HLMSG),$D(^HLMA(HLMSG,"P")) S $P(^("P"),U,6)=HLDRETR("COUNT")
    51         ; patch HL*1.6*122 end
    52         ;
    53         ;device open
    54         I 'POP S HLPORT=IO D  Q $S($G(HLERROR)]"":0,1:1)
    55         . N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP2" ;HL*1.6*77
    56         . ;if address came from DNS, set back into LL
    57         . I $D(HLIP) S $P(^HLCS(870,HLDP,400),U)=HLTCPADD
    58         . ; write and read to check if still open
    59         . Q:HLOS'["OpenM"  X "U IO:(::""-M"")" ; must be Cache/NT + use packet mode
    60         . Q:$P(^HLCS(870,HLDP,400),U,7)'="Y"  ; must want to SAY HELO
    61         . U IO W "HELO "_$$KSP^XUPARAM("WHERE"),! R X:1
    62         ;openfail-try DNS lookup
    63         ;
    64         ; patch HL*1.6*122 start
    65         ;I '$D(HLDOM) S HLDOM=+$P(^HLCS(870,HLDP,0),U,7),HLDOM=$P($G(^DIC(4.2,HLDOM,0)),U) D:HLDOM]"" DNS
    66         I '$D(HLDOM) D
    67         . S HLDOM=+$P(^HLCS(870,HLDP,0),U,7),HLDOM=$P($G(^DIC(4.2,HLDOM,0)),U)
    68         . S HLDOM("DNS")=$P($G(^HLCS(870,+$G(HLDP),0)),"^",8)
    69         . D:HLDOM]""!($L(HLDOM("DNS"),".")>2) DNS
    70         ;
    71         Q:$$STOP^HLCSTCP 0
    72         ;HLIP=ip add. from DNS call, get first one and try open again
    73         I $D(HLIP) S HLTCPADD=$P(HLIP,","),HLIP=$P(HLIP,",",2,99) G:HLTCPADD OPENA
    74         ; open error
    75         ;cleanup and close
    76         ; patch 133
    77         I $G(HLDIRECT("OPEN TIMEOUT")) D
    78         . D MON^HLCSTCP("Openfail")
    79         . I $D(HLPORT) D CLOSE^%ZISTCP K HLPORT
    80         E  D
    81         . D CC^HLCSTCP2("Openfail")
    82         Q 0
    83         ; patch HL*1.6*122 end
    84         ;
    85         ;
    86         ;following code was removed, site's complained of to many alerts
    87         ;couldn't open, send 1 alert
    88         ;I '$G(HLPORTA) D
    89         ;. ;send alert
    90         ;. N XQA,XQAMSG,XQAOPT,XQAROU,XQAID,Z
    91         ;. ;get mailgroup from file 869.3
    92         ;. S Z=$P($$PARAM^HLCS2,U,8),HLPORTA="" Q:Z=""
    93         ;. S XQA("G."_Z)="",XQAMSG=$$HTE^XLFDT($H,2)_" Logical Link "_$P(^HLCS(870,HLDP,0),U)_" exceeded Open Retries."
    94         ;. D SETUP^XQALERT
    95         ;open error
    96         ;D CC("Openfail") H 3
    97         ;Q 0
    98         ;
    99         ;
    100 DNS     ;VA domains must have "med" inserted.
    101         ;All domains must use port 5000 and are prepended with "HL7"
    102         ;non-VA DNS lookups will succeed if site uses port 5000 and
    103         ;configure their local DNS with "HL7.yourdomain.com" and entries
    104         ;are created in the logical link file and domain file.
    105         D MON^HLCSTCP("DNS Lkup")
    106         I HLDOM["VA.GOV"&(HLDOM'[".MED.") S HLDOM=$P(HLDOM,".VA.GOV")_".MED.VA.GOV"
    107         I HLTCPORT=5000 S HLDOM="HL7."_HLDOM
    108         I HLTCPORT=5500 S HLDOM="MPI."_HLDOM
    109         ;
    110         ; patch HL*1.6*122 start
    111         I $L($G(HLDOM("DNS")),".")>2 D
    112         . S HLDOM=HLDOM("DNS")
    113         ; patch HL*1.6*122 end
    114         ;
    115         S HLIP=$$ADDRESS^XLFNSLK(HLDOM)
    116         K:HLIP="" HLIP
    117         Q
    118         ;
     1HLCSTCP3 ;SFIRMFO/RSD - BI-DIRECTIONAL TCP ;09/13/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**76,77,133**;OCT 13, 1995;Build 13
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5OPENA I $G(HLMSG),$D(^HLMA(HLMSG,"P")) S HLPORTA=+$P(^("P"),U,6)
     6 D MON^HLCSTCP("Open")
     7 S POP=1
     8 I $G(HLDIRECT("OPEN TIMEOUT")) D
     9 .S HLI=1
     10 .D CALL^%ZISTCP(HLTCPADD,HLTCPORT,HLDIRECT("OPEN TIMEOUT"))
     11 E  D
     12 .F HLI=1:1:HLDRETR D CALL^%ZISTCP(HLTCPADD,HLTCPORT) Q:'POP
     13 ;set # of opens back in msg
     14 I $G(HLMSG),$D(^HLMA(HLMSG,"P")) S $P(^("P"),U,6)=HLPORTA+HLI
     15 ;device open
     16 I 'POP S HLPORT=IO D  Q $S($G(HLERROR)]"":0,1:1)
     17 . N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLCSTCP2" ;HL*1.6*77
     18 . ;if address came from DNS, set back into LL
     19 . I $D(HLIP) S $P(^HLCS(870,HLDP,400),U)=HLTCPADD
     20 . ; write and read to check if still open
     21 . Q:HLOS'["OpenM"  X "U IO:(::""-M"")" ; must be Cache/NT + use packet mode
     22 . Q:$P(^HLCS(870,HLDP,400),U,7)'="Y"  ; must want to SAY HELO
     23 . U IO W "HELO "_$$KSP^XUPARAM("WHERE"),! R X:1
     24 ;openfail-try DNS lookup
     25 I '$D(HLDOM) S HLDOM=+$P(^HLCS(870,HLDP,0),U,7),HLDOM=$P($G(^DIC(4.2,HLDOM,0)),U) D:HLDOM]"" DNS
     26 ;HLIP=ip add. from DNS call, get first one and try open again
     27 I $D(HLIP) S HLTCPADD=$P(HLIP,","),HLIP=$P(HLIP,",",2,99) G:HLTCPADD OPENA
     28 ;open error
     29 I $G(HLDIRECT("OPEN TIMEOUT")) D
     30 .D MON^HLCSTCP("Openfail")
     31 .I $D(HLPORT) D CLOSE^%ZISTCP K HLPORT
     32 E  D
     33 .D CC^HLCSTCP2("Openfail") H 3
     34 Q 0
     35 ;
     36 ;following code was removed, site's complained of to many alerts
     37 ;couldn't open, send 1 alert
     38 ;I '$G(HLPORTA) D
     39 ;. ;send alert
     40 ;. N XQA,XQAMSG,XQAOPT,XQAROU,XQAID,Z
     41 ;. ;get mailgroup from file 869.3
     42 ;. S Z=$P($$PARAM^HLCS2,U,8),HLPORTA="" Q:Z=""
     43 ;. S XQA("G."_Z)="",XQAMSG=$$HTE^XLFDT($H,2)_" Logical Link "_$P(^HLCS(870,HLDP,0),U)_" exceeded Open Retries."
     44 ;. D SETUP^XQALERT
     45 ;open error
     46 ;D CC("Openfail") H 3
     47 ;Q 0
     48 ;
     49 ;
     50DNS ;VA domains must have "med" inserted.
     51 ;All domains must use port 5000 and are prepended with "HL7"
     52 ;non-VA DNS lookups will succeed if site uses port 5000 and
     53 ;configure their local DNS with "HL7.yourdomain.com" and entries
     54 ;are created in the logical link file and domain file.
     55 D MON^HLCSTCP("DNS Lkup")
     56 I HLDOM["VA.GOV"&(HLDOM'[".MED.") S HLDOM=$P(HLDOM,".VA.GOV")_".MED.VA.GOV"
     57 I HLTCPORT=5000 S HLDOM="HL7."_HLDOM
     58 I HLTCPORT=5500 S HLDOM="MPI."_HLDOM
     59 S HLIP=$$ADDRESS^XLFNSLK(HLDOM)
     60 K:HLIP="" HLIP
     61 Q
     62 ;
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSTCP4.m

    r613 r623  
    1 HLCSTCP4        ;SFIRMFO/RSD - BI-DIRECTIONAL TCP ;04/16/08  14:20
    2         ;;1.6;HEALTH LEVEL SEVEN;**109,122,140**;Oct 13,1995;Build 5
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         Q
    6         ; RDERR & ERROR moved from HLCSTCP2 on 12/2/2003 - LJA
    7         ;
    8 RDERR   ; Error during read process, decrement counter
    9         D LLCNT^HLCSTCP(HLDP,4,1)
    10 ERROR   ; Error trap
    11         ; OPEN ERROR-retry.
    12         ; WRITE ERROR (SERVER DISCONNECT)-close channel, retry
    13         ;
    14         ;**109**
    15         ;I $G(HLMSG) L -^HLMA(HLMSG)
    16         ;
    17         ; patch HL*1.6*122 start
    18         N STOP
    19         S STOP=0
    20         I $G(HLDP) S STOP=$$STOP^HLCSTCP
    21         ; patch HL*1.6*140
    22         S $ETRAP="D HALT^ZU" ;RWF
    23         S HLTCP("$ZA\8192#2")=""
    24         I (^%ZOSF("OS")["OpenM") D
    25         . S HLTCP("$ZA")=$ZA
    26         . ; For TCP devices $ZA\8192#2: the device is currently in the
    27         . ; Connected state talking to a remote host.
    28         . S HLTCP("$ZA\8192#2")=$ZA\8192#2
    29         ;
    30         S HLTCPERR("ERR-$ZE")=$$EC^%ZOSV
    31         ; I $$EC^%ZOSV["OPENERR"!($$EC^%ZOSV["NOTOPEN")!($$EC^%ZOSV["DEVNOTOPN") D CC^HLCSTCP2("Op-err") S:$G(HLPRIO)="I" HLERROR="15^Open Related Error" D UNWIND^%ZTER Q
    32         I $$EC^%ZOSV["OPENERR"!($$EC^%ZOSV["NOTOPEN")!($$EC^%ZOSV["DEVNOTOPN") D  G:STOP H2^XUSCLEAN Q
    33         . D CC^HLCSTCP2("Op-err")
    34         . S:$G(HLPRIO)="I" HLERROR="15^Open Related Error"
    35         . I STOP D  Q
    36         .. D CC^HLCSTCP2("Shutdown: (with 'Op-err')")
    37         . I 'STOP D UNWIND^%ZTER
    38         ; patch HL*1.6*140 start
    39         ; I $$EC^%ZOSV["WRITE" D  G:STOP!(HLTCP("$ZA\8192#2")=0) H2^XUSCLEAN Q
    40         I $$EC^%ZOSV["WRITE" D  G:STOP!(HLTCP("$ZA\8192#2")) H2^XUSCLEAN Q
    41         . ; S:$G(HLPRIO)="I" HLERROR="108^Write Error"
    42         . I $G(HLPRIO)="I" D  Q
    43         .. S HLERROR="108^Write Error"
    44         .. D CC^HLCSTCP2("Wr-err")
    45         .. D UNWIND^%ZTER
    46         . ;
    47         . I STOP D  Q
    48         .. D ^%ZTER,CC^HLCSTCP2("Shutdown: (with 'Wr-err')")
    49         . E  D  Q
    50         .. I HLTCP("$ZA\8192#2") D ^%ZTER,CC^HLCSTCP2("Wr-err") Q
    51         .. E  D  Q
    52         ... D CC^HLCSTCP2("Halt (Wr): (Disconnected with 'Wr-err')")
    53         ... D UNWIND^%ZTER
    54         ;
    55         ; I $$EC^%ZOSV["READ" D CC^HLCSTCP2("Rd-err") S:$G(HLPRIO)="I" HLERROR="108^Read Error" D UNWIND^%ZTER Q
    56         ; I $$EC^%ZOSV["READ" D  G:STOP!(HLTCP("$ZA\8192#2")=0) H2^XUSCLEAN Q
    57         I $$EC^%ZOSV["READ" D  G:STOP!(HLTCP("$ZA\8192#2")) H2^XUSCLEAN Q
    58         . ; S:$G(HLPRIO)="I" HLERROR="108^Read Error"
    59         . I $G(HLPRIO)="I" D  Q
    60         .. S HLERROR="108^Read Error"
    61         .. D CC^HLCSTCP2("Rd-err")
    62         .. D UNWIND^%ZTER
    63         . ;
    64         . I STOP D  Q
    65         .. D ^%ZTER,CC^HLCSTCP2("Shutdown: (with 'Rd-err')")
    66         . E  D  Q
    67         .. I HLTCP("$ZA\8192#2") D ^%ZTER,CC^HLCSTCP2("Rd-err") Q
    68         .. E  D  Q
    69         ... D CC^HLCSTCP2("Halt (Rd): (Disconnected with 'Rd-err')")
    70         ... D UNWIND^%ZTER
    71         ;
    72         ; S HLCSOUT=1 D ^%ZTER,CC^HLCSTCP2("Error"),SDFLD^HLCSTCP
    73         ; S:$G(HLPRIO)="I" HLERROR="9^Error"
    74         D ^%ZTER
    75         I $G(HLPRIO)="I" D  Q
    76         . S HLERROR="9^Error"
    77         . D CC^HLCSTCP2("Error")
    78         . D UNWIND^%ZTER
    79         ;
    80         I STOP D  Q
    81         . D CC^HLCSTCP2("Shutdown: (with 'Error')")
    82         . D H2^XUSCLEAN
    83         ;
    84         D CC^HLCSTCP2("Error")
    85         ; patch HL*1.6*122 end
    86         D H2^XUSCLEAN
    87         ; patch HL*1.6*140 end
    88         Q
    89         ;
    90 PROXY   ; set DUZ for application proxy user
    91         ;
    92         ; removed the execution: patch 122 TEST v2
    93         Q
    94         ;
    95         ;; S HLDUZ=+$$APFIND^XUSAP("HLSEVEN,APPLICATION PROXY")
    96         ;; S DUZ=HLDUZ
    97         ;; D DUZ^XUP(DUZ)
    98         ;; Q
    99         ;
    100 HLDUZ   ; compare DUZ and set DUZ to application proxy user
    101         ;
    102         ; removed the execution: patch 122 TEST v2
    103         Q
    104         ;
    105         ;; I '$G(HLDUZ) D PROXY
    106         ;
    107 HLDUZ2  ; compare DUZ and HLDUZ
    108         I $G(DUZ)'=HLDUZ D
    109         . S DUZ=HLDUZ
    110         . D DUZ^XUP(DUZ)
    111         Q
    112         ;
    113 CLEANVAR        ; clean variables for server, called from HLCSTCP1
    114         ;
    115         ; clean variables except Kernel related variables
    116         ; protect variables defined in HLCSTCP
    117         N HLDP
    118         N HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT,HLOS
    119         N HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL,HLZRULE
    120         ;
    121         ; protect variables defined in LISTEN^HLCSTCP
    122         ; N HLLSTN,HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT
    123         ; N HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL
    124         N HLLSTN
    125         ;
    126         ; protect variables defined in CACHEVMS^HLCSTCP and EN^HLCSTCP
    127         N %
    128         ; protect variables defined in this routine HLCSTCP1
    129         N $ETRAP,$ESTACK
    130         N HLMIEN,HLASTMSG
    131         N HLTMBUF
    132         N HLDUZ,DUZ
    133         ; Kernel variables for single listener
    134         N ZISOS,ZRULE
    135         ;
    136         D KILL^XUSCLEAN
    137         Q
    138 MIEN    ; sets HLIND1=ien in 773^ien in 772 for message
    139         N HLMID,X
    140         I HLIND1 D
    141         . S:'$G(^HLMA(+HLIND1,0)) HLIND1=0
    142         . S:'$G(^HL(772,+$P(HLIND1,U,2),0)) HLIND1=0
    143         ;msg. id is 10th of MSH & 11th for BSH or FSH
    144         S X=10+($E(HLMSG(1,0),1,3)'="MSH"),HLMID=$$PMSH(.HLMSG,X)
    145         ;if HLIND1 is set, kill old message, use HLIND1 for new
    146         ;message, it means we never got end block for 1st msg.
    147         I HLIND1 D  Q
    148         . ;get pointer to 772, kill header
    149         . ;
    150         . ; patch HL*1.6*122: MPI-client/server
    151         . F  L +^HLMA(+HLIND1):10 Q:$T  H 1
    152         . K ^HLMA(+HLIND1,"MSH")
    153         . L -^HLMA(+HLIND1)
    154         . ;
    155         . I $D(^HL(772,+$P(HLIND1,U,2),"IN")) K ^("IN")
    156         . S X=$$MAID^HLTF(+HLIND1,HLMID)
    157         . D SAVE^HLCSTCP1(.HLMSG,"^HLMA("_+HLIND1_",""MSH"")")
    158         . S:$P(HLIND1,U,3) $P(HLIND1,U,3)=""
    159         D TCP^HLTF(.HLMID,.X,.HLDT)
    160         S HLBUFF("IEN773")=X
    161         I 'X D  Q
    162         . ;error - record and reset array
    163         . ;killing HLLSTN will allow MON^HLCSTCP to work with multi-server
    164         . D CLEAN^HLCSTCP1 K HLLSTN
    165         . ;error 100=LLP could not en-queue the message, reset array
    166         . D MONITOR^HLCSDR2(100,19,HLDP),MON^HLCSTCP("ERROR") H 30
    167         ;HLIND1=ien in 773^ien in 772
    168         S HLIND1=X_U_+$G(^HLMA(X,0))
    169         S HLBUFF("HLIND1")=HLIND1
    170         ;save MSH into 773
    171         D SAVE^HLCSTCP1(.HLMSG,"^HLMA("_+HLIND1_",""MSH"")")
    172         Q
    173         ;
    174 PMSH(MSH,P)     ;get piece P from MSH array (passed by ref.)
    175         N FS,I,L,L1,L2,X,Y
    176         S FS=$E(MSH(1,0),4),(L2,Y)=0,X=""
    177         F I=1:1 S L1=$L($G(MSH(I,0)),FS),L=L1+Y-1 D  Q:$L(X)!'$D(MSH(I,0))
    178         . S:L1=1 L=L+1
    179         . S:P'>L X=$P($G(MSH(I-1,0)),FS,P-L2)_$P($G(MSH(I,0)),FS,(P-Y))
    180         . S L2=Y,Y=L
    181         Q X
    182         ;
    183 ERROR1  ;
    184         ; moved from ERROR^HLCSTCP1
    185         ; Error trap for disconnect error and return back to the read loop.
    186         ; patch HL*1.6*122 start
    187         ; patch HL*1.6*140
    188         ; S $ETRAP="D HALT^ZU" ;RWF
    189         S $ETRAP="H 1 D HALT^ZU" ;RWF
    190         I (^%ZOSF("OS")["OpenM") D
    191         . S HLTCP("$ZA")=$ZA
    192         . ; For TCP devices $ZA\8192#2: the device is currently in the
    193         . ; Connected state talking to a remote host.
    194         . S HLTCP("$ZA\8192#2")=$ZA\8192#2
    195         . I HLTCP("$ZA\8192#2")=0 D
    196         .. ; decrement counter of multi-listener
    197         .. I $D(^HLCS(870,"E","M",+$G(HLDP))) D EXITM^HLCSTCP
    198         .. ; process terminated
    199         .. D H2^XUSCLEAN
    200         ; patch HL*1.6*140
    201         ;S $ETRAP="D UNWIND^%ZTER" ;RWF
    202         ; I $$EC^%ZOSV["READ"!($$EC^%ZOSV["NOTOPEN")!($$EC^%ZOSV["DEVNOTOPN") D UNWIND^%ZTER Q
    203         I ($$EC^%ZOSV["NOTOPEN")!($$EC^%ZOSV["DEVNOTOPN") D  Q
    204         . ; if it is not a multi-listener
    205         . I '$D(^HLCS(870,"E","M",+$G(HLDP))) D CC^HLCSTCP1("Open-err")
    206         . D UNWIND^%ZTER
    207         I $$EC^%ZOSV["READ" D  Q
    208         . ; if it is not a multi-listener
    209         . I '$D(^HLCS(870,"E","M",+$G(HLDP))) D CC^HLCSTCP1("Rd-err")
    210         . D UNWIND^%ZTER
    211         ;
    212         ; I $$EC^%ZOSV["WRITE" D CC("Wr-err") D UNWIND^%ZTER Q
    213         I $$EC^%ZOSV["WRITE" D  Q
    214         . ; if it is not a multi-listener
    215         . I '$D(^HLCS(870,"E","M",+$G(HLDP))) D CC^HLCSTCP1("Wr-err")
    216         . D UNWIND^%ZTER
    217         ;
    218         ; for GT.M
    219         I $ECODE["UREAD" D  Q
    220         . ; if it is not a multi-listener
    221         . I '$D(^HLCS(870,"E","M",+$G(HLDP))) D CC^HLCSTCP1("Rd-err")
    222         . D UNWIND^%ZTER
    223         ;
    224         ; S HLCSOUT=1 D ^%ZTER,CC("Error")
    225         S HLCSOUT=1
    226         D ^%ZTER
    227         ; if it is not a multi-listener
    228         I '$D(^HLCS(870,"E","M",+$G(HLDP))) D CC^HLCSTCP1("Error")
    229         ; patch HL*1.6*122 end
    230         ;
    231         D UNWIND^%ZTER
    232         Q
    233         ;
    234 CLRMCNTR        ;
    235         ; clear the counter to set as "0 server" for multi-listener
    236         ; HL*1.6*122 start
    237         Q:'$G(HLDP)
    238         Q:'$D(^HLCS(870,"E","M",HLDP))
    239         S $P(^HLCS(870,HLDP,0),"^",4)="MS"
    240         S $P(^HLCS(870,HLDP,0),U,5)="0 server"
    241         Q
    242         ;
    243 CREATUSR        ;
    244         ; patch HL*1.6*122 TEST v2: DUZ code removed
    245         ; create application proxy users for listeners and incoming filer
    246         ;; N HLTEMP
    247         ;; S HLTEMP=$$CREATE^XUSAP("HLSEVEN,APPLICATION PROXY","#")
    248         Q
     1HLCSTCP4 ;SFIRMFO/RSD - BI-DIRECTIONAL TCP ;11/03/2006  13:31
     2 ;;1.6;HEALTH LEVEL SEVEN;**109,122**;Oct 13,1995;Build 4
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 Q
     6 ; RDERR & ERROR moved from HLCSTCP2 on 12/2/2003 - LJA
     7 ;
     8RDERR ; Error during read process, decrement counter
     9 D LLCNT^HLCSTCP(HLDP,4,1)
     10ERROR ; Error trap
     11 ; OPEN ERROR-retry.
     12 ; WRITE ERROR (SERVER DISCONNECT)-close channel, retry
     13 ;
     14 ;**109**
     15 ;I $G(HLMSG) L -^HLMA(HLMSG)
     16 ;
     17 S $ETRAP="D UNWIND^%ZTER"
     18 ; patch HL*1.6*122
     19 S HLTCPERR("$P")=$P
     20 S HLTCPERR("ERR-$ZE")=$$EC^%ZOSV
     21 ; I $$EC^%ZOSV["OPENERR"!($$EC^%ZOSV["NOTOPEN")!($$EC^%ZOSV["DEVNOTOPN") D CC^HLCSTCP2("Op-err") S:$G(HLPRIO)="I" HLERROR="15^Open Related Error" D UNWIND^%ZTER Q
     22 I $$EC^%ZOSV["OPENERR"!($$EC^%ZOSV["NOTOPEN")!($$EC^%ZOSV["DEVNOTOPN") D  Q
     23 . D CC^HLCSTCP2("Op-err")
     24 . S:$G(HLPRIO)="I" HLERROR="15^Open Related Error"
     25 . D UNWIND^%ZTER
     26 I $$EC^%ZOSV["WRITE" D  Q  ;HL*1.6*77 modifications start here
     27 .  D CC^HLCSTCP2("Wr-err")
     28 .  S:$G(HLPRIO)="I" HLERROR="108^Write Error"
     29 .  D UNWIND^%ZTER ;HL*1.6*77 modifications end here
     30 ; I $$EC^%ZOSV["READ" D CC^HLCSTCP2("Rd-err") S:$G(HLPRIO)="I" HLERROR="108^Read Error" D UNWIND^%ZTER Q
     31 I $$EC^%ZOSV["READ" D  Q
     32 . D CC^HLCSTCP2("Rd-err")
     33 . S:$G(HLPRIO)="I" HLERROR="108^Read Error"
     34 . D UNWIND^%ZTER
     35 S HLCSOUT=1 D ^%ZTER,CC^HLCSTCP2("Error"),SDFLD^HLCSTCP
     36 S:$G(HLPRIO)="I" HLERROR="9^Error"
     37 D UNWIND^%ZTER
     38 Q
     39 ;
     40PROXY ; set DUZ for application proxy user
     41 S HLDUZ=+$$APFIND^XUSAP("HLSEVEN,APPLICATION PROXY")
     42 S DUZ=HLDUZ
     43 D DUZ^XUP(DUZ)
     44 Q
     45 ;
     46HLDUZ ; compare DUZ and set DUZ to application proxy user
     47 I '$G(HLDUZ) D PROXY
     48 I $G(DUZ)'=HLDUZ D
     49 . S DUZ=HLDUZ
     50 . D DUZ^XUP(DUZ)
     51 Q
     52 ;
     53CLEANVAR ; clean variables for server, called from HLCSTCP1
     54 ;
     55 ; clean variables except Kernel related variables
     56 ; protect variables defined in HLCSTCP
     57 N HLDP
     58 N HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT,HLOS
     59 N HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL,HLZRULE
     60 ;
     61 ; protect variables defined in LISTEN^HLCSTCP
     62 ; N HLLSTN,HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT
     63 ; N HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL
     64 N HLLSTN
     65 ;
     66 ; protect variables defined in CACHEVMS^HLCSTCP and EN^HLCSTCP
     67 N %
     68 ; protect variables defined in this routine HLCSTCP1
     69 N $ETRAP,$ESTACK
     70 N HLMIEN,HLASTMSG
     71 N HLTMBUF
     72 N HLDUZ,DUZ
     73 ; Kernel variables for single listener
     74 N ZISOS,ZRULE
     75 ;
     76 D KILL^XUSCLEAN
     77 Q
     78MIEN ; sets HLIND1=ien in 773^ien in 772 for message
     79 N HLMID,X
     80 I HLIND1 D
     81 . S:'$G(^HLMA(+HLIND1,0)) HLIND1=0
     82 . S:'$G(^HL(772,+$P(HLIND1,U,2),0)) HLIND1=0
     83 ;msg. id is 10th of MSH & 11th for BSH or FSH
     84 S X=10+($E(HLMSG(1,0),1,3)'="MSH"),HLMID=$$PMSH(.HLMSG,X)
     85 ;if HLIND1 is set, kill old message, use HLIND1 for new
     86 ;message, it means we never got end block for 1st msg.
     87 I HLIND1 D  Q
     88 . ;get pointer to 772, kill header
     89 . K ^HLMA(+HLIND1,"MSH")
     90 . I $D(^HL(772,+$P(HLIND1,U,2),"IN")) K ^("IN")
     91 . S X=$$MAID^HLTF(+HLIND1,HLMID)
     92 . D SAVE^HLCSTCP1(.HLMSG,"^HLMA("_+HLIND1_",""MSH"")")
     93 . S:$P(HLIND1,U,3) $P(HLIND1,U,3)=""
     94 D TCP^HLTF(.HLMID,.X,.HLDT)
     95 S HLBUFF("IEN773")=X
     96 I 'X D  Q
     97 . ;error - record and reset array
     98 . ;killing HLLSTN will allow MON^HLCSTCP to work with multi-server
     99 . D CLEAN^HLCSTCP1 K HLLSTN
     100 . ;error 100=LLP Could not Enqueue the Message, reset array
     101 . D MONITOR^HLCSDR2(100,19,HLDP),MON^HLCSTCP("ERROR") H 30
     102 ;HLIND1=ien in 773^ien in 772
     103 S HLIND1=X_U_+$G(^HLMA(X,0))
     104 S HLBUFF("HLIND1")=HLIND1
     105 ;save MSH into 773
     106 D SAVE^HLCSTCP1(.HLMSG,"^HLMA("_+HLIND1_",""MSH"")")
     107 Q
     108 ;
     109PMSH(MSH,P) ;get piece P from MSH array (passed by ref.)
     110 N FS,I,L,L1,L2,X,Y
     111 S FS=$E(MSH(1,0),4),(L2,Y)=0,X=""
     112 F I=1:1 S L1=$L($G(MSH(I,0)),FS),L=L1+Y-1 D  Q:$L(X)!'$D(MSH(I,0))
     113 . S:L1=1 L=L+1
     114 . S:P'>L X=$P($G(MSH(I-1,0)),FS,P-L2)_$P($G(MSH(I,0)),FS,(P-Y))
     115 . S L2=Y,Y=L
     116 Q X
     117 ;
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSTCPA.m

    r613 r623  
    1 HLCSTCPA        ;OIFO-O/RJH - (TCP/IP) VMS ;07/26/2007  10:29
    2         ;;1.6;HEALTH LEVEL SEVEN;**84,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ; 1. port number is input from VMS COM file, such as HLSxxxxDSM.COM,
    6         ;    HLSxxxxCACHE.COM, or HLSxxxxGTM.COM file, where xxxx is port
    7         ;    number.
    8         ; 2. find the ien of #870(logical link file) for the multi-listener
    9         Q
    10         ;
    11 GTMPORT(%)      ; From tcpip ZFOO for GT.M
    12         ; %: device^port number
    13         N HLPORT
    14         S HLPORT=$P($G(%),"^",2)
    15         I $G(^%ZOSF("OS"))'["GT.M" D ^%ZTER Q
    16         D IEN
    17         Q
    18         ;
    19 PORT    ;
    20         ; HLPORT: port number of multi-listener
    21         ; input of DSM: % = device^port number of multi-listener
    22         ; input of Cache: port number of TCPIP
    23         ;
    24         N HLPORT
    25         S HLPORT=0
    26         I ^%ZOSF("OS")["OpenM" D
    27         . S HLPORT=$ZF("GETSYM","PORT")
    28         I ^%ZOSF("OS")["DSM" D
    29         . S HLPORT=$P(%,"^",2)
    30         ;
    31 IEN     ;
    32         ; HLIEN870: ien in #870 (logical link file)
    33         ; HLPRTS: port number in entry to be tested
    34         ;
    35         N HLIEN870
    36         I 'HLPORT D ^%ZTER Q
    37         S HLIEN870=0
    38         F  S HLIEN870=$O(^HLCS(870,"E","M",HLIEN870)) Q:'HLIEN870  D  Q:(HLPRTS=HLPORT)
    39         . S HLPRTS=$P(^HLCS(870,HLIEN870,400),"^",2)
    40         I 'HLIEN870 D ^%ZTER Q
    41         ;
    42         K HLPORT,HLPRTS
    43         ; patch 122
    44         S U="^"
    45         ;
    46         ;for Cache/VMS
    47         I ^%ZOSF("OS")["OpenM" D  Q
    48         . D CACHEVMS(HLIEN870)
    49         ;
    50         ;for DSM
    51         I ^%ZOSF("OS")["DSM" D  Q
    52         . S $P(%,"^",2)=HLIEN870   ;set % = device^ien of #870
    53         . K HLIEN870
    54         . D EN
    55         ;
    56         ;for GT.M
    57         I ^%ZOSF("OS")["GT.M" D  Q
    58         . S HLDP=HLIEN870   ;set HLDP = ien of #870
    59         . K HLIEN870
    60         . D GTMUCX
    61         ;
    62         D ^%ZTER
    63         Q
    64 GTMUCX  ; GT.M /VMS tcpip
    65         ;listener,  % = device^port
    66         S U="^",IO=$P(%,U)
    67         ; S IO(0)=$P O IO(0) ;Setup null device
    68         ; GTM specific code
    69         S @("$ZINTERRUPT=""I $$JOBEXAM^ZU($ZPOSITION)""")
    70         X "O IO:(RECORDSIZE=512)"
    71         D LISTEN^HLCSTCP
    72         C IO
    73         Q
    74         ;
    75         ; $ x=f$trnlnm("sys$net")  !This is our MBX device
    76         ; $!
    77         ; $! for GT.M
    78         ; $ assign 'f$trnlnm("SYS$NET")' SYS$NET
    79         ; $! Depending on how your command files are set up, you may need to
    80         ; $! run the GT.M profile file.
    81         ; $ @<user$:[gtmmgr]>gtmprofile.com
    82         ; $ forfoo="$" + f$parse("user$:[gtmmgr.r]ZFOO.exe")
    83         ; $ PORT=5000
    84         ; $ data="''x'^''PORT'"
    85         ; $ forfoo GTMPORT^HLCSTCPA("''data'")
    86         ;
    87 CACHEVMS(%)     ;Cache'/VMS tcpip
    88         ;listener,  % = HLDP
    89         I $G(%)="" D ^%ZTER Q
    90         ; patch 133
    91         S IO="SYS$NET",U="^",HLDP=%
    92         S IO(0)="_NLA0:" O IO(0) ;Setup null device
    93         ; **Cache'/VMS specific code**
    94         O IO::5 E  D MON^HLCSTCP("Openfail") Q
    95         X "U IO:(::""-M"")" ;Packet mode like DSM
    96         D LISTEN^HLCSTCP
    97         C IO
    98         Q
    99         ;
    100 EN      ; DSM/VMS tcpip
    101         ;listener,  % = device^HLDP
    102         I $G(%)="" D ^%ZTER Q
    103         ; patch 122
    104         ; S IO="SYS$NET",U="^",HLDP=$P(%,U,2)
    105         S U="^",IO=$P(%,U),HLDP=$P(%,U,2)
    106         ; patch 133
    107         S IO(0)="_NLA0:" O IO(0) ;Setup null device
    108         ; **VMS specific code, need to share device**
    109         O IO:(TCPDEV):60 E  D MON^HLCSTCP("Openfail") Q
    110         ; patch 122
    111         D LISTEN^HLCSTCP
    112         C IO
    113         Q
     1HLCSTCPA ;OIFO-O/RJH - (TCP/IP) VMS ;07/10/2003  10:12
     2 ;;1.6;HEALTH LEVEL SEVEN;**84**;Oct 13, 1995
     3 ;
     4 ; 1. port number is input from VMS HLSxxxxDSM.COM or HLSxxxxCACHE.COM
     5 ;    file, where xxxx is port number.
     6 ; 2. find the ien of #870(logical link file) for the HL7 multi-listener
     7 ; 3. call the appropriate entry:
     8 ;    for Cache: CACHEVMS^HLCSTCP(ien of #870)
     9 ;    for DSM:   EN^HLCSTCP
     10 Q
     11PORT ;
     12 ;HLIEN870: ien in #870 (logical link file)
     13 ;HLPORT: port number of multi-listener
     14 ;HLPRTS: port number in entry to be tested
     15 ;input of DSM: % = device^port number of multi-listener
     16 ;input of Cache: port number of TCPIP
     17 ;
     18 I ^%ZOSF("OS")["OpenM" D
     19 . S HLPORT=$ZF("GETSYM","PORT")
     20 I ^%ZOSF("OS")["DSM" D
     21 . S HLPORT=$P(%,"^",2)
     22 I 'HLPORT D ^%ZTER Q
     23 S HLIEN870=0
     24 F  S HLIEN870=$O(^HLCS(870,"E","M",HLIEN870)) Q:'HLIEN870  D  Q:(HLPRTS=HLPORT)
     25 . S HLPRTS=$P(^HLCS(870,HLIEN870,400),"^",2)
     26 I 'HLIEN870 D ^%ZTER Q
     27 ;
     28 K HLPORT,HLPRTS
     29 ;
     30 ;for Cache/VMS
     31 I ^%ZOSF("OS")["OpenM" D  Q
     32 .D CACHEVMS^HLCSTCP(HLIEN870)
     33 ;
     34 ;for DSM
     35 I ^%ZOSF("OS")["DSM" D  Q
     36 . S $P(%,"^",2)=HLIEN870   ;set % = device^ien of #870
     37 . K HLIEN870
     38 . D EN^HLCSTCP
     39 ;
     40 D ^%ZTER
     41 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLCSTERM.m

    r613 r623  
    1 HLCSTERM        ;ALB/RJS - SET UP VIDEO ATTRIBUTES ;06/27/2007  17:04
    2         ;;1.6;HEALTH LEVEL SEVEN;**40,49,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 TERM    ; -- set up term characteristics
    6         N X
    7         I '$D(IOST(0)) D HOME^%ZIS
    8         S X=$$IO D ENDR^%ZISS
    9         S (HLCON,HLCOFF)=""
    10         I $E(IOST,1,4)="C-VT" S HLCOFF=$C(13,27,91)_"?25l"_$C(13),HLCON=$C(27,91)_"?25h"
    11         Q
    12 HEADER  ;
    13         ;Write out Header
    14         ;
    15         N HLMIDDLE,HLLNGTH,HLJUST
    16         W @IOF,!
    17         S HLPARAM=$$PARAM^HLCS2
    18         S HLSITE=$P(HLPARAM,U,5),HLPROD=$P(HLPARAM,U,3)
    19         S HLHDR="SYSTEM LINK MONITOR for "_HLSITE_" ("_HLPROD_" System)"
    20         S HLMIDDLE=IOM\2,HLLNGTH=$L(HLHDR)\2,HLJUST=HLMIDDLE-HLLNGTH
    21         D WDATA^HLCSMON1(HLJUST,1,IORVON,IORVOFF,HLHDR,75)
    22         D WDATA^HLCSMON1(5,4,IOUON,IOUOFF,"NODE",8)
    23         D WDATA^HLCSMON1(16,3,"","","MESSAGES",8),WDATA^HLCSMON1(16,4,IOUON,IOUOFF,"RECEIVED",8)
    24         D WDATA^HLCSMON1(26,3,"","","MESSAGES",8),WDATA^HLCSMON1(26,4,IOUON,IOUOFF,"PROCESSED",9)
    25         D WDATA^HLCSMON1(37,3,"","","MESSAGES",8),WDATA^HLCSMON1(37,4,IOUON,IOUOFF,"TO SEND ",8)
    26         D WDATA^HLCSMON1(47,3,"","","MESSAGES",8),WDATA^HLCSMON1(47,4,IOUON,IOUOFF,"SENT    ",8)
    27         ; patch HL*1.6*122
    28         ; D WDATA^HLCSMON1(57,3,"","","DEVICE",8),WDATA^HLCSMON1(57,4,IOUON,IOUOFF,"TYPE   ",8)
    29         D WDATA^HLCSMON1(57,3,"","","DEVICE",8),WDATA^HLCSMON1(57,4,IOUON,IOUOFF,"TYPE   ",6)
    30         ;
    31         D WDATA^HLCSMON1(66,4,IOUON,IOUOFF,"STATE",8)
    32         Q
    33 KVAR    ;
    34         D KILL^%ZISS
    35         K HLCON,HLCOFF
    36         Q
    37 IO()    ; -- what device params
    38         Q "IOELALL;IOELEOL;IORESET;IORVON;IORVOFF;IOIL;IOSTBM;IOSC;IORC;IOEDEOP;IOINHI;IOINORM;IOUON;IOUOFF;IOBOFF;IOBON"
    39         Q
     1HLCSTERM ;ALB/RJS - SET UP VIDEO ATTRIBUTES - 8/1/94 ;07/28/98  09:43
     2 ;;1.6;HEALTH LEVEL SEVEN;**40,49**;Oct 13, 1995
     3TERM ; -- set up term characteristics
     4 N X
     5 I '$D(IOST(0)) D HOME^%ZIS
     6 S X=$$IO D ENDR^%ZISS
     7 S (HLCON,HLCOFF)=""
     8 I $E(IOST,1,4)="C-VT" S HLCOFF=$C(13,27,91)_"?25l"_$C(13),HLCON=$C(27,91)_"?25h"
     9 Q
     10HEADER ;
     11 ;Write out Header
     12 ;
     13 N HLMIDDLE,HLLNGTH,HLJUST
     14 W @IOF,!
     15 S HLPARAM=$$PARAM^HLCS2
     16 S HLSITE=$P(HLPARAM,U,5),HLPROD=$P(HLPARAM,U,3)
     17 S HLHDR="SYSTEM LINK MONITOR for "_HLSITE_" ("_HLPROD_" System)"
     18 S HLMIDDLE=IOM\2,HLLNGTH=$L(HLHDR)\2,HLJUST=HLMIDDLE-HLLNGTH
     19 D WDATA^HLCSMON1(HLJUST,1,IORVON,IORVOFF,HLHDR,75)
     20 D WDATA^HLCSMON1(5,4,IOUON,IOUOFF,"NODE",8)
     21 D WDATA^HLCSMON1(16,3,"","","MESSAGES",8),WDATA^HLCSMON1(16,4,IOUON,IOUOFF,"RECEIVED",8)
     22 D WDATA^HLCSMON1(26,3,"","","MESSAGES",8),WDATA^HLCSMON1(26,4,IOUON,IOUOFF,"PROCESSED",9)
     23 D WDATA^HLCSMON1(37,3,"","","MESSAGES",8),WDATA^HLCSMON1(37,4,IOUON,IOUOFF,"TO SEND ",8)
     24 D WDATA^HLCSMON1(47,3,"","","MESSAGES",8),WDATA^HLCSMON1(47,4,IOUON,IOUOFF,"SENT    ",8)
     25 D WDATA^HLCSMON1(57,3,"","","DEVICE",8),WDATA^HLCSMON1(57,4,IOUON,IOUOFF,"TYPE   ",8)
     26 D WDATA^HLCSMON1(66,4,IOUON,IOUOFF,"STATE",8)
     27 Q
     28KVAR ;
     29 D KILL^%ZISS
     30 K HLCON,HLCOFF
     31 Q
     32IO() ; -- what device params
     33 Q "IOELALL;IOELEOL;IORESET;IORVON;IORVOFF;IOIL;IOSTBM;IOSC;IORC;IOEDEOP;IOINHI;IOINORM;IOUON;IOUOFF;IOBOFF;IOBON"
     34 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLDIE.m

    r613 r623  
    1 HLDIE   ;CIOFO-O/LJA - Direct 772 & 773 Sets ; 10/19/2007 11:15
    2         ;;1.6;HEALTH LEVEL SEVEN;**109,122**;Oct 13,1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         Q
    5         ;
    6         ; Rules: if any of these rules is broken, FILE^DIE is called instead
    7         ;
    8         ;         * Can't edit files other than 772,773
    9         ;         * Don't pass IENS value with multiples IENs.  You can only
    10         ;             edit one IEN at a time!
    11         ;         * Only flag "S" is honored.  Flag "K" is ignored. Other
    12         ;             flags result in FILE^DIE being called.
    13         ;         * Can't edit ^HLMA(IEN,90) data.
    14         ;         * Can't edit ^HLMA(IEN,91) data.
    15         ;         * Can't edit ^HL(772,IEN,"IN") data (field #200, MESSAGE TEXT)
    16         ;         * No checking of data performed!  (Data format MUST be OK.)
    17         ;         * No locking of records in files 772 or 773. (Locks on queues.)
    18         ;
    19 FILE(FLAGS,ROOT,ERR,SUB,RTN)    ; FILE^DIE functional equivalent...
    20         ; This call has similar parameters to FILE^DIE, but changes data
    21         ; using hard sets.  The first two parameters of this API are the
    22         ; same as FILE^DIE.  So, if any file other than 772 or 773 is being
    23         ; edited, this API just passes on the FLAGS,ROOT,ERR parameters to
    24         ; FILE^DIE and quits.  If file 772 or 773 is being edited, the hard
    25         ; set code in HLDIE772 and HLDIE773 is called.
    26         ;
    27         N DEBUG,FILE,HLEDITOR,LERR,IEN,X,XECMCODE
    28         ;
    29         S DT=$$NOW^XLFDT\1
    30         ;
    31         D BEGIN ; Debug call at beginning or process
    32         ;
    33         ; Check FILE, IEN, FIELDs passed, etc...
    34         I '$$CHECKS D  QUIT  ;->
    35         .
    36         .  S HLEDITOR="FILE^DIE"
    37         .
    38         .  ; Call FILEMAN...
    39         .  D FILE^DIE($G(FLAGS),$G(ROOT),$G(ERR))
    40         .
    41         .  ; Debug call made even with Fileman...
    42         .  D END
    43         ;
    44         S HLEDITOR="FILE^HLDIE"
    45         ;
    46         ; If this point is reached, file 772 or 773 is being edited, data
    47         ; in ROOT() has been checked, and data is being hard set...
    48         ;
    49         ;
    50         ; Make sure ERR is defined...
    51         I $G(ERR)']"" N HLERR S ERR="HLERR"
    52         ;
    53         ; All editing occurs in this call...
    54         D EDITALL(.ROOT,FILE,IEN)
    55         ;
    56         ; Store debug data if XTMP debug string set...
    57         D END
    58         ;
    59         ;check if ROOT needs to be retained
    60         I FLAGS'["S" K @ROOT,FLAGS
    61         ;
    62         Q
    63         ;
    64 EDITALL(ROOT,FILE,IEN)  ; Edit 772 or 773 by direct sets...
    65         ;
    66         ; FILE,IEN -- optional (parsed from ROOT())
    67         ;
    68         N ERRNO,FIELD,GBL,NODE,ROUTINE,TAG,VALUE,XRF
    69         ;
    70         S GBL=$$GBL(FILE,+IEN)
    71         ;
    72         ;check if .01="@" for deletion of record...
    73         I $G(@ROOT@(FILE,IEN,.01))="@" D  Q
    74         .I FILE=773 D DEL773^HLUOPT3(+IEN) Q
    75         .I FILE=772 D DEL772^HLUOPT3(+IEN)
    76         ;
    77         ; patch HL*1.6*122: MPI-client/server
    78         ; If no data in record passed in, log an error and quit...
    79         ; I '$D(@GBL) D  Q  ; Remember.  GBL contains IEN...
    80         N HLDGBL
    81         F  L +@GBL:10 Q:$T  H 1
    82         S HLDGBL=$D(@GBL)
    83         L -@GBL
    84         I 'HLDGBL D  Q  ; Remember.  GBL contains IEN...
    85         .  S ERRNO=$$ERRNO(601,"The entry does not exist.",FILE,2)
    86         .  S @ERR@("DIERR",+ERRNO,"PARAM","IENS")=IEN_$S(IEN'[",":",",1:"")
    87         ;
    88         ;
    89         ; What routine holds the file-specific field/xref set code?
    90         S ROUTINE=$S(FILE=772:"HLDIE772",FILE=773:"HLDIE773",1:"")
    91         ;
    92         ; Load NODEs...
    93         D GETNODES(FILE,+IEN,.NODE)
    94         ;
    95         ; When a field is edited, the NODE(1) is changed
    96         ;
    97         ; Edit NODE(1), adding new values, and set XRF(XREF) nodes...
    98         S FIELD=0
    99         F  S FIELD=$O(@ROOT@(FILE,IEN,FIELD)) Q:FIELD'>0  D
    100         .  ; VALUE = value passed in by process that is to be stored in file
    101         .  S VALUE=$G(@ROOT@(FILE,IEN,FIELD))
    102         .
    103         .  ; If field should be deleted, VALUE will equal @...
    104         .  I VALUE="@" S VALUE=""
    105         .
    106         .  ; Get and check tag...
    107         .  S TAG="F"_(FILE-770)_$TR(FIELD,".","")_U_ROUTINE
    108         .  S TAG(1)=$T(@TAG) I TAG(1)']"" D  QUIT  ;->
    109         .  .  S ERRNO=$$ERRNO(501,"No set logic for file #"_FILE_"'s field# "_FIELD,FILE,3)
    110         .  .  S @ERR@("DIERR",+ERRNO,"PARAM",1)=FIELD
    111         .  .  S @ERR@("DIERR",+ERRNO,"PARAM","FIELD")=FIELD
    112         .
    113         .  ; Call the subroutine below that is for the specific field...
    114         .  ; (No editing of xrefs or global data occurs in these calls.)
    115         .  D @("F"_(FILE-770)_$TR(FIELD,".","")_U_ROUTINE)
    116         ;
    117         ; If no data actually changed, quit...
    118         QUIT:'$D(NODE("CHG"))  ;->
    119         ;
    120         ; patch HL*1.6*122: MPI-client/server
    121         I FILE=773 D
    122         . F  L +^HLMA(IEN):10 Q:$T  H 1
    123         E  D
    124         . F  L +^HL(772,IEN):10 Q:$T  H 1
    125         ;
    126         ; Store changes in the global now...
    127         D STORE(FILE,IEN,.NODE)
    128         ;
    129         ; Set xrefs to correspond to the just-stored data...
    130         S XRF=""
    131         F  S XRF=$O(XRF(XRF)) Q:XRF']""  D
    132         .  D @("XRF"_XRF_U_ROUTINE)
    133         ;
    134         ; patch HL*1.6*122: MPI-client/server
    135         I FILE=773 L -^HLMA(IEN)
    136         E  L -^HL(772,IEN)
    137         ;
    138         Q
    139         ;
    140 GETNODES(FILE,IEN,NODE) ; Load pre-change data for each node in
    141         ; NODE(node,0), and load node to be changed in NODE(node,1).
    142         ; GBL -- req
    143         F NODE=0,1,2,"P","S" D
    144         .  ; After setting, NODE(NODE,0) will equal each other.
    145         .  ; However, after each edited field is processed, the pieces of
    146         .  ; data in NODE(NODE,1) will be changed.  The pre and post nodes
    147         .  ; then are of comparison value.
    148         .  S NODE(NODE,0)=$G(@GBL@(NODE)) ; Pre-change node
    149         .  S NODE(NODE,1)=NODE(NODE,0) ; Node that is changed
    150         Q
    151         ;
    152 STORE(FILE,IEN,NODE)    ; Store changes in file...
    153         N DATA,ND
    154         ;
    155         ; Loop thru change nodes, get changed data, and store it...
    156         S ND=""
    157         F  S ND=$O(NODE("CHG",ND)) Q:ND']""  D
    158         .  S DATA=$G(NODE(ND,1))
    159         .  ; Even if no data no node, store it.  (Will be removed by purge.)
    160         .  I FILE=772 S ^HL(772,+IEN,ND)=DATA
    161         .  I FILE=773 S ^HLMA(+IEN,ND)=DATA
    162         ;
    163         QUIT
    164         ;
    165 GBL(FILE,IEN)   QUIT $S(FILE=772:"^HL(772,"_+IEN_")",1:"^HLMA("_+IEN_")")
    166         ;
    167 CHKFLD(FILE,FIELD)      ; Does passed-in field exist?
    168         ; Returns -- @ERR@(...) ->
    169         ;
    170         ; Quit if field exists...
    171         QUIT:$D(^DD(+FILE,+FIELD)) 1 ;->
    172         ;
    173         ; Field doesn't exist.  Log error...
    174         S ERRNO=$$ERRNO(501,"File #"_FILE_" does not contain a field "_FIELD_".",FILE,3)
    175         S @ERR@("DIERR",+ERRNO,"PARAM",1)=FIELD
    176         S @ERR@("DIERR",+ERRNO,"PARAM","FIELD")=FIELD
    177         ;
    178         Q ""
    179         ;
    180 ERRNO(NUM,TXT,FILE,PNO) ; Return next ERROR number and create general data...
    181         N NO
    182         S NO=$G(@ERR@("DIERR"))+1,@ERR@("DIERR")=+NO_U_+NO
    183         S @ERR@("DIERR",NO)=NUM
    184         S @ERR@("DIERR",NO,"PARAM",0)=PNO
    185         S @ERR@("DIERR",NO,"PARAM","FILE")=FILE
    186         S @ERR@("DIERR",NO,"TEXT",1)=TXT
    187         S @ERR@("DIERR","E",NUM,NO)=""
    188         Q NO
    189         ;
    190 GENLERR(ETXT)   ; Store GENERAL (and fatal) error...
    191         ; ERR -- req
    192         N NO
    193         S NO=$G(@ERR@("DIERR"))+1,@ERR@("DIERR")=+NO_U_+NO
    194         S @ERR@("DIERR",NO)=999_U_ETXT ; Made up error number
    195         Q
    196         ;
    197 CHECKS()        ; Check ROOT() for file and validity of data...
    198         ; FLAGS, ROOT() -- req --> FILE,IEN
    199         N I,OK,FIELD
    200         ;
    201         ;check the file & ien
    202         S FILE=$O(@ROOT@(0))
    203         I FILE'=772,FILE'=773 D  QUIT "" ;->
    204         .  S IEN=$S(FILE:$O(@ROOT@(FILE,0)),1:0) ; Set for debugging
    205         ;
    206         ; ;shouldn't be more than 1 file!
    207         QUIT:$O(@ROOT@(FILE)) "" ;->
    208         ;
    209         ;check the ien structure, and that only ien passed...
    210         S IEN=$O(@ROOT@(FILE,0))
    211         ; Structure check...
    212         QUIT:$P(IEN,",")'=+IEN_"," "" ;->
    213         ; Is it numeric?
    214         QUIT:'(+IEN) "" ;->
    215         ; Has more than one IEN been passed?
    216         QUIT:($O(@ROOT@(FILE,IEN))'="") "" ;->
    217         ;
    218         ;check the flags.  Only K and S flags allowed...
    219         I $L(FLAGS) D  QUIT:'OK "" ;->
    220         .  S OK=1
    221         .  F I=0:1:$L(FLAGS) I $E(FLAGS,I)'="K",$E(FLAGS,I)'="S" S OK=0
    222         ;
    223         ; Check for existence of FIELD in FILE's DD & if an excluded field.
    224         ; (See rules for fields which cannot be updated by FILE^HLDIE.)
    225         S FIELD=0,OK=1
    226         F  S FIELD=$O(@ROOT@(FILE,IEN,FIELD)) Q:FIELD=""  D  Q:'OK
    227         .  I '$$CHKFLD(FILE,FIELD) S OK=0 Q
    228         .  I FILE=773,FIELD\1=90 S OK=0 Q
    229         .  I FILE=773,FIELD\1=91 S OK=0 Q
    230         .  I FILE=772,FIELD=200 S OK=0 Q
    231         ;
    232         ; If not OK to use FILE^HLDIE, skip any further testing...
    233         QUIT:'OK "" ;->
    234         ;
    235         ;                    *** WARNING ***
    236         ; The following check **MUST** be removed after FILE^HLDIE is working.
    237         ;
    238         ; Final check for whether FILE^HLDIE should be used...
    239         I $G(^XTMP("HLDIE-DEBUG","CALL"))]"" QUIT "" ;->
    240         ; If this node exists and follows null, FILE^DIE will be used.
    241         ; Otherwise, execution defaults to using FILE^HLDIE.
    242         ;
    243         Q OK
    244         ;
    245 BEGIN   ; Always call here before any ^HLDIE or ^DIE calls...
    246         D DEBUG(1)
    247         Q
    248         ;
    249 END     ; Always call here after all ^HLDIE or ^DIE actions...
    250         D DEBUG(2)
    251         Q
    252         ;
    253 DEBUG(LOC)      ; Debug presets and setup...
    254         ; Most variables created here should be left around.  These variables
    255         ; are newed above.
    256         N STORE
    257         ;
    258         S RTN=$G(RTN),SUB=$G(SUB)
    259         ;
    260         ; First-time (beginning) call setups...
    261         I LOC=1 D
    262         .  S RTN=$S(RTN]"":RTN,1:"HLDIE")_"~"_$S(RTN="HLDIE":"FILE",1:SUB)
    263         .  S DEBUG=$G(^XTMP("HLDIE-DEBUG","STATUS"))
    264         .  S XECMCODE=$P(DEBUG,U,3)
    265         ; DEBUG is always called at beginning (LOC=1) and end (LOC=2) or
    266         ; FILE^HLDIE.  So, set up variables only once, at beginning...
    267         ;
    268         ; Setup that is individual to each (1 or 2) call...
    269         S STORE=$P(DEBUG,U,LOC),STORE=$S(STORE=1:1,STORE=2:2,1:"")
    270         ; Some, All, or no data stored?
    271         ;
    272         ; If no STORE instructions, and no M code to specify STORE, quit...
    273         QUIT:'STORE&($G(XECMCODE)'=1)  ;->
    274         ;
    275         ; Call DEBUG to STORE data...
    276         D DEBUG^HLDIEDBG(RTN,LOC,STORE,XECMCODE)
    277         ;
    278         Q
    279         ;
    280 EOR     ;HLDIE - Direct 772 & 773 Sets ; 11/18/2003 11:17
     1HLDIE ;CIOFO-O/LJA - Direct 772 & 773 Sets ; 11/18/2003 11:17
     2 ;;1.6;HEALTH LEVEL SEVEN;**109**;Oct 13,1995
     3 ;
     4 ; Rules: if any of these rules is broken, FILE^DIE is called instead
     5 ;
     6 ;         * Can't edit files other than 772,773
     7 ;         * Don't pass IENS value with multiples IENs.  You can only
     8 ;             edit one IEN at a time!
     9 ;         * Only flag "S" is honored.  Flag "K" is ignored. Other
     10 ;             flags result in FILE^DIE being called.
     11 ;         * Can't edit ^HLMA(IEN,90) data.
     12 ;         * Can't edit ^HLMA(IEN,91) data.
     13 ;         * Can't edit ^HL(772,IEN,"IN") data (field #200, MESSAGE TEXT)
     14 ;         * No checking of data performed!  (Data format MUST be OK.)
     15 ;         * No locking of records in files 772 or 773. (Locks on queues.)
     16 ;
     17FILE(FLAGS,ROOT,ERR,SUB,RTN) ; FILE^DIE functional equivalent...
     18 ; This call has similar parameters to FILE^DIE, but changes data
     19 ; using hard sets.  The first two parameters of this API are the
     20 ; same as FILE^DIE.  So, if any file other than 772 or 773 is being
     21 ; edited, this API just passes on the FLAGS,ROOT,ERR parameters to
     22 ; FILE^DIE and quits.  If file 772 or 773 is being edited, the hard
     23 ; set code in HLDIE772 and HLDIE773 is called.
     24 ;
     25 N DEBUG,FILE,HLEDITOR,LERR,IEN,X,XECMCODE
     26 ;
     27 S DT=$$NOW^XLFDT\1
     28 ;
     29 D BEGIN ; Debug call at beginning or process
     30 ;
     31 ; Check FILE, IEN, FIELDs passed, etc...
     32 I '$$CHECKS D  QUIT  ;->
     33 .
     34 .  S HLEDITOR="FILE^DIE"
     35 .
     36 .  ; Call FILEMAN...
     37 .  D FILE^DIE($G(FLAGS),$G(ROOT),$G(ERR))
     38 .
     39 .  ; Debug call made even with Fileman...
     40 .  D END
     41 ;
     42 S HLEDITOR="FILE^HLDIE"
     43 ;
     44 ; If this point is reached, file 772 or 773 is being edited, data
     45 ; in ROOT() has been checked, and data is being hard set...
     46 ;
     47 ;
     48 ; Make sure ERR is defined...
     49 I $G(ERR)']"" N HLERR S ERR="HLERR"
     50 ;
     51 ; All editing occurs in this call...
     52 D EDITALL(.ROOT,FILE,IEN)
     53 ;
     54 ; Store debug data if XTMP debug string set...
     55 D END
     56 ;
     57 ;check if ROOT needs to be retained
     58 I FLAGS'["S" K @ROOT,FLAGS
     59 ;
     60 Q
     61 ;
     62EDITALL(ROOT,FILE,IEN) ; Edit 772 or 773 by direct sets...
     63 ;
     64 ; FILE,IEN -- optional (parsed from ROOT())
     65 ;
     66 N ERRNO,FIELD,GBL,NODE,ROUTINE,TAG,VALUE,XRF
     67 ;
     68 S GBL=$$GBL(FILE,+IEN)
     69 ;
     70 ;check if .01="@" for deletion of record...
     71 I $G(@ROOT@(FILE,IEN,.01))="@" D  Q
     72 .I FILE=773 D DEL773^HLUOPT3(+IEN) Q
     73 .I FILE=772 D DEL772^HLUOPT3(+IEN)
     74 ;
     75 ; If no data in record passed in, log an error and quit...
     76 I '$D(@GBL) D  Q  ; Remember.  GBL contains IEN...
     77 .  S ERRNO=$$ERRNO(601,"The entry does not exist.",FILE,2)
     78 .  S @ERR@("DIERR",+ERRNO,"PARAM","IENS")=IEN_$S(IEN'[",":",",1:"")
     79 ;
     80 ;
     81 ; What routine holds the file-specific field/xref set code?
     82 S ROUTINE=$S(FILE=772:"HLDIE772",FILE=773:"HLDIE773",1:"")
     83 ;
     84 ; Load NODEs...
     85 D GETNODES(FILE,+IEN,.NODE)
     86 ;
     87 ; When a field is edited, the NODE(1) is changed
     88 ;
     89 ; Edit NODE(1), adding new values, and set XRF(XREF) nodes...
     90 S FIELD=0
     91 F  S FIELD=$O(@ROOT@(FILE,IEN,FIELD)) Q:FIELD'>0  D
     92 .  ; VALUE = value passed in by process that is to be stored in file
     93 .  S VALUE=$G(@ROOT@(FILE,IEN,FIELD))
     94 .
     95 .  ; If field should be deleted, VALUE will equal @...
     96 .  I VALUE="@" S VALUE=""
     97 .
     98 .  ; Get and check tag...
     99 .  S TAG="F"_(FILE-770)_$TR(FIELD,".","")_U_ROUTINE
     100 .  S TAG(1)=$T(@TAG) I TAG(1)']"" D  QUIT  ;->
     101 .  .  S ERRNO=$$ERRNO(501,"No set logic for file #"_FILE_"'s field# "_FIELD,FILE,3)
     102 .  .  S @ERR@("DIERR",+ERRNO,"PARAM",1)=FIELD
     103 .  .  S @ERR@("DIERR",+ERRNO,"PARAM","FIELD")=FIELD
     104 .
     105 .  ; Call the subroutine below that is for the specific field...
     106 .  ; (No editing of xrefs or global data occurs in these calls.)
     107 .  D @("F"_(FILE-770)_$TR(FIELD,".","")_U_ROUTINE)
     108 ;
     109 ; If no data actually changed, quit...
     110 QUIT:'$D(NODE("CHG"))  ;->
     111 ;
     112 ; Store changes in the global now...
     113 D STORE(FILE,IEN,.NODE)
     114 ;
     115 ; Set xrefs to correspond to the just-stored data...
     116 S XRF=""
     117 F  S XRF=$O(XRF(XRF)) Q:XRF']""  D
     118 .  D @("XRF"_XRF_U_ROUTINE)
     119 ;
     120 Q
     121 ;
     122GETNODES(FILE,IEN,NODE) ; Load pre-change data for each node in
     123 ; NODE(node,0), and load node to be changed in NODE(node,1).
     124 ; GBL -- req
     125 F NODE=0,1,2,"P","S" D
     126 .  ; After setting, NODE(NODE,0) will equal each other.
     127 .  ; However, after each edited field is processed, the pieces of
     128 .  ; data in NODE(NODE,1) will be changed.  The pre and post nodes
     129 .  ; then are of comparison value.
     130 .  S NODE(NODE,0)=$G(@GBL@(NODE)) ; Pre-change node
     131 .  S NODE(NODE,1)=NODE(NODE,0) ; Node that is changed
     132 Q
     133 ;
     134STORE(FILE,IEN,NODE) ; Store changes in file...
     135 N DATA,ND
     136 ;
     137 ; Loop thru change nodes, get changed data, and store it...
     138 S ND=""
     139 F  S ND=$O(NODE("CHG",ND)) Q:ND']""  D
     140 .  S DATA=$G(NODE(ND,1))
     141 .  ; Even if no data no node, store it.  (Will be removed by purge.)
     142 .  I FILE=772 S ^HL(772,+IEN,ND)=DATA
     143 .  I FILE=773 S ^HLMA(+IEN,ND)=DATA
     144 ;
     145 QUIT
     146 ;
     147GBL(FILE,IEN) QUIT $S(FILE=772:"^HL(772,"_+IEN_")",1:"^HLMA("_+IEN_")")
     148 ;
     149CHKFLD(FILE,FIELD) ; Does passed-in field exist?
     150 ; Returns -- @ERR@(...) ->
     151 ;
     152 ; Quit if field exists...
     153 QUIT:$D(^DD(+FILE,+FIELD)) 1 ;->
     154 ;
     155 ; Field doesn't exist.  Log error...
     156 S ERRNO=$$ERRNO(501,"File #"_FILE_" does not contain a field "_FIELD_".",FILE,3)
     157 S @ERR@("DIERR",+ERRNO,"PARAM",1)=FIELD
     158 S @ERR@("DIERR",+ERRNO,"PARAM","FIELD")=FIELD
     159 ;
     160 Q ""
     161 ;
     162ERRNO(NUM,TXT,FILE,PNO) ; Return next ERROR number and create general data...
     163 N NO
     164 S NO=$G(@ERR@("DIERR"))+1,@ERR@("DIERR")=+NO_U_+NO
     165 S @ERR@("DIERR",NO)=NUM
     166 S @ERR@("DIERR",NO,"PARAM",0)=PNO
     167 S @ERR@("DIERR",NO,"PARAM","FILE")=FILE
     168 S @ERR@("DIERR",NO,"TEXT",1)=TXT
     169 S @ERR@("DIERR","E",NUM,NO)=""
     170 Q NO
     171 ;
     172GENLERR(ETXT) ; Store GENERAL (and fatal) error...
     173 ; ERR -- req
     174 N NO
     175 S NO=$G(@ERR@("DIERR"))+1,@ERR@("DIERR")=+NO_U_+NO
     176 S @ERR@("DIERR",NO)=999_U_ETXT ; Made up error number
     177 Q
     178 ;
     179CHECKS() ; Check ROOT() for file and validity of data...
     180 ; FLAGS, ROOT() -- req --> FILE,IEN
     181 N I,OK,FIELD
     182 ;
     183 ;check the file & ien
     184 S FILE=$O(@ROOT@(0))
     185 I FILE'=772,FILE'=773 D  QUIT "" ;->
     186 .  S IEN=$S(FILE:$O(@ROOT@(FILE,0)),1:0) ; Set for debugging
     187 ;
     188 ; ;shouldn't be more than 1 file!
     189 QUIT:$O(@ROOT@(FILE)) "" ;->
     190 ;
     191 ;check the ien structure, and that only ien passed...
     192 S IEN=$O(@ROOT@(FILE,0))
     193 ; Structure check...
     194 QUIT:$P(IEN,",")'=+IEN_"," "" ;->
     195 ; Is it numeric?
     196 QUIT:'(+IEN) "" ;->
     197 ; Has more than one IEN been passed?
     198 QUIT:($O(@ROOT@(FILE,IEN))'="") "" ;->
     199 ;
     200 ;check the flags.  Only K and S flags allowed...
     201 I $L(FLAGS) D  QUIT:'OK "" ;->
     202 .  S OK=1
     203 .  F I=0:1:$L(FLAGS) I $E(FLAGS,I)'="K",$E(FLAGS,I)'="S" S OK=0
     204 ;
     205 ; Check for existence of FIELD in FILE's DD & if an excluded field.
     206 ; (See rules for fields which cannot be updated by FILE^HLDIE.)
     207 S FIELD=0,OK=1
     208 F  S FIELD=$O(@ROOT@(FILE,IEN,FIELD)) Q:FIELD=""  D  Q:'OK
     209 .  I '$$CHKFLD(FILE,FIELD) S OK=0 Q
     210 .  I FILE=773,FIELD\1=90 S OK=0 Q
     211 .  I FILE=773,FIELD\1=91 S OK=0 Q
     212 .  I FILE=772,FIELD=200 S OK=0 Q
     213 ;
     214 ; If not OK to use FILE^HLDIE, skip any further testing...
     215 QUIT:'OK "" ;->
     216 ;
     217 ;                    *** WARNING ***
     218 ; The following check **MUST** be removed after FILE^HLDIE is working.
     219 ;
     220 ; Final check for whether FILE^HLDIE should be used...
     221 I $G(^XTMP("HLDIE-DEBUG","CALL"))]"" QUIT "" ;->
     222 ; If this node exists and follows null, FILE^DIE will be used.
     223 ; Otherwise, execution defaults to using FILE^HLDIE.
     224 ;
     225 Q OK
     226 ;
     227BEGIN ; Always call here before any ^HLDIE or ^DIE calls...
     228 D DEBUG(1)
     229 Q
     230 ;
     231END ; Always call here after all ^HLDIE or ^DIE actions...
     232 D DEBUG(2)
     233 Q
     234 ;
     235DEBUG(LOC) ; Debug presets and setup...
     236 ; Most variables created here should be left around.  These variables
     237 ; are newed above.
     238 N STORE
     239 ;
     240 S RTN=$G(RTN),SUB=$G(SUB)
     241 ;
     242 ; First-time (beginning) call setups...
     243 I LOC=1 D
     244 .  S RTN=$S(RTN]"":RTN,1:"HLDIE")_"~"_$S(RTN="HLDIE":"FILE",1:SUB)
     245 .  S DEBUG=$G(^XTMP("HLDIE-DEBUG","STATUS"))
     246 .  S XECMCODE=$P(DEBUG,U,3)
     247 ; DEBUG is always called at beginning (LOC=1) and end (LOC=2) or
     248 ; FILE^HLDIE.  So, set up variables only once, at beginning...
     249 ;
     250 ; Setup that is individual to each (1 or 2) call...
     251 S STORE=$P(DEBUG,U,LOC),STORE=$S(STORE=1:1,STORE=2:2,1:"")
     252 ; Some, All, or no data stored?
     253 ;
     254 ; If no STORE instructions, and no M code to specify STORE, quit...
     255 QUIT:'STORE&($G(XECMCODE)'=1)  ;->
     256 ;
     257 ; Call DEBUG to STORE data...
     258 D DEBUG^HLDIEDBG(RTN,LOC,STORE,XECMCODE)
     259 ;
     260 Q
     261 ;
     262EOR ;HLDIE - Direct 772 & 773 Sets ; 11/18/2003 11:17
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLFNC.m

    r613 r623  
    1 HLFNC   ;AISC/SAW/OAK-OIFO/RBN-Routine of Functions and Other Calls Used for HL7 Messages  ;03/26/2008  11:34
    2         ;;1.6;HEALTH LEVEL SEVEN;**38,42,51,66,141**;Oct 13, 1995;Build 11
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 HLNAME(X,HLECDE)        ;Convert a name in DHCP format to HL7 format
    6         ; INPUT: X - Name in DHCP format
    7         ;        Optional - HLECDE - HL7 encoding chars
    8         ;**** NOTE: ****
    9         ;If this function is called without HLECDE as parameter than HLECH
    10         ;must be define.
    11         ;
    12         Q:'$D(X) ""  Q:X="" ""
    13         I '$D(HLECH),'$D(HLECDE) Q ""
    14         I $D(HLECDE) N HLECH S HLECH=HLECDE
    15         I '$D(HLECH) Q ""
    16         N %,X1,X2,Y
    17         S X1=$P(X,",",2),X2=$L(X1," "),Y=$P(X,",")_$E(HLECH)_$P(X1," ") I X2 F %=2:1:X2 Q:$P(X1," ",%)']""  S Y=Y_$E(HLECH)_$P(X1," ",%)
    18         Q Y
    19         ;
    20 FMNAME(X,HLECDE)        ;Convert a name in HL7 format to DHCP format
    21         ; INPUT: X - Name in HL7 format
    22         ;        Optional - HLECDE - HL7 encoding chars
    23         ;**** NOTE: ****
    24         ;If this function is called without HLECDE as parameter than HLECH
    25         ;must be define.
    26         ;
    27         Q:'$D(X) ""  Q:X="" ""
    28         I '$D(HLECH),'$D(HLECDE) Q ""
    29         I $D(HLECDE) N HLECH S HLECH=HLECDE
    30         I '$D(HLECH) Q ""
    31         N %,X1 S X1=$L(X,$E(HLECH)),Y="" F %=1:1:X1 D
    32         .I $P(X,$E(HLECH),%)]"",$P(X,$E(HLECH),%)'="""""" D
    33         ..;Only last name,first name.
    34         ..I %<3 S Y=Y_$P(X,$E(HLECH),%)_$S(%=1:",",1:"") Q
    35         ..S Y=Y_" "_$P(X,$E(HLECH),%)
    36         Q Y
    37         ;
    38 HLDATE(X,Y)     ;Convert date, date/time or time only in FM format to HL7 format
    39         ;Optional Variables:
    40         ;Y = The type of format to be returned if you want to force return of a
    41         ;    specific format.  Y must be equal to one of the following:
    42         ;    DT - Date only
    43         ;    TM - Time only
    44         ;    TS - Date and time
    45         I X="" Q ""
    46         S Y=$G(Y)
    47         N %,Z
    48         I $L(X)<7 D  Q % ;Time input
    49         . S %=$S(X=2400:"0000",$L(X)<4:$E(X_"000",1,4),1:X) S:$L(%)=5 %=%_0
    50         . Q
    51         I Y="TM" D  Q % ;Only time
    52         . S %=$P(X,".",2),%=$S(%="":"",$E(%,1,2)=24:"0000",$L(%)<4:$E(%_"000",1,4),1:%) S:$L(%)=5 %=%_0
    53         . Q
    54         S %=$$FMTHL7^XLFDT(X)
    55         Q $S(Y="DT":$E(%,1,8),1:%)
    56         ;
    57 FMDATE(X)       ; Convert a date, date/time or time only in HL7 format to FM format
    58         I X="" Q ""
    59         N %
    60         S %=$P($TR(X,"+-","^"),"^")
    61         I $L(X)<7 Q %
    62         Q $$HL7TFM^XLFDT(X)
    63         ;
    64 M10(X,HLECDE)   ; M10  check digit scheme
    65         ; INPUT : X - ID number
    66         ;        Optional HLECDE - Encoding chars
    67         ;**** NOTE: ****
    68         ;If this function is called without HLECDE as parameter then HLECH
    69         ;must be defined.
    70         ;Return X if encoding character is not defined
    71         ;Return X with encoding characters concatenated if X is alphanumeric
    72         ;
    73         N HLCNT,HLODD,HLEVEN,HLX1,HLDIGIT
    74         Q:'$D(X) ""
    75         I $D(HLECDE) N HLECH S HLECH=HLECDE
    76         ;Return X if encoding character is not defined
    77         I '$D(HLECH) Q X
    78         ;Return X with encoding characters concatenated if X is alphanumeric
    79         I '(X?1.N) Q X_$E(HLECH)_$E(HLECH)
    80         ;
    81         S HLX1=+X
    82         S HLODD=""
    83         F HLCNT=$L(HLX1):-2:1 S HLODD=HLODD_$E(HLX1,HLCNT)
    84         S HLODD=HLODD*2
    85         S HLEVEN=""
    86         F HLCNT=($L(HLX1)-1):-2:1 S HLEVEN=HLEVEN_$E(HLX1,HLCNT)
    87         S HLX1=HLEVEN_HLODD
    88         S HLDIGIT=0
    89         F HLCNT=1:1:$L(HLX1) S HLDIGIT=HLDIGIT+$E(HLX1,HLCNT)
    90         S HLDIGIT=((HLDIGIT\10+1)*10-HLDIGIT)#10
    91         Q X_$E(HLECH)_HLDIGIT_$E(HLECH)_"M10"
    92         ;
    93 M11(X,HLECDE)   ; M11 check digit scheme
    94         ; INPUT : X - ID number
    95         ;        Optional HLECDE - Encoding chars
    96         ;**** NOTE: ****
    97         ;If this function is called without HLECDE as parameter then HLECH
    98         ;must be defined.
    99         ;Return X if encoding character is not defined
    100         ;Return X with encoding characters concatenated if X is alphanumeric
    101         ;
    102         N HLX1,HLCNT,HLWT,HLDIGIT
    103         Q:'$D(X) ""
    104         I $D(HLECDE) N HLECH S HLECH=HLECDE
    105         ;Return X if encoding character is not defined
    106         I '$D(HLECH) Q X
    107         ;Return X with encoding characters concatenated if X is alphanumeric
    108         I '(X?1N.N) Q X_$E(HLECH)_$E(HLECH)
    109         ;
    110         S HLX1=+X
    111         S HLDIGIT=0,HLWT=2
    112         F HLCNT=$L(HLX1):-1:1 D
    113         . I HLWT>7 S HLWT=2
    114         . S HLDIGIT=HLDIGIT+($E(HLX1,HLCNT)*HLWT)
    115         . S HLWT=HLWT+1
    116         S HLDIGIT=HLDIGIT#11
    117         I HLDIGIT=0 S HLDIGIT=1
    118         S HLDIGIT=(11-HLDIGIT)#10
    119         Q X_$E(HLECH)_HLDIGIT_$E(HLECH)_"M11"
    120         ;
    121 OLDM10(X,HLECDE)        ;Calculate M10 checksum
    122         ; INPUT : X - String to calc checksum
    123         ;        Optional HLECDE - Encoding chars
    124         ;**** NOTE: ****
    125         ;If this function is called without HLECDE as parameter than HLECH
    126         ;must be define.
    127         ;
    128         Q:'$D(X) ""
    129         I '$D(HLECH),'$D(HLECDE) Q ""
    130         I $D(HLECDE) N HLECH S HLECH=HLECDE
    131         I '$D(HLECH) Q ""
    132         N %,Y
    133         S Y=0 F %=1:1:$L(X) S Y=Y+$E(X,%)
    134         Q X_$E(HLECH)_(Y#10)_$E(HLECH)_"M10"
    135         ;
    136 OLDM11(X,HLECDE)        ;Calculate M11 checksum
    137         ; INPUT : X - String to calc checksum
    138         ;        Optional HLECDE - Encoding chars
    139         ;**** NOTE: ****
    140         ;If this function is called without HLECDE as parameter than HLECH
    141         ;must be define.
    142         ;
    143         Q:'$D(X) ""
    144         I '$D(HLECH),'$D(HLECDE) Q ""
    145         I $D(HLECDE) N HLECH S HLECH=HLECDE
    146         I '$D(HLECH) Q ""
    147         N %,Y S Y=0 F %=1:1:$L(X) S Y=Y+$E(X,%)
    148         Q X_$E(HLECH)_(Y#11)_$E(HLECH)_"M11"
    149 UPPER(X)        ;Convert lowercase letters to uppercase
    150         Q:'$D(X) ""
    151         Q $TR(X,"abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    152 HLPHONE(X,B,C)  ;Convert DHCP Phone Number to HL7 Format
    153         ;Required parameters:
    154         ;X = Seven digit phone number at a minimum.  Optionally, in addition,
    155         ;    a three digit area code, two digit country code and other
    156         ;    formatting characters (e.g., dashes)
    157         ;Optional Variables:
    158         ;B = Beeper number
    159         ;C = Comments
    160         Q:'$D(X) ""  Q:$L(X)<7 ""
    161         N I,Y,Y1,Z S B=$S('$D(B):"",1:"B"_B),C=$S('$D(C):"",1:"C"_C)
    162         ;
    163         ; patch HL*1.6*141 start
    164         ; S Y="" F I=1:1:$L(X) S Y=Y_$S($E(X,I)?1N:$E(X,I),"X,x"[$E(X,I)&('$D(Z)):"X",1:"") I "X,x"[$E(X,I) S Z=""
    165         N CH
    166         S Y=""
    167         F I=1:1:$L(X) D
    168         . S CH=$E(X,I)
    169         . ; Next line modified by RBN
    170         . ;S Y=Y_$S(CH?1N:CH,"Xx"[CH&('$D(Z)):"X",1:"")
    171         . S Y=Y_$S(CH?1N:CH,"Xx,*"[CH&('$D(Z)):"X",1:"")
    172         . I "Xx"[CH S Z=""
    173         ;
    174         ; the number, following "X" character, should be greater than 0
    175         I Y["X",+$P(Y,"X",2)<1 S Y=$P(Y,"X")
    176         ; patch HL*1.6*141 end
    177         ;
    178         I $L(Y)<7 Q ""
    179         S Y1=$S(Y["X":"X"_$P(Y,"X",2),1:""),Y=$P(Y,"X") I $L(Y)<7 Q ""
    180         I $L(Y)=8,189[$E(Y) S Y=$E(Y,2,8)
    181         I $L(Y)=11,189[$E(Y) S Y=$E(Y,2,11)
    182         I $L(Y)=7 Q $E($E(Y,1,3)_"-"_$E(Y,4,7)_Y1_B_C,1,40)
    183         I $L(Y)=10 Q $E("("_$E(Y,1,3)_")"_$E(Y,4,6)_"-"_$E(Y,7,10)_Y1_B_C,1,40)
    184         I $L(Y)=12 Q $E($E(Y,1,2)_" ("_$E(Y,3,5)_")"_$E(Y,6,8)_"-"_$E(Y,9,12)_Y1_B_C,1,40)
    185         Q ""
    186 HLADDR(AD,GL,HLECDE)    ;Convert DHCP address fields to HL7 address format
    187         ;Required parameters:
    188         ;AD = One to four street address lines separated by uparrows (^).
    189         ;GL = Three to four geographic location components separated by
    190         ;     uparrows (^).  City^State or Province^Zip Code^Country Code.
    191         ;     If the fourth component is not defined, it will be set to 'USA'.
    192         ;     The second component must be null or an IEN in the
    193         ;     State file (#5).  The third component must be null or pattern
    194         ;     match 5N, 9N or 5N1"-"4N.
    195         ;
    196         ;        Optional HLECDE - Encoding chars
    197         ;**** NOTE: ****
    198         ;If this function is called without HLECDE as parameter than HLECH
    199         ;must be define.
    200         ;
    201         ;
    202         ;A string will be returned with six components separated by the HL7
    203         ;component separator.  The length of the string (including separators)
    204         ;may exceed 106 characters.
    205         ;
    206         Q:'$D(AD) ""  Q:'$D(GL) ""
    207         I '$D(HLECH),'$D(HLECDE) Q ""
    208         I $D(HLECDE) N HLECH S HLECH=HLECDE
    209         I '$D(HLECH) Q ""
    210         I $D(XRTL) D T0^%ZOSV
    211         N I,X,Y
    212         I $P(GL,"^",4)="" S $P(GL,"^",4)="USA"
    213         I $P(GL,"^",4)="USA" S X=$P(GL,"^",3) S:X?9N X=$E(X,1,5)_"-"_$E(X,6,9) S $P(GL,"^",3)=$S(X?5N!(X?5N1"-"4N):X,1:"")
    214         S X=+$P(GL,"^",2) S $P(GL,"^",2)=$S('X:"",$P($G(^DIC(5,X,0)),"^",2)]"":$E($P(^(0),"^",2),1,2),1:"")
    215         S Y=$E(HLECH)_$P(GL,"^")_$E(HLECH)_$P(GL,"^",2)_$E(HLECH)_$P(GL,"^",3)_$E(HLECH)_$P(GL,"^",4)
    216         S X=$P(AD,"^",1,4) F I=1,2 I X["^^" S X=$P(X,"^^")_"^"_$P(X,"^^",2,3)
    217         I $E(X,$L(X))="^" S X=$E(X,1,($L(X)-1))
    218         I $D(XRT0) S XRTN="HLFNC" D T1^%ZOSV
    219         I $L(X,"^")=1 Q $P(X,"^")_$E(HLECH)_Y
    220         I $L(X,"^")=2 Q $P(X,"^")_$E(HLECH)_$P(X,"^",2)_Y
    221         I $L(X,"^")=3 Q $P(X,"^")_", "_$P(X,"^",2)_$E(HLECH)_$P(X,"^",3)_Y
    222         I $L(X,"^")=4 Q $P(X,"^")_", "_$P(X,"^",2)_$E(HLECH)_$P(X,"^",3)_", "_$P(X,"^",4)_Y
     1HLFNC ;AISC/SAW-Routine of Functions and Other Calls Used for HL7 Messages ;08/03/2000  15:45
     2 ;;1.6;HEALTH LEVEL SEVEN;**38,42,51,66**;Oct 13, 1995
     3HLNAME(X,HLECDE) ;Convert a name in DHCP format to HL7 format
     4 ; INPUT: X - Name in DHCP format
     5 ;        Optional - HLECDE - HL7 encoding chars
     6 ;**** NOTE: ****
     7 ;If this function is called without HLECDE as parameter than HLECH
     8 ;must be define.
     9 ;
     10 Q:'$D(X) ""  Q:X="" ""
     11 I '$D(HLECH),'$D(HLECDE) Q ""
     12 I $D(HLECDE) N HLECH S HLECH=HLECDE
     13 I '$D(HLECH) Q ""
     14 N %,X1,X2,Y
     15 S X1=$P(X,",",2),X2=$L(X1," "),Y=$P(X,",")_$E(HLECH)_$P(X1," ") I X2 F %=2:1:X2 Q:$P(X1," ",%)']""  S Y=Y_$E(HLECH)_$P(X1," ",%)
     16 Q Y
     17 ;
     18FMNAME(X,HLECDE) ;Convert a name in HL7 format to DHCP format
     19 ; INPUT: X - Name in HL7 format
     20 ;        Optional - HLECDE - HL7 encoding chars
     21 ;**** NOTE: ****
     22 ;If this function is called without HLECDE as parameter than HLECH
     23 ;must be define.
     24 ;
     25 Q:'$D(X) ""  Q:X="" ""
     26 I '$D(HLECH),'$D(HLECDE) Q ""
     27 I $D(HLECDE) N HLECH S HLECH=HLECDE
     28 I '$D(HLECH) Q ""
     29 N %,X1 S X1=$L(X,$E(HLECH)),Y="" F %=1:1:X1 D
     30 .I $P(X,$E(HLECH),%)]"",$P(X,$E(HLECH),%)'="""""" D
     31 ..;Only last name,first name.
     32 ..I %<3 S Y=Y_$P(X,$E(HLECH),%)_$S(%=1:",",1:"") Q
     33 ..S Y=Y_" "_$P(X,$E(HLECH),%)
     34 Q Y
     35 ;
     36HLDATE(X,Y) ;Convert date, date/time or time only in FM format to HL7 format
     37 ;Optional Variables:
     38 ;Y = The type of format to be returned if you want to force return of a
     39 ;    specific format.  Y must be equal to one of the following:
     40 ;    DT - Date only
     41 ;    TM - Time only
     42 ;    TS - Date and time
     43 I X="" Q ""
     44 S Y=$G(Y)
     45 N %,Z
     46 I $L(X)<7 D  Q % ;Time input
     47 . S %=$S(X=2400:"0000",$L(X)<4:$E(X_"000",1,4),1:X) S:$L(%)=5 %=%_0
     48 . Q
     49 I Y="TM" D  Q % ;Only time
     50 . S %=$P(X,".",2),%=$S(%="":"",$E(%,1,2)=24:"0000",$L(%)<4:$E(%_"000",1,4),1:%) S:$L(%)=5 %=%_0
     51 . Q
     52 S %=$$FMTHL7^XLFDT(X)
     53 Q $S(Y="DT":$E(%,1,8),1:%)
     54 ;
     55FMDATE(X) ;Convert a date, date/time or time only in HL7 format to FM format
     56 I X="" Q ""
     57 N %
     58 S %=$P($TR(X,"+-","^"),"^")
     59 I $L(X)<7 Q %
     60 Q $$HL7TFM^XLFDT(X)
     61 ;
     62M10(X,HLECDE) ; M10  check digit scheme
     63 ; INPUT : X - ID number
     64 ;        Optional HLECDE - Encoding chars
     65 ;**** NOTE: ****
     66 ;If this function is called without HLECDE as parameter then HLECH
     67 ;must be defined.
     68 ;Return X if encoding character is not defined
     69 ;Return X with encoding characters concatenated if X is alphanumeric
     70 ;
     71 N HLCNT,HLODD,HLEVEN,HLX1,HLDIGIT
     72 Q:'$D(X) ""
     73 I $D(HLECDE) N HLECH S HLECH=HLECDE
     74 ;Return X if encoding character is not defined
     75 I '$D(HLECH) Q X
     76 ;Return X with encoding characters concatenated if X is alphanumeric
     77 I '(X?1.N) Q X_$E(HLECH)_$E(HLECH)
     78 ;
     79 S HLX1=+X
     80 S HLODD=""
     81 F HLCNT=$L(HLX1):-2:1 S HLODD=HLODD_$E(HLX1,HLCNT)
     82 S HLODD=HLODD*2
     83 S HLEVEN=""
     84 F HLCNT=($L(HLX1)-1):-2:1 S HLEVEN=HLEVEN_$E(HLX1,HLCNT)
     85 S HLX1=HLEVEN_HLODD
     86 S HLDIGIT=0
     87 F HLCNT=1:1:$L(HLX1) S HLDIGIT=HLDIGIT+$E(HLX1,HLCNT)
     88 S HLDIGIT=((HLDIGIT\10+1)*10-HLDIGIT)#10
     89 Q X_$E(HLECH)_HLDIGIT_$E(HLECH)_"M10"
     90 ;
     91M11(X,HLECDE) ; M11 check digit scheme
     92 ; INPUT : X - ID number
     93 ;        Optional HLECDE - Encoding chars
     94 ;**** NOTE: ****
     95 ;If this function is called without HLECDE as parameter then HLECH
     96 ;must be defined.
     97 ;Return X if encoding character is not defined
     98 ;Return X with encoding characters concatenated if X is alphanumeric
     99 ;
     100 N HLX1,HLCNT,HLWT,HLDIGIT
     101 Q:'$D(X) ""
     102 I $D(HLECDE) N HLECH S HLECH=HLECDE
     103 ;Return X if encoding character is not defined
     104 I '$D(HLECH) Q X
     105 ;Return X with encoding characters concatenated if X is alphanumeric
     106 I '(X?1N.N) Q X_$E(HLECH)_$E(HLECH)
     107 ;
     108 S HLX1=+X
     109 S HLDIGIT=0,HLWT=2
     110 F HLCNT=$L(HLX1):-1:1 D
     111 . I HLWT>7 S HLWT=2
     112 . S HLDIGIT=HLDIGIT+($E(HLX1,HLCNT)*HLWT)
     113 . S HLWT=HLWT+1
     114 S HLDIGIT=HLDIGIT#11
     115 I HLDIGIT=0 S HLDIGIT=1
     116 S HLDIGIT=(11-HLDIGIT)#10
     117 Q X_$E(HLECH)_HLDIGIT_$E(HLECH)_"M11"
     118 ;
     119OLDM10(X,HLECDE) ;Calculate M10 checksum
     120 ; INPUT : X - String to calc checksum
     121 ;        Optional HLECDE - Encoding chars
     122 ;**** NOTE: ****
     123 ;If this function is called without HLECDE as parameter than HLECH
     124 ;must be define.
     125 ;
     126 Q:'$D(X) ""
     127 I '$D(HLECH),'$D(HLECDE) Q ""
     128 I $D(HLECDE) N HLECH S HLECH=HLECDE
     129 I '$D(HLECH) Q ""
     130 N %,Y
     131 S Y=0 F %=1:1:$L(X) S Y=Y+$E(X,%)
     132 Q X_$E(HLECH)_(Y#10)_$E(HLECH)_"M10"
     133 ;
     134OLDM11(X,HLECDE) ;Calculate M11 checksum
     135 ; INPUT : X - String to calc checksum
     136 ;        Optional HLECDE - Encoding chars
     137 ;**** NOTE: ****
     138 ;If this function is called without HLECDE as parameter than HLECH
     139 ;must be define.
     140 ;
     141 Q:'$D(X) ""
     142 I '$D(HLECH),'$D(HLECDE) Q ""
     143 I $D(HLECDE) N HLECH S HLECH=HLECDE
     144 I '$D(HLECH) Q ""
     145 N %,Y S Y=0 F %=1:1:$L(X) S Y=Y+$E(X,%)
     146 Q X_$E(HLECH)_(Y#11)_$E(HLECH)_"M11"
     147UPPER(X) ;Convert lowercase letters to uppercase
     148 Q:'$D(X) ""
     149 Q $TR(X,"abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ")
     150HLPHONE(X,B,C) ;Convert DHCP Phone Number to HL7 Format
     151 ;Required parameters:
     152 ;X = Seven digit phone number at a minimum.  Optionally, in addition,
     153 ;    a three digit area code, two digit country code and other
     154 ;    formatting characters (e.g., dashes)
     155 ;Optional Variables:
     156 ;B = Beeper number
     157 ;C = Comments
     158 Q:'$D(X) ""  Q:$L(X)<7 ""
     159 N I,Y,Y1,Z S B=$S('$D(B):"",1:"B"_B),C=$S('$D(C):"",1:"C"_C)
     160 S Y="" F I=1:1:$L(X) S Y=Y_$S($E(X,I)?1N:$E(X,I),"X,x"[$E(X,I)&('$D(Z)):"X",1:"") I "X,x"[$E(X,I) S Z=""
     161 I $L(Y)<7 Q ""
     162 S Y1=$S(Y["X":"X"_$P(Y,"X",2),1:""),Y=$P(Y,"X") I $L(Y)<7 Q ""
     163 I $L(Y)=8,189[$E(Y) S Y=$E(Y,2,8)
     164 I $L(Y)=11,189[$E(Y) S Y=$E(Y,2,11)
     165 I $L(Y)=7 Q $E($E(Y,1,3)_"-"_$E(Y,4,7)_Y1_B_C,1,40)
     166 I $L(Y)=10 Q $E("("_$E(Y,1,3)_")"_$E(Y,4,6)_"-"_$E(Y,7,10)_Y1_B_C,1,40)
     167 I $L(Y)=12 Q $E($E(Y,1,2)_" ("_$E(Y,3,5)_")"_$E(Y,6,8)_"-"_$E(Y,9,12)_Y1_B_C,1,40)
     168 Q ""
     169HLADDR(AD,GL,HLECDE) ;Convert DHCP address fields to HL7 address format
     170 ;Required parameters:
     171 ;AD = One to four street address lines separated by uparrows (^).
     172 ;GL = Three to four geographic location components separated by
     173 ;     uparrows (^).  City^State or Province^Zip Code^Country Code.
     174 ;     If the fourth component is not defined, it will be set to 'USA'.
     175 ;     The second component must be null or an IEN in the
     176 ;     State file (#5).  The third component must be null or pattern
     177 ;     match 5N, 9N or 5N1"-"4N.
     178 ;
     179 ;        Optional HLECDE - Encoding chars
     180 ;**** NOTE: ****
     181 ;If this function is called without HLECDE as parameter than HLECH
     182 ;must be define.
     183 ;
     184 ;
     185 ;A string will be returned with six components separated by the HL7
     186 ;component separator.  The length of the string (including separators)
     187 ;may exceed 106 characters.
     188 ;
     189 Q:'$D(AD) ""  Q:'$D(GL) ""
     190 I '$D(HLECH),'$D(HLECDE) Q ""
     191 I $D(HLECDE) N HLECH S HLECH=HLECDE
     192 I '$D(HLECH) Q ""
     193 I $D(XRTL) D T0^%ZOSV
     194 N I,X,Y
     195 I $P(GL,"^",4)="" S $P(GL,"^",4)="USA"
     196 I $P(GL,"^",4)="USA" S X=$P(GL,"^",3) S:X?9N X=$E(X,1,5)_"-"_$E(X,6,9) S $P(GL,"^",3)=$S(X?5N!(X?5N1"-"4N):X,1:"")
     197 S X=+$P(GL,"^",2) S $P(GL,"^",2)=$S('X:"",$P($G(^DIC(5,X,0)),"^",2)]"":$E($P(^(0),"^",2),1,2),1:"")
     198 S Y=$E(HLECH)_$P(GL,"^")_$E(HLECH)_$P(GL,"^",2)_$E(HLECH)_$P(GL,"^",3)_$E(HLECH)_$P(GL,"^",4)
     199 S X=$P(AD,"^",1,4) F I=1,2 I X["^^" S X=$P(X,"^^")_"^"_$P(X,"^^",2,3)
     200 I $E(X,$L(X))="^" S X=$E(X,1,($L(X)-1))
     201 I $D(XRT0) S XRTN="HLFNC" D T1^%ZOSV
     202 I $L(X,"^")=1 Q $P(X,"^")_$E(HLECH)_Y
     203 I $L(X,"^")=2 Q $P(X,"^")_$E(HLECH)_$P(X,"^",2)_Y
     204 I $L(X,"^")=3 Q $P(X,"^")_", "_$P(X,"^",2)_$E(HLECH)_$P(X,"^",3)_Y
     205 I $L(X,"^")=4 Q $P(X,"^")_", "_$P(X,"^",2)_$E(HLECH)_$P(X,"^",3)_", "_$P(X,"^",4)_Y
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLMA.m

    r613 r623  
    1 HLMA    ;AISC/SAW-Message Administration Module ;05/02/2008  10:27
    2         ;;1.6;HEALTH LEVEL SEVEN;**19,43,58,63,66,82,91,109,115,133,132,122,140**;Oct 13, 1995;Build 5
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4 GENERATE(HLEID,HLARYTYP,HLFORMAT,HLRESLT,HLMTIEN,HLP)   ;
    5         ;Entry point to generate a deferred message
    6         ;
    7         ;This is a subroutine call with parameter passing.  It returns a
    8         ;value in the variable HLRESLT with 1 to 3 pieces separated by uparrows
    9         ;as follows:  1st message ID^error code^error description
    10         ;If no error occurs, only the first piece is returned equal to a unique
    11         ;ID for the 1st message.  If message was sent to more than 1 subscriber
    12         ;than the other message IDs will be in the array HLRESLT(n)=ID
    13         ;Otherwise, three pieces are returned with the
    14         ;first piece equal to the message ID, if one was assigned, otherwise 0
    15         ;
    16         ;Required Input Parameters
    17         ;     HLEID = Name or IEN of event driver protocol in the Protocol file
    18         ;  HLARYTYP = Array type.  One of the following codes:
    19         ;               LM = local array containing a single message
    20         ;               LB = local array containig a batch of messages
    21         ;               GM = global array containing a single message
    22         ;               GB = global array containing a batch of messages
    23         ;  HLFORMAT = Format of array, 1 for pre-formatted in HL7 format,
    24         ;               otherwise 0
    25         ;NOTE:  The parameter HLRESLT must be passed by reference
    26         ;   HLRESLT = The variable that will be returned to the calling
    27         ;               application as descibed above
    28         ;Optional Parameters
    29         ;   HLMTIEN = IEN of entry in Message Text file where the message
    30         ;               being generated is to be stored.  This parameter is
    31         ;               only passed for a batch type message
    32         ;NOTE:  The parameter HLP used for the following parameters must be
    33         ;       passed by reference
    34         ;  HLP("SECURITY") = A 1 to 40 character string
    35         ;   HLP("CONTPTR") = Continuation pointer, a 1 to 180 character string
    36         ; HLP("NAMESPACE") = Passed in by application namespace - HL*1.6*91
    37         ; HLP("EXCLUDE SUBSCRIBER",<n=1,2,3...>)=<subscriber protocol ien> or
    38         ;   <subscriber protocol name> - A list of protocols to dynamically
    39         ;   drop from the event protocol's subscriber multiple.
    40         ;
    41         ;can't have link open when generating new message
    42         N HLTCP,HLTCPO,HLPRIO,HLMIDAR
    43         S HLPRIO="D"
    44         S HLRESLT=""
    45         ;Check for required parameters
    46 CONT    ;
    47         I $G(HLEID)']""!($G(HLARYTYP)']"")!($G(HLFORMAT)']"") D  G EXIT
    48         . S HLRESLT="0^7^"_$G(^HL(771.7,7,0))_" at GENERATE^HLMA entry point"
    49         I 'HLEID S HLEID=$O(^ORD(101,"B",HLEID,0)) I 'HLEID S HLRESLT="0^1^"_$G(^HL(771.7,1,0)) G EXIT
    50         N HLRESLT1,HLRESLTA S (HLRESLTA,HLRESLT1)=""
    51         I "GL"'[$E(HLARYTYP) S HLRESLT="0^4^"_$G(^HL(771.7,4,0)) G EXIT
    52         I $L($G(HLP("SECURITY")))>40 S HLRESLT="0^6^"_$G(^HL(771.7,6,0)) G EXIT
    53         I $L($G(HLP("CONTPTR")))>180 S HLRESLT="0^11^"_$G(^HL(771.7,11,0)) G EXIT
    54         I $D(HLL("LINKS")) D  G:$G(HLRESLT)]"" EXIT
    55         . N I,HLPNAM,HLPIEN,HLLNAM,HLLIEN
    56         . S I=0
    57         . F  S I=$O(HLL("LINKS",I)) Q:'I  D  Q:$G(HLRESLT)]""
    58         . . S HLPNAM=$P(HLL("LINKS",I),U)
    59         . . S HLPIEN=+$O(^ORD(101,"B",HLPNAM,0))
    60         . . I $P($G(^ORD(101,HLPIEN,0)),U,4)'="S" S HLRESLT="0^15^Invalid Subscriber Protocol in HLL('LINKS'): "_HLL("LINKS",I) Q
    61         . . S HLLNAM=$P(HLL("LINKS",I),U,2)
    62         . . S HLLIEN=+$O(^HLCS(870,"B",HLLNAM,0))
    63         . . I '$D(^HLCS(870,HLLIEN,0)) S HLRESLT="0^15^Invalid HL Node in HLL('LINKS'): "_HLL("LINKS",I) Q
    64         ;Extract data from Protocol file
    65         D EVENT^HLUTIL1(HLEID,"15,20,771",.HLN)
    66         S HLENROU=$G(HLN(20)),HLEXROU=$G(HLN(15))
    67         S HLP("GROUTINE")=$G(HLN(771)) K HLN I HLP("GROUTINE")']"",'HLFORMAT S HLRESLT="0^3^"_$G(^HL(771.7,3,0)) G EXIT
    68         ;Create message ID and Message Text IEN if Message Text IEN not
    69         ;previously created ('$G(HLMTIEN))
    70         I '$G(HLMTIEN) D CREATE^HLTF(.HLMID,.HLMTIEN,.HLDT,.HLDT1)
    71         ;Get message ID if Message Text IEN already created
    72         I '$G(HLMID) D
    73         .S HLDT=$G(^HL(772,HLMTIEN,0)),HLMID=$P(HLDT,"^",6),HLDT=+HLDT
    74         .S HLDT1=$$HLDATE^HLFNC(HLDT)
    75         S HLMIDAR=0,HLRESLT=HLMID,HLP("DT")=HLDT,HLP("DTM")=HLDT1
    76         ;Execute entry action for event driver protocol
    77         I HLENROU]"" X HLENROU
    78         ;Invoke transaction processor
    79         K HLDT,HLDT1,HLENROU
    80         D GENERATE^HLTP(HLMID,HLMTIEN,HLEID,HLARYTYP,HLFORMAT,.HLRESLT1,.HLP)
    81         ;HLMIDAR is array of message IDs, only set for broadcast messages
    82         I HLMIDAR K HLMIDAR("N") M HLRESLT=HLMIDAR
    83         S HLRESLT=HLRESLT_"^"_HLRESLT1
    84         ;
    85         ; patch HL*1.6*122
    86         S HLRESLT("HLMID")=$G(HLMIDAR("HLMID"))
    87         S HLRESLT("IEN773")=$G(HLMIDAR("IEN773"))
    88         ;
    89         ;Execute exit action for event driver protocol
    90         I HLEXROU]"" X HLEXROU
    91 EXIT    ;Update status if Message Text file entry has been created
    92         K HLTCP
    93         I $D(HLMTIEN) D STATUS^HLTF0(HLMTIEN,$S($P(HLRESLT,"^",2):4,1:3),$S($P(HLRESLT,"^",2):$P(HLRESLT,"^",2),1:""),$S($P(HLRESLT,"^",2):$P(HLRESLT,"^",3),1:""))
    94         K HLDT,HLDT1,HLMID,HLRESLT1,HLENROU,HLEXROU
    95         Q
    96 DIRECT(HLEID,HLARYTYP,HLFORMAT,HLRESLT,HLMTIENO,HLP)    ;
    97         ;Entry point to generate an immediate message, must be TCP Logical Link
    98         ;Input:
    99         ;  The same as GENERATE,with one additional subscript to the HLP input
    100         ;  array:
    101         ;
    102         ;  HLP("OPEN TIMEOUT") (optional, pass by reference) a number between
    103         ;    1 and 120 that specifies how many seconds the DIRECT CONNECT should
    104         ;    try to open a connection before failing.  It is killed upon
    105         ;    completion.
    106         ;
    107         N HLTCP,HLTCPO,HLPRIO,HLSAN,HLN,HLMIDAR,HLMTIENR,ZMID,HLDIRECT
    108         ; patch HL*1.6*140- to protect application who call this entry
    109         N IO,IOF,ION,IOT,IOST,POP
    110         S HLRESLT=""
    111         ;HLMTIENO=ien passed in, batch message
    112         S HLMTIEN=$G(HLMTIENO)
    113         I $G(HLP("OPEN TIMEOUT")),((HLP("OPEN TIMEOUT")\1)'=+HLP("OPEN TIMEOUT"))!HLP("OPEN TIMEOUT")>120 Q "0^4^INVALID OPEN TIMEOUT PARAMETER"
    114         I $G(HLP("OPEN TIMEOUT")) D
    115         .S HLDIRECT("OPEN TIMEOUT")=HLP("OPEN TIMEOUT")
    116         .K HLP("OPEN TIMEOUT")
    117         K HL,HLMTIENO
    118         D INIT^HLFNC2(HLEID,.HL)
    119         I $G(HL) S HLRESLT="0^"_HL Q
    120         S HLPRIO="I" D CONT
    121         ;HLMTIENO=original msg. ien in file 772, HLMTIENR=response ien set in HLMA2
    122         S HLMTIENO=HLMTIEN,HLMTIEN=$G(HLMTIENR)
    123         ;Set special HL variables
    124         S HLQUIT=0,HLNODE="",HLNEXT="D HLNEXT^HLCSUTL"
    125         Q
    126         ;
    127 CLOSE(LOGLINK)  ;close connection that was open in tag DIRECT
    128         Q
    129 PING    ;ping another VAMC to test Link
    130         ;set HLQUIET =1 to skip writes
    131         ;look for HLTPUT to get turnaround time over network.
    132         N DA,DIC,HLDP,HLDPNM,HLDPDM,HLCSOUT,HLDBSIZE,HLDREAD,HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL,HLPARAM
    133         N HCS,HCSCMD,HLCS,HCSDAT,HCSER,HCSEXIT,HCSTRACE,HLDT1,HLDRETR,HLRETRA,HLDBACK,HLDWAIT,HLTCPCS,INPUT,OUTPUT,POP,X,Y,HLX1,HLX2
    134         S HLQUIET=$G(HLQUIET)
    135         S HLCS="",HCSTRACE="C: ",POP=1,INPUT="INPUT",OUTPUT="OUTPUT"
    136         S DIC="^HLCS(870,",DIC(0)="QEAMZ"
    137         D ^DIC Q:Y<0
    138         S HLDP=+Y,HLDPNM=Y(0,0),HLDPDM=$P($$PARAM^HLCS2,U,2)
    139         ;I $P($G(^HLCS(870,HLDP,400)),U)="" W !,"Missing IP Address" Q
    140         D SETUP^HLCSAC G:HLCS PINGQ
    141         ; patch HL*1.6*122
    142         G:$$DONTPING^HLMA4 PINGQ
    143         ;PING header=MSH^PING^domain^PING^logical link^datetime
    144         S INPUT(1)="MSH^PING^"_HLDPDM_"^PING^"_HLDPNM_"^"_$$HTE^XLFDT($H)
    145         D OPEN^HLCSAC
    146         I HLCS D DNS G:HLCS PINGQ
    147         D
    148         . N $ETRAP,$ESTACK S $ETRAP="D PINGERR^HLMA"
    149         . ;non-standard HL7 header; start block,header,end block
    150         . S HLX1=$H
    151         . ;
    152         . ; HL*1.6*122 start
    153         . ; replace flush character '!' with @IOF (! or #)
    154         . ; W $C(11)_INPUT(1)_$C(28)_$C(13),! ;HL*1.6*115, restored ! char
    155         . ; patch HL*1.6*140, flush character- HLTCPLNK("IOF")
    156         . ; W $C(11)_INPUT(1)_$C(28)_$C(13),@IOF
    157         . W $C(11)_INPUT(1)_$C(28)_$C(13),@HLTCPLNK("IOF")
    158         . ; HL*1.6*122 end
    159         . ;
    160         . ;read response
    161         . R X:HLDREAD
    162         . S HLX2=$H
    163         . S X=$P(X,$C(28)),HLCS=$S(X=INPUT(1):"PING worked",X="":"No response",1:"Incorrect response")
    164         . ;Get roundtrip time
    165         . K HLTPUT I X]"" S HLTPUT=$$HDIFF^XLFDT(HLX2,HLX1,2)
    166         D CLOSE^%ZISTCP
    167 PINGQ   ;write back status and quit
    168         I 'HLQUIET W !,HLCS,!
    169         Q
    170 PINGERR ;process errors from PING
    171         S $ETRAP="G UNWIND^%ZTER",HLCS="-1^Error"
    172         ;I $ZE["READ" S HLCS="-1^Error during read"
    173         ;I $ZE["WRITE" S HLCS="-1^Error during write"
    174         ; HL*1.6*115, SACC compliance
    175         I $$EC^%ZOSV["READ" S HLCS="-1^Error during read"
    176         I $$EC^%ZOSV["WRITE" S HLCS="-1^Error during write"
    177         G UNWIND^%ZTER
    178 DNS     ;
    179         ;openfail-try DNS lookup-Link must contain point to Domain Name
    180         S POP=$G(POP)
    181         S HLQUIET=$G(HLQUIET)
    182         I 'HLQUIET W !,"Calling DNS"
    183         N HLDOM,HLIP S HLCS=""
    184         S HLDOM=$P(^HLCS(870,HLDP,0),U,7)
    185         ; patch HL*1.6*122 start
    186         S HLDOM("DNS")=$P($G(^HLCS(870,+$G(HLDP),0)),"^",8)
    187         ; I 'HLDOM,'HLQUIET W !,"Domain Unknown" Q
    188         I 'HLDOM,($L(HLDOM("DNS"),".")<3) D  Q
    189         . I 'HLQUIET W !,"Domain Unknown"
    190         . S HLCS="-1^Connection Fail"
    191         ; patch HL*1.6*122 end
    192         I HLDOM S HLDOM=$P(^DIC(4.2,HLDOM,0),U)
    193         ; patch HL*1.6*122
    194         ; I HLDOM]"" D  Q:'POP
    195         I HLDOM]""!($L(HLDOM("DNS"),".")>2) D  Q:'POP
    196         . I HLDOM["VA.GOV"&(HLDOM'[".MED.") S HLDOM=$P(HLDOM,".VA.GOV")_".MED.VA.GOV"
    197         . I HLTCPORT=5000 S HLDOM="HL7."_HLDOM
    198         . I HLTCPORT=5500 S HLDOM="MPI."_HLDOM
    199         . ; patch HL*1.6*122
    200         . I ($L(HLDOM("DNS"),".")>2) S HLDOM=HLDOM("DNS")
    201         . I 'HLQUIET W !,"Domain, "_HLDOM
    202         . I 'HLQUIET W !,"Port: ",HLTCPORT
    203         . S HLIP=$$ADDRESS^XLFNSLK(HLDOM)
    204         . I HLIP]"",'HLQUIET W !,"DNS Returned: ",HLIP
    205         . I HLIP]"" D
    206         . . ;If more than one IP returned, try each, cache successful open
    207         . . N HLI,HLJ,HLIP1
    208         . . F HLJ=1:1:$L(HLIP,",") D  Q:'POP
    209         . . . S HLIP1=$P(HLIP,",",HLJ)
    210         . . . F HLI=1:1:HLDRETR W:'HLQUIET !,"Trying ",HLIP1 D CALL^%ZISTCP(HLIP1,HLTCPORT,1) Q:'POP
    211         . . . I 'POP S $P(^HLCS(870,HLDP,400),U)=HLIP1
    212         . . . U IO
    213         I POP S HLCS="-1^DNS Lookup Failed"
     1HLMA ;AISC/SAW-Message Administration Module ;10/25/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**19,43,58,63,66,82,91,109,115,133,132**;Oct 13, 1995;Build 6
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4GENERATE(HLEID,HLARYTYP,HLFORMAT,HLRESLT,HLMTIEN,HLP) ;
     5 ;Entry point to generate a deferred message
     6 ;
     7 ;This is a subroutine call with parameter passing.  It returns a
     8 ;value in the variable HLRESLT with 1 to 3 pieces separated by uparrows
     9 ;as follows:  1st message ID^error code^error description
     10 ;If no error occurs, only the first piece is returned equal to a unique
     11 ;ID for the 1st message.  If message was sent to more than 1 subscriber
     12 ;than the other message IDs will be in the array HLRESLT(n)=ID
     13 ;Otherwise, three pieces are returned with the
     14 ;first piece equal to the message ID, if one was assigned, otherwise 0
     15 ;
     16 ;Required Input Parameters
     17 ;     HLEID = Name or IEN of event driver protocol in the Protocol file
     18 ;  HLARYTYP = Array type.  One of the following codes:
     19 ;               LM = local array containing a single message
     20 ;               LB = local array containig a batch of messages
     21 ;               GM = global array containing a single message
     22 ;               GB = global array containing a batch of messages
     23 ;  HLFORMAT = Format of array, 1 for pre-formatted in HL7 format,
     24 ;               otherwise 0
     25 ;NOTE:  The parameter HLRESLT must be passed by reference
     26 ;   HLRESLT = The variable that will be returned to the calling
     27 ;               application as descibed above
     28 ;Optional Parameters
     29 ;   HLMTIEN = IEN of entry in Message Text file where the message
     30 ;               being generated is to be stored.  This parameter is
     31 ;               only passed for a batch type message
     32 ;NOTE:  The parameter HLP used for the following parameters must be
     33 ;       passed by reference
     34 ;  HLP("SECURITY") = A 1 to 40 character string
     35 ;   HLP("CONTPTR") = Continuation pointer, a 1 to 180 character string
     36 ; HLP("NAMESPACE") = Passed in by application namespace - HL*1.6*91
     37 ; HLP("EXLCLUDE SUBSCRIBER",<n=1,2,3...>)=<subsciber protocol ien> - A list of protocols to dynamically drop from the event protocol's subscriber multiple.
     38 ;
     39 ;can't have link open when generating new message
     40 N HLTCP,HLTCPO,HLPRIO,HLMIDAR
     41 S HLPRIO="D"
     42 S HLRESLT=""
     43 ;Check for required parameters
     44CONT I $G(HLEID)']""!($G(HLARYTYP)']"")!($G(HLFORMAT)']"") S HLRESLT="0^7^"_$G(^HL(771.7,7,0))_" at GENERATE^HLMA entry point" G EXIT
     45 I 'HLEID S HLEID=$O(^ORD(101,"B",HLEID,0)) I 'HLEID S HLRESLT="0^1^"_$G(^HL(771.7,1,0)) G EXIT
     46 N HLRESLT1,HLRESLTA S (HLRESLTA,HLRESLT1)=""
     47 I "GL"'[$E(HLARYTYP) S HLRESLT="0^4^"_$G(^HL(771.7,4,0)) G EXIT
     48 I $L($G(HLP("SECURITY")))>40 S HLRESLT="0^6^"_$G(^HL(771.7,6,0)) G EXIT
     49 I $L($G(HLP("CONTPTR")))>180 S HLRESLT="0^11^"_$G(^HL(771.7,11,0)) G EXIT
     50 I $D(HLL("LINKS")) D  G:$G(HLRESLT)]"" EXIT
     51 . N I,HLPNAM,HLPIEN,HLLNAM,HLLIEN
     52 . S I=0
     53 . F  S I=$O(HLL("LINKS",I)) Q:'I  D  Q:$G(HLRESLT)]""
     54 . . S HLPNAM=$P(HLL("LINKS",I),U)
     55 . . S HLPIEN=+$O(^ORD(101,"B",HLPNAM,0))
     56 . . I $P($G(^ORD(101,HLPIEN,0)),U,4)'="S" S HLRESLT="0^15^Invalid Subscriber Protocol in HLL('LINKS'): "_HLL("LINKS",I) Q
     57 . . S HLLNAM=$P(HLL("LINKS",I),U,2)
     58 . . S HLLIEN=+$O(^HLCS(870,"B",HLLNAM,0))
     59 . . I '$D(^HLCS(870,HLLIEN,0)) S HLRESLT="0^15^Invalid HL Node in HLL('LINKS'): "_HLL("LINKS",I) Q
     60 ;Extract data from Protocol file
     61 D EVENT^HLUTIL1(HLEID,"15,20,771",.HLN)
     62 S HLENROU=$G(HLN(20)),HLEXROU=$G(HLN(15))
     63 S HLP("GROUTINE")=$G(HLN(771)) K HLN I HLP("GROUTINE")']"",'HLFORMAT S HLRESLT="0^3^"_$G(^HL(771.7,3,0)) G EXIT
     64 ;Create message ID and Message Text IEN if Message Text IEN not
     65 ;previously created ('$G(HLMTIEN))
     66 I '$G(HLMTIEN) D CREATE^HLTF(.HLMID,.HLMTIEN,.HLDT,.HLDT1)
     67 ;Get message ID if Message Text IEN already created
     68 I '$G(HLMID) D
     69 .S HLDT=$G(^HL(772,HLMTIEN,0)),HLMID=$P(HLDT,"^",6),HLDT=+HLDT
     70 .S HLDT1=$$HLDATE^HLFNC(HLDT)
     71 S HLMIDAR=0,HLRESLT=HLMID,HLP("DT")=HLDT,HLP("DTM")=HLDT1
     72 ;Execute entry action for event driver protocol
     73 I HLENROU]"" X HLENROU
     74 ;Invoke transaction processor
     75 K HLDT,HLDT1,HLENROU
     76 D GENERATE^HLTP(HLMID,HLMTIEN,HLEID,HLARYTYP,HLFORMAT,.HLRESLT1,.HLP)
     77 ;HLMIDAR is array of message IDs, only set for broadcast messages
     78 I HLMIDAR K HLMIDAR("N") M HLRESLT=HLMIDAR
     79 S HLRESLT=HLRESLT_"^"_HLRESLT1
     80 ;Execute exit action for event driver protocol
     81 I HLEXROU]"" X HLEXROU
     82EXIT ;Update status if Message Text file entry has been created
     83 K HLTCP
     84 I $D(HLMTIEN) D STATUS^HLTF0(HLMTIEN,$S($P(HLRESLT,"^",2):4,1:3),$S($P(HLRESLT,"^",2):$P(HLRESLT,"^",2),1:""),$S($P(HLRESLT,"^",2):$P(HLRESLT,"^",3),1:""))
     85 K HLDT,HLDT1,HLMID,HLRESLT1,HLENROU,HLEXROU
     86 Q
     87DIRECT(HLEID,HLARYTYP,HLFORMAT,HLRESLT,HLMTIENO,HLP) ;
     88 ;Entry point to generate an immediate message, must be TCP Logical Link
     89 ;Input:
     90 ;  The same as GENERATE,with one additional subscript to the HLP input array:
     91 ;
     92 ;  HLP("OPEN TIMEOUT") (optional, pass by reference) a number between
     93 ;    1 and 120 that specifies how many seconds the DIRECT CONNECT should
     94 ;    try to open a connection before failing.  It is killed upon completion.
     95 ;
     96 N HLTCP,HLTCPO,HLPRIO,HLSAN,HLN,HLMIDAR,HLMTIENR,ZMID,HLDIRECT
     97 S HLRESLT=""
     98 ;HLMTIENO=ien passed in, batch message
     99 S HLMTIEN=$G(HLMTIENO)
     100 I $G(HLP("OPEN TIMEOUT")),((HLP("OPEN TIMEOUT")\1)'=+HLP("OPEN TIMEOUT"))!HLP("OPEN TIMEOUT")>120 Q "0^4^INVALID OPEN TIMEOUT PARAMETER"
     101 I $G(HLP("OPEN TIMEOUT")) D
     102 .S HLDIRECT("OPEN TIMEOUT")=HLP("OPEN TIMEOUT")
     103 .K HLP("OPEN TIMEOUT")
     104 K HL,HLMTIENO
     105 D INIT^HLFNC2(HLEID,.HL)
     106 I $G(HL) S HLRESLT="0^"_HL Q
     107 S HLPRIO="I" D CONT
     108 ;HLMTIENO=original msg. ien in file 772, HLMTIENR=response ien set in HLMA2
     109 S HLMTIENO=HLMTIEN,HLMTIEN=$G(HLMTIENR)
     110 ;Set special HL variables
     111 S HLQUIT=0,HLNODE="",HLNEXT="D HLNEXT^HLCSUTL"
     112 Q
     113 ;
     114CLOSE(LOGLINK) ;close connection that was open in tag DIRECT
     115 Q
     116PING ;ping another VAMC to test Link
     117 ;set HLQUIET =1 to skip writes
     118 ;look for HLTPUT to get turnaround time over network.
     119 N DA,DIC,HLDP,HLDPNM,HLDPDM,HLCSOUT,HLDBSIZE,HLDREAD,HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL,HLPARAM
     120 N HCS,HCSCMD,HLCS,HCSDAT,HCSER,HCSEXIT,HCSTRACE,HLDT1,HLDRETR,HLRETRA,HLDBACK,HLDWAIT,HLTCPCS,INPUT,OUTPUT,POP,X,Y,HLX1,HLX2
     121 S HLQUIET=$G(HLQUIET)
     122 S HLCS="",HCSTRACE="C: ",POP=1,INPUT="INPUT",OUTPUT="OUTPUT"
     123 S DIC="^HLCS(870,",DIC(0)="QEAMZ"
     124 D ^DIC Q:Y<0
     125 S HLDP=+Y,HLDPNM=Y(0,0),HLDPDM=$P($$PARAM^HLCS2,U,2)
     126 ;I $P($G(^HLCS(870,HLDP,400)),U)="" W !,"Missing IP Address" Q
     127 D SETUP^HLCSAC G:HLCS PINGQ
     128 ;PING header=MSH^PING^domain^PING^logical link^datetime
     129 S INPUT(1)="MSH^PING^"_HLDPDM_"^PING^"_HLDPNM_"^"_$$HTE^XLFDT($H)
     130 D OPEN^HLCSAC
     131 I HLCS D DNS G:HLCS PINGQ
     132 D
     133 . N $ETRAP,$ESTACK S $ETRAP="D PINGERR^HLMA"
     134 . ;non-standard HL7 header; start block,header,end block
     135 . S HLX1=$H
     136 . W $C(11)_INPUT(1)_$C(28)_$C(13),! ;HL*1.6*115, restored ! char
     137 . ;read response
     138 . R X:HLDREAD
     139 . S HLX2=$H
     140 . S X=$P(X,$C(28)),HLCS=$S(X=INPUT(1):"PING worked",X="":"No response",1:"Incorrect response")
     141 . ;Get roundtrip time
     142 . K HLTPUT I X]"" S HLTPUT=$$HDIFF^XLFDT(HLX2,HLX1,2)
     143 D CLOSE^%ZISTCP
     144PINGQ ;write back status and quit
     145 I 'HLQUIET W !,HLCS,!
     146 Q
     147PINGERR ;process errors from PING
     148 S $ETRAP="G UNWIND^%ZTER",HLCS="-1^Error"
     149 ;I $ZE["READ" S HLCS="-1^Error during read"
     150 ;I $ZE["WRITE" S HLCS="-1^Error during write"
     151 ; HL*1.6*115, SACC compliance
     152 I $$EC^%ZOSV["READ" S HLCS="-1^Error during read"
     153 I $$EC^%ZOSV["WRITE" S HLCS="-1^Error during write"
     154 G UNWIND^%ZTER
     155DNS ;
     156 ;openfail-try DNS lookup-Link must contain point to Domain Name
     157 S POP=$G(POP)
     158 S HLQUIET=$G(HLQUIET)
     159 I 'HLQUIET W !,"Calling DNS"
     160 N HLDOM,HLIP S HLCS=""
     161 S HLDOM=$P(^HLCS(870,HLDP,0),U,7)
     162 I 'HLDOM,'HLQUIET W !,"Domain Unknown" Q
     163 I HLDOM S HLDOM=$P(^DIC(4.2,HLDOM,0),U)
     164 I HLDOM]"" D  Q:'POP
     165 . I HLDOM["VA.GOV"&(HLDOM'[".MED.") S HLDOM=$P(HLDOM,".VA.GOV")_".MED.VA.GOV"
     166 . I HLTCPORT=5000 S HLDOM="HL7."_HLDOM
     167 . I HLTCPORT=5500 S HLDOM="MPI."_HLDOM
     168 . I 'HLQUIET W !,"Domain, "_HLDOM
     169 . I 'HLQUIET W !,"Port: ",HLTCPORT
     170 . S HLIP=$$ADDRESS^XLFNSLK(HLDOM)
     171 . I HLIP]"",'HLQUIET W !,"DNS Returned: ",HLIP
     172 . I HLIP]"" D
     173 . . ;If more than one IP returned, try each, cache successful open
     174 . . N HLI,HLJ,HLIP1
     175 . . F HLJ=1:1:$L(HLIP,",") D  Q:'POP
     176 . . . S HLIP1=$P(HLIP,",",HLJ)
     177 . . . F HLI=1:1:HLDRETR W:'HLQUIET !,"Trying ",HLIP1 D CALL^%ZISTCP(HLIP1,HLTCPORT,1) Q:'POP
     178 . . . I 'POP S $P(^HLCS(870,HLDP,400),U)=HLIP1
     179 . . . U IO
     180 I POP S HLCS="-1^DNS Lookup Failed"
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOAPI1.m

    r613 r623  
    1 HLOAPI1 ;ALB/CJM-HL7 - Developer API's for sending & receiving messages(continued) ;07/18/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,132,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 SENDONE(HLMSTATE,PARMS,WHOTO,ERROR)     ;
    6         ;Sends the message to a single receiving application.
    7         ;
    8         ;Input:
    9         ;HLMSTATE() - (pass by reference, required) This array is used by the HL7 package to track the progress of the message.  The application MUST NOT touch it
    10         ;PARMS( *pass by reference*
    11         ;  "APP ACK RESPONSE")=<tag^routine> to call when the app ack is received (optional)
    12         ;    (NOTE: For batch messages, HLO best supports returning application
    13         ;     acknowledgments via a batch response.  However, non-VistA systems
    14         ;     may return individual messages as application acknowledgments to
    15         ;     messages within the original batch message, so for applications
    16         ;     sending batch messages might best code the "APP ACK RESPONSE"
    17         ;     routine to first check whether the response message is a batch.
    18         ;
    19         ;  "ACCEPT ACK RESPONSE")=<tag^routine> to call when the commit ack is received (optional)
    20         ;  "ACCEPT ACK TYPE") = <AL,NE> (optional, defaults to AL)
    21         ;  "APP ACK TYPE") = <AL,NE> (optional, defaults to NE)
    22         ;  "FAILURE RESPONSE" - <tag>^<routine> (optional) The sending application routine to execute when the transmission of the message fails, i.e., the message can not be sent or no commit ack is received.
    23         ;  "QUEUE" - (optional) An application can name its own private queue - just a string up to 20 characters, it should be namespaced.
    24         ;  "SECURITY")=security information to include in the header segment, SEQ 8 (optional)
    25         ;  "SENDING APPLICATION")=name of sending app (required, 60 maximum length)
    26         ;
    27         ;  WHOTO (required,pass by reference) an array specifying a single recipient. These subscripts are allowed:
    28         ;
    29         ;    "RECEIVING APPLICATION" - (string, 60 char max, required)
    30         ;
    31         ;  EXACTLY ONE of these parameters must be provided to identify the Receiving Facility:
    32         ;
    33         ;   "FACILITY LINK IEN" - ien of the logical link
    34         ;   "FACILITY LINK NAME" - name of the logical link
    35         ;   "INSTITUTION IEN" - ptr to the INSTITUTION file
    36         ;   "STATION NUMBER" -  station # with suffix
    37         ;
    38         ;  EXACTLY ONE of these MAY be provided - optionally - to identify the interface engine to route the message through:
    39         ;
    40         ;   "IE LINK IEN" -  ptr to a logical link for the interface engine
    41         ;   "IE LINK NAME" - name of the logical link for the interface engine
    42         ;
    43         ;Output:
    44         ;  Function returns the ien of the message in file 778 on success, 0 on failure
    45         ;   HLMSTATE() - (pass by reference, required) This array is used by the HL7 package to track the progress of the message.  The application MUST NOT touch it!
    46         ;   ERROR (pass by reference, optional) - on failure, will contain an error message
    47         ;   PARMS - left undefined when the function returns
    48         ;   WHOTO - left undefined when the function returns
    49         ;
    50         ;
    51         N SUCCESS,ERR1,ERR2
    52         S SUCCESS=0
    53         D
    54         .I '$G(HLMSTATE("BODY")),'$G(HLMSTATE("UNSTORED LINES")) S ERROR="MESSAGE NOT YET CREATED" Q
    55         .;
    56         .I $$CHKPARMS^HLOAPI2(.HLMSTATE,.PARMS,.ERR1)&$$CHKWHO^HLOAPI2(.HLMSTATE,.WHOTO,.ERR2) D
    57         ..I $$SEND(.HLMSTATE,.ERROR) S SUCCESS=1
    58         .E  D
    59         ..S ERROR=$G(ERR1)_": "_$G(ERR2)
    60         ..D DONTSEND(.HLMSTATE,ERROR)
    61         K PARMS,WHOTO
    62         Q $S(SUCCESS:HLMSTATE("IEN"),1:0)
    63         ;
    64 SENDMANY(HLMSTATE,PARMS,WHOTO)  ;
    65         ;Sends the message to a list of receiving applications
    66         ;
    67         ;Input: Same as for $$SENDONE, except WHOTO is a list.
    68         ;  WHOTO (pass by reference)
    69         ;    Specifies a list of recipients.  Each recipient should be on the
    70         ;    list as WHOTO(i), where i=1,2,3,4, etc. for as many messages as to
    71         ;    send.  At each subscript WHOTO(i), the same lower level subscripts
    72         ;    may be defined as in the $$SENDONE API.  For example:
    73         ;
    74         ;      WHOTO(1,"LINK NAME")="VAALB"
    75         ;      WHOTO(1,"RECEIVING APPLICATION")="MPI"
    76         ;      WHOTO(2,"STATION NUMBER")=500
    77         ;      WHOTO(2,"RECEIVING APPLICATION")="MPI"
    78         ;
    79         ;
    80         ;Output:
    81         ;  Function returns 1 if a message is queued to be sent to each intended recipient, 0 otherwise
    82         ;  PARMS - left undefined when the function returns
    83         ;  WHOTO (pass by reference) returns the status of each message to be sent in the format:
    84         ;    (<i>,"QUEUED")= <1 if queued to be sent, 0 otherwise)
    85         ;   (<i>,"IEN")=<ien, file 778>
    86         ;   (<i>,"ERROR")= error message if an error was encountered (status=0), not defined otherwise
    87         ;
    88         ;
    89         N ERROR,RETURN,WHO,STATE,I
    90         S RETURN=1
    91         I '$G(HLMSTATE("BODY")),'$G(HLMSTATE("UNSTORED LINES")) D  K PARMS Q 0
    92         .S ERROR="MESSAGE NOT YET CREATED"
    93         .S I=0 F  S I=$O(WHOTO(I)) Q:'I  S WHOTO(I,"QUEUED")=0,WHOTO(I,"IEN")=0,WHOTO(I,"ERROR")=ERROR
    94         ;
    95         I '$$CHKPARMS^HLOAPI2(.HLMSTATE,.PARMS,.ERROR) D  K PARMS Q 0
    96         .S I=0 F  S I=$O(WHOTO(I)) Q:'I  D
    97         ..K WHO M WHO=WHOTO(I)
    98         ..K STATE M STATE=HLMSTATE S STATE("IEN")=""
    99         ..S WHOTO(I,"QUEUED")=0
    100         ..D DONTSEND(.STATE,$G(ERROR))
    101         ..S WHOTO(I,"IEN")=$G(STATE("IEN"))
    102         ..S WHOTO(I,"ERROR")=ERROR
    103         ;
    104         S I=0 F  S I=$O(WHOTO(I)) Q:'I  D
    105         .K WHO M WHO=WHOTO(I)
    106         .K STATE M STATE=HLMSTATE S STATE("IEN")=""
    107         .S ERROR=""
    108         .I $$CHKWHO^HLOAPI2(.STATE,.WHO,.ERROR) D
    109         ..I $$SEND(.STATE,.ERROR) D
    110         ...S WHOTO(I,"QUEUED")=1
    111         ...S WHOTO(I,"IEN")=STATE("IEN")
    112         ...S WHOTO(I,"ERROR")=""
    113         ..E  D
    114         ...S WHOTO(I,"QUEUED")=0
    115         ...S WHOTO(I,"IEN")=$G(STATE("IEN"))
    116         ...S WHOTO(I,"ERROR")=$G(ERROR)
    117         ...S RETURN=0
    118         .E  D  ;who not adequately determined
    119         ..S WHOTO(I,"QUEUED")=0,RETURN=0
    120         ..D DONTSEND(.STATE,$G(ERROR))
    121         ..S WHOTO(I,"IEN")=$G(STATE("IEN")),WHOTO(I,"ERROR")=$G(ERROR)
    122         K PARMS
    123         Q RETURN
    124         ;
    125 SENDSUB(HLMSTATE,PARMS,MESSAGES)        ;
    126         ;Sends the message to a list of receiving applications based on the HL7 Subscription Registry
    127         ;
    128         ;Input:
    129         ;  HLMSTATE (pass by reference, required) same as $$SENDMANY
    130         ;  PARMS (pass by reference, required) same as $$SENDMANY, with one additional subscript:
    131         ;    "SUBSCRIPTION IEN" - the ien of an entry in the HL7 Subscription Registry, defining the intended recipients of this message
    132         ;
    133         ;Output:
    134         ;  Function returns 1 if a message is queued to be sent to each intended recipient, 0 otherwise
    135         ;  PARMS - left undefined when the function returns
    136         ;  MESSAGES (pass by reference) returns the status of each message to be sent in this format, where subien is the ien of the recipient in the RECIPEINTS subfile of the HL7 Subscription Registry
    137         ;   (<subien>,"QUEUED")= <1 if queued to be sent, 0 otherwise)
    138         ;   (<subien>,"IEN")=<ien, file 778>
    139         ;   (<subien>,"ERROR")= error message if an error was encountered (status=0), not defined otherwise
    140         ;
    141         ;
    142         K MESSAGES
    143         N ERROR,RETURN,STATE,SUBIEN,WHO
    144         ;
    145         S RETURN=1
    146         ;
    147         ;
    148         I '$G(HLMSTATE("BODY")),'$G(HLMSTATE("UNSTORED LINES")) S ERROR="MESSAGE NOT YET CREATED" K PARMS Q 0
    149         I '$G(PARMS("SUBSCRIPTION IEN")) S ERROR="SUBSCRIPTION REGISTRY IEN NOT PROVIDED" K PARMS Q 0
    150         ;
    151         I '$$CHKPARMS^HLOAPI2(.HLMSTATE,.PARMS,.ERROR) D  K PARMS Q 0
    152         .S SUBIEN=0 F  S SUBIEN=$$NEXT^HLOASUB(PARMS("SUBSCRIPTION IEN"),.WHO) Q:'SUBIEN  D
    153         ..N SARY,HARY
    154         ..S HARY="STATE(""HDR"")"
    155         ..S SARY="STATE(""STATUS"")"
    156         ..K STATE M STATE=HLMSTATE S STATE("IEN")=""
    157         ..;move parameters into HLMSTATE
    158         ..S @SARY@("LINK IEN")=WHO("LINK IEN")
    159         ..S @SARY@("LINK NAME")=WHO("LINK NAME")
    160         ..S @HARY@("RECEIVING APPLICATION")=WHO("RECEIVING APPLICATION")
    161         ..M @HARY@("RECEIVING FACILITY")=WHO("RECEIVING FACILITY")
    162         ..D DONTSEND(.STATE,$G(ERROR))
    163         ..S MESSAGES(SUBIEN,"QUEUED")=0
    164         ..S MESSAGES(SUBIEN,"IEN")=$G(STATE("IEN"))
    165         ..S MESSAGES(SUBIEN,"ERROR")=$G(ERROR)
    166         ;
    167         F  S SUBIEN=$$NEXT^HLOASUB(PARMS("SUBSCRIPTION IEN"),.WHO) Q:'SUBIEN  D
    168         .N SARY,HARY
    169         .S HARY="STATE(""HDR"")"
    170         .S SARY="STATE(""STATUS"")"
    171         .K STATE M STATE=HLMSTATE S STATE("IEN")=""
    172         .;move parameters into HLMSTATE
    173         .S @SARY@("LINK IEN")=WHO("LINK IEN")
    174         .S @SARY@("LINK NAME")=WHO("LINK NAME")
    175         .S @HARY@("RECEIVING APPLICATION")=WHO("RECEIVING APPLICATION")
    176         .M @HARY@("RECEIVING FACILITY")=WHO("RECEIVING FACILITY")
    177         .S ERROR=""
    178         .I $$SEND(.STATE,.ERROR) D
    179         ..S MESSAGES(SUBIEN,"QUEUED")=1
    180         .E  D
    181         ..S MESSAGES(SUBIEN,"QUEUED")=0,RETURN=0
    182         .S MESSAGES(SUBIEN,"IEN")=$G(STATE("IEN")),MESSAGES(SUBIEN,"ERROR")=$G(ERROR)
    183         K PARMS
    184         Q RETURN
    185         ;
    186 SEND(HLMSTATE,ERROR)    ;
    187         ;
    188         K ERROR
    189         I HLMSTATE("UNSTORED LINES"),'$$SAVEMSG^HLOF777(.HLMSTATE) S ERROR="$$SAVE^HLOF777 FAILED!" Q 0
    190         ;
    191         I '$$SAVEMSG^HLOF778(.HLMSTATE) S ERROR="$$SAVE^HLOF778 FAILED!" Q 0
    192         I HLMSTATE("BATCH"),$L($G(HLMSTATE("STATUS","SEQUENCE QUEUE"))) S ERROR="SEQUENCE QUEUES NOT SUPPORTED FOR BATCH MESSAGES" Q 0
    193         I $L($G(HLMSTATE("STATUS","SEQUENCE QUEUE"))) D
    194         .S HLMSTATE("STATUS","MOVED TO OUT QUEUE")=$$SQUE^HLOQUE(HLMSTATE("STATUS","SEQUENCE QUEUE"),HLMSTATE("STATUS","LINK NAME"),$G(HLMSTATE("STATUS","PORT")),HLMSTATE("STATUS","QUEUE"),HLMSTATE("IEN")) D:HLMSTATE("STATUS","MOVED TO OUT QUEUE")
    195         ..S $P(^HLB(HLMSTATE("IEN"),5),"^",2)=1
    196         E  D
    197         .D OUTQUE^HLOQUE(HLMSTATE("STATUS","LINK NAME"),$G(HLMSTATE("STATUS","PORT")),HLMSTATE("STATUS","QUEUE"),HLMSTATE("IEN"))
    198         Q HLMSTATE("IEN")
    199         ;
    200 DONTSEND(HLMSTATE,ERROR)        ;
    201         ;This procedure does NOT send a message.  Rather, it creates an entry in file 778 with the status ER. 
    202         ;Input:
    203         ;       HLMSTATE - pass-by-reference
    204         ;       ERROR (optional, pass-by-value) error text to store with the message
    205         ;Output: none
    206         ;
    207         I HLMSTATE("UNSTORED LINES"),'$$SAVEMSG^HLOF777(.HLMSTATE) ; just continue
    208         ;
    209         S HLMSTATE("STATUS")="ER"
    210         S HLMSTATE("STATUS","PURGE")=$$FMADD^XLFDT(HLMSTATE("DT/TM CREATED"),HLMSTATE("SYSTEM","ERROR PURGE"))
    211         S HLMSTATE("STATUS","ERROR TEXT")=$G(ERROR)
    212         I '$$SAVEMSG^HLOF778(.HLMSTATE) ;already reported an error to the app
    213         Q
     1HLOAPI1 ;ALB/CJM-HL7 - Developer API's for sending & receiving messages(continued) ;02/06/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,132,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5SENDONE(HLMSTATE,PARMS,WHOTO,ERROR) ;
     6 ;Sends the message to a single receiving application.
     7 ;
     8 ;Input:
     9 ;HLMSTATE() - (pass by reference, required) This array is used by the HL7 package to track the progress of the message.  The application MUST NOT touch it
     10 ;PARMS( *pass by reference*
     11 ;  "APP ACK RESPONSE")=<tag^routine> to call when the app ack is received (optional)
     12 ;    (NOTE: For batch messages, HLO best supports returning application
     13 ;     acknowledgments via a batch response.  However, non-VistA systems
     14 ;     may return individual messages as application acknowledgments to
     15 ;     messages within the original batch message, so for applications
     16 ;     sending batch messages might best code the "APP ACK RESPONSE"
     17 ;     routine to first check whether the response message is a batch.
     18 ;
     19 ;  "ACCEPT ACK RESPONSE")=<tag^routine> to call when the commit ack is received (optional)
     20 ;  "ACCEPT ACK TYPE") = <AL,NE> (optional, defaults to AL)
     21 ;  "APP ACK TYPE") = <AL,NE> (optional, defaults to NE)
     22 ;  "FAILURE RESPONSE" - <tag>^<routine> (optional) The sending application routine to execute when the transmission of the message fails, i.e., the message can not be sent or no commit ack is received.
     23 ;  "QUEUE" - (optional) An application can name its own private queue - just a string up to 20 characters, it should be namespaced.
     24 ;  "SECURITY")=security information to include in the header segment, SEQ 8 (optional)
     25 ;  "SENDING APPLICATION")=name of sending app (required, 60 maximum length)
     26 ;
     27 ;  WHOTO (required,pass by reference) an array specifying a single recipient. These subscripts are allowed:
     28 ;
     29 ;    "RECEIVING APPLICATION" - (string, 60 char max, required)
     30 ;
     31 ;  EXACTLY ONE of these parameters must be provided to identify the Receiving Facility:
     32 ;
     33 ;   "FACILITY LINK IEN" - ien of the logical link
     34 ;   "FACILITY LINK NAME" - name of the logical link
     35 ;   "INSTITUTION IEN" - ptr to the INSTITUTION file
     36 ;   "STATION NUMBER" -  station # with suffix
     37 ;
     38 ;  EXACTLY ONE of these MAY be provided - optionally - to identify the interface engine to route the message through:
     39 ;
     40 ;   "IE LINK IEN" -  ptr to a logical link for the interface engine
     41 ;   "IE LINK NAME" - name of the logical link for the interface engine
     42 ;
     43 ;Output:
     44 ;  Function returns the ien of the message in file 778 on success, 0 on failure
     45 ;   HLMSTATE() - (pass by reference, required) This array is used by the HL7 package to track the progress of the message.  The application MUST NOT touch it!
     46 ;   ERROR (pass by reference, optional) - on failure, will contain an error message
     47 ;   PARMS - left undefined when the function returns
     48 ;   WHOTO - left undefined when the function returns
     49 ;
     50 ;
     51 N SUCCESS,ERR1,ERR2
     52 S SUCCESS=0
     53 D
     54 .I '$G(HLMSTATE("BODY")),'$G(HLMSTATE("UNSTORED LINES")) S ERROR="MESSAGE NOT YET CREATED" Q
     55 .;
     56 .I $$CHKPARMS^HLOAPI2(.HLMSTATE,.PARMS,.ERR1)&$$CHKWHO(.HLMSTATE,.WHOTO,.ERR2) D
     57 ..I $$SEND(.HLMSTATE,.ERROR) S SUCCESS=1
     58 .E  D
     59 .S ERROR=$G(ERR1)_": "_$G(ERR2)
     60 .D DONTSEND(.HLMSTATE,ERROR)
     61 K PARMS,WHOTO
     62 Q $S(SUCCESS:HLMSTATE("IEN"),1:0)
     63 ;
     64SENDMANY(HLMSTATE,PARMS,WHOTO) ;
     65 ;Sends the message to a list of receiving applications
     66 ;
     67 ;Input: Same as for $$SENDONE, except WHOTO is a list.
     68 ;  WHOTO (pass by reference)
     69 ;    Specifies a list of recipients.  Each recipient should be on the
     70 ;    list as WHOTO(i), where i=1,2,3,4, etc. for as many messages as to
     71 ;    send.  At each subscript WHOTO(i), the same lower level subscripts
     72 ;    may be defined as in the $$SENDONE API.  For example:
     73 ;
     74 ;      WHOTO(1,"LINK NAME")="VAALB"
     75 ;      WHOTO(1,"RECEIVING APPLICATION")="MPI"
     76 ;      WHOTO(2,"STATION NUMBER")=500
     77 ;      WHOTO(2,"RECEIVING APPLICATION")="MPI"
     78 ;
     79 ;
     80 ;Output:
     81 ;  Function returns 1 if a message is queued to be sent to each intended recipient, 0 otherwise
     82 ;  PARMS - left undefined when the function returns
     83 ;  WHOTO (pass by reference) returns the status of each message to be sent in the format:
     84 ;    (<i>,"QUEUED")= <1 if queued to be sent, 0 otherwise)
     85 ;   (<i>,"IEN")=<ien, file 778>
     86 ;   (<i>,"ERROR")= error message if an error was encountered (status=0), not defined otherwise
     87 ;
     88 ;
     89 N ERROR,RETURN,WHO,STATE,I
     90 S RETURN=1
     91 I '$G(HLMSTATE("BODY")),'$G(HLMSTATE("UNSTORED LINES")) D  K PARMS Q 0
     92 .S ERROR="MESSAGE NOT YET CREATED"
     93 .S I=0 F  S I=$O(WHOTO(I)) Q:'I  S WHOTO(I,"QUEUED")=0,WHOTO(I,"IEN")=0,WHOTO(I,"ERROR")=ERROR
     94 ;
     95 I '$$CHKPARMS^HLOAPI2(.HLMSTATE,.PARMS,.ERROR) D  K PARMS Q 0
     96 .S I=0 F  S I=$O(WHOTO(I)) Q:'I  D
     97 ..K WHO M WHO=WHOTO(I)
     98 ..K STATE M STATE=HLMSTATE S STATE("IEN")=""
     99 ..S WHOTO(I,"QUEUED")=0
     100 ..D DONTSEND(.STATE,$G(ERROR))
     101 ..S WHOTO(I,"IEN")=$G(STATE("IEN"))
     102 ..S WHOTO(I,"ERROR")=ERROR
     103 ;
     104 S I=0 F  S I=$O(WHOTO(I)) Q:'I  D
     105 .K WHO M WHO=WHOTO(I)
     106 .K STATE M STATE=HLMSTATE S STATE("IEN")=""
     107 .S ERROR=""
     108 .I $$CHKWHO(.STATE,.WHO,.ERROR) D
     109 ..I $$SEND(.STATE,.ERROR) D
     110 ...S WHOTO(I,"QUEUED")=1
     111 ...S WHOTO(I,"IEN")=STATE("IEN")
     112 ...S WHOTO(I,"ERROR")=""
     113 ..E  D
     114 ...S WHOTO(I,"QUEUED")=0
     115 ...S WHOTO(I,"IEN")=$G(STATE("IEN"))
     116 ...S WHOTO(I,"ERROR")=$G(ERROR)
     117 ...S RETURN=0
     118 .E  D  ;who not adequately determined
     119 ..S WHOTO(I,"QUEUED")=0,RETURN=0
     120 ..D DONTSEND(.STATE,$G(ERROR))
     121 ..S WHOTO(I,"IEN")=$G(STATE("IEN")),WHOTO(I,"ERROR")=$G(ERROR)
     122 K PARMS
     123 Q RETURN
     124 ;
     125SENDSUB(HLMSTATE,PARMS,MESSAGES) ;
     126 ;Sends the message to a list of receiving applications based on the HL7 Subscription Registry
     127 ;
     128 ;Input:
     129 ;  HLMSTATE (pass by reference, required) same as $$SENDMANY
     130 ;  PARMS (pass by reference, required) same as $$SENDMANY, with one additional subscript:
     131 ;    "SUBSCRIPTION IEN" - the ien of an entry in the HL7 Subscription Registry, defining the intended recipients of this message
     132 ;
     133 ;Output:
     134 ;  Function returns 1 if a message is queued to be sent to each intended recipient, 0 otherwise
     135 ;  PARMS - left undefined when the function returns
     136 ;  MESSAGES (pass by reference) returns the status of each message to be sent in this format, where subien is the ien of the recipient in the RECIPEINTS subfile of the HL7 Subscription Registry
     137 ;   (<subien>,"QUEUED")= <1 if queued to be sent, 0 otherwise)
     138 ;   (<subien>,"IEN")=<ien, file 778>
     139 ;   (<subien>,"ERROR")= error message if an error was encountered (status=0), not defined otherwise
     140 ;
     141 ;
     142 K MESSAGES
     143 N ERROR,RETURN,STATE,SUBIEN,WHO
     144 ;
     145 S RETURN=1
     146 ;
     147 ;
     148 I '$G(HLMSTATE("BODY")),'$G(HLMSTATE("UNSTORED LINES")) S ERROR="MESSAGE NOT YET CREATED" K PARMS Q 0
     149 I '$G(PARMS("SUBSCRIPTION IEN")) S ERROR="SUBSCRIPTION REGISTRY IEN NOT PROVIDED" K PARMS Q 0
     150 ;
     151 I '$$CHKPARMS^HLOAPI2(.HLMSTATE,.PARMS,.ERROR) D  K PARMS Q 0
     152 .S SUBIEN=0 F  S SUBIEN=$$NEXT^HLOASUB(PARMS("SUBSCRIPTION IEN"),.WHO) Q:'SUBIEN  D
     153 ..N SARY,HARY
     154 ..S HARY="STATE(""HDR"")"
     155 ..S SARY="STATE(""STATUS"")"
     156 ..K STATE M STATE=HLMSTATE S STATE("IEN")=""
     157 ..;move parameters into HLMSTATE
     158 ..S @SARY@("LINK IEN")=WHO("LINK IEN")
     159 ..S @SARY@("LINK NAME")=WHO("LINK NAME")
     160 ..S @HARY@("RECEIVING APPLICATION")=WHO("RECEIVING APPLICATION")
     161 ..M @HARY@("RECEIVING FACILITY")=WHO("RECEIVING FACILITY")
     162 ..D DONTSEND(.STATE,$G(ERROR))
     163 ..S MESSAGES(SUBIEN,"QUEUED")=0
     164 ..S MESSAGES(SUBIEN,"IEN")=$G(STATE("IEN"))
     165 ..S MESSAGES(SUBIEN,"ERROR")=$G(ERROR)
     166 ;
     167 F  S SUBIEN=$$NEXT^HLOASUB(PARMS("SUBSCRIPTION IEN"),.WHO) Q:'SUBIEN  D
     168 .N SARY,HARY
     169 .S HARY="STATE(""HDR"")"
     170 .S SARY="STATE(""STATUS"")"
     171 .K STATE M STATE=HLMSTATE S STATE("IEN")=""
     172 .;move parameters into HLMSTATE
     173 .S @SARY@("LINK IEN")=WHO("LINK IEN")
     174 .S @SARY@("LINK NAME")=WHO("LINK NAME")
     175 .S @HARY@("RECEIVING APPLICATION")=WHO("RECEIVING APPLICATION")
     176 .M @HARY@("RECEIVING FACILITY")=WHO("RECEIVING FACILITY")
     177 .S ERROR=""
     178 .I $$SEND(.STATE,.ERROR) D
     179 ..S MESSAGES(SUBIEN,"QUEUED")=1
     180 .E  D
     181 ..S MESSAGES(SUBIEN,"QUEUED")=0,RETURN=0
     182 .S MESSAGES(SUBIEN,"IEN")=$G(STATE("IEN")),MESSAGES(SUBIEN,"ERROR")=$G(ERROR)
     183 K PARMS
     184 Q RETURN
     185 ;
     186SEND(HLMSTATE,ERROR) ;
     187 ;
     188 K ERROR
     189 I HLMSTATE("UNSTORED LINES"),'$$SAVEMSG^HLOF777(.HLMSTATE) S ERROR="$$SAVE^HLOF777 FAILED!" Q 0
     190 ;
     191 I '$$SAVEMSG^HLOF778(.HLMSTATE) S ERROR="$$SAVE^HLOF778 FAILED!" Q 0
     192 D OUTQUE^HLOQUE(HLMSTATE("STATUS","LINK NAME"),$G(HLMSTATE("STATUS","PORT")),HLMSTATE("STATUS","QUEUE"),HLMSTATE("IEN"))
     193 Q HLMSTATE("IEN")
     194 ;
     195DONTSEND(HLMSTATE,ERROR) ;
     196 ;This procedure does NOT send a message.  Rather, it creates an entry in file 778 with the
     197 ;of "SE". 
     198 ;Input:
     199 ;       HLMSTATE - pass-by-reference
     200 ;       ERROR (optional, pass-by-value) error text to store with the message
     201 ;Output: none
     202 ;
     203 I HLMSTATE("UNSTORED LINES"),'$$SAVEMSG^HLOF777(.HLMSTATE) ; just continue
     204 ;
     205 S HLMSTATE("STATUS")="SE"
     206 S HLMSTATE("STATUS","PURGE")=$$FMADD^XLFDT(HLMSTATE("DT/TM CREATED"),HLMSTATE("SYSTEM","ERROR PURGE"))
     207 S HLMSTATE("STATUS","ERROR TEXT")=$G(ERROR)
     208 I '$$SAVEMSG^HLOF778(.HLMSTATE) ;already reported an error to the app
     209 Q
     210 ;
     211CHKWHO(HLMSTATE,WHOTO,ERROR) ;
     212 N RETURN,I
     213 S RETURN=1
     214 I '$$CHECKWHO^HLOASUB1(.WHOTO,.RETURN,.ERROR) S RETURN=0
     215 ;
     216 ;move parameters into HLMSTATE
     217 S HLMSTATE("STATUS","LINK IEN")=$G(RETURN("LINK IEN"))
     218 S HLMSTATE("STATUS","LINK NAME")=$G(RETURN("LINK NAME"))
     219 S HLMSTATE("STATUS","PORT")=$P($G(RETURN("RECEIVING FACILITY",2)),":",2)
     220 S HLMSTATE("HDR","RECEIVING APPLICATION")=$G(RETURN("RECEIVING APPLICATION"))
     221 F I=1:1:3 S HLMSTATE("HDR","RECEIVING FACILITY",I)=$G(RETURN("RECEIVING FACILITY",I))
     222 Q RETURN
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOAPI2.m

    r613 r623  
    1 HLOAPI2 ;ALB/CJM-HL7 - Developer API's for sending application acks ;07/30/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,131,133,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 ACK(HLMSTATE,PARMS,ACK,ERROR)   ;Default behavior is to return a general
    6         ;application ack. The application may optionally specify the message
    7         ;type and event or call $$ADDSEG^HLOAPI to add segments.
    8         ;A generic MSA segment (components 1-3) is added automatically IF the
    9         ;application doesn't call $$ADDSEG^HLOAPI to add an MSA segment as the
    10         ;FIRST segment following the header.
    11         ;$$SENDACK must be called when the ack is completed. The return
    12         ;destination is determined automatically from the original message
    13         ;
    14         ;This API should NOT be called for batch messages, use $$BATCHACK instead.
    15         ;Input:
    16         ;  HLMSTATE (pass by reference, required) the array obtained by calling $$STARTMSG^HLOPRS when parsing the original message
    17         ;  PARMS (pass by reference) These subscripts may be defined:
    18         ;    "ACK CODE" (required) MSA1[ {AA,AE,AR}
    19         ;    "ERROR MESSAGE" - MSA3, should be used only if AE or AR
    20         ;    "ACCEPT ACK RESPONSE" - the <tag^routine> to call when the commit ack is received (optional)
    21         ;    "ACCEPT ACK TYPE" - {AL,NE} (optional, defaults to AL)
    22         ;    "CONTINUATION POINTER" (optional)indicates a fragmented message
    23         ;    "COUNTRY" - the 3 character country code (optional)
    24         ;    "EVENT" - the 3 character event type (optional, defaults to the event code of the original message)
    25         ;     "ENCODING CHARACTERS" - the four HL7 encoding characters (optional,defaults to "^~\&"
    26         ;    "FAILURE RESPONSE" (optional) the <tag>^<routine> that the sending application routine should execute if the transmission of the message fails, i.e., the message can not be sent or a requested commit ack is not received.
    27         ;    "FIELD SEPARATOR" - field separator (optional, defaults to "|")
    28         ;    "MESSAGE TYPE" - if not defined, ACK is used
    29         ;    "MESSAGE STRUCTURE" (optional)
    30         ;    "QUEUE" - (optional) An application can name its own private queue (a string under 20 characters,namespaced). The default is the name of the queue of the original message
    31         ;    "SECURITY" (optional) security information to include in the header segment, SEQ 8 (optional)
    32         ;    "VERSION" - the HL7 Version ID (optional, defaults to 2.4)
    33         ;Output:
    34         ;  Function returns 1 on success, 0 on failure
    35         ;  PARMS - left undefined when the function returns
    36         ;  ACK (pass by reference, required) the acknowledgment message being built.
    37         ;  ERROR (pass by reference) error msg
    38         N I,SEG,TOLINK,SUCCESS
    39         S SUCCESS=0,ERROR=""
    40         ;
    41         D
    42         .N PORT
    43         .I $G(PARMS("ACK CODE"))'="AA",$G(PARMS("ACK CODE"))'="AE",$G(PARMS("ACK CODE"))'="AR" S ERROR="INVALID ACK CODE" Q
    44         .;
    45         .I '$G(HLMSTATE("IEN")) S ERROR="ORIGINAL MESSAGE TO ACKNOWLEDGE IS NOT IDENTIFIED" Q
    46         .I $G(HLMSTATE("BATCH")) S ERROR="BATCH ACKNOWLEDGMENTS MUST USE $$BATCHACK^HLOAPI3" Q
    47         .;
    48         .I $G(HLMSTATE("HDR","MESSAGE CONTROL ID"))="" S ERROR="MESSAGE CONTROL ID MUST EXIST TO RETURN AN APPLICATION ACK" Q
    49         .S PARMS("MESSAGE TYPE")=$G(PARMS("MESSAGE TYPE"),"ACK")
    50         .S:PARMS("MESSAGE TYPE")="ACK" PARMS("MESSAGE STRUCTURE")="ACK"
    51         .S PARMS("EVENT")=$G(PARMS("EVENT"),$G(HLMSTATE("HDR","EVENT")))
    52         .I $$NEWMSG^HLOAPI(.PARMS,.ACK)  ;can't fail!
    53         .;
    54         .;if the return link can not be determined, the HL Logical Link file has a problem that must be fixed at the site
    55         .S PORT=$P(HLMSTATE("HDR","SENDING FACILITY",2),":",2)
    56         .S TOLINK=$$ACKLINK(.HLMSTATE)
    57         .I TOLINK="" S ERROR="TRANSMISSION LINK FOR APPLICATION ACK CANNOT BE DETERMINED" Q
    58         .I 'PORT S PORT=$$PORT2^HLOTLNK(TOLINK)
    59         .;
    60         .S ACK("HDR","APP ACK TYPE")="NE"
    61         .S ACK("HDR","ACCEPT ACK TYPE")=$G(PARMS("ACCEPT ACK TYPE"),"AL")
    62         .S ACK("STATUS","QUEUE")=$G(PARMS("QUEUE"),$G(HLMSTATE("STATUS","QUEUE")))
    63         .S ACK("STATUS","PORT")=PORT
    64         .S ACK("HDR","SECURITY")=$G(PARMS("SECURITY"))
    65         .S ACK("HDR","SENDING APPLICATION")=$G(HLMSTATE("HDR","RECEIVING APPLICATION"))
    66         .S ACK("HDR","RECEIVING APPLICATION")=$G(HLMSTATE("HDR","SENDING APPLICATION"))
    67         .F I=1:1:3 S ACK("HDR","RECEIVING FACILITY",I)=$G(HLMSTATE("HDR","SENDING FACILITY",I))
    68         .S ACK("ACK TO","STATUS")=$S(PARMS("ACK CODE")="AA":"SU",1:"ER")
    69         .S ACK("ACK TO")=$G(HLMSTATE("HDR","MESSAGE CONTROL ID"))
    70         .S ACK("ACK TO","IEN")=HLMSTATE("IEN")
    71         .S ACK("STATUS","LINK NAME")=TOLINK
    72         .S ACK("LINE COUNT")=0
    73         .S ACK("MSA")="MSA"_ACK("HDR","FIELD SEPARATOR")_PARMS("ACK CODE")_ACK("HDR","FIELD SEPARATOR")_$G(HLMSTATE("HDR","MESSAGE CONTROL ID"))_ACK("HDR","FIELD SEPARATOR")_$G(PARMS("ERROR MESSAGE"))
    74         .S SUCCESS=1
    75         K PARMS
    76         K:'SUCCESS ACK
    77         Q SUCCESS
    78         ;
    79 SENDACK(ACK,ERROR)      ;This is used to signal that an application acknowledgment is complete.
    80         ;Input:
    81         ;  ACK (pass by reference,required) An array that contains the acknowledgment msg
    82         ;Output:
    83         ; Function returns 1 on success, 0 on failure
    84         ; ERROR (pass by reference) error msg
    85         ;
    86         N SEG
    87         ;if the application added its own MSA, then the ACK("MSA") node was killed
    88         I $D(ACK("MSA")) S SEG(1)=ACK("MSA") D ADDSEG^HLOMSG(.ACK,.SEG)
    89         ;
    90         I $$SEND^HLOAPI1(.ACK,.ERROR) Q 1
    91         Q 0
    92         ;
    93 ACKLINK(HLMSTATE)       ;
    94         ;Finds the link to return the application ack to.
    95         N LINK
    96         S LINK=$$RTRNLNK^HLOAPP($G(HLMSTATE("HDR","RECEIVING APPLICATION")))
    97         Q:LINK]"" LINK
    98         S LINK=$$RTRNLNK^HLOTLNK($G(HLMSTATE("HDR","SENDING FACILITY",1)),$G(HLMSTATE("HDR","SENDING FACILITY",2)),$G(HLMSTATE("HDR","SENDING FACILITY",3)))
    99         Q LINK
    100         ;
    101 CHKPARMS(HLMSTATE,PARMS,ERROR)  ;
    102         N LEN,SARY,HARY
    103         ;
    104         ;shortcut to reference the header sub-array
    105         S HARY="HLMSTATE(""HDR"")"
    106         ;
    107         ;shortcut to reference the status sub-array
    108         S SARY="HLMSTATE(""STATUS"")"
    109         ;
    110         S ERROR=""
    111         I $G(PARMS("ACCEPT ACK TYPE"))="" S PARMS("ACCEPT ACK TYPE")="AL"
    112         I $G(PARMS("APP ACK TYPE"))="" S PARMS("APP ACK TYPE")="NE"
    113         I PARMS("ACCEPT ACK TYPE")'="NE",PARMS("ACCEPT ACK TYPE")'="AL" S ERROR="INVALID ACCEPT ACKNOWLEDGMENT TYPE"
    114         I PARMS("APP ACK TYPE")'="NE",PARMS("APP ACK TYPE")'="AL" S ERROR="INVALID APPLICATION ACKNOWLEDGMENT TYPE"
    115         S LEN=$L($G(PARMS("QUEUE")))
    116         I $G(PARMS("QUEUE"))["^" S ERROR="QUEUE NAME MAY NOT CONTAIN '^'"
    117         I LEN>20 S ERROR="QUEUE PARAMETER IS MAX 20 LENGTH",PARMS("QUEUE")=$E(PARMS("QUEUE"),1,20)
    118         I 'LEN S PARMS("QUEUE")="DEFAULT"
    119         D
    120         .N APPIEN
    121         .I $G(PARMS("SENDING APPLICATION"))="" D  Q
    122         ..S ERROR="SENDING APPLICATION IS REQUIRED"
    123         ..S PARMS("SENDING APPLICATION")=""
    124         .E  D  Q:'APPIEN
    125         ..S APPIEN=$$GETIEN^HLOAPP(PARMS("SENDING APPLICATION"))
    126         ..I 'APPIEN S ERROR="SENDING APPLICATION NOT FOUND IN THE HLO APPLICATION REGISTRY"
    127         .I $L($G(PARMS("SEQUENCE QUEUE"))) D
    128         ..I ($L(PARMS("SEQUENCE QUEUE"))>30) S ERROR="SEQUENCE QUEUE NAME > 30 CHARACTERS" Q
    129         ..I PARMS("SEQUENCE QUEUE")["^" S ERROR="SEQUENCE QUEUE NAME MAY NOT CONTAIN '^'" Q
    130         ..I $G(PARMS("APP ACK TYPE"))'="AL" S ERROR="SEQUENCE QUEUES REQUIRE AN APPLICATION ACKNOWLEDGMENT" Q
    131         ..I $G(PARMS("ACCEPT ACK TYPE"))'="AL" S ERROR="SEQUENCE QUEUES REQUIRE AN ACCEPT ACKNOWLEDGMENT" Q
    132         ;
    133         ;move parameters into HLMSTATE
    134         S @HARY@("ACCEPT ACK TYPE")=PARMS("ACCEPT ACK TYPE")
    135         S @HARY@("APP ACK TYPE")=PARMS("APP ACK TYPE")
    136         S @HARY@("SENDING APPLICATION")=$E(PARMS("SENDING APPLICATION"),1,60)
    137         S @HARY@("SECURITY")=$G(PARMS("SECURITY"))
    138         S @SARY@("APP ACK RESPONSE")=$G(PARMS("APP ACK RESPONSE"))
    139         S @SARY@("ACCEPT ACK RESPONSE")=$G(PARMS("ACCEPT ACK RESPONSE"))
    140         S @SARY@("FAILURE RESPONSE")=$G(PARMS("FAILURE RESPONSE"))
    141         S @SARY@("QUEUE")=PARMS("QUEUE")
    142         S @SARY@("SEQUENCE QUEUE")=$G(PARMS("SEQUENCE QUEUE"))
    143         Q:$L(ERROR) 0
    144         Q 1
    145         ;
    146         ;
    147 SETCODE(SEG,VALUE,FIELD,COMP,REP)       ;
    148         ;Implements SETCNE and SETCWE
    149         ;
    150         N SUB,VAR
    151         Q:'$G(FIELD)
    152         S:'$G(REP) REP=1
    153         I '$G(COMP) D
    154         .S VAR="COMP",SUB=1
    155         E  D
    156         .S VAR="SUB"
    157         S @VAR=1,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ID"))
    158         S @VAR=2,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("TEXT"))
    159         S @VAR=3,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("SYSTEM"))
    160         S @VAR=4,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ALTERNATE ID"))
    161         S @VAR=5,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ALTERNATE TEXT"))
    162         S @VAR=6,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ALTERNATE SYSTEM"))
    163         S @VAR=7,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("SYSTEM VERSION"))
    164         S @VAR=8,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ALTERNATE SYSTEM VERSION"))
    165         S @VAR=9,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ORIGINAL TEXT"))
    166         Q
    167         ;
    168 CHKWHO(HLMSTATE,WHOTO,ERROR)    ;
    169         N RETURN,I
    170         S RETURN=1
    171         I '$$CHECKWHO^HLOASUB1(.WHOTO,.RETURN,.ERROR) S RETURN=0
    172         ;
    173         ;move parameters into HLMSTATE
    174         S HLMSTATE("STATUS","LINK IEN")=$G(RETURN("LINK IEN"))
    175         S HLMSTATE("STATUS","LINK NAME")=$G(RETURN("LINK NAME"))
    176         S HLMSTATE("STATUS","PORT")=$P($G(RETURN("RECEIVING FACILITY",2)),":",2)
    177         S HLMSTATE("HDR","RECEIVING APPLICATION")=$G(RETURN("RECEIVING APPLICATION"))
    178         F I=1:1:3 S HLMSTATE("HDR","RECEIVING FACILITY",I)=$G(RETURN("RECEIVING FACILITY",I))
    179         Q RETURN
     1HLOAPI2 ;ALB/CJM-HL7 - Developer API's for sending application acks ;12/11/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,131,133,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5ACK(HLMSTATE,PARMS,ACK,ERROR) ;Default behavior is to return a general
     6 ;application ack. The application may optionally specify the message
     7 ;type and event or call $$ADDSEG^HLOAPI to add segments.
     8 ;A generic MSA segment (components 1-3) is added automatically IF the
     9 ;application doesn't call $$ADDSEG^HLOAPI to add an MSA segment as the
     10 ;FIRST segment following the header.
     11 ;$$SENDACK must be called when the ack is completed. The return
     12 ;destination is determined automatically from the original message
     13 ;
     14 ;This API should NOT be called for batch messages, use $$BATCHACK instead.
     15 ;Input:
     16 ;  HLMSTATE (pass by reference, required) the array obtained by calling $$STARTMSG^HLOPRS when parsing the original message
     17 ;  PARMS (pass by reference) These subscripts may be defined:
     18 ;    "ACK CODE" (required) MSA1[ {AA,AE,AR}
     19 ;    "ERROR MESSAGE" - MSA3, should be used only if AE or AR
     20 ;    "ACCEPT ACK RESPONSE" - the <tag^routine> to call when the commit ack is received (optional)
     21 ;    "ACCEPT ACK TYPE" - {AL,NE} (optional, defaults to AL)
     22 ;    "CONTINUATION POINTER" (optional)indicates a fragmented message
     23 ;    "COUNTRY" - the 3 character country code (optional)
     24 ;    "EVENT" - the 3 character event type (optional, defaults to the event code of the original message)
     25 ;     "ENCODING CHARACTERS" - the four HL7 encoding characters (optional,defaults to "^~\&"
     26 ;    "FAILURE RESPONSE" (optional) the <tag>^<routine> that the sending application routine should execute if the transmission of the message fails, i.e., the message can not be sent or a requested commit ack is not received.
     27 ;    "FIELD SEPARATOR" - field separator (optional, defaults to "|")
     28 ;    "MESSAGE TYPE" - if not defined, ACK is used
     29 ;    "MESSAGE STRUCTURE" (optional)
     30 ;    "QUEUE" - (optional) An application can name its own private queue (a string under 20 characters,namespaced). The default is the name of the queue of the original message
     31 ;    "SECURITY" (optional) security information to include in the header segment, SEQ 8 (optional)
     32 ;    "VERSION" - the HL7 Version ID (optional, defaults to 2.4)
     33 ;Output:
     34 ;  Function returns 1 on success, 0 on failure
     35 ;  PARMS - left undefined when the function returns
     36 ;  ACK (pass by reference, required) the acknowledgment message being built.
     37 ;  ERROR (pass by reference) error msg
     38 N I,SEG,TOLINK,SUCCESS
     39 S SUCCESS=0,ERROR=""
     40 ;
     41 D
     42 .N PORT
     43 .I $G(PARMS("ACK CODE"))'="AA",$G(PARMS("ACK CODE"))'="AE",$G(PARMS("ACK CODE"))'="AR" S ERROR="INVALID ACK CODE" Q
     44 .;
     45 .I '$G(HLMSTATE("IEN")) S ERROR="ORIGINAL MESSAGE TO ACKNOWLEDGE IS NOT IDENTIFIED" Q
     46 .I $G(HLMSTATE("BATCH")) S ERROR="BATCH ACKNOWLEDGMENTS MUST USE $$BATCHACK^HLOAPI3" Q
     47 .;
     48 .I $G(HLMSTATE("HDR","MESSAGE CONTROL ID"))="" S ERROR="MESSAGE CONTROL ID MUST EXIST TO RETURN AN APPLICATION ACK" Q
     49 .S PARMS("MESSAGE TYPE")=$G(PARMS("MESSAGE TYPE"),"ACK")
     50 .S:PARMS("MESSAGE TYPE")="ACK" PARMS("MESSAGE STRUCTURE")="ACK"
     51 .S PARMS("EVENT")=$G(PARMS("EVENT"),$G(HLMSTATE("HDR","EVENT")))
     52 .I $$NEWMSG^HLOAPI(.PARMS,.ACK)  ;can't fail!
     53 .;
     54 .;if the return link can not be determined, the HL Logical Link file has a problem that must be fixed at the site
     55 .S PORT=$P(HLMSTATE("HDR","SENDING FACILITY",2),":",2)
     56 .S TOLINK=$$ACKLINK(.HLMSTATE)
     57 .I TOLINK="" S ERROR="TRANSMISSION LINK FOR APPLICATION ACK CANNOT BE DETERMINED" Q
     58 .I 'PORT S PORT=$$PORT2^HLOTLNK(TOLINK)
     59 .;
     60 .S ACK("HDR","APP ACK TYPE")="NE"
     61 .S ACK("HDR","ACCEPT ACK TYPE")=$G(PARMS("ACCEPT ACK TYPE"),"AL")
     62 .S ACK("STATUS","QUEUE")=$G(PARMS("QUEUE"),$G(HLMSTATE("STATUS","QUEUE")))
     63 .S ACK("STATUS","PORT")=PORT
     64 .S ACK("HDR","SECURITY")=$G(PARMS("SECURITY"))
     65 .S ACK("HDR","SENDING APPLICATION")=$G(HLMSTATE("HDR","RECEIVING APPLICATION"))
     66 .S ACK("HDR","RECEIVING APPLICATION")=$G(HLMSTATE("HDR","SENDING APPLICATION"))
     67 .F I=1:1:3 S ACK("HDR","RECEIVING FACILITY",I)=$G(HLMSTATE("HDR","SENDING FACILITY",I))
     68 .S ACK("ACK TO","STATUS")=$S(PARMS("ACK CODE")="AA":"SU",1:"AE")
     69 .S ACK("ACK TO")=$G(HLMSTATE("HDR","MESSAGE CONTROL ID"))
     70 .S ACK("ACK TO","IEN")=HLMSTATE("IEN")
     71 .S ACK("STATUS","LINK NAME")=TOLINK
     72 .S ACK("LINE COUNT")=0
     73 .S ACK("MSA")="MSA"_ACK("HDR","FIELD SEPARATOR")_PARMS("ACK CODE")_ACK("HDR","FIELD SEPARATOR")_$G(HLMSTATE("HDR","MESSAGE CONTROL ID"))_ACK("HDR","FIELD SEPARATOR")_$G(PARMS("ERROR MESSAGE"))
     74 .S SUCCESS=1
     75 K PARMS
     76 K:'SUCCESS ACK
     77 Q SUCCESS
     78 ;
     79SENDACK(ACK,ERROR) ;This is used to signal that an application acknowledgment is complete.
     80 ;Input:
     81 ;  ACK (pass by reference,required) An array that contains the acknowledgment msg
     82 ;Output:
     83 ; Function returns 1 on success, 0 on failure
     84 ; ERROR (pass by reference) error msg
     85 ;
     86 N SEG
     87 ;if the application added its own MSA, then the ACK("MSA") node was killed
     88 I $D(ACK("MSA")) S SEG(1)=ACK("MSA") D ADDSEG^HLOMSG(.ACK,.SEG)
     89 ;
     90 I $$SEND^HLOAPI1(.ACK,.ERROR) Q 1
     91 Q 0
     92 ;
     93ACKLINK(HLMSTATE) ;
     94 ;Finds the link to return the application ack to.
     95 N LINK
     96 S LINK=$$RTRNLNK^HLOAPP($G(HLMSTATE("HDR","RECEIVING APPLICATION")))
     97 Q:LINK]"" LINK
     98 S LINK=$$RTRNLNK^HLOTLNK($G(HLMSTATE("HDR","SENDING FACILITY",1)),$G(HLMSTATE("HDR","SENDING FACILITY",2)),$G(HLMSTATE("HDR","SENDING FACILITY",3)))
     99 Q LINK
     100 ;
     101CHKPARMS(HLMSTATE,PARMS,ERROR) ;
     102 N LEN,SARY,HARY
     103 ;
     104 ;shortcut to reference the header sub-array
     105 S HARY="HLMSTATE(""HDR"")"
     106 ;
     107 ;shortcut to reference the status sub-array
     108 S SARY="HLMSTATE(""STATUS"")"
     109 ;
     110 S ERROR=""
     111 I $G(PARMS("ACCEPT ACK TYPE"))="" S PARMS("ACCEPT ACK TYPE")="AL"
     112 I $G(PARMS("APP ACK TYPE"))="" S PARMS("APP ACK TYPE")="NE"
     113 I PARMS("ACCEPT ACK TYPE")'="NE",PARMS("ACCEPT ACK TYPE")'="AL" S ERROR="INVALID ACCEPT ACKNOWLEDGMENT TYPE"
     114 I PARMS("APP ACK TYPE")'="NE",PARMS("APP ACK TYPE")'="AL" S ERROR="INVALID APPLICATION ACKNOWLEDGMENT TYPE"
     115 S LEN=$L($G(PARMS("QUEUE")))
     116 I $G(PARMS("QUEUE"))["^" S ERROR="QUEUE NAME MAY NOT CONTAIN '^'"
     117 I LEN>20 S ERROR="QUEUE PARAMETER IS MAX 20 LENGTH",PARMS("QUEUE")=$E(PARMS("QUEUE"),1,20)
     118 I 'LEN S PARMS("QUEUE")="DEFAULT"
     119 I $G(PARMS("SENDING APPLICATION"))="" D
     120 .S ERROR="SENDING APPLICATION IS REQUIRED"
     121 .S PARMS("SENDING APPLICATION")=""
     122 E  D
     123 .I '$D(^HLD(779.2,"C",PARMS("SENDING APPLICATION"))) S ERROR="SENDING APPLICATION NOT FOUND IN THE HLO APPLICATION REGISTRY"
     124 ;
     125 ;move parameters into HLMSTATE
     126 S @HARY@("ACCEPT ACK TYPE")=PARMS("ACCEPT ACK TYPE")
     127 S @HARY@("APP ACK TYPE")=PARMS("APP ACK TYPE")
     128 S @HARY@("SENDING APPLICATION")=$E(PARMS("SENDING APPLICATION"),1,60)
     129 S @HARY@("SECURITY")=$G(PARMS("SECURITY"))
     130 S @SARY@("APP ACK RESPONSE")=$G(PARMS("APP ACK RESPONSE"))
     131 S @SARY@("ACCEPT ACK RESPONSE")=$G(PARMS("ACCEPT ACK RESPONSE"))
     132 S @SARY@("FAILURE RESPONSE")=$G(PARMS("FAILURE RESPONSE"))
     133 S @SARY@("QUEUE")=PARMS("QUEUE")
     134 Q:$L(ERROR) 0
     135 Q 1
     136 ;
     137SETCODE(SEG,VALUE,FIELD,COMP,REP) ;
     138 ;Implements SETCNE and SETCWE
     139 ;
     140 N SUB,VAR
     141 Q:'$G(FIELD)
     142 S:'$G(REP) REP=1
     143 I '$G(COMP) D
     144 .S VAR="COMP",SUB=1
     145 E  D
     146 .S VAR="SUB"
     147 S @VAR=1,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ID"))
     148 S @VAR=2,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("TEXT"))
     149 S @VAR=3,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("SYSTEM"))
     150 S @VAR=4,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ALTERNATE ID"))
     151 S @VAR=5,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ALTERNATE TEXT"))
     152 S @VAR=6,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ALTERNATE SYSTEM"))
     153 S @VAR=7,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("SYSTEM VERSION"))
     154 S @VAR=8,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ALTERNATE SYSTEM VERSION"))
     155 S @VAR=9,SEG(FIELD,REP,COMP,SUB)=$G(VALUE("ORIGINAL TEXT"))
     156 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOAPI3.m

    r613 r623  
    1 HLOAPI3 ;ALB/CJM-HL7 - Developer API's for sending application acks ;07/10/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,133,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 BATCHACK(HLMSTATE,PARMS,ACK,ERROR)      ;Starts a batch message that is the response to a batch message. Individual acks are placed in the batch by calling $$ADDACK.
    6         ;$$SENDACK^HLOAPI2 must be called when the batch of acks is complete. The return destination is determined automatically from the original message.
    7         ;
    8         ;Input:
    9         ;  HLMSTATE (pass by reference, required) the array obtained by calling $$STARTMSG^HLOPRS when parsing the original message
    10         ;  PARMS (optional, pass by reference) These subscripts may be defined:
    11         ;    "ACCEPT ACK RESPONSE")=<tag^routine> to call when the commit ack is received (optional)
    12         ;    "ACCEPT ACK TYPE") = <AL,NE> (optional, defaults to AL)
    13         ;    "COUNTRY") - a 3 character country code from the HL7 standard table (optional)
    14         ;     "ENCODING CHARACTERS" - the 4 HL7 encoding characters (optional,defaults to "^~\&"
    15         ;    "FAILURE RESPONSE" (optional) the <tag>^<routine> that the sending application routine should execute if the transmission of the message fails, i.e., the message can not be sent or a requested commit ack is not received.
    16         ;     "FIELD SEPARATOR" - the field separator (optional, defaults to "|")
    17         ;     "QUEUE" (optional) An application can name a private queue (a string under 20 characters, namespaced). The default is the name of the queue of the original message
    18         ;     "SECURITY" - security information to include in the header segment, SEQ 8 (optional)
    19         ;    "VERSION" - the HL7 Version ID (optional, defaults to 2.4)
    20         ;Output:
    21         ;  Function returns 1 on success, 0 on failure
    22         ;  PARMS - left undefined upon completion
    23         ;  ACK (pass by reference, required) the batch acknowledgment message being built.
    24         ;  ERROR (pass by reference) error message
    25         N I,TOLINK,SUCCESS
    26         S SUCCESS=0
    27         ;
    28         D
    29         .N PORT
    30         .I '$G(HLMSTATE("IEN")) S ERROR="ORIGINAL MESSAGE TO ACKNOWLEDGMENT IS NOT IDENTIFIED" Q
    31         .;if the return link can not be determined, the HL Logical Link file has a problem
    32         .S TOLINK=$$ACKLINK^HLOAPI2(.HLMSTATE)
    33         .I TOLINK="" S ERROR="TRANSMISSION LINK FOR APPLICATION ACK CANNOT BE DETERMINED" Q
    34         .S PORT=$P(HLMSTATE("HDR","SENDING FACILITY",2),":",2)
    35         .I 'PORT S PORT=$$PORT2^HLOTLNK(TOLINK)
    36         .;
    37         .I $$NEWBATCH^HLOAPI(.PARMS,.ACK)  ;can't fail!
    38         .S ACK("STATUS","QUEUE")=$G(PARMS("QUEUE"),$G(HLMSTATE("STATUS","QUEUE")))
    39         .S ACK("STATUS","PORT")=PORT
    40         .S ACK("HDR","SECURITY")=$G(PARMS("SECURITY"))
    41         .S ACK("HDR","SENDING APPLICATION")=$G(HLMSTATE("HDR","RECEIVING APPLICATION"))
    42         .S ACK("HDR","RECEIVING APPLICATION")=$G(HLMSTATE("HDR","SENDING APPLICATION"))
    43         .F I=1:1:3 S ACK("HDR","RECEIVING FACILITY",I)=$G(HLMSTATE("HDR","SENDING FACILITY",I))
    44         .S ACK("HDR","APP ACK TYPE")="NE"
    45         .S ACK("HDR","ACCEPT ACK TYPE")=$G(PARMS("ACCEPT ACK TYPE"),"AL")
    46         .S ACK("ACK TO")=$G(HLMSTATE("HDR","BATCH CONTROL ID"))
    47         .S ACK("ACK TO","IEN")=HLMSTATE("IEN")
    48         .S ACK("ACK TO","BODY")=$G(HLMSTATE("BODY"))
    49         .S ACK("STATUS","LINK NAME")=TOLINK
    50         .S ACK("LINE COUNT")=0
    51         .S SUCCESS=1
    52         K PARMS
    53         Q SUCCESS
    54         ;
    55 ADDACK(ACK,PARMS,ERROR) ;This API adds an application acknowledgment to a batch
    56         ;of acknowledgments that was started by calling $$BATCHACK.
    57         ;The Default behavior is to return a general application ack.
    58         ;The application may optionally specify the message
    59         ;type and event and/or call $$ADDSEG^HLOAPI to add segments.
    60         ;A generic MSA segment (components 1-3) will be added automatically
    61         ;if the application doesn't call $$ADDSEG^HLOAPI to add an MSA segment
    62         ;as the FIRST segment following the MSH segment.
    63         ;$$SENDACK^HLOAPI2 must be called when the batch is complete.
    64         ;
    65         ;Input:
    66         ;  ACK (pass by reference,required) the batch of acks that is being built
    67         ;  PARMS (pass by reference) These subscripts may be defined:
    68         ;    "ACK CODE" (required) MSA1[ {AA,AE,AR}
    69         ;    "ERROR MESSAGE" (optional) MSA3, should be used only if AE or AR
    70         ;    "EVENT" - 3 character event type (optional, defaults to the event code of the original message)
    71         ;    "MESSAGE CONTROL ID" (required) this is the message control id of the original individual message within the batch which is being acknowledged
    72         ;    "MESSAGE STRUCTURE" (optional)
    73         ;    "MESSAGE TYPE" (optional, defaults to ACK)
    74         ;    "SECURITY" (optional) security information to include in the header segment SEQ 8
    75         ;Output:
    76         ;  Function returns 1 on success, 0 on failure
    77         ;  ACK (pass by reference, required) The batch, updated with another ack
    78         ;  PARMS  - left undefined when this function returns
    79         ;  ERROR (pass by reference) error msg
    80         ;
    81         N SUB,SUCCESS
    82         S SUCCESS=0
    83         D
    84         .I $G(PARMS("ACK CODE"))'="AA",$G(PARMS("ACK CODE"))'="AE",$G(PARMS("ACK CODE"))'="AR" S ERROR="INVALID ACK CODE" Q
    85         .;
    86         .I $G(PARMS("MESSAGE CONTROL ID"))="" S ERROR="MESSAGE CONTROL ID MUST EXIST TO RETURN AN APPLICATION ACK" Q
    87         .S SUB=""
    88         .F  S SUB=$O(^HLB("AE",PARMS("MESSAGE CONTROL ID"),SUB)) Q:SUB=""  I $P(SUB,"^")=ACK("ACK TO","IEN"),$P(SUB,"^",2) S PARMS("ACK TO","IEN")=SUB Q
    89         .S PARMS("MESSAGE TYPE")=$G(PARMS("MESSAGE TYPE"),"ACK")
    90         .S:PARMS("MESSAGE TYPE")="ACK" PARMS("MESSAGE STRUCTURE")="ACK"
    91         .S PARMS("EVENT")=$G(PARMS("EVENT"))
    92         .I PARMS("EVENT")="",ACK("ACK TO","BODY"),$P(SUB,"^",2) S PARMS("EVENT")=$P($G(^HLA(ACK("ACK TO","BODY"),2,$P(SUB,"^",2),0)),"^",3)
    93         .S PARMS("ACK TO")=PARMS("MESSAGE CONTROL ID")
    94         .S PARMS("ACK TO","STATUS")=$S(PARMS("ACK CODE")="AA":"SU",1:"ER")
    95         .Q:'$$ADDMSG^HLOAPI(.ACK,.PARMS,.ERROR)
    96         .S ACK("MSA")="MSA|"_PARMS("ACK CODE")_"|"_PARMS("MESSAGE CONTROL ID")_"|"_$G(PARMS("ERROR MESSAGE"))
    97         .S SUCCESS=1
    98         K PARMS
    99         Q SUCCESS
    100         ;
    101 RESEND(MSGIEN,ERROR)    ;
    102         ;This message will re-transmit an out-going message. It copies a copy the message, reusing all the original parameters. Then the message is requeued.
    103         ;
    104         ;Input:
    105         ;  MSGIEN - the ien (file #778) of the message that is to be sent
    106         ;Output:
    107         ;  Function returns the ien of the message in file 778 on success, 0 on failure
    108         ;  ERROR (pass by reference, optional)an error message
    109         ;
    110         N MSG,SUB,HDR
    111         I '$$STARTMSG^HLOPRS(.MSG,MSGIEN) S ERROR="MESSAGE NOT FOUND" Q 0
    112         I MSG("DIRECTION")'="OUT" S ERROR="MESSAGE IS NOT OUTGOING" Q 0
    113         I MSG("STATUS","LINK NAME")="" S ERROR="LINK NOT DEFINED" Q 0
    114         F SUB="ID","IEN","DT/TM","ACK BY","STATUS" S MSG(SUB)=""
    115         F SUB="PURGE" K MSG("STATUS",SUB)
    116         D GETSYS^HLOAPI(.MSG)
    117         I $$SAVEMSG^HLOF778(.MSG) D OUTQUE^HLOQUE(MSG("STATUS","LINK NAME"),$G(MSG("STATUS","PORT")),MSG("STATUS","QUEUE"),MSG("IEN")) Q +MSG("IEN")
    118         Q 0
    119         ;
    120 SETPURGE(MSGIEN,TIME)   ;
    121         ;Resets the purge date/time.
    122         ;Input:
    123         ;   MSGIEN (required) ien of the message, file #778
    124         ;   TIME (optional) dt/time to set the purge time to, defaults to NOW
    125         ;Output:
    126         ;   Function returns 1 on success, 0 on failure
    127         N NODE,OLDTIME,HLDIR
    128         Q:'$G(MSGIEN) 0
    129         S NODE=$G(^HLB(MSGIEN,0))
    130         Q:NODE="" 0
    131         S OLDTIME=$P(NODE,"^",9)
    132         S:'$G(TIME) TIME=$$NOW^XLFDT
    133         S HLDIR=$S($E($P(NODE,"^",4))="I":"IN",1:"OUT")
    134         K:OLDTIME ^HLB("AD",HLDIR,OLDTIME,MSGIEN)
    135         S $P(^HLB(MSGIEN,0),"^",9)=TIME
    136         S ^HLB("AD",HLDIR,TIME,MSGIEN)=""
    137         Q 1
    138         ;
    139 REPROC(MSGIEN,ERROR)    ;
    140         ;This message will re-process an incoming message by placing it on an incoming queue. If successful the message will be purged.
    141         ;
    142         ;Input:
    143         ;  MSGIEN - the ien (file #778) of the message that is to be processed
    144         ;Output:
    145         ;  Function returns 1 on success, 0 on failure
    146         ;  ERROR (pass by reference, optional) an error message
    147         ;
    148         N MSG,HDR,ACTION,QUEUE,FROM
    149         ;
    150         I '$$STARTMSG^HLOPRS(.MSG,MSGIEN) S ERROR="MESSAGE NOT FOUND" Q 0
    151         I MSG("DIRECTION")'="IN" S ERROR="MESSAGE IS NOT INCOMING" Q 0
    152         M HDR=MSG("HDR")
    153         I $G(MSG("ACK TO"))]"" S ACTION=MSG("STATUS","APP ACK RESPONSE")
    154         I ACTION="",'$$ACTION^HLOAPP(.HDR,.ACTION,.QUEUE),$G(MSG("ACK TO"))="" S ERROR="RECEIVING APPLICATION NOT DEFINED"
    155         ;If this message references an earlier message, get the action specified by the original message
    156         I ACTION="",$G(MSG("ACK TO"))]"" D
    157         .N NODE,IEN
    158         .S IEN=$O(^HLB("B",$P(MSG("ACK TO"),"-"),0))
    159         .S:IEN NODE=$G(^HLB(IEN,0))
    160         .I ($P(NODE,"^",11)]"") S ACTION=$P(NODE,"^",10,11),QUEUE=$S($P(NODE,"^",6)]"":$P(NODE,"^",6),1:"DEFAULT")
    161         I ACTION="" S ERROR="ORIGINAL MESSAGE NOT FOUND" Q 0
    162         S FROM=$S(MSG("HDR","SENDING FACILITY",2)]"":MSG("HDR","SENDING FACILITY",2),1:MSG("HDR","SENDING FACILITY",1))
    163         D INQUE^HLOQUE(FROM,QUEUE,MSGIEN,ACTION,1)
    164         Q 1
    165         ;
    166 PROCNOW(MSGIEN,PURGE,ERROR)     ;
    167         ;This message will re-process an incoming message immediately.
    168         ;
    169         ;Input:
    170         ;  MSGIEN - the ien (file #778) of the message that is to be processed
    171         ;Output:
    172         ;  Function returns 1 on success, 0 on failure
    173         ;  PURGE (optional) a date/time to purge the message
    174         ;  ERROR (pass by reference, optional) an error message
    175         ;
    176         N MSG,HDR,ACTION,MCODE,HLMSGIEN
    177         ;
    178         S ERROR=""
    179         I '$$STARTMSG^HLOPRS(.MSG,MSGIEN) S ERROR="MESSAGE NOT FOUND" Q 0
    180         I MSG("DIRECTION")'="IN" S ERROR="MESSAGE IS NOT INCOMING" Q 0
    181         M HDR=MSG("HDR")
    182         I $G(MSG("ACK TO"))]"" S ACTION=MSG("STATUS","APP ACK RESPONSE")
    183         I ACTION="",'$$ACTION^HLOAPP(.HDR,.ACTION,.QUEUE),$G(MSG("ACK TO"))="" S ERROR="RECEIVING APPLICATION NOT DEFINED" Q 0
    184         ;If this message references an earlier message, get the action specified by the original message
    185         I $G(ACTION)="",$G(MSG("ACK TO IEN")) S ACTION=$P($G(^HLB(+MSG("ACK TO IEN"),0)),"^",10,11) I $P(ACTION,"^",2)="" S ERROR="ORIGINAL MESSAGE NOT FOUND" Q 0
    186         D:$G(PURGE)
    187         .K:MSG("STATUS","PURGE") ^HLB("AD","IN",MSG("STATUS","PURGE"),MSGIEN)
    188         .S $P(^HLB(MSGIEN,0),"^",9)=PURGE
    189         .S ^HLB("AD","IN",PURGE,MSGIEN)=""
    190         .I $G(MSG("ACK TO IEN")),$D(^HLB(MSG("ACK TO IEN"),0)) K ^HLB("AD","OUT",MSG("STATUS","PURGE"),MSG("ACK TO IEN")) S $P(^HLB(MSG("ACK TO IEN"),0),"^",9)=PURGE,^HLB("AD","OUT",PURGE,MSG("ACK TO IEN"))=""
    191         S HLMSGIEN=MSGIEN
    192         S $P(^HLB(MSGIEN,0),"^",19)=1
    193         S MCODE="D "_ACTION
    194         X MCODE
    195         Q 1
     1HLOAPI3 ;ALB/CJM-HL7 - Developer API's for sending application acks ;03/13/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,133,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5BATCHACK(HLMSTATE,PARMS,ACK,ERROR) ;Starts a batch message that is the response to a batch message. Individual acks are placed in the batch by calling $$ADDACK.
     6 ;$$SENDACK^HLOAPI2 must be called when the batch of acks is complete. The return destination is determined automatically from the original message.
     7 ;
     8 ;Input:
     9 ;  HLMSTATE (pass by reference, required) the array obtained by calling $$STARTMSG^HLOPRS when parsing the original message
     10 ;  PARMS (optional, pass by reference) These subscripts may be defined:
     11 ;    "ACCEPT ACK RESPONSE")=<tag^routine> to call when the commit ack is received (optional)
     12 ;    "ACCEPT ACK TYPE") = <AL,NE> (optional, defaults to AL)
     13 ;    "COUNTRY") - a 3 character country code from the HL7 standard table (optional)
     14 ;     "ENCODING CHARACTERS" - the 4 HL7 encoding characters (optional,defaults to "^~\&"
     15 ;    "FAILURE RESPONSE" (optional) the <tag>^<routine> that the sending application routine should execute if the transmission of the message fails, i.e., the message can not be sent or a requested commit ack is not received.
     16 ;     "FIELD SEPARATOR" - the field separator (optional, defaults to "|")
     17 ;     "QUEUE" (optional) An application can name a private queue (a string under 20 characters, namespaced). The default is the name of the queue of the original message
     18 ;     "SECURITY" - security information to include in the header segment, SEQ 8 (optional)
     19 ;    "VERSION" - the HL7 Version ID (optional, defaults to 2.4)
     20 ;Output:
     21 ;  Function returns 1 on success, 0 on failure
     22 ;  PARMS - left undefined upon completion
     23 ;  ACK (pass by reference, required) the batch acknowledgment message being built.
     24 ;  ERROR (pass by reference) error message
     25 N I,TOLINK,SUCCESS
     26 S SUCCESS=0
     27 ;
     28 D
     29 .N PORT
     30 .I '$G(HLMSTATE("IEN")) S ERROR="ORIGINAL MESSAGE TO ACKNOWLEDGMENT IS NOT IDENTIFIED" Q
     31 .;if the return link can not be determined, the HL Logical Link file has a problem
     32 .S TOLINK=$$ACKLINK^HLOAPI2(.HLMSTATE)
     33 .I TOLINK="" S ERROR="TRANSMISSION LINK FOR APPLICATION ACK CANNOT BE DETERMINED" Q
     34 .S PORT=$P(HLMSTATE("HDR","SENDING FACILITY",2),":",2)
     35 .I 'PORT S PORT=$$PORT2^HLOTLNK(TOLINK)
     36 .;
     37 .I $$NEWBATCH^HLOAPI(.PARMS,.ACK)  ;can't fail!
     38 .S ACK("STATUS","QUEUE")=$G(PARMS("QUEUE"),$G(HLMSTATE("STATUS","QUEUE")))
     39 .S ACK("STATUS","PORT")=PORT
     40 .S ACK("HDR","SECURITY")=$G(PARMS("SECURITY"))
     41 .S ACK("HDR","SENDING APPLICATION")=$G(HLMSTATE("HDR","RECEIVING APPLICATION"))
     42 .S ACK("HDR","RECEIVING APPLICATION")=$G(HLMSTATE("HDR","SENDING APPLICATION"))
     43 .F I=1:1:3 S ACK("HDR","RECEIVING FACILITY",I)=$G(HLMSTATE("HDR","SENDING FACILITY",I))
     44 .S ACK("HDR","APP ACK TYPE")="NE"
     45 .S ACK("HDR","ACCEPT ACK TYPE")=$G(PARMS("ACCEPT ACK TYPE"),"AL")
     46 .S ACK("ACK TO")=$G(HLMSTATE("HDR","BATCH CONTROL ID"))
     47 .S ACK("ACK TO","IEN")=HLMSTATE("IEN")
     48 .S ACK("ACK TO","BODY")=$G(HLMSTATE("BODY"))
     49 .S ACK("STATUS","LINK NAME")=TOLINK
     50 .S ACK("LINE COUNT")=0
     51 .S SUCCESS=1
     52 K PARMS
     53 Q SUCCESS
     54 ;
     55ADDACK(ACK,PARMS,ERROR) ;This API adds an application acknowledgment to a batch
     56 ;of acknowledgments that was started by calling $$BATCHACK.
     57 ;The Default behavior is to return a general application ack.
     58 ;The application may optionally specify the message
     59 ;type and event and/or call $$ADDSEG^HLOAPI to add segments.
     60 ;A generic MSA segment (components 1-3) will be added automatically
     61 ;if the application doesn't call $$ADDSEG^HLOAPI to add an MSA segment
     62 ;as the FIRST segment following the MSH segment.
     63 ;$$SENDACK^HLOAPI2 must be called when the batch is complete.
     64 ;
     65 ;Input:
     66 ;  ACK (pass by reference,required) the batch of acks that is being built
     67 ;  PARMS (pass by reference) These subscripts may be defined:
     68 ;    "ACK CODE" (required) MSA1[ {AA,AE,AR}
     69 ;    "ERROR MESSAGE" (optional) MSA3, should be used only if AE or AR
     70 ;    "EVENT" - 3 character event type (optional, defaults to the event code of the original message)
     71 ;    "MESSAGE CONTROL ID" (required) this is the message control id of the original individual message within the batch which is being acknowledged
     72 ;    "MESSAGE STRUCTURE" (optional)
     73 ;    "MESSAGE TYPE" (optional, defaults to ACK)
     74 ;    "SECURITY" (optional) security information to include in the header segment SEQ 8
     75 ;Output:
     76 ;  Function returns 1 on success, 0 on failure
     77 ;  ACK (pass by reference, required) The batch, updated with another ack
     78 ;  PARMS  - left undefined when this function returns
     79 ;  ERROR (pass by reference) error msg
     80 ;
     81 N SUB,SUCCESS
     82 S SUCCESS=0
     83 D
     84 .I $G(PARMS("ACK CODE"))'="AA",$G(PARMS("ACK CODE"))'="AE",$G(PARMS("ACK CODE"))'="AR" S ERROR="INVALID ACK CODE" Q
     85 .;
     86 .I $G(PARMS("MESSAGE CONTROL ID"))="" S ERROR="MESSAGE CONTROL ID MUST EXIST TO RETURN AN APPLICATION ACK" Q
     87 .S SUB=""
     88 .F  S SUB=$O(^HLB("AE",PARMS("MESSAGE CONTROL ID"),SUB)) Q:SUB=""  I $P(SUB,"^")=ACK("ACK TO","IEN"),$P(SUB,"^",2) S PARMS("ACK TO","IEN")=SUB Q
     89 .S PARMS("MESSAGE TYPE")=$G(PARMS("MESSAGE TYPE"),"ACK")
     90 .S:PARMS("MESSAGE TYPE")="ACK" PARMS("MESSAGE STRUCTURE")="ACK"
     91 .S PARMS("EVENT")=$G(PARMS("EVENT"))
     92 .I PARMS("EVENT")="",ACK("ACK TO","BODY"),$P(SUB,"^",2) S PARMS("EVENT")=$P($G(^HLA(ACK("ACK TO","BODY"),2,$P(SUB,"^",2),0)),"^",3)
     93 .S PARMS("ACK TO")=PARMS("MESSAGE CONTROL ID")
     94 .S PARMS("ACK TO","STATUS")=$S(PARMS("ACK CODE")="AA":"SU",1:"AE")
     95 .Q:'$$ADDMSG^HLOAPI(.ACK,.PARMS,.ERROR)
     96 .S ACK("MSA")="MSA|"_PARMS("ACK CODE")_"|"_PARMS("MESSAGE CONTROL ID")_"|"_$G(PARMS("ERROR MESSAGE"))
     97 .S SUCCESS=1
     98 K PARMS
     99 Q SUCCESS
     100 ;
     101RESEND(MSGIEN,ERROR) ;
     102 ;This message will re-transmit an out-going message. It copies a copy the message, reusing all the original parameters. Then the message is requeued.
     103 ;
     104 ;Input:
     105 ;  MSGIEN - the ien (file #778) of the message that is to be sent
     106 ;Output:
     107 ;  Function returns the ien of the message in file 778 on success, 0 on failure
     108 ;  ERROR (pass by reference, optional)an error message
     109 ;
     110 N MSG,SUB,HDR
     111 I '$$STARTMSG^HLOPRS(.MSG,MSGIEN) S ERROR="MESSAGE NOT FOUND" Q 0
     112 I MSG("DIRECTION")'="OUT" S ERROR="MESSAGE IS NOT OUTGOING" Q 0
     113 I MSG("STATUS","LINK NAME")="" S ERROR="LINK NOT DEFINED" Q 0
     114 F SUB="ID","IEN","DT/TM","ACK BY","STATUS" S MSG(SUB)=""
     115 F SUB="PURGE" K MSG("STATUS",SUB)
     116 D GETSYS^HLOAPI(.MSG)
     117 I $$SAVEMSG^HLOF778(.MSG) D OUTQUE^HLOQUE(MSG("STATUS","LINK NAME"),$G(MSG("STATUS","PORT")),MSG("STATUS","QUEUE"),MSG("IEN")) Q +MSG("IEN")
     118 Q 0
     119 ;
     120SETPURGE(MSGIEN,TIME) ;
     121 ;Resets the purge date/time.
     122 ;Input:
     123 ;   MSGIEN (required) ien of the message, file #778
     124 ;   TIME (optional) dt/time to set the purge time to, defaults to NOW
     125 ;Output:
     126 ;   Function returns 1 on success, 0 on failure
     127 N NODE,OLDTIME,HLDIR
     128 Q:'$G(MSGIEN) 0
     129 S NODE=$G(^HLB(MSGIEN,0))
     130 Q:NODE="" 0
     131 S OLDTIME=$P(NODE,"^",9)
     132 S:'$G(TIME) TIME=$$NOW^XLFDT
     133 S HLDIR=$S($E($P(NODE,"^",4))="I":"IN",1:"OUT")
     134 K:OLDTIME ^HLB("AD",HLDIR,OLDTIME,MSGIEN)
     135 S $P(^HLB(MSGIEN,0),"^",9)=TIME
     136 S ^HLB("AD",HLDIR,TIME,MSGIEN)=""
     137 Q 1
     138 ;
     139REPROC(MSGIEN,ERROR) ;
     140 ;This message will re-process an incoming message by placing it on an incoming queue. If successful the message will be purged.
     141 ;
     142 ;Input:
     143 ;  MSGIEN - the ien (file #778) of the message that is to be processed
     144 ;Output:
     145 ;  Function returns 1 on success, 0 on failure
     146 ;  ERROR (pass by reference, optional) an error message
     147 ;
     148 N MSG,HDR,ACTION,QUEUE,FROM
     149 ;
     150 I '$$STARTMSG^HLOPRS(.MSG,MSGIEN) S ERROR="MESSAGE NOT FOUND" Q 0
     151 I MSG("DIRECTION")'="IN" S ERROR="MESSAGE IS NOT INCOMING" Q 0
     152 M HDR=MSG("HDR")
     153 I $G(MSG("ACK TO"))]"" S ACTION=MSG("STATUS","APP ACK RESPONSE")
     154 I ACTION="",'$$ACTION^HLOAPP(.HDR,.ACTION,.QUEUE),$G(MSG("ACK TO"))="" S ERROR="RECEIVING APPLICATION NOT DEFINED"
     155 ;If this message references an earlier message, get the action specified by the original message
     156 I ACTION="",$G(MSG("ACK TO"))]"" D
     157 .N NODE,IEN
     158 .S IEN=$O(^HLB("B",$P(MSG("ACK TO"),"-"),0))
     159 .S:IEN NODE=$G(^HLB(IEN,0))
     160 .I ($P(NODE,"^",11)]"") S ACTION=$P(NODE,"^",10,11),QUEUE=$S($P(NODE,"^",6)]"":$P(NODE,"^",6),1:"DEFAULT")
     161 I ACTION="" S ERROR="ORIGINAL MESSAGE NOT FOUND" Q 0
     162 S FROM=$S(MSG("HDR","SENDING FACILITY",2)]"":MSG("HDR","SENDING FACILITY",2),1:MSG("HDR","SENDING FACILITY",1))
     163 D INQUE^HLOQUE(FROM,QUEUE,MSGIEN,ACTION,1)
     164 Q 1
     165 ;
     166PROCNOW(MSGIEN,PURGE,ERROR) ;
     167 ;This message will re-process an incoming message immediately.
     168 ;
     169 ;Input:
     170 ;  MSGIEN - the ien (file #778) of the message that is to be processed
     171 ;Output:
     172 ;  Function returns 1 on success, 0 on failure
     173 ;  PURGE (optional) a date/time to purge the message
     174 ;  ERROR (pass by reference, optional) an error message
     175 ;
     176 N MSG,HDR,ACTION,MCODE,HLMSGIEN
     177 ;
     178 S ERROR=""
     179 I '$$STARTMSG^HLOPRS(.MSG,MSGIEN) S ERROR="MESSAGE NOT FOUND" Q 0
     180 I MSG("DIRECTION")'="IN" S ERROR="MESSAGE IS NOT INCOMING" Q 0
     181 M HDR=MSG("HDR")
     182 I $G(MSG("ACK TO"))]"" S ACTION=MSG("STATUS","APP ACK RESPONSE")
     183 I ACTION="",'$$ACTION^HLOAPP(.HDR,.ACTION,.QUEUE),$G(MSG("ACK TO"))="" S ERROR="RECEIVING APPLICATION NOT DEFINED" Q 0
     184 ;If this message references an earlier message, get the action specified by the original message
     185 I $G(ACTION)="",$G(MSG("ACK TO IEN")) S ACTION=$P($G(^HLB(+MSG("ACK TO IEN"),0)),"^",10,11) I $P(ACTION,"^",2)="" S ERROR="ORIGINAL MESSAGE NOT FOUND" Q 0
     186 D:$G(PURGE)
     187 .K:MSG("STATUS","PURGE") ^HLB("AD","IN",MSG("STATUS","PURGE"),MSGIEN)
     188 .S $P(^HLB(MSGIEN,0),"^",9)=PURGE
     189 .S ^HLB("AD","IN",PURGE,MSGIEN)=""
     190 .I $G(MSG("ACK TO IEN")),$D(^HLB(MSG("ACK TO IEN"),0)) K ^HLB("AD","OUT",MSG("STATUS","PURGE"),MSG("ACK TO IEN")) S $P(^HLB(MSG("ACK TO IEN"),0),"^",9)=PURGE,^HLB("AD","OUT",PURGE,MSG("ACK TO IEN"))=""
     191 S HLMSGIEN=MSGIEN
     192 S $P(^HLB(MSGIEN,0),"^",19)=1
     193 S MCODE="D "_ACTION
     194 X MCODE
     195 Q 1
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOAPP.m

    r613 r623  
    1 HLOAPP  ;ALB/CJM-HL7 -Application Registry ;07/09/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,132,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 GETIEN(NAME)    ;given the application name, it finds the ien.  Returns 0 on failure
    6         Q:'$L($G(NAME)) 0
    7         Q +$O(^HLD(779.2,"C",$E(NAME,1,60),0))
    8         ;
    9 ACTION(HEADER,ACTION,QUEUE)     ;Given the parsed header of a message it returns both the action that should be performed in response to the message and the incoming queue that it should be placed on.
    10         ;
    11         ;Input:
    12         ;  HEADER() subscripts are used: "RECEIVING APPLICATION","SEGMENT TYPE", "MESSAGE TYPE", "EVENT", "VERSION"
    13         ;Output:
    14         ;  Function returns 1 on success, 0 on failure
    15         ;  ACTION (pass by reference) <tag>^<rtn>
    16         ;  QUEUE (pass by reference) returns the named queue if there is one, else "DEFAULT"
    17         ;
    18         N IEN
    19         S (ACTION,QUEUE)=""
    20         S IEN=$$GETIEN(HEADER("RECEIVING APPLICATION"))
    21         Q:'$G(IEN) 0
    22         I $G(HEADER("SEGMENT TYPE"))="BHS" D
    23         .S NODE=$G(^HLD(779.2,IEN,0))
    24         .I $P(NODE,"^",5)]"" D
    25         ..S ACTION=$P(NODE,"^",4,5)
    26         .E  I $P(NODE,"^",7)]"" S ACTION=$P(NODE,"^",6,7)
    27         .I $P(NODE,"^",8)]"" D
    28         ..S QUEUE=$P(NODE,"^",8)
    29         .E  I $P(NODE,"^",3)]"" S QUEUE=$P(NODE,"^",3)
    30         E  I HEADER("SEGMENT TYPE")="MSH" D
    31         .I HEADER("MESSAGE TYPE")'="",HEADER("EVENT")'="" D
    32         ..N SUBIEN,NODE
    33         ..;did the application specify an action for the particular version of this message?
    34         ..I HEADER("VERSION")'="" S SUBIEN=$O(^HLD(779.2,IEN,1,"D",HEADER("MESSAGE TYPE"),HEADER("EVENT"),HEADER("VERSION"),0))
    35         ..;if not, look on the "C" index
    36         ..S:'$G(SUBIEN) SUBIEN=$O(^HLD(779.2,IEN,1,"C",HEADER("MESSAGE TYPE"),HEADER("EVENT"),0))
    37         ..;
    38         ..I SUBIEN D
    39         ...S NODE=$G(^HLD(779.2,IEN,1,SUBIEN,0))
    40         ...I $P(NODE,"^",5)]"" S ACTION=$P(NODE,"^",4,5)
    41         ...I $P(NODE,"^",3)]"" S QUEUE=$P(NODE,"^",3)
    42         ..I ACTION="" S NODE=$G(^HLD(779.2,IEN,0)) I $P(NODE,"^",7)]"" S ACTION=$P(NODE,"^",6,7)
    43         ..I QUEUE="" S NODE=$G(^HLD(779.2,IEN,0)) I $P(NODE,"^",3)]"" S QUEUE=$P(NODE,"^",3)
    44         I QUEUE="" S QUEUE="DEFAULT"
    45         I ACTION="" Q 0
    46         Q 1
    47         ;
    48 RTRNLNK(APPNAME)        ;
    49         ;given the name of a receiving application, this returns the return
    50         ;link for application acks if one is provided.  Otherwise, return
    51         ;acks are routed based on the information provide in the message hdr
    52         ;
    53         Q:(APPNAME="") ""
    54         N IEN
    55         S IEN=$$GETIEN(APPNAME)
    56         Q:IEN $P($G(^HLD(779.2,IEN,0)),"^",2)
    57         Q ""
    58         ;
    59 RTRNPORT(APPNAME)       ;
    60         ;Given the name of the sending application, IF the application has its
    61         ;own listener, its port # is returned.  Application acks should be
    62         ;returned using that port
    63         Q:(APPNAME="") ""
    64         N IEN,LINK
    65         S IEN=$$GETIEN(APPNAME)
    66         Q:'IEN ""
    67         S LINK=$P($G(^HLD(779.2,IEN,0)),"^",9)
    68         Q:'LINK ""
    69         Q $$PORT^HLOTLNK(LINK)
    70         ;
    71 ACTIVE(APP,MSGTYPE,EVENT,VERSION)       ;
    72         ;Returns 1 if the message's INACTIVE flag has NOT been set.
    73         ;
    74         ;Input:
    75         ;  APP (required) the name of the sending application
    76         ;  MSGTYPE (required) 3 character HL7 message type
    77         ;  EVENT (required) 3 character HL7 event
    78         ;  VERSION (optional) HL7 version ID as it appears in the message header
    79         ;Output:
    80         ;  Function returns 1 if the message type specified by the input parameters has not been set to INACTIVE.  It returns 0 otherwise.
    81         ;
    82         N IEN,ACTIVE,SUBIEN
    83         S ACTIVE=1
    84         S IEN=$$GETIEN($G(APP))
    85         Q:'$G(IEN) ACTIVE
    86         Q:$G(MSGTYPE)="" ACTIVE
    87         Q:$G(EVENT)="" ACTIVE
    88         ;did the application specify an action for the particular version of this message?
    89         I $G(VERSION)'="" S SUBIEN=$O(^HLD(779.2,IEN,1,"D",MSGTYPE,EVENT,VERSION,0))
    90         ;if not, look on the "C" index
    91         S:'$G(SUBIEN) SUBIEN=$O(^HLD(779.2,IEN,1,"C",MSGTYPE,EVENT,0))
    92         ;
    93         S:SUBIEN ACTIVE='(+$P($G(^HLD(779.2,IEN,1,SUBIEN,0)),"^",7))
    94         Q ACTIVE
    95         ;
    96 EXCEPT(APPNAME) ;
    97         ;returns the exception handler (tag^routine) that should be invoked
    98         ;when an applicaiton's messages are being sequenced and an app ack
    99         ;is not timely received
    100         ;
    101         N IEN,RTN
    102         S IEN=$$GETIEN($G(APPNAME))
    103         I IEN S RTN=$P($G(^HLD(779.2,IEN,0)),"^",10,11)
    104         I $L($G(RTN))>1 Q RTN
    105         Q "DEFAULT^HLOAPP"
    106         ;
    107 DEFAULT ;default exception handler if the app doesn't specify one
    108         S ^TMP("HLO SEQUENCING EXCEPTION",$J,$$NOW^XLFDT,+$G(HLMSGIEN))=""
    109         Q
    110         ;
    111 TIMEOUT(APPNAME)        ;
    112         N IEN,TIME
    113         S IEN=$$GETIEN($G(APPNAME))
    114         I IEN S TIME=$P($G(^HLD(779.2,IEN,0)),"^",12)
    115         Q:'$G(TIME) 10
    116         Q TIME
     1HLOAPP ;ALB/CJM-HL7 -Application Registry ;10/31/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,132**;Oct 13, 1995;Build 6
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5GETIEN(NAME) ;given the application name, it finds the ien.  Returns 0 on failure
     6 Q:'$L($G(NAME)) 0
     7 N IEN,SUB
     8 S SUB=$E(NAME,1,60)
     9 S IEN=0
     10 F  S IEN=$O(^HLD(779.2,"B",SUB,IEN)) Q:'IEN  Q:$P($G(^HLD(779.2,IEN,0)),"^")=NAME
     11 Q +IEN
     12 ;
     13ACTION(HEADER,ACTION,QUEUE) ;Given the parsed header of a message it returns both the action that should be performed in response to the message and the incoming queue that it should be placed on.
     14 ;
     15 ;Input:
     16 ;  HEADER() subscripts are used: "RECEIVING APPLICATION","SEGMENT TYPE", "MESSAGE TYPE", "EVENT", "VERSION"
     17 ;Output:
     18 ;  Function returns 1 on success, 0 on failure
     19 ;  ACTION (pass by reference) <tag>^<rtn>
     20 ;  QUEUE (pass by reference) returns the named queue if there is one, else "DEFAULT"
     21 ;
     22 N IEN
     23 S (ACTION,QUEUE)=""
     24 S IEN=$$GETIEN(HEADER("RECEIVING APPLICATION"))
     25 Q:'$G(IEN) 0
     26 I $G(HEADER("SEGMENT TYPE"))="BHS" D
     27 .S NODE=$G(^HLD(779.2,IEN,0))
     28 .I $P(NODE,"^",5)]"" D
     29 ..S ACTION=$P(NODE,"^",4,5)
     30 .E  I $P(NODE,"^",7)]"" S ACTION=$P(NODE,"^",6,7)
     31 .I $P(NODE,"^",8)]"" D
     32 ..S QUEUE=$P(NODE,"^",8)
     33 .E  I $P(NODE,"^",3)]"" S QUEUE=$P(NODE,"^",3)
     34 E  I HEADER("SEGMENT TYPE")="MSH" D
     35 .I HEADER("MESSAGE TYPE")'="",HEADER("EVENT")'="" D
     36 ..N SUBIEN,NODE
     37 ..;did the application specify an action for the particular version of this message?
     38 ..I HEADER("VERSION")'="" S SUBIEN=$O(^HLD(779.2,IEN,1,"D",HEADER("MESSAGE TYPE"),HEADER("EVENT"),HEADER("VERSION"),0))
     39 ..;if not, look on the "C" index
     40 ..S:'$G(SUBIEN) SUBIEN=$O(^HLD(779.2,IEN,1,"C",HEADER("MESSAGE TYPE"),HEADER("EVENT"),0))
     41 ..;
     42 ..I SUBIEN D
     43 ...S NODE=$G(^HLD(779.2,IEN,1,SUBIEN,0))
     44 ...I $P(NODE,"^",5)]"" S ACTION=$P(NODE,"^",4,5)
     45 ...I $P(NODE,"^",3)]"" S QUEUE=$P(NODE,"^",3)
     46 ..I ACTION="" S NODE=$G(^HLD(779.2,IEN,0)) I $P(NODE,"^",7)]"" S ACTION=$P(NODE,"^",6,7)
     47 ..I QUEUE="" S NODE=$G(^HLD(779.2,IEN,0)) I $P(NODE,"^",3)]"" S QUEUE=$P(NODE,"^",3)
     48 I QUEUE="" S QUEUE="DEFAULT"
     49 I ACTION="" Q 0
     50 Q 1
     51 ;
     52RTRNLNK(APPNAME) ;
     53 ;given the name of a receiving application, this returns the return
     54 ;link for application acks if one is provided.  Otherwise, return
     55 ;acks are routed based on the information provide in the message hdr
     56 ;
     57 Q:(APPNAME="") ""
     58 N IEN
     59 S IEN=$$GETIEN(APPNAME)
     60 Q:IEN $P($G(^HLD(779.2,IEN,0)),"^",2)
     61 Q ""
     62 ;
     63RTRNPORT(APPNAME) ;
     64 ;Given the name of the sending application, IF the application has its
     65 ;own listener, its port # is returned.  Application acks should be
     66 ;returned using that port
     67 Q:(APPNAME="") ""
     68 N IEN,LINK
     69 S IEN=$$GETIEN(APPNAME)
     70 Q:'IEN ""
     71 S LINK=$P($G(^HLD(779.2,IEN,0)),"^",9)
     72 Q:'LINK ""
     73 Q $$PORT^HLOTLNK(LINK)
     74 ;
     75ACTIVE(APP,MSGTYPE,EVENT,VERSION) ;
     76 ;Returns 1 if the message's INACTIVE flag has NOT been set.
     77 ;
     78 ;Input:
     79 ;  APP (required) the name of the sending application
     80 ;  MSGTYPE (required) 3 character HL7 message type
     81 ;  EVENT (required) 3 character HL7 event
     82 ;  VERSION (optional) HL7 version ID as it appears in the message header
     83 ;Output:
     84 ;  Function returns 1 if the message type specified by the input parameters has not been set to INACTIVE.  It returns 0 otherwise.
     85 ;
     86 N IEN,ACTIVE,SUBIEN
     87 S ACTIVE=1
     88 S IEN=$$GETIEN($G(APP))
     89 Q:'$G(IEN) ACTIVE
     90 Q:$G(MSGTYPE)="" ACTIVE
     91 Q:$G(EVENT)="" ACTIVE
     92 ;did the application specify an action for the particular version of this message?
     93 I $G(VERSION)'="" S SUBIEN=$O(^HLD(779.2,IEN,1,"D",MSGTYPE,EVENT,VERSION,0))
     94 ;if not, look on the "C" index
     95 S:'$G(SUBIEN) SUBIEN=$O(^HLD(779.2,IEN,1,"C",MSGTYPE,EVENT,0))
     96 ;
     97 S:SUBIEN ACTIVE='(+$P($G(^HLD(779.2,IEN,1,SUBIEN,0)),"^",7))
     98 Q ACTIVE
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOCLNT.m

    r613 r623  
    1 HLOCLNT ;ALB/CJM- Client for sending messages - 10/4/94 1pm ;08/15/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,130,131,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;GET WORK function for the process running under the Process Manager
    6 GETWORK(QUE)    ;
    7         ;Input:
    8         ;  QUE - (pass by reference) These subscripts are used:
    9         ;    ("LINK")  - <link name>_":"_<port> last obtained
    10         ;    ("QUEUE") - name of the queue last obtained
    11         ;Output:
    12         ;  Function returns 1 if success, 0 if no more work
    13         ;  QUE -  updated to identify next queue of messages to process.
    14         ;    ("LINK") - <link name>_":"_<port>
    15         ;    ("QUEUE") - the named queue on the link
    16         ;    ("DOWN") - =1 means that the last OPEN attempt failed
    17         ;
    18         N LINK,QUEUE
    19         S LINK=$G(QUE("LINK")),QUEUE=$G(QUE("QUEUE"))
    20         I (LINK]""),(QUEUE]"") D
    21         .L -^HLB("QUEUE","OUT",LINK,QUEUE)
    22         .I '$$CNNCTD(LINK),$$FAILING(.LINK) S QUEUE="" Q
    23         .F  S QUEUE=$O(^HLB("QUEUE","OUT",LINK,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("OUT",QUEUE) L +^HLB("QUEUE","OUT",LINK,QUEUE):0  Q:$T
    24         I (LINK]""),(QUEUE="") D
    25         .F  S LINK=$O(^HLB("QUEUE","OUT",LINK)) Q:LINK=""  D  Q:$L(QUEUE)
    26         ..I '$$CNNCTD(LINK),$$FAILING(.LINK) Q
    27         ..S QUEUE="" F  S QUEUE=$O(^HLB("QUEUE","OUT",LINK,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("OUT",QUEUE) L +^HLB("QUEUE","OUT",LINK,QUEUE):0 Q:$T
    28         I LINK="" D
    29         .F  S LINK=$O(^HLB("QUEUE","OUT",LINK)) Q:LINK=""  D  Q:$L(QUEUE)
    30         ..I '$$CNNCTD(LINK),$$FAILING(.LINK) Q
    31         ..S QUEUE="" F  S QUEUE=$O(^HLB("QUEUE","OUT",LINK,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("OUT",QUEUE) L +^HLB("QUEUE","OUT",LINK,QUEUE):0 Q:$T
    32         S QUE("LINK")=LINK,QUE("QUEUE")=QUEUE,QUE("DOWN")=$G(LINK("DOWN"))
    33         Q:$L(QUEUE) 1
    34         D:$G(HLCSTATE("CONNECTED")) CLOSE^HLOT(.HLCSTATE)
    35         Q 0
    36         ;
    37 FAILING(LINK)   ;
    38         ;Returns 1 if the link has failed in the last 30 seconds, 0 otherwise
    39         ;Also returns LINK("DOWN")=1 if the link was failing > 30 seconds ago, not yet known if its up
    40         ;
    41         N LASTTIME,SET
    42         S LINK("DOWN")=0
    43         S LASTTIME=$G(^HLB("QUEUE","OUT",LINK))
    44         S SET=$S(LASTTIME]"":1,1:0)
    45         I SET D
    46         .I $$HDIFF^XLFDT($H,LASTTIME,2)>30 S ^HLB("QUEUE","OUT",LINK)="",SET=0,LINK("DOWN")=1
    47         I $D(^HLTMP("FAILING LINKS",LINK)) S LINK("DOWN")=1
    48         Q SET
    49         ;
    50 LINKDOWN(HLCSTATE)      ;
    51         D:$G(HLCSTATE("CONNECTED")) CLOSE^HLOT(.HLCSTATE)
    52         I $D(HLCSTATE("LINK","NAME")),$D(HLCSTATE("LINK","PORT")) D
    53         .S TO=HLCSTATE("LINK","NAME")_":"_HLCSTATE("LINK","PORT")
    54         .S ^HLB("QUEUE","OUT",TO)=$H
    55         .S:'$D(^HLTMP("FAILING LINKS",TO)) ^HLTMP("FAILING LINKS",TO)=$H
    56         Q
    57         ;
    58 ERROR   ;error trap
    59         S $ETRAP="Q:$QUIT """" Q"
    60         N HOUR
    61         S HOUR=$E($$NOW^XLFDT,1,10)
    62         S ^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2))=$G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))+1
    63         D END
    64         D LINKDOWN(.HLCSTATE)
    65         ;
    66         I ($ECODE["TOOMANYFILES")!($ECODE["EDITED") Q:$QUIT "" Q
    67         ;while debugging quit on all errors - this will return the process to the Process Manager error trap
    68         I $G(^HLTMP("LOG ALL ERRORS")) Q:$QUIT "" Q
    69         ;
    70         ;don't log some common errors
    71         I ($ECODE["READ")!($ECODE["NOTOPEN")!($ECODE["DEVNOTOPN")!($ECODE["WRITE")!($ECODE["OPENERR") D
    72         .;
    73         E  D
    74         .;but do log all the others
    75         .D ^%ZTER
    76         ;
    77         ;a lot of errors of the same type may indicate an endless loop
    78         ;return to the Process Manager error trap
    79         I ($G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))>30) Q:$QUIT "" Q
    80         ;
    81         ;resume execution of the process manager executing the client
    82         D UNWIND^%ZTER
    83         Q
    84         ;
    85 DOWORK(QUEUE)   ;sends the messages on the queue
    86         N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOCLNT"
    87         N MSGIEN,DEQUE,SUCCESS,MSGCOUNT
    88         S DEQUE=0
    89         S SUCCESS=1
    90         ;
    91         I '$$CNNCTD(QUEUE("LINK")),'$$CONNECT^HLOCLNT1($P(QUEUE("LINK"),":"),$P(QUEUE("LINK"),":",2),30,.HLCSTATE) Q
    92         ;
    93         S (MSGCOUNT,MSGIEN)=0
    94         F  S MSGIEN=$O(^HLB("QUEUE","OUT",QUEUE("LINK"),QUEUE("QUEUE"),MSGIEN)) Q:'MSGIEN  D  Q:'SUCCESS  Q:MSGCOUNT>1000
    95         .N UPDATE
    96         .S ^HLB(MSGIEN,"TRIES")=$G(^HLB(MSGIEN,"TRIES"))+1
    97         .S SUCCESS=0
    98         .S:$$TRANSMIT(.HLCSTATE,MSGIEN,.UPDATE) SUCCESS=1
    99         .Q:('SUCCESS)!('$D(UPDATE))
    100         .D DEQUE(.UPDATE)
    101         .S MSGCOUNT=MSGCOUNT+1
    102         .D:HLCSTATE("COUNTS")>4 SAVECNTS^HLOSTAT(.HLCSTATE)
    103         .;
    104         .;if the queue was on the down list, and not since shutdown, mark it as up, since a message has been successfully transmitted across it
    105         .I $G(QUEUE("DOWN"))!$$FAILING(QUEUE("LINK")),'$$IFSHUT^HLOTLNK(QUEUE("LINK")) S QUEUE("DOWN")=0,^HLB("QUEUE","OUT",QUEUE("LINK"))="" K ^HLTMP("FAILING LINKS",QUEUE("LINK"))
    106         ;
    107 END     D DEQUE()
    108         D SAVECNTS^HLOSTAT(.HLCSTATE)
    109         Q
    110 CNNCTD(LINK)    ;
    111         ;Connected to LINK?  HLCSTATE must be defined, LINK=<link name>:<port>
    112         ;
    113         I ($G(HLCSTATE("LINK","NAME"))=$P(LINK,":")),($G(HLCSTATE("LINK","PORT"))=$P(LINK,":",2)),$G(HLCSTATE("CONNECTED")) Q 1
    114         Q 0
    115         ;
    116 DEQUE(UPDATE)   ;
    117         I $D(UPDATE) S DEQUE=DEQUE+1,DEQUE(+UPDATE)=$P(UPDATE,"^",2,99) S:$G(UPDATE("MSA"))]"" DEQUE(+UPDATE,"MSA")=UPDATE("MSA") S:$G(UPDATE("ACTION"))]"" DEQUE(+UPDATE,"ACTION")=UPDATE("ACTION")
    118         I '$D(UPDATE)!(DEQUE>15) D
    119         .N MSGIEN S MSGIEN=0
    120         .F  S MSGIEN=$O(DEQUE(MSGIEN)) Q:'MSGIEN  D
    121         ..N NODE,TIME
    122         ..D DEQUE^HLOQUE(QUEUE("LINK"),QUEUE("QUEUE"),"OUT",MSGIEN)
    123         ..S TIME=$P(DEQUE(MSGIEN),"^")
    124         ..Q:'TIME
    125         ..S NODE=QUEUE("LINK")_"^"_QUEUE("QUEUE")_"^"_$P(DEQUE(MSGIEN),"^",2,99)
    126         ..S ^HLTMP("CLIENT UPDATES",$J,TIME,MSGIEN)=NODE
    127         ..S:$G(DEQUE(MSGIEN,"MSA"))]"" ^HLTMP("CLIENT UPDATES",$J,TIME,MSGIEN,"MSA")=DEQUE(MSGIEN,"MSA")
    128         ..S:$G(DEQUE(MSGIEN,"ACTION"))]"" ^HLTMP("CLIENT UPDATES",$J,TIME,MSGIEN,"ACTION")=DEQUE(MSGIEN,"ACTION")
    129         .K DEQUE S DEQUE=0
    130         Q
    131         ;
    132 TRANSMIT(HLCSTATE,MSGIEN,UPDATE)        ;
    133         ;Transmits a single message and if a commit ack was requested reads it.  Updates file 778 with the result.  Queues for the infiler the application accept action if one was requested.
    134         ;Input:
    135         ;   HLCSTATE (pass by reference)
    136         ;   MSGIEN - ien, file 778, of message to be transmitted
    137         ;Output:
    138         ;  Function returns 1 on success, 0 on failure
    139         ;  UPDATE - (pass by reference) to contain updates needed for message
    140         ;
    141         N HLMSTATE,MSA,HDR,SUCCESS
    142         ;
    143         S SUCCESS=0
    144         S HLCSTATE("ATTEMPT")=0
    145         ;
    146         ;start saving updates needed after the message is transmitted
    147         S UPDATE=MSGIEN
    148         Q:'$$GETMSG^HLOCLNT2(MSGIEN,.HLMSTATE) 1  ;returns 1 so the message will be removed from the queue
    149         I HLMSTATE("DT/TM"),HLMSTATE("STATUS","ACCEPTED")!(HLMSTATE("HDR","ACCEPT ACK TYPE")="NE") Q 1  ;the message was already transmitted
    150         ;
    151         S UPDATE=UPDATE_"^"_$$NOW^XLFDT
    152 RETRY   D
    153         .S HLCSTATE("ATTEMPT")=HLCSTATE("ATTEMPT")+1
    154         .I 'HLCSTATE("CONNECTED") D OPEN^HLOT(.HLCSTATE) Q:'HLCSTATE("CONNECTED")
    155         .;
    156         .;try to send the message
    157         .;
    158         .;
    159         .Q:'$$WRITEMSG^HLOCLNT1(.HLCSTATE,.HLMSTATE)
    160         .;does the message need an accept ack?
    161         .I HLMSTATE("HDR","ACCEPT ACK TYPE")="AL" D
    162         ..N FS
    163         ..Q:'$$READACK^HLOCLNT1(.HLCSTATE,.HDR,.MSA)
    164         ..;does the MSA refer to the correct control id?
    165         ..S FS=$E(HDR(1),4)
    166         ..Q:$P(MSA,FS,3)'=HLMSTATE("ID")
    167         ..N ACKID,ACKCODE
    168         ..S ACKCODE=$P(MSA,FS,2)
    169         ..S ACKID=$S($E(HDR(1),1,3)="MSH":$P(HDR(2),FS,5),1:$P(HDR(2),FS,6))
    170         ..S $P(UPDATE,"^",5)=1
    171         ..S UPDATE("MSA")=ACKID_"^"_MSA
    172         ..I '(ACKCODE="CA") S $P(UPDATE,"^",3)="ER",$P(UPDATE,"^",4)=2
    173         ..I ACKCODE="CA",HLMSTATE("HDR","APP ACK TYPE")="NE" S $P(UPDATE,"^",3)="SU",$P(UPDATE,"^",4)=$S(HLMSTATE("BATCH"):"2",1:1)
    174         ..I ($P(UPDATE,"^",3)="ER") S $P(UPDATE,"^",6)=$P(HLMSTATE("HDR",1),FS,5) ;errors need the application for xref
    175         ..;
    176         ..;if it's from a sequence queue, timestamp the queue
    177         ..I $L($G(HLMSTATE("STATUS","SEQUENCE QUEUE"))) D
    178         ...L +^HLB("QUEUE","SEQUENCE",HLMSTATE("STATUS","SEQUENCE QUEUE")):200
    179         ...I $P($G(^HLB("QUEUE","SEQUENCE",HLMSTATE("STATUS","SEQUENCE QUEUE"))),"^")'=MSGIEN L -^HLB("QUEUE","SEQUENCE",HLMSTATE("STATUS","SEQUENCE QUEUE")) Q
    180         ...I ACKCODE="CA" S $P(^HLB("QUEUE","SEQUENCE",HLMSTATE("STATUS","SEQUENCE QUEUE")),"^",2)=$$FMADD^XLFDT($P(UPDATE,"^",2),,,$$TIMEOUT^HLOAPP($$GETSAP^HLOCLNT2(MSGIEN))) L -^HLB("QUEUE","SEQUENCE",HLMSTATE("STATUS","SEQUENCE QUEUE")) Q
    181         ...;if the message wasn't accepted, need to notify without waiting
    182         ...S $P(^HLB("QUEUE","SEQUENCE",HLMSTATE("STATUS","SEQUENCE QUEUE")),"^",2)=$P(UPDATE,"^",2)
    183         ...L -^HLB("QUEUE","SEQUENCE",HLMSTATE("STATUS","SEQUENCE QUEUE"))
    184         ..;
    185         ..;does the app need notification of accept ack?
    186         ..S UPDATE("ACTION")=HLMSTATE("ACCEPT ACK RESPONSE")
    187         ..;
    188         ..S SUCCESS=1
    189         .E  D  ;accept ack wasn't requested
    190         ..S SUCCESS=1
    191         ..I HLMSTATE("HDR","APP ACK TYPE")="NE" S $P(UPDATE,"^",3)="SU",$P(UPDATE,"^",4)=$S(HLMSTATE("BATCH"):2,1:1)
    192         ;
    193         I 'SUCCESS,'HLCSTATE("CONNECTED"),(HLCSTATE("ATTEMPT")<2) G RETRY
    194         I SUCCESS D
    195         .D COUNT^HLOSTAT(.HLCSTATE,HLMSTATE("HDR","RECEIVING APPLICATION"),HLMSTATE("HDR","SENDING APPLICATION"),$S(HLMSTATE("BATCH"):"BATCH",1:HLMSTATE("HDR","MESSAGE TYPE")_"~"_HLMSTATE("HDR","EVENT")))
    196         .;if this is an ack to a message need to purge the original message, so store its ien with the purge date
    197         .S:$G(HLMSTATE("ACK TO IEN")) $P(UPDATE,"^",4)=$P(UPDATE,"^",4)_"-"_HLMSTATE("ACK TO IEN")
    198         I ('HLCSTATE("CONNECTED"))!('SUCCESS) D LINKDOWN(.HLCSTATE)
    199         Q SUCCESS
     1HLOCLNT ;ALB/CJM- Client for sending messages - 10/4/94 1pm ;03/22/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,130,131,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ;GET WORK function for the process running under the Process Manager
     6GETWORK(QUE) ;
     7 ;Input:
     8 ;  QUE - (pass by reference) These subscripts are used:
     9 ;    ("LINK")  - <link name>_":"_<port> last obtained
     10 ;    ("QUEUE") - name of the queue last obtained
     11 ;Output:
     12 ;  Function returns 1 if success, 0 if no more work
     13 ;  QUE -  updated to identify next queue of messages to process.
     14 ;    ("LINK") - <link name>_":"_<port>
     15 ;    ("QUEUE") - the named queue on the link
     16 ;    ("DOWN") - =1 means that the last OPEN attempt failed
     17 ;
     18 N LINK,QUEUE
     19 S LINK=$G(QUE("LINK")),QUEUE=$G(QUE("QUEUE"))
     20 I (LINK]""),(QUEUE]"") D
     21 .L -^HLB("QUEUE","OUT",LINK,QUEUE)
     22 .I '$$CNNCTD(LINK),$$FAILING(.LINK) S QUEUE="" Q
     23 .F  S QUEUE=$O(^HLB("QUEUE","OUT",LINK,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("OUT",QUEUE) L +^HLB("QUEUE","OUT",LINK,QUEUE):0  Q:$T
     24 I (LINK]""),(QUEUE="") D
     25 .F  S LINK=$O(^HLB("QUEUE","OUT",LINK)) Q:LINK=""  D  Q:$L(QUEUE)
     26 ..I '$$CNNCTD(LINK),$$FAILING(.LINK) Q
     27 ..S QUEUE="" F  S QUEUE=$O(^HLB("QUEUE","OUT",LINK,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("OUT",QUEUE) L +^HLB("QUEUE","OUT",LINK,QUEUE):0 Q:$T
     28 I LINK="" D
     29 .F  S LINK=$O(^HLB("QUEUE","OUT",LINK)) Q:LINK=""  D  Q:$L(QUEUE)
     30 ..I '$$CNNCTD(LINK),$$FAILING(.LINK) Q
     31 ..S QUEUE="" F  S QUEUE=$O(^HLB("QUEUE","OUT",LINK,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("OUT",QUEUE) L +^HLB("QUEUE","OUT",LINK,QUEUE):0 Q:$T
     32 S QUE("LINK")=LINK,QUE("QUEUE")=QUEUE,QUE("DOWN")=$G(LINK("DOWN"))
     33 Q:$L(QUEUE) 1
     34 D:$G(HLCSTATE("CONNECTED")) CLOSE^HLOT(.HLCSTATE)
     35 Q 0
     36 ;
     37FAILING(LINK) ;
     38 ;Returns 1 if the link has failed in the last 30 seconds, 0 otherwise
     39 ;Also returns LINK("DOWN")=1 if the link was failing > 30 seconds ago, not yet known if its up
     40 ;
     41 N LASTTIME,SET
     42 S LINK("DOWN")=0
     43 S LASTTIME=$G(^HLB("QUEUE","OUT",LINK))
     44 S SET=$S(LASTTIME]"":1,1:0)
     45 I SET D
     46 .I $$HDIFF^XLFDT($H,LASTTIME,2)>30 S ^HLB("QUEUE","OUT",LINK)="",SET=0,LINK("DOWN")=1
     47 I $D(^HLTMP("FAILING LINKS",LINK)) S LINK("DOWN")=1
     48 Q SET
     49 ;
     50LINKDOWN(HLCSTATE) ;
     51 D:$G(HLCSTATE("CONNECTED")) CLOSE^HLOT(.HLCSTATE)
     52 I $D(HLCSTATE("LINK","NAME")),$D(HLCSTATE("LINK","PORT")) D
     53 .S TO=HLCSTATE("LINK","NAME")_":"_HLCSTATE("LINK","PORT")
     54 .S ^HLB("QUEUE","OUT",TO)=$H
     55 .S:'$D(^HLTMP("FAILING LINKS",TO)) ^HLTMP("FAILING LINKS",TO)=$H
     56 Q
     57 ;
     58ERROR ;error trap
     59 S $ETRAP="Q:$QUIT """" Q"
     60 N HOUR
     61 S HOUR=$E($$NOW^XLFDT,1,10)
     62 S ^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2))=$G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))+1
     63 D END
     64 D LINKDOWN(.HLCSTATE)
     65 ;
     66 I ($ECODE["TOOMANYFILES")!($ECODE["EDITED") Q:$QUIT "" Q
     67 ;while debugging quit on all errors - this will return the process to the Process Manager error trap
     68 I $G(^HLTMP("LOG ALL ERRORS")) Q:$QUIT "" Q
     69 ;
     70 ;don't log some common errors
     71 I ($ECODE["READ")!($ECODE["NOTOPEN")!($ECODE["DEVNOTOPN")!($ECODE["WRITE")!($ECODE["OPENERR") D
     72 .;
     73 E  D
     74 .;but do log all the others
     75 .D ^%ZTER
     76 ;
     77 ;a lot of errors of the same type may indicate an endless loop
     78 ;return to the Process Manager error trap
     79 I ($G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))>30) Q:$QUIT "" Q
     80 ;
     81 ;resume execution of the process manager executing the client
     82 D UNWIND^%ZTER
     83 Q
     84 ;
     85DOWORK(QUEUE) ;sends the messages on the queue
     86 N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOCLNT"
     87 N MSGIEN,DEQUE,SUCCESS,MSGCOUNT
     88 S DEQUE=0
     89 S SUCCESS=1
     90 ;
     91 I '$$CNNCTD(QUEUE("LINK")),'$$CONNECT^HLOCLNT1($P(QUEUE("LINK"),":"),$P(QUEUE("LINK"),":",2),30,.HLCSTATE) Q
     92 ;
     93 S (MSGCOUNT,MSGIEN)=0
     94 F  S MSGIEN=$O(^HLB("QUEUE","OUT",QUEUE("LINK"),QUEUE("QUEUE"),MSGIEN)) Q:'MSGIEN  D  Q:'SUCCESS  Q:MSGCOUNT>1000
     95 .N UPDATE
     96 .S ^HLB(MSGIEN,"TRIES")=$G(^HLB(MSGIEN,"TRIES"))+1
     97 .S SUCCESS=0
     98 .S:$$TRANSMIT(.HLCSTATE,MSGIEN,.UPDATE) SUCCESS=1
     99 .Q:('SUCCESS)!('$D(UPDATE))
     100 .D DEQUE(.UPDATE)
     101 .S MSGCOUNT=MSGCOUNT+1
     102 .D:HLCSTATE("COUNTS")>4 SAVECNTS^HLOSTAT(.HLCSTATE)
     103 .;
     104 .;if the queue was on the down list, and not since shutdown, mark it as up, since a message has been successfully transmitted across it
     105 .I $G(QUEUE("DOWN"))!$$FAILING(QUEUE("LINK")),'$$IFSHUT^HLOTLNK(QUEUE("LINK")) S QUEUE("DOWN")=0,^HLB("QUEUE","OUT",QUEUE("LINK"))="" K ^HLTMP("FAILING LINKS",QUEUE("LINK"))
     106 ;
     107END D DEQUE()
     108 D SAVECNTS^HLOSTAT(.HLCSTATE)
     109 Q
     110CNNCTD(LINK) ;
     111 ;Connected to LINK?  HLCSTATE must be defined, LINK=<link name>:<port>
     112 ;
     113 I ($G(HLCSTATE("LINK","NAME"))=$P(LINK,":")),($G(HLCSTATE("LINK","PORT"))=$P(LINK,":",2)),$G(HLCSTATE("CONNECTED")) Q 1
     114 Q 0
     115 ;
     116DEQUE(UPDATE) ;
     117 I $D(UPDATE) S DEQUE=DEQUE+1,DEQUE(+UPDATE)=$P(UPDATE,"^",2,99) S:$G(UPDATE("MSA"))]"" DEQUE(+UPDATE,"MSA")=UPDATE("MSA") S:$G(UPDATE("ACTION"))]"" DEQUE(+UPDATE,"ACTION")=UPDATE("ACTION")
     118 I '$D(UPDATE)!(DEQUE>15) D
     119 .N MSGIEN S MSGIEN=0
     120 .F  S MSGIEN=$O(DEQUE(MSGIEN)) Q:'MSGIEN  D
     121 ..N NODE,TIME
     122 ..D DEQUE^HLOQUE(QUEUE("LINK"),QUEUE("QUEUE"),"OUT",MSGIEN)
     123 ..S TIME=$P(DEQUE(MSGIEN),"^")
     124 ..Q:'TIME
     125 ..S NODE=QUEUE("LINK")_"^"_QUEUE("QUEUE")_"^"_$P(DEQUE(MSGIEN),"^",2,99)
     126 ..S ^HLTMP("CLIENT UPDATES",$J,TIME,MSGIEN)=NODE
     127 ..S:$G(DEQUE(MSGIEN,"MSA"))]"" ^HLTMP("CLIENT UPDATES",$J,TIME,MSGIEN,"MSA")=DEQUE(MSGIEN,"MSA")
     128 ..S:$G(DEQUE(MSGIEN,"ACTION"))]"" ^HLTMP("CLIENT UPDATES",$J,TIME,MSGIEN,"ACTION")=DEQUE(MSGIEN,"ACTION")
     129 .K DEQUE S DEQUE=0
     130 Q
     131 ;
     132TRANSMIT(HLCSTATE,MSGIEN,UPDATE) ;
     133 ;Transmits a single message and if a commit ack was requested reads it.  Updates file 778 with the result.  Queues for the infiler the application accept action if one was requested.
     134 ;Input:
     135 ;   HLCSTATE (pass by reference)
     136 ;   MSGIEN - ien, file 778, of message to be transmitted
     137 ;Output:
     138 ;  Function returns 1 on success, 0 on failure
     139 ;  UPDATE - (pass by reference) to contain updates needed for message
     140 ;
     141 N HLMSTATE,MSA,HDR,SUCCESS
     142 ;
     143 S SUCCESS=0
     144 S HLCSTATE("ATTEMPT")=0
     145 ;
     146 ;start saving updates needed after the message is transmitted
     147 S UPDATE=MSGIEN
     148 Q:'$$GETMSG^HLOCLNT2(MSGIEN,.HLMSTATE) 1  ;returns 1 so the message will be removed from the queue
     149 I HLMSTATE("DT/TM"),HLMSTATE("STATUS","ACCEPTED")!(HLMSTATE("HDR","ACCEPT ACK TYPE")="NE") Q 1  ;the message was already transmitted
     150 ;
     151 S UPDATE=UPDATE_"^"_$$NOW^XLFDT
     152RETRY D
     153 .S HLCSTATE("ATTEMPT")=HLCSTATE("ATTEMPT")+1
     154 .I 'HLCSTATE("CONNECTED") D OPEN^HLOT(.HLCSTATE) Q:'HLCSTATE("CONNECTED")
     155 .;
     156 .;try to send the message
     157 .Q:'$$WRITEMSG^HLOCLNT1(.HLCSTATE,.HLMSTATE)
     158 .;does the message need an accept ack?
     159 .I HLMSTATE("HDR","ACCEPT ACK TYPE")="AL" D
     160 ..N FS
     161 ..Q:'$$READACK^HLOCLNT1(.HLCSTATE,.HDR,.MSA)
     162 ..;does the MSA refer to the correct control id?
     163 ..S FS=$E(HDR(1),4)
     164 ..Q:$P(MSA,FS,3)'=HLMSTATE("ID")
     165 ..N ACKID,ACKCODE
     166 ..S ACKCODE=$P(MSA,FS,2)
     167 ..S ACKID=$S($E(HDR(1),1,3)="MSH":$P(HDR(2),FS,5),1:$P(HDR(2),FS,6))
     168 ..S $P(UPDATE,"^",5)=1
     169 ..S UPDATE("MSA")=ACKID_"^"_MSA
     170 ..I '(ACKCODE="CA") S $P(UPDATE,"^",3)="SE",$P(UPDATE,"^",4)=2
     171 ..I ACKCODE="CA",HLMSTATE("HDR","APP ACK TYPE")="NE" S $P(UPDATE,"^",3)="SU",$P(UPDATE,"^",4)=$S(HLMSTATE("BATCH"):"2",1:1)
     172 ..I ($P(UPDATE,"^",3)="SE") S $P(UPDATE,"^",6)=$P(HLMSTATE("HDR",1),FS,5) ;errors need the application for xref
     173 ..;
     174 ..;did the app request notification of accept ack?
     175 ..S UPDATE("ACTION")=HLMSTATE("ACCEPT ACK RESPONSE")
     176 ..S SUCCESS=1
     177 .E  D  ;accept ack wasn't requested
     178 ..S SUCCESS=1
     179 ..I HLMSTATE("HDR","APP ACK TYPE")="NE" S $P(UPDATE,"^",3)="SU",$P(UPDATE,"^",4)=$S(HLMSTATE("BATCH"):2,1:1)
     180 ;
     181 I 'SUCCESS,'HLCSTATE("CONNECTED"),(HLCSTATE("ATTEMPT")<2) G RETRY
     182 I SUCCESS D
     183 .D COUNT^HLOSTAT(.HLCSTATE,HLMSTATE("HDR","RECEIVING APPLICATION"),HLMSTATE("HDR","SENDING APPLICATION"),$S(HLMSTATE("BATCH"):"BATCH",1:HLMSTATE("HDR","MESSAGE TYPE")_"~"_HLMSTATE("HDR","EVENT")))
     184 .;if this is an ack to a message need to purge the original message, so store its ien with the purge date
     185 .S:$G(HLMSTATE("ACK TO IEN")) $P(UPDATE,"^",4)=$P(UPDATE,"^",4)_"-"_HLMSTATE("ACK TO IEN")
     186 I ('HLCSTATE("CONNECTED"))!('SUCCESS) D LINKDOWN(.HLCSTATE)
     187 Q SUCCESS
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOCLNT1.m

    r613 r623  
    1 HLOCLNT1        ;IRMFO-ALB/CJM - Writing messages, reading acks;03/24/2004  14:43 ;07/10/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,130,131,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;
    6 WRITEMSG(HLCSTATE,HLMSTATE)     ;
    7         ;Description:  This function uses the services offered by the transport layer to send a message over an open communication channel.
    8         ;
    9         ;Input:
    10         ;  HLCSTATE (pass by reference, required) Defines the LLP & its state
    11         ;  HLMSTATE (pass by reference, required) The message
    12         ;Output:
    13         ;  Function returns 1 on success, 0 on failure
    14         ;
    15         N SEG,QUIT,HDR
    16         S QUIT=0
    17         Q:'$G(HLMSTATE("IEN")) 0
    18         S HDR(1)=HLMSTATE("HDR",1),HDR(2)=HLMSTATE("HDR",2)
    19         Q:'$$WRITEHDR^HLOT(.HLCSTATE,.HDR) 0
    20         I HLMSTATE("BATCH") D
    21         .N LAST S LAST=0
    22         .S HLMSTATE("BATCH","CURRENT MESSAGE")=0
    23         .F  Q:'$$NEXTMSG^HLOMSG(.HLMSTATE,.SEG)  D  Q:QUIT
    24         ..S LAST=HLMSTATE("BATCH","CURRENT MESSAGE")
    25         ..I '$$WRITESEG^HLOT(.HLCSTATE,.SEG) S QUIT=1 Q
    26         ..F  Q:'$$HLNEXT^HLOMSG(.HLMSTATE,.SEG)  D  Q:QUIT
    27         ...I '$$WRITESEG^HLOT(.HLCSTATE,.SEG) S QUIT=1 Q
    28         .K SEG S SEG(1)="BTS"_HLMSTATE("HDR","FIELD SEPARATOR")_LAST
    29         .S:'$$WRITESEG^HLOT(.HLCSTATE,.SEG) QUIT=1
    30         E  D
    31         .F  Q:'$$HLNEXT^HLOMSG(.HLMSTATE,.SEG)  D  Q:QUIT
    32         ..S:'$$WRITESEG^HLOT(.HLCSTATE,.SEG) QUIT=1
    33         S:'$$ENDMSG^HLOT(.HLCSTATE) QUIT=1
    34         Q 'QUIT
    35         ;
    36 READACK(HLCSTATE,HDR,MSA)       ;
    37         ;Description:  This function uses the services offered by the transport layer to read an accept ack.
    38         ;
    39         ;Input:
    40         ;  HLCSTATE (pass by reference, required) Defines the communication channel and its state.
    41         ;Output:
    42         ;  Function returns 1 on success, 0 on failure
    43         ;  HDR (pass by reference) the message header:
    44         ;   HDR(1) is components 1-6
    45         ;   HDR(2) is components 7-end
    46         ;  MSA (pass by reference) the MSA segment as an unsubscripted variable
    47         ;
    48         N SEG
    49         K HDR,MSA,MAX,I
    50         S MAX=HLCSTATE("SYSTEM","MAXSTRING")-40 ;MAX is the maximum that can be safely stored on a node, leaving room for the other fields stored with MSA seg
    51         Q:'$$READHDR^HLOT(.HLCSTATE,.HDR) 0
    52         F  Q:'$$READSEG^HLOT(.HLCSTATE,.SEG)  D
    53         .I $E($E(SEG(1),1,3)_$E($G(SEG(2)),1,3),1,3)="MSA" D
    54         ..S MSA=""
    55         ..F I=1:1 Q:'$D(SEG(I))  S MSA=MSA_$S((MAX-$L(MSA))<1:"",1:$E(SEG(I),1,MAX))
    56         I $D(MSA),HLCSTATE("MESSAGE ENDED") D  Q 1
    57         .D SPLITHDR^HLOSRVR1(.HDR)
    58         .S HLCSTATE("COUNTS","ACKS")=$G(HLCSTATE("COUNTS","ACKS"))+1
    59         Q 0
    60         ;
    61 CONNECT(LINK,PORT,TIMEOUT,HLCSTATE)     ;
    62         ;sets up HLCSTATE() and opens a client connection
    63         ;Input:
    64         ;  LINK - name of the link to connect to
    65         ;  PORT (optional) port # to connect to, defaults to that specified by the link
    66         ;  TIMEOUT (optional) specifies the open timeout in seconds, defaults to 30
    67         ;Output:
    68         ;   HLCSTATE - array to hold the connection state
    69         ;
    70         I $G(HLCSTATE("CONNECTED")) D  Q:HLCSTATE("CONNECTED")
    71         .I $G(HLCSTATE("LINK","NAME"))]"",($G(HLCSTATE("LINK","NAME"))'=LINK) D CLOSE^HLOT(.HLCSTATE) Q
    72         .I $G(HLCSTATE("LINK","NAME"))]"",$G(PORT),($G(HLCSTATE("LINK","PORT"))'=PORT) D CLOSE^HLOT(.HLCSTATE) Q
    73         .I (HLCSTATE("SYSTEM","OS")="CACHE") D  Q
    74         ..U HLCSTATE("DEVICE") S HLCSTATE("CONNECTED")=($ZA\8192#2)
    75         ..I 'HLCSTATE("CONNECTED") D CLOSE^HLOT(.HLCSTATE)
    76         .;D CLOSE^HLOT(.HLCSTATE)
    77         K HLCSTATE
    78         N ARY,NODE
    79         I '$$GETLINK^HLOTLNK(LINK,.ARY) S HLCSTATE("LINK","NAME")=LINK,HLCSTATE("LINK","PORT")=$G(PORT) D LINKDOWN^HLOCLNT(.HLCSTATE) Q 0
    80         M HLCSTATE("LINK")=ARY
    81         I HLCSTATE("LINK","SHUTDOWN") S HLCSTATE("CONNECTED")=0 D LINKDOWN^HLOCLNT(.HLCSTATE) Q 0
    82         ;overlay the port if supplied from the queue
    83         S:$G(PORT) HLCSTATE("LINK","PORT")=PORT
    84         S HLCSTATE("READ TIMEOUT")=20
    85         S HLCSTATE("OPEN TIMEOUT")=$S($G(TIMEOUT):TIMEOUT,1:30)
    86         S HLCSTATE("COUNTS")=0
    87         S HLCSTATE("READ")="" ;where the reads are stored
    88         ;
    89         ;HLCSTATE("BUFFER",<seg>,<line>) serves as a write buffer so that a lot can be written all at once
    90         S HLCSTATE("BUFFER","BYTE COUNT")=0 ;count of BYTES in buffer
    91         S HLCSTATE("BUFFER","SEGMENT COUNT")=0 ;count of segments in buffer
    92         ;
    93         S HLCSTATE("MESSAGE ENDED")=0 ;end of message flag
    94         S NODE=^%ZOSF("OS")
    95         S HLCSTATE("SERVER")=0
    96         S HLCSTATE("SYSTEM","OS")=$S(NODE["DSM":"DSM",NODE["OpenM":"CACHE",NODE["G.TM":"G.TM",1:"")
    97         I HLCSTATE("SYSTEM","OS")="" D LINKDOWN^HLOCLNT(.HLCSTATE) Q 0
    98         D
    99         .N SYS
    100         .D SYSPARMS^HLOSITE(.SYS)
    101         .S HLCSTATE("SYSTEM","BUFFER")=SYS("HL7 BUFFER")
    102         .S HLCSTATE("SYSTEM","MAXSTRING")=SYS("MAXSTRING")
    103         .S HLCSTATE("SYSTEM","NORMAL PURGE")=SYS("NORMAL PURGE")
    104         .S HLCSTATE("SYSTEM","ERROR PURGE")=SYS("ERROR PURGE")
    105         I HLCSTATE("LINK","LLP")="TCP" D
    106         .S HLCSTATE("OPEN")="OPEN^HLOTCP"
    107         E  ;no other LLP implemented
    108         D OPEN^HLOT(.HLCSTATE)
    109         ;
    110         ;mark the failure time for the link so other processes know not to try for a while
    111         I 'HLCSTATE("CONNECTED") D LINKDOWN^HLOCLNT(.HLCSTATE)
    112         Q HLCSTATE("CONNECTED")
    113         ;
    114 BADMSGS(WORK)   ;
    115         ;finds messages that won't transmit after 8 hours of trying and takes them off the outgoing queue
    116         N LINK
    117         S LINK=""
    118         F  S LINK=$O(^HLTMP("FAILING LINKS",LINK)) Q:LINK=""  D
    119         .N TIME,QUE,COUNT
    120         .S TIME=$G(^HLTMP("FAILING LINKS",LINK)) Q:TIME=""
    121         .Q:$$HDIFF^XLFDT($H,TIME,2)<28800  ;8 hours
    122         .Q:'$$IFOPEN^HLOUSR1(LINK)
    123         .L +^HLB("QUEUE","OUT",LINK):0
    124         .S QUE=""
    125         .F  S QUE=$O(^HLB("QUEUE","OUT",LINK,QUE)) Q:QUE=""  D
    126         ..N MSG S MSG=0
    127         ..S MSG=$O(^HLB("QUEUE","OUT",LINK,QUE,MSG))
    128         ..Q:'MSG
    129         ..S COUNT=$G(^HLB(MSG,"TRIES"))
    130         ..I COUNT>20 D
    131         ...N NODE0,NODE1,NODE2,TIME,RAPP,SAPP,FS,CS,ACTION,MTYPE,EVENT
    132         ...S NODE0=$G(^HLB(MSG,0))
    133         ...Q:'$P(NODE0,"^",2)
    134         ...S TIME=$$NOW^XLFDT
    135         ...S NODE1=$G(^HLB(MSG,1))
    136         ...S NODE2=$G(^HLB(MSG,2))
    137         ...S FS=$E(NODE1,4)
    138         ...Q:FS=""
    139         ...S CS=$E(NODE1,5)
    140         ...Q:CS=""
    141         ...S SAPP=$P(NODE1,FS,3)
    142         ...S:SAPP="" SAPP="UNKNOWN"
    143         ...S RAPP=$P(NODE1,FS,5)
    144         ...S MTYPE=$P($P(NODE2,FS,4),CS)
    145         ...S EVENT=$P($P(NODE2,FS,4),CS,2)
    146         ...S $P(^HLB(MSG,0),"^",21)=COUNT_" FAILED TRANSMISSIONS"
    147         ...S $P(^HLB(MSG,0),"^",20)="TF"
    148         ...S ^HLB("ERRORS",RAPP,TIME,MSG)=""
    149         ...D COUNT^HLOESTAT("OUT",RAPP,SAPP,MTYPE,EVENT)
    150         ...S ACTION=$P(NODE0,"^",14,15)
    151         ...I ACTION'="^",ACTION]"" D INQUE^HLOQUE(LINK,QUE,MSG,ACTION,1)
    152         ...D DEQUE^HLOQUE(LINK,QUE,"OUT",MSG)
    153         .L -^HLB("QUEUE","OUT",LINK)
    154         Q
     1HLOCLNT1 ;IRMFO-ALB/CJM - Writing messages, reading acks;03/24/2004  14:43 ;03/19/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,130,131,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ;
     6WRITEMSG(HLCSTATE,HLMSTATE) ;
     7 ;Description:  This function uses the services offered by the transport layer to send a message over an open communication channel.
     8 ;
     9 ;Input:
     10 ;  HLCSTATE (pass by reference, required) Defines the LLP & its state
     11 ;  HLMSTATE (pass by reference, required) The message
     12 ;Output:
     13 ;  Function returns 1 on success, 0 on failure
     14 ;
     15 N SEG,QUIT,HDR
     16 S QUIT=0
     17 Q:'$G(HLMSTATE("IEN")) 0
     18 S HDR(1)=HLMSTATE("HDR",1),HDR(2)=HLMSTATE("HDR",2)
     19 Q:'$$WRITEHDR^HLOT(.HLCSTATE,.HDR) 0
     20 I HLMSTATE("BATCH") D
     21 .N LAST S LAST=0
     22 .S HLMSTATE("BATCH","CURRENT MESSAGE")=0
     23 .F  Q:'$$NEXTMSG^HLOMSG(.HLMSTATE,.SEG)  D  Q:QUIT
     24 ..S LAST=HLMSTATE("BATCH","CURRENT MESSAGE")
     25 ..I '$$WRITESEG^HLOT(.HLCSTATE,.SEG) S QUIT=1 Q
     26 ..F  Q:'$$HLNEXT^HLOMSG(.HLMSTATE,.SEG)  D  Q:QUIT
     27 ...I '$$WRITESEG^HLOT(.HLCSTATE,.SEG) S QUIT=1 Q
     28 .K SEG S SEG(1)="BTS"_HLMSTATE("HDR","FIELD SEPARATOR")_LAST
     29 .S:'$$WRITESEG^HLOT(.HLCSTATE,.SEG) QUIT=1
     30 E  D
     31 .F  Q:'$$HLNEXT^HLOMSG(.HLMSTATE,.SEG)  D  Q:QUIT
     32 ..S:'$$WRITESEG^HLOT(.HLCSTATE,.SEG) QUIT=1
     33 S:'$$ENDMSG^HLOT(.HLCSTATE) QUIT=1
     34 Q 'QUIT
     35 ;
     36READACK(HLCSTATE,HDR,MSA) ;
     37 ;Description:  This function uses the services offered by the transport layer to read an accept ack.
     38 ;
     39 ;Input:
     40 ;  HLCSTATE (pass by reference, required) Defines the communication channel and its state.
     41 ;Output:
     42 ;  Function returns 1 on success, 0 on failure
     43 ;  HDR (pass by reference) the message header:
     44 ;   HDR(1) is components 1-6
     45 ;   HDR(2) is components 7-end
     46 ;  MSA (pass by reference) the MSA segment as an unsubscripted variable
     47 ;
     48 N SEG
     49 K HDR,MSA,MAX,I
     50 S MAX=HLCSTATE("SYSTEM","MAXSTRING")-40 ;MAX is the maximum that can be safely stored on a node, leaving room for the other fields stored with MSA seg
     51 Q:'$$READHDR^HLOT(.HLCSTATE,.HDR) 0
     52 F  Q:'$$READSEG^HLOT(.HLCSTATE,.SEG)  D
     53 .I $E($E(SEG(1),1,3)_$E($G(SEG(2)),1,3),1,3)="MSA" D
     54 ..S MSA=""
     55 ..F I=1:1 Q:'$D(SEG(I))  S MSA=MSA_$S((MAX-$L(MSA))<1:"",1:$E(SEG(I),1,MAX))
     56 I $D(MSA),HLCSTATE("MESSAGE ENDED") D  Q 1
     57 .D SPLITHDR^HLOSRVR1(.HDR)
     58 .S HLCSTATE("COUNTS","ACKS")=$G(HLCSTATE("COUNTS","ACKS"))+1
     59 Q 0
     60 ;
     61CONNECT(LINK,PORT,TIMEOUT,HLCSTATE) ;
     62 ;sets up HLCSTATE() and opens a client connection
     63 ;Input:
     64 ;  LINK - name of the link to connect to
     65 ;  PORT (optional) port # to connect to, defaults to that specified by the link
     66 ;  TIMEOUT (optional) specifies the open timeout in seconds, defaults to 30
     67 ;Output:
     68 ;   HLCSTATE - array to hold the connection state
     69 ;
     70 I $G(HLCSTATE("CONNECTED")) D  Q:HLCSTATE("CONNECTED")
     71 .I $G(HLCSTATE("LINK","NAME"))]"",($G(HLCSTATE("LINK","NAME"))'=LINK) D CLOSE^HLOT(.HLCSTATE) Q
     72 .I $G(HLCSTATE("LINK","NAME"))]"",$G(PORT),($G(HLCSTATE("LINK","PORT"))'=PORT) D CLOSE^HLOT(.HLCSTATE) Q
     73 .I (HLCSTATE("SYSTEM","OS")="CACHE") D  Q
     74 ..U HLCSTATE("DEVICE") S HLCSTATE("CONNECTED")=($ZA\8192#2)
     75 ..I 'HLCSTATE("CONNECTED") D CLOSE^HLOT(.HLCSTATE)
     76 .;D CLOSE^HLOT(.HLCSTATE)
     77 K HLCSTATE
     78 N ARY,NODE
     79 I '$$GETLINK^HLOTLNK(LINK,.ARY) S HLCSTATE("LINK","NAME")=LINK,HLCSTATE("LINK","PORT")=$G(PORT) D LINKDOWN^HLOCLNT(.HLCSTATE) Q 0
     80 M HLCSTATE("LINK")=ARY
     81 I HLCSTATE("LINK","SHUTDOWN") S HLCSTATE("CONNECTED")=0 D LINKDOWN^HLOCLNT(.HLCSTATE) Q 0
     82 ;overlay the port if supplied from the queue
     83 S:$G(PORT) HLCSTATE("LINK","PORT")=PORT
     84 S HLCSTATE("READ TIMEOUT")=20
     85 S HLCSTATE("OPEN TIMEOUT")=$S($G(TIMEOUT):TIMEOUT,1:30)
     86 S HLCSTATE("COUNTS")=0
     87 S HLCSTATE("READ")="" ;where the reads are stored
     88 ;
     89 ;HLCSTATE("BUFFER",<seg>,<line>) serves as a write buffer so that a lot can be written all at once
     90 S HLCSTATE("BUFFER","BYTE COUNT")=0 ;count of BYTES in buffer
     91 S HLCSTATE("BUFFER","SEGMENT COUNT")=0 ;count of segments in buffer
     92 ;
     93 S HLCSTATE("MESSAGE ENDED")=0 ;end of message flag
     94 S NODE=^%ZOSF("OS")
     95 S HLCSTATE("SERVER")=0
     96 S HLCSTATE("SYSTEM","OS")=$S(NODE["DSM":"DSM",NODE["OpenM":"CACHE",NODE["G.TM":"G.TM",1:"")
     97 I HLCSTATE("SYSTEM","OS")="" D LINKDOWN^HLOCLNT(.HLCSTATE) Q 0
     98 D
     99 .N SYS
     100 .D SYSPARMS^HLOSITE(.SYS)
     101 .S HLCSTATE("SYSTEM","BUFFER")=SYS("HL7 BUFFER")
     102 .S HLCSTATE("SYSTEM","MAXSTRING")=SYS("MAXSTRING")
     103 .S HLCSTATE("SYSTEM","NORMAL PURGE")=SYS("NORMAL PURGE")
     104 .S HLCSTATE("SYSTEM","ERROR PURGE")=SYS("ERROR PURGE")
     105 I HLCSTATE("LINK","LLP")="TCP" D
     106 .S HLCSTATE("OPEN")="OPEN^HLOTCP"
     107 E  ;no other LLP implemented
     108 D OPEN^HLOT(.HLCSTATE)
     109 ;
     110 ;mark the failure time for the link so other processes know not to try for a while
     111 I 'HLCSTATE("CONNECTED") D LINKDOWN^HLOCLNT(.HLCSTATE)
     112 Q HLCSTATE("CONNECTED")
     113 ;
     114BADMSGS(WORK) ;
     115 ;finds messages that won't transmit after 8 hours of trying and takes them off the outgoing queue
     116 N LINK
     117 S LINK=""
     118 F  S LINK=$O(^HLTMP("FAILING LINKS",LINK)) Q:LINK=""  D
     119 .N TIME,QUE,COUNT
     120 .S TIME=$G(^HLTMP("FAILING LINKS",LINK)) Q:TIME=""
     121 .Q:$$HDIFF^XLFDT($H,TIME,2)<28800  ;8 hours
     122 .Q:'$$IFOPEN^HLOUSR1(LINK)
     123 .L +^HLB("QUEUE","OUT",LINK):0
     124 .S QUE=""
     125 .F  S QUE=$O(^HLB("QUEUE","OUT",LINK,QUE)) Q:QUE=""  D
     126 ..N MSG S MSG=0
     127 ..S MSG=$O(^HLB("QUEUE","OUT",LINK,QUE,MSG))
     128 ..Q:'MSG
     129 ..S COUNT=$G(^HLB(MSG,"TRIES"))
     130 ..I COUNT>20 D
     131 ...N NODE0,NODE1,NODE2,TIME,RAPP,SAPP,FS,CS,ACTION,MTYPE,EVENT
     132 ...S NODE0=$G(^HLB(MSG,0))
     133 ...Q:'$P(NODE0,"^",2)
     134 ...S TIME=$$NOW^XLFDT
     135 ...S NODE1=$G(^HLB(MSG,1))
     136 ...S NODE2=$G(^HLB(MSG,2))
     137 ...S FS=$E(NODE1,4)
     138 ...Q:FS=""
     139 ...S CS=$E(NODE1,5)
     140 ...Q:CS=""
     141 ...S SAPP=$P(NODE1,FS,3)
     142 ...S:SAPP="" SAPP="UNKNOWN"
     143 ...S RAPP=$P(NODE1,FS,5)
     144 ...S MTYPE=$P($P(NODE2,FS,4),CS)
     145 ...S EVENT=$P($P(NODE2,FS,4),CS,2)
     146 ...S $P(^HLB(MSG,0),"^",21)=COUNT_" FAILED TRANSMISSIONS"
     147 ...S $P(^HLB(MSG,0),"^",20)="TF"
     148 ...S ^HLB("ERRORS","TF",SAPP,TIME,MSG)=""
     149 ...D COUNT^HLOESTAT("OUT",RAPP,SAPP,MTYPE,EVENT)
     150 ...S ACTION=$P(NODE0,"^",14,15)
     151 ...I ACTION'="^",ACTION]"" D INQUE^HLOQUE(LINK,QUE,MSG,ACTION,1)
     152 ...D DEQUE^HLOQUE(LINK,QUE,"OUT",MSG)
     153 .L -^HLB("QUEUE","OUT",LINK)
     154 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOCLNT2.m

    r613 r623  
    1 HLOCLNT2        ;ALB/CJM- Performs message updates for the client - 10/4/94 1pm ;07/10/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 GETWORK(WORK)   ;
    6         ;
    7         N OLD,DOLLARJ,SUCCESS,NOW
    8         S SUCCESS=0
    9         S NOW=$$NOW^XLFDT
    10         S (OLD,DOLLARJ)=$G(WORK("DOLLARJ"))
    11         F  S DOLLARJ=$O(^HLTMP("CLIENT UPDATES",DOLLARJ)) Q:DOLLARJ=""  D  Q:SUCCESS
    12         .L +^HLTMP("CLIENT UPDATES",DOLLARJ):0
    13         .Q:'$T
    14         .N TIME S TIME=$O(^HLTMP("CLIENT UPDATES",DOLLARJ,""))
    15         .I $$FMDIFF^XLFDT(NOW,TIME,2)<2 L -^HLTMP("CLIENT UPDATES",DOLLARJ) Q
    16         .S SUCCESS=1
    17         ;
    18         I OLD'="",'SUCCESS F  S DOLLARJ=$O(^HLTMP("CLIENT UPDATES",DOLLARJ)) Q:DOLLARJ=""  Q:DOLLARJ>OLD  D  Q:SUCCESS
    19         .L +^HLTMP("CLIENT UPDATES",DOLLARJ):0
    20         .Q:'$T
    21         .N TIME S TIME=$O(^HLTMP("CLIENT UPDATES",DOLLARJ,""))
    22         .I $$FMDIFF^XLFDT(NOW,TIME,2)<2 L -^HLTMP("CLIENT UPDATES",DOLLARJ) Q
    23         .S SUCCESS=1
    24         S WORK("DOLLARJ")=DOLLARJ,WORK("NOW")=NOW
    25         Q $S($L(WORK("DOLLARJ")):1,1:0)
    26         ;
    27 DOWORK(WORK)    ;
    28         ;
    29         N DOLLARJ,TIME,IEN,PARMS,SYSTEM
    30         S TIME=""
    31         S DOLLARJ=WORK("DOLLARJ")
    32         D SYSPARMS^HLOSITE(.SYSTEM)
    33         F  S TIME=$O(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME)) Q:TIME=""  Q:$$FMDIFF^XLFDT(WORK("NOW"),TIME,2)<2  D
    34         .S IEN=0
    35         .F  S IEN=$O(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN)) Q:'IEN  D
    36         ..N NODE
    37         ..S NODE=$G(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN))
    38         ..S PARMS("LINK")=$P(NODE,"^")
    39         ..S PARMS("QUEUE")=$P(NODE,"^",2)
    40         ..S PARMS("STATUS")=$P(NODE,"^",3)
    41         ..S PARMS("PURGE TYPE")=$P(NODE,"^",4)
    42         ..S PARMS("ACK TO IEN")=+$P($P(NODE,"^",4),"-",2)
    43         ..S PARMS("ACCEPT ACK")=$P(NODE,"^",5)
    44         ..S PARMS("RECEIVING APP")=$P(NODE,"^",6)
    45         ..S:PARMS("RECEIVING APP")="" PARMS("RECEIVING APP")="UNKNOWN RECEIVING APPLICATION"
    46         ..S PARMS("MSA")=$G(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN,"MSA"))
    47         ..S PARMS("ACTION")=$G(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN,"ACTION"))
    48         ..D UPDATE(IEN,TIME,.PARMS)
    49         ..K ^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN)
    50         L -^HLTMP("CLIENT UPDATES",DOLLARJ)
    51         Q
    52         ;
    53 UPDATE(MSGIEN,TIME,PARMS)       ;
    54         S:PARMS("STATUS")]"" $P(^HLB(MSGIEN,0),"^",20)=PARMS("STATUS")
    55         I PARMS("STATUS")="ER" D
    56         .S ^HLB("ERRORS",PARMS("RECEIVING APP"),TIME,MSGIEN_"^")=""
    57         .D COUNT^HLOESTAT("OUT",PARMS("RECEIVING APP"),$$GETSAP(MSGIEN),$$GETMTYPE(MSGIEN))
    58         S:PARMS("ACCEPT ACK") $P(^HLB(MSGIEN,0),"^",17)=PARMS("ACCEPT ACK")
    59         S $P(^HLB(MSGIEN,0),"^",16)=TIME
    60         S:PARMS("MSA")]"" ^HLB(MSGIEN,4)=TIME_"^"_PARMS("MSA")
    61         I PARMS("PURGE TYPE"),PARMS("ACTION")="" D
    62         .;don't set purge if going on the infiler - let infiler do it
    63         .N PTIME
    64         .S:(PARMS("PURGE TYPE")=2) PTIME=$$FMADD^XLFDT(TIME,SYSTEM("ERROR PURGE")) ;error purge is in days
    65         .S:(PARMS("PURGE TYPE")'=2) PTIME=$$FMADD^XLFDT(TIME,,SYSTEM("NORMAL PURGE")) ;normal purge is in hours
    66         .S $P(^HLB(MSGIEN,0),"^",9)=PTIME,^HLB("AD","OUT",PTIME,MSGIEN)=""
    67         .I PARMS("ACK TO IEN"),$D(^HLB(PARMS("ACK TO IEN"),0)) S $P(^HLB(PARMS("ACK TO IEN"),0),"^",9)=PTIME,^HLB("AD","OUT",PTIME,PARMS("ACK TO IEN"))=""
    68         D:PARMS("ACTION")]""
    69         .N PURGE
    70         .S PURGE=$S(PARMS("PURGE TYPE"):1,1:0)
    71         .S:PARMS("ACK TO IEN") PURGE("ACKTOIEN")=PARMS("ACK TO IEN")
    72         .D INQUE^HLOQUE(PARMS("LINK"),PARMS("QUEUE"),MSGIEN,PARMS("ACTION"),.PURGE)
    73         Q
    74         ;
    75 GETMSG(IEN,MSG) ;
    76         ;
    77         ;Description: given the message ien=MSGIEN (required), it returns the MSG array containing information about the message, defined below.
    78         ;Input:
    79         ;  IEN - the ien of the message in file 778
    80         ;Output:
    81         ;  Function returns 1 on success, 0 on failure
    82         ;  MSG (pass by reference, required) These are the subscripts returned:
    83         ;    "ACCEPT ACK RESPONSE" - if the sending app requested notification of the accept ack, this is the routine to perform
    84         ;    "ACKTOIEN" - if this is an app ack to a message not in a batch, this is the ien of the original message
    85         ;    "BATCH"  = 1 if this is a batch message, 0  if not
    86         ;    "CURRENT MESSAGE" - defined only for batch messages -  a counterused during building and parsing messages to indicate the current message.  It will be set to 0 initially.
    87         ;    "BODY" - ptr to file 778 which contains the body of the message.
    88         ;    "LINE COUNT" -  a counter used during writing of the
    89         ;     messages to indicate the current line. For
    90         ;     batch messages where each message within the batch is stored
    91         ;     separately, this field indicates the position within the current
    92         ;     individual message
    93         ;    "HDR" at these lower subscripts:
    94         ;       1    - components 1-6
    95         ;       2    - components 7-end
    96         ;       "ACCEPT ACK TYPE" = "AL" or "NE"
    97         ;       "APP ACK TYPE" = "AL" or "NE"
    98         ;       "MESSAGE CONTROL ID" - defined if NOT batch
    99         ;       "BATCH CONTROL ID" - defined if batch
    100         ;
    101         ;    "ID" - message id from the header
    102         ;    "IEN" - ien, file 778
    103         ;    "STATUS","SEQUENCE QUEUE")=name of the sequence queue (optional)
    104         ;
    105         K MSG
    106         Q:'$G(IEN) 0
    107         N NODE,FS,CS,REP,SUBCOMP,ESCAPE
    108         S MSG("IEN")=IEN
    109         S NODE=$G(^HLB(IEN,0))
    110         S MSG("BODY")=$P(NODE,"^",2)
    111         S MSG("ID")=$P(NODE,"^")
    112         Q:'MSG("BODY") 0
    113         S MSG("STATUS","ACCEPTED")=$P(NODE,"^",17)
    114         S MSG("DT/TM")=$P(NODE,"^",16)
    115         S MSG("STATUS","QUEUE")=$P(NODE,"^",6)
    116         I MSG("STATUS","QUEUE")="" S MSG("STATUS","QUEUE")="DEFAULT"
    117         S MSG("ACCEPT ACK RESPONSE")=$P(NODE,"^",12,13)
    118         I MSG("ACCEPT ACK RESPONSE")="^" S MSG("ACCEPT ACK RESPONSE")=""
    119         ;
    120         S MSG("BATCH")=+$P($G(^HLA(MSG("BODY"),0)),"^",2)
    121         I MSG("BATCH") D
    122         .S MSG("BATCH","CURRENT MESSAGE")=0
    123         E  D
    124         .N ACKTO
    125         .S ACKTO=$P(NODE,"^",3)
    126         .I ACKTO]"" S ACKTO=$$ACKTOIEN^HLOMSG1(MSG("ID"),ACKTO)
    127         .I ACKTO,+ACKTO=ACKTO S MSG("ACK TO IEN")=ACKTO
    128         S MSG("LINE COUNT")=0
    129         S MSG("HDR",1)=$G(^HLB(IEN,1))
    130         S MSG("HDR",2)=$G(^HLB(IEN,2))
    131         S FS=$E(MSG("HDR",1),4)
    132         S CS=$E(MSG("HDR",1),5)
    133         S REP=$E(MSG("HDR",1),6)
    134         S ESCAPE=$E(MSG("HDR",1),7)
    135         S SUBCOMP=$E(MSG("HDR",1),8)
    136         S MSG("HDR","FIELD SEPARATOR")=FS
    137         S MSG("HDR","SENDING APPLICATION")=$$DESCAPE^HLOPRS1($P($P(MSG("HDR",1),FS,3),CS),FS,CS,SUBCOMP,REP,ESCAPE)
    138         S MSG("HDR","RECEIVING APPLICATION")=$$DESCAPE^HLOPRS1($P($P(MSG("HDR",1),FS,5),CS),FS,CS,SUBCOMP,REP,ESCAPE)
    139         I 'MSG("BATCH") D
    140         .S MSG("HDR","MESSAGE TYPE")=$P($P(MSG("HDR",2),FS,4),CS)
    141         .S MSG("HDR","EVENT")=$P($P(MSG("HDR",2),FS,4),CS,2)
    142         .S MSG("HDR","ACCEPT ACK TYPE")=$E($P(MSG("HDR",2),FS,10),1,2)
    143         .S MSG("HDR","APP ACK TYPE")=$E($P(MSG("HDR",2),FS,11),1,2)
    144         .S MSG("HDR","MESSAGE CONTROL ID")=MSG("ID")
    145         E  D
    146         .S MSG("HDR","BATCH CONTROL ID")=MSG("ID")
    147         .S MSG("HDR","ACCEPT ACK TYPE")=$E($P($P(MSG("HDR",2),FS,4),"ACCEPT ACK TYPE=",2),1,2)
    148         .S MSG("HDR","APP ACK TYPE")=$E($P($P(MSG("HDR",2),FS,4),"APP ACK TYPE=",2),1,2)
    149         S MSG("STATUS","SEQUENCE QUEUE")=$P($G(^HLB(IEN,5)),"^")
    150         Q 1
    151         ;
    152 GETMTYPE(MSGIEN)        ;returns <message type>~<event> OR "BATCH"
    153         Q:'$G(MSGIEN) "UNKNOWN"
    154         N FS,CS,HDR1,HDR2
    155         S HDR1=$G(^HLB(IEN,1))
    156         I $E(HDR1,1,3)="BHS" Q "BATCH"
    157         S HDR2=$G(^HLB(IEN,2))
    158         S FS=$E(HDR1,4)
    159         S CS=$E(HDR1,5)
    160         Q $P($P(HDR2,FS,4),CS)_"~"_$P($P(HDR2,FS,4),CS,2)
    161         ;
    162 GETEVENT(MSGIEN)        ; returns event if not a batch message
    163         Q:'$G(MSGIEN) ""
    164         N FS,CS,HDR1,HDR2
    165         S HDR1=$G(^HLB(MSGIEN,1))
    166         I $E(HDR1,1,3)="BHS" Q ""
    167         S HDR2=$G(^HLB(MSGIEN,2))
    168         S FS=$E(HDR1,4)
    169         S CS=$E(HDR1,5)
    170         Q $P($P(HDR2,FS,4),CS,2)
    171         ;
    172 GETSAP(MSGIEN)  ;
    173         ;
    174         ;
    175         Q:'$G(MSGIEN) "UNKNOWN"
    176         N FS,CS,HDR1,REP,ESCAPE,SUBCOMP
    177         S HDR1=$G(^HLB(MSGIEN,1))
    178         S FS=$E(HDR1,4)
    179         S CS=$E(HDR1,5)
    180         S REP=$E(HDR1,6)
    181         S ESCAPE=$E(HDR1,7)
    182         S SUBCOMP=$E(HDR1,8)
    183         Q $$DESCAPE^HLOPRS1($P($P(HDR1,FS,3),CS),FS,CS,SUBCOMP,REP,ESCAPE)
     1HLOCLNT2 ;ALB/CJM- Performs message updates for the client - 10/4/94 1pm ;03/09/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 ;
     5GETWORK(WORK) ;
     6 ;
     7 N OLD,DOLLARJ,SUCCESS,NOW
     8 S SUCCESS=0
     9 S NOW=$$NOW^XLFDT
     10 S (OLD,DOLLARJ)=$G(WORK("DOLLARJ"))
     11 F  S DOLLARJ=$O(^HLTMP("CLIENT UPDATES",DOLLARJ)) Q:DOLLARJ=""  D  Q:SUCCESS
     12 .L +^HLTMP("CLIENT UPDATES",DOLLARJ):0
     13 .Q:'$T
     14 .N TIME S TIME=$O(^HLTMP("CLIENT UPDATES",DOLLARJ,""))
     15 .I $$FMDIFF^XLFDT(NOW,TIME,2)<2 L -^HLTMP("CLIENT UPDATES",DOLLARJ) Q
     16 .S SUCCESS=1
     17 ;
     18 I OLD'="",'SUCCESS F  S DOLLARJ=$O(^HLTMP("CLIENT UPDATES",DOLLARJ)) Q:DOLLARJ=""  Q:DOLLARJ>OLD  D  Q:SUCCESS
     19 .L +^HLTMP("CLIENT UPDATES",DOLLARJ):0
     20 .Q:'$T
     21 .N TIME S TIME=$O(^HLTMP("CLIENT UPDATES",DOLLARJ,""))
     22 .I $$FMDIFF^XLFDT(NOW,TIME,2)<2 L -^HLTMP("CLIENT UPDATES",DOLLARJ) Q
     23 .S SUCCESS=1
     24 S WORK("DOLLARJ")=DOLLARJ,WORK("NOW")=NOW
     25 Q $S($L(WORK("DOLLARJ")):1,1:0)
     26 ;
     27DOWORK(WORK) ;
     28 ;
     29 N DOLLARJ,TIME,IEN,PARMS,SYSTEM
     30 S TIME=""
     31 S DOLLARJ=WORK("DOLLARJ")
     32 D SYSPARMS^HLOSITE(.SYSTEM)
     33 F  S TIME=$O(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME)) Q:TIME=""  Q:$$FMDIFF^XLFDT(WORK("NOW"),TIME,2)<2  D
     34 .S IEN=0
     35 .F  S IEN=$O(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN)) Q:'IEN  D
     36 ..N NODE
     37 ..S NODE=$G(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN))
     38 ..S PARMS("LINK")=$P(NODE,"^")
     39 ..S PARMS("QUEUE")=$P(NODE,"^",2)
     40 ..S PARMS("STATUS")=$P(NODE,"^",3)
     41 ..S PARMS("PURGE TYPE")=$P(NODE,"^",4)
     42 ..S PARMS("ACK TO IEN")=+$P($P(NODE,"^",4),"-",2)
     43 ..S PARMS("ACCEPT ACK")=$P(NODE,"^",5)
     44 ..S PARMS("RECEIVING APP")=$P(NODE,"^",6)
     45 ..S:PARMS("RECEIVING APP")="" PARMS("RECEIVING APP")="UNKNOWN RECEIVING APPLICATION"
     46 ..S PARMS("MSA")=$G(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN,"MSA"))
     47 ..S PARMS("ACTION")=$G(^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN,"ACTION"))
     48 ..D UPDATE(IEN,TIME,.PARMS)
     49 ..K ^HLTMP("CLIENT UPDATES",DOLLARJ,TIME,IEN)
     50 L -^HLTMP("CLIENT UPDATES",DOLLARJ)
     51 Q
     52 ;
     53UPDATE(MSGIEN,TIME,PARMS) ;
     54 S:PARMS("STATUS")]"" $P(^HLB(MSGIEN,0),"^",20)=PARMS("STATUS")
     55 S:PARMS("STATUS")="SE" ^HLB("ERRORS","SE",PARMS("RECEIVING APP"),TIME,MSGIEN)=""
     56 S:PARMS("STATUS")="AE" ^HLB("ERRORS","AE",PARMS("RECEIVING APP"),TIME,MSGIEN_"^")=""
     57 I PARMS("STATUS")["E" D COUNT^HLOESTAT("OUT",PARMS("RECEIVING APP"),$$GETSAP(MSGIEN),$$GETMTYPE(MSGIEN))
     58 S:PARMS("ACCEPT ACK") $P(^HLB(MSGIEN,0),"^",17)=PARMS("ACCEPT ACK")
     59 S $P(^HLB(MSGIEN,0),"^",16)=TIME
     60 S:PARMS("MSA")]"" ^HLB(MSGIEN,4)=TIME_"^"_PARMS("MSA")
     61 I PARMS("PURGE TYPE"),PARMS("ACTION")="" D
     62 .;don't set purge if going on the infiler - let infiler do it
     63 .N PTIME
     64 .S:(PARMS("PURGE TYPE")=2) PTIME=$$FMADD^XLFDT(TIME,SYSTEM("ERROR PURGE")) ;error purge is in days
     65 .S:(PARMS("PURGE TYPE")'=2) PTIME=$$FMADD^XLFDT(TIME,,SYSTEM("NORMAL PURGE")) ;normal purge is in hours
     66 .S $P(^HLB(MSGIEN,0),"^",9)=PTIME,^HLB("AD","OUT",PTIME,MSGIEN)=""
     67 .I PARMS("ACK TO IEN"),$D(^HLB(PARMS("ACK TO IEN"),0)) S $P(^HLB(PARMS("ACK TO IEN"),0),"^",9)=PTIME,^HLB("AD","OUT",PTIME,PARMS("ACK TO IEN"))=""
     68 D:PARMS("ACTION")]""
     69 .N PURGE
     70 .S PURGE=$S(PARMS("PURGE TYPE"):1,1:0)
     71 .S:PARMS("ACK TO IEN") PURGE("ACKTOIEN")=PARMS("ACK TO IEN")
     72 .D INQUE^HLOQUE(PARMS("LINK"),PARMS("QUEUE"),MSGIEN,PARMS("ACTION"),.PURGE)
     73 Q
     74 ;
     75GETMSG(IEN,MSG) ;
     76 ;
     77 ;Description: given the message ien=MSGIEN (required), it returns the MSG array containing information about the message, defined below.
     78 ;Input:
     79 ;  IEN - the ien of the message in file 778
     80 ;Output:
     81 ;  Function returns 1 on success, 0 on failure
     82 ;  MSG (pass by reference, required) These are the subscripts returned:
     83 ;    "ACCEPT ACK RESPONSE" - if the sending app requested notification of the accept ack, this is the routine to perform
     84 ;    "ACKTOIEN" - if this is an app ack to a message not in a batch, this is the ien of the original message
     85 ;    "BATCH"  = 1 if this is a batch message, 0  if not
     86 ;    "CURRENT MESSAGE" - defined only for batch messages -  a counterused during building and parsing messages to indicate the current message.  It will be set to 0 initially.
     87 ;    "BODY" - ptr to file 778 which contains the body of the message.
     88 ;    "LINE COUNT" -  a counter used during writing of the
     89 ;     messages to indicate the current line. For
     90 ;     batch messages where each message within the batch is stored
     91 ;     separately, this field indicates the position within the current
     92 ;     individual message
     93 ;    "HDR" at these lower subscripts:
     94 ;       1    - components 1-6
     95 ;       2    - components 7-end
     96 ;       "ACCEPT ACK TYPE" = "AL" or "NE"
     97 ;       "APP ACK TYPE" = "AL" or "NE"
     98 ;       "MESSAGE CONTROL ID" - defined if NOT batch
     99 ;       "BATCH CONTROL ID" - defined if batch
     100 ;
     101 ;    "ID" - message id from the header
     102 ;    "IEN" - ien, file 778
     103 ;
     104 K MSG
     105 Q:'$G(IEN) 0
     106 N NODE,FS,CS,REP,SUBCOMP,ESCAPE
     107 S MSG("IEN")=IEN
     108 S NODE=$G(^HLB(IEN,0))
     109 S MSG("BODY")=$P(NODE,"^",2)
     110 S MSG("ID")=$P(NODE,"^")
     111 Q:'MSG("BODY") 0
     112 S MSG("STATUS","ACCEPTED")=$P(NODE,"^",17)
     113 S MSG("DT/TM")=$P(NODE,"^",16)
     114 S MSG("STATUS","QUEUE")=$P(NODE,"^",6)
     115 I MSG("STATUS","QUEUE")="" S MSG("STATUS","QUEUE")="DEFAULT"
     116 S MSG("ACCEPT ACK RESPONSE")=$P(NODE,"^",12,13)
     117 I MSG("ACCEPT ACK RESPONSE")="^" S MSG("ACCEPT ACK RESPONSE")=""
     118 ;
     119 S MSG("BATCH")=+$P($G(^HLA(MSG("BODY"),0)),"^",2)
     120 I MSG("BATCH") D
     121 .S MSG("BATCH","CURRENT MESSAGE")=0
     122 E  D
     123 .N ACKTO
     124 .S ACKTO=$P(NODE,"^",3)
     125 .I ACKTO]"" S ACKTO=$$ACKTOIEN^HLOMSG1(MSG("ID"),ACKTO)
     126 .I ACKTO,+ACKTO=ACKTO S MSG("ACK TO IEN")=ACKTO
     127 S MSG("LINE COUNT")=0
     128 S MSG("HDR",1)=$G(^HLB(IEN,1))
     129 S MSG("HDR",2)=$G(^HLB(IEN,2))
     130 S FS=$E(MSG("HDR",1),4)
     131 S CS=$E(MSG("HDR",1),5)
     132 S REP=$E(MSG("HDR",1),6)
     133 S ESCAPE=$E(MSG("HDR",1),7)
     134 S SUBCOMP=$E(MSG("HDR",1),8)
     135 S MSG("HDR","FIELD SEPARATOR")=FS
     136 S MSG("HDR","SENDING APPLICATION")=$$DESCAPE^HLOPRS1($P($P(MSG("HDR",1),FS,3),CS),FS,CS,SUBCOMP,REP,ESCAPE)
     137 S MSG("HDR","RECEIVING APPLICATION")=$$DESCAPE^HLOPRS1($P($P(MSG("HDR",1),FS,5),CS),FS,CS,SUBCOMP,REP,ESCAPE)
     138 I 'MSG("BATCH") D
     139 .S MSG("HDR","MESSAGE TYPE")=$P($P(MSG("HDR",2),FS,4),CS)
     140 .S MSG("HDR","EVENT")=$P($P(MSG("HDR",2),FS,4),CS,2)
     141 .S MSG("HDR","ACCEPT ACK TYPE")=$E($P(MSG("HDR",2),FS,10),1,2)
     142 .S MSG("HDR","APP ACK TYPE")=$E($P(MSG("HDR",2),FS,11),1,2)
     143 .S MSG("HDR","MESSAGE CONTROL ID")=MSG("ID")
     144 E  D
     145 .S MSG("HDR","BATCH CONTROL ID")=MSG("ID")
     146 .S MSG("HDR","ACCEPT ACK TYPE")=$E($P($P(MSG("HDR",2),FS,4),"ACCEPT ACK TYPE=",2),1,2)
     147 .S MSG("HDR","APP ACK TYPE")=$E($P($P(MSG("HDR",2),FS,4),"APP ACK TYPE=",2),1,2)
     148 Q 1
     149 ;
     150GETMTYPE(MSGIEN) ;returns <message type>~<event> OR "BATCH"
     151 Q:'$G(MSGIEN) "UNKNOWN"
     152 N FS,CS,HDR1,HDR2
     153 S HDR1=$G(^HLB(IEN,1))
     154 I $E(HDR1,1,3)="BHS" Q "BATCH"
     155 S HDR2=$G(^HLB(IEN,2))
     156 S FS=$E(HDR1,4)
     157 S CS=$E(HDR1,5)
     158 Q $P($P(HDR2,FS,4),CS)_"~"_$P($P(HDR2,FS,4),CS,2)
     159 ;
     160GETEVENT(MSGIEN) ; returns event if not a batch message
     161 Q:'$G(MSGIEN) ""
     162 N FS,CS,HDR1,HDR2
     163 S HDR1=$G(^HLB(MSGIEN,1))
     164 I $E(HDR1,1,3)="BHS" Q ""
     165 S HDR2=$G(^HLB(MSGIEN,2))
     166 S FS=$E(HDR1,4)
     167 S CS=$E(HDR1,5)
     168 Q $P($P(HDR2,FS,4),CS,2)
     169 ;
     170GETSAP(MSGIEN) ;
     171 ;
     172 ;
     173 Q:'$G(MSGIEN) "UNKNOWN"
     174 N FS,CS,HDR1,REP,ESCAPE,SUBCOMP
     175 S HDR1=$G(^HLB(MSGIEN,1))
     176 S FS=$E(HDR1,4)
     177 S CS=$E(HDR1,5)
     178 S REP=$E(HDR1,6)
     179 S ESCAPE=$E(HDR1,7)
     180 S SUBCOMP=$E(HDR1,8)
     181 Q $$DESCAPE^HLOPRS1($P($P(HDR1,FS,3),CS),FS,CS,SUBCOMP,REP,ESCAPE)
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOCLNT3.m

    r613 r623  
    1 HLOCLNT3        ;ALB/CJM- Updates messages missing application acks - 10/4/94 1pm ;07/10/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,130,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 DOWORK(WORK)    ;
    6         ;
    7         N CUTOFF,MSGIEN,QUIT,NOW,SYSTEM
    8         S NOW=$$NOW^XLFDT
    9         S QUIT=0
    10         D SYSPARMS^HLOSITE(.SYSTEM)
    11         S PURGE=$$FMADD^XLFDT($$NOW^XLFDT,,24*SYSTEM("ERROR PURGE"))
    12         ;
    13         ;7 day wait for an application ack is more than reasonable
    14         S CUTOFF=$$FMADD^XLFDT(NOW,-3)
    15         ;
    16         S MSGIEN=+$G(^HLTMP("LAST IEN CHECKED FOR MISSING APPLICATION ACK"))
    17         F  S MSGIEN=$O(^HLB(MSGIEN)) Q:'MSGIEN  Q:MSGIEN>99999999999  D  Q:QUIT
    18         .N MSG,HDR
    19         .Q:'$$GETMSG^HLOMSG(MSGIEN,.MSG)
    20         .Q:'MSG("DT/TM")
    21         .Q:'MSG("BODY")
    22         .I MSG("DT/TM")>CUTOFF S:MSG("DT/TM CREATED")>CUTOFF QUIT=1,MSGIEN=MSGIEN-1 Q
    23         .Q:MSG("STATUS")'=""
    24         .Q:MSG("DIRECTION")'="OUT"
    25         .Q:MSG("BATCH")
    26         .Q:MSG("STATUS","APP ACK'D")
    27         .;Q:MSG("STATUS","APP ACK RESPONSE")=""
    28         .;message has been in a non-complete status for a longtime, pending an application ack - set status to error and schedule for purging
    29         .S $P(^HLB(MSGIEN,0),"^",9)=PURGE
    30         .S ^HLB("AD","OUT",PURGE,MSGIEN)=""
    31         .S $P(^HLB(MSGIEN,0),"^",20)="ER"
    32         .S $P(^HLB(MSGIEN,0),"^",21)="MISSING APPLICATION ACKNOWLEDGMENT"
    33         .M HDR=MSG("HDR")
    34         .Q:'$$PARSEHDR^HLOPRS(.HDR)
    35         .S ^HLB("ERRORS",$S($L(HDR("RECEIVING APPLICATION")):HDR("RECEIVING APPLICATION"),1:"UNKNOWN"),NOW,MSGIEN)=""
    36         .D COUNT^HLOESTAT("OUT",HDR("RECEIVING APPLICATION"),HDR("SENDING APPLICATION"),$S(MSG("BATCH"):"BATCH",1:$G(HDR("MESSAGE TYPE"))),$G(HDR("EVENT")))
    37         S:MSGIEN>99999999999 MSGIEN=0
    38         S ^HLTMP("LAST IEN CHECKED FOR MISSING APPLICATION ACK")=MSGIEN
    39         Q
     1HLOCLNT3 ;ALB/CJM- Updates messages missing application acks - 10/4/94 1pm ;03/22/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,130,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5DOWORK(WORK) ;
     6 ;
     7 N CUTOFF,MSGIEN,QUIT,NOW,SYSTEM
     8 S NOW=$$NOW^XLFDT
     9 S QUIT=0
     10 D SYSPARMS^HLOSITE(.SYSTEM)
     11 S PURGE=$$FMADD^XLFDT($$NOW^XLFDT,,24*SYSTEM("ERROR PURGE"))
     12 ;
     13 ;7 day wait for an application ack is more than reasonable
     14 S CUTOFF=$$FMADD^XLFDT(NOW,-3)
     15 ;
     16 S MSGIEN=+$G(^HLTMP("LAST IEN CHECKED FOR MISSING APPLICATION ACK"))
     17 F  S MSGIEN=$O(^HLB(MSGIEN)) Q:'MSGIEN  Q:MSGIEN>99999999999  D  Q:QUIT
     18 .N MSG,HDR
     19 .Q:'$$GETMSG^HLOMSG(MSGIEN,.MSG)
     20 .Q:'MSG("DT/TM")
     21 .Q:'MSG("BODY")
     22 .I MSG("DT/TM")>CUTOFF S:MSG("DT/TM CREATED")>CUTOFF QUIT=1,MSGIEN=MSGIEN-1 Q
     23 .Q:MSG("STATUS")'=""
     24 .Q:MSG("DIRECTION")'="OUT"
     25 .Q:MSG("BATCH")
     26 .Q:MSG("STATUS","APP ACK'D")
     27 .;Q:MSG("STATUS","APP ACK RESPONSE")=""
     28 .;message has been in a non-complete status for a longtime, pending an application ack - set status to error and schedule for purging
     29 .S $P(^HLB(MSGIEN,0),"^",9)=PURGE
     30 .S ^HLB("AD","OUT",PURGE,MSGIEN)=""
     31 .S $P(^HLB(MSGIEN,0),"^",20)="AE"
     32 .S $P(^HLB(MSGIEN,0),"^",21)="MISSING APPLICATION ACKNOWLEDGMENT"
     33 .M HDR=MSG("HDR")
     34 .Q:'$$PARSEHDR^HLOPRS(.HDR)
     35 .S ^HLB("ERRORS","AE",$S($L(HDR("RECEIVING APPLICATION")):HDR("RECEIVING APPLICATION"),1:"UNKNOWN"),NOW,MSGIEN)=""
     36 .D COUNT^HLOESTAT("OUT",HDR("RECEIVING APPLICATION"),HDR("SENDING APPLICATION"),$S(MSG("BATCH"):"BATCH",1:$G(HDR("MESSAGE TYPE"))),$G(HDR("EVENT")))
     37 S:MSGIEN>99999999999 MSGIEN=0
     38 S ^HLTMP("LAST IEN CHECKED FOR MISSING APPLICATION ACK")=MSGIEN
     39 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOCNRT.m

    r613 r623  
    1 HLOCNRT ;DAOU/ALA-Generate HL7 Optimized Message ;07/24/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,132,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;**Program Description**
    6         ;  This program takes a current HL7 1.6 message and converts
    7         ;  it to use the new HL Optimized code if it follows the standard
    8         ;  1.6 methodology of protocols.
    9         ;
    10         ;  **If the VistA HL7 Protocol does not exist, calls to HL Optimized
    11         ;  will have to be coded separately and this program cannot be used**
    12         Q
    13         ;
    14 EN(HLOPRTCL,ARYTYP,HLP,HLL,RESULT)      ;Entry Point
    15         ;  Input Parameters
    16         ;   HLOPRTCL = Protocol IEN or Protocol Name
    17         ;   ARYTYP = The array where HL7 message resides
    18         ;   HLP = Additional HL7 message parameters (optional, pass by reference)
    19         ;        These optional subscripts to HLP are supported for input:
    20         ;             "APP ACK RESPONSE" = <tag^routine> to call when the app ack is received
    21         ;             "CONTPTR"
    22         ;             "SECURITY"
    23         ;             "SEQUENCE QUEUE" - queue used to maintain the order of the messages via application acks.  If used, the application MUST specify that both an accept ack and application ack be returned.
    24         ;       
    25         ;   HLL  (optional, pass by reference) Additional message recipients being dynamically added
    26         ;
    27         ;  Output
    28         ;    RESULT (pass-by-reference)=<subscriber protocol ien>^<link ien>^<message id>^<0 if sucess, error code if failure>^<optional error message>
    29         ;             If the message was sent to more than 1 destination,
    30         ;             the addtional mssage ids returned as RESULT(1), RESULT(2), etc.
    31         ;    ZTSTOP = Stop processing flag (used by HDR)
    32         ;    Function returns 1 on success, else returns an error message
    33         ;
    34         NEW HLORESL,HLMSTATE,APPARMS,WHOTO,ERROR,WHO
    35         S ZTSTOP=0,HLORESL=1,RESULT=""
    36         ;
    37         ;  Get IEN of protocol if name is passed
    38         I '$L(HLOPRTCL) S HLORESL="^99^HL7 1.6 Protocol not found",RESULT="^^"_HLORESL,ZTSTOP=1 Q HLORESL
    39         I ('HLOPRTCL)!(HLOPRTCL'=+HLOPRTCL) S HLOPRTCL=+$O(^ORD(101,"B",HLOPRTCL,0))
    40         I 'HLOPRTCL S HLORESL="^99^HL7 1.6 Protocol not found",RESULT="^^"_HLORESL,ZTSTOP=1 Q HLORESL
    41         I '$D(^ORD(101,HLOPRTCL)) S HLORESL="^99^HL7 1.6 Protocol not found",RESULT="^^"_HLORESL,ZTSTOP=1 Q HLORESL
    42         ;
    43         ;  If the VistA HL7 Protocol exists, call the Conversion Utility
    44         ;  to set up the APPARMS, WHOTO arrays from protocol logical link,
    45         ;   and the optional HLL and HLP arrays
    46         D APAR^HLOCVU(HLOPRTCL,.APPARMS,.WHO,.WHOTO,.HLP,.HLL)
    47         ;
    48         ; If special HLP parameters are defined, convert them
    49         I $D(HLP) D
    50         . I $G(HLP("SECURITY"))'="" S APPARMS("SECURITY")=HLP("SECURITY")
    51         . I $G(HLP("CONTPTR"))'="" S APPARMS("CONTINUATION POINTER")=HLP("CONTPTR")
    52         . I $G(HLP("QUEUE"))'="" S APPARMS("QUEUE")=HLP("QUEUE")
    53         . I $G(HLP("SEQUENCE QUEUE"))'="" S APPARMS("SEQUENCE QUEUE")=HLP("SEQUENCE QUEUE")
    54         . I $G(HLP("APP ACK RESPONSE"))'="" S APPARMS("APP ACK RESPONSE")=HLP("APP ACK RESPONSE")
    55         ;
    56         ;  Create HL Optimized message
    57         I '$$NEWMSG^HLOAPI(.APPARMS,.HLMSTATE,.ERROR) S HLORESL="^99^"_ERROR,ZTSTOP=1,RESULT="^^"_HLORESL Q HLORESL
    58         I $E(ARYTYP,1)="G" S HLOMESG="^TMP(""HLS"",$J)"
    59         I $E(ARYTYP,1)="L" S HLOMESG="HLA(""HLS"")"
    60         ;
    61         ;  Move the existing message from array into HL Optimized
    62         D MOVEMSG^HLOAPI(.HLMSTATE,HLOMESG)
    63         ;
    64         ;  Send message via HL Optimized
    65         I $D(WHOTO) D
    66         .N COUNT
    67         .I '$$SENDMANY^HLOAPI1(.HLMSTATE,.APPARMS,.WHOTO) D
    68         ..S HLORESL="^99^Unable to send message",ZTSTOP=1
    69         .I $G(WHOTO(1,"IEN")) D
    70         ..S RESULT=WHO(1)_"^"_$P($G(^HLB(WHOTO(1,"IEN"),0)),"^")_"^"_$S($G(WHOTO(1,"QUEUED")):0,1:1)_"^"_$G(WHOTO(1,"ERROR"))
    71         .E  D
    72         ..S RESULT=WH0(1)_"^^1^"_$G(WHOTO(1,"ERROR"))
    73         ..S HLORESL="^99^"_$G(WHOTO(1,"ERROR")),ZTSTOP=1
    74         .S COUNT=1
    75         .F  S COUNT=$O(WHOTO(COUNT)) Q:'COUNT  D
    76         ..I $G(WHOTO(COUNT,"IEN")) D
    77         ...S RESULT(COUNT-1)=WHO(COUNT)_"^"_$P($G(^HLB(WHOTO(COUNT,"IEN"),0)),"^")_"^"_$S($G(WHOTO(COUNT,"QUEUED")):0,1:1)_"^"_$G(WHOTO(COUNT,"ERROR"))
    78         ..E  D
    79         ...S RESULT(COUNT-1)=WH0(COUNT)_"^^1^"_$G(WHOTO(COUNT,"ERROR"))
    80         ;
    81         E  S HLORESL="^99^Unable to send message",ZTSTOP=1,RESULT="^^"_HLORESL
    82         Q HLORESL
     1HLOCNRT ;DAOU/ALA-Generate HL7 Optimized Message ;03/15/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,132,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ;**Program Description**
     6 ;  This program takes a current HL7 1.6 message and converts
     7 ;  it to use the new HL Optimized code if it follows the standard
     8 ;  1.6 methodology of protocols.
     9 ;
     10 ;  **If the VistA HL7 Protocol does not exist, calls to HL Optimized
     11 ;  will have to be coded separately and this program cannot be used**
     12 Q
     13 ;
     14EN(HLOPRTCL,ARYTYP,HLP,HLL,RESULT) ;Entry Point
     15 ;  Input Parameters
     16 ;   HLOPRTCL = Protocol IEN or Protocol Name
     17 ;   ARYTYP = The array where HL7 message resides
     18 ;   HLP = Additional HL7 message parameters (optional, pass by reference)
     19 ;        These optional subscripts to HLL are supported for input:
     20 ;             "SECURITY"
     21 ;              "CONTPTR"
     22 ;              "APP ACK RESPONSE" = <tag^routine> to call when the app ack is received
     23 ;       
     24 ;   HLL  (optional, pass by reference) Additional message recipients being dynamically added
     25 ;
     26 ;  Output
     27 ;    RESULT (pass-by-reference)=<subscriber protocol ien>^<link ien>^<message id>^<0 if sucess, error code if failure>^<optional error message>
     28 ;             If the message was sent to more than 1 destination,
     29 ;             the addtional mssage ids returned as RESULT(1), RESULT(2), etc.
     30 ;    ZTSTOP = Stop processing flag (used by HDR)
     31 ;    Function returns 1 on success, else returns an error message
     32 ;
     33 NEW HLORESL,HLMSTATE,APPARMS,WHOTO,ERROR,WHO
     34 S ZTSTOP=0,HLORESL=1,RESULT=""
     35 ;
     36 ;  Get IEN of protocol if name is passed
     37 I '$L(HLOPRTCL) S HLORESL="^99^HL7 1.6 Protocol not found",RESULT="^^"_HLORESL,ZTSTOP=1 Q HLORESL
     38 I ('HLOPRTCL)!(HLOPRTCL'=+HLOPRTCL) S HLOPRTCL=+$O(^ORD(101,"B",HLOPRTCL,0))
     39 I 'HLOPRTCL S HLORESL="^99^HL7 1.6 Protocol not found",RESULT="^^"_HLORESL,ZTSTOP=1 Q HLORESL
     40 I '$D(^ORD(101,HLOPRTCL)) S HLORESL="^99^HL7 1.6 Protocol not found",RESULT="^^"_HLORESL,ZTSTOP=1 Q HLORESL
     41 ;
     42 ;  If the VistA HL7 Protocol exists, call the Conversion Utility
     43 ;  to set up the APPARMS, WHOTO arrays from protocol logical link,
     44 ;   and the optional HLL and HLP arrays
     45 D APAR^HLOCVU(HLOPRTCL,.APPARMS,.WHO,.WHOTO,.HLP,.HLL)
     46 ;
     47 ; If special HLP parameters are defined, convert them
     48 I $D(HLP) D
     49 . I $G(HLP("SECURITY"))'="" S APPARMS("SECURITY")=HLP("SECURITY")
     50 . I $G(HLP("CONTPTR"))'="" S APPARMS("CONTINUATION POINTER")=HLP("CONTPTR")
     51 . I $G(HLP("QUEUE"))'="" S APPARMS("QUEUE")=HLP("QUEUE")
     52 . I $G(HLP("APP ACK RESPONSE"))'="" S APPARMS("APP ACK RESPONSE")=HLP("APP ACK RESPONSE")
     53 ;
     54 ;  Create HL Optimized message
     55 I '$$NEWMSG^HLOAPI(.APPARMS,.HLMSTATE,.ERROR) S HLORESL="^99^"_ERROR,ZTSTOP=1,RESULT="^^"_HLORESL Q HLORESL
     56 I $E(ARYTYP,1)="G" S HLOMESG="^TMP(""HLS"",$J)"
     57 I $E(ARYTYP,1)="L" S HLOMESG="HLA(""HLS"")"
     58 ;
     59 ;  Move the existing message from array into HL Optimized
     60 D MOVEMSG^HLOAPI(.HLMSTATE,HLOMESG)
     61 ;
     62 ;  Send message via HL Optimized
     63 I $D(WHOTO) D
     64 .N COUNT
     65 .I '$$SENDMANY^HLOAPI1(.HLMSTATE,.APPARMS,.WHOTO) D
     66 ..S HLORESL="^99^Unable to send message",ZTSTOP=1
     67 .I $G(WHOTO(1,"IEN")) D
     68 ..S RESULT=WHO(1)_"^"_$P($G(^HLB(WHOTO(1,"IEN"),0)),"^")_"^"_$S($G(WHOTO(1,"QUEUED")):0,1:1)_"^"_$G(WHOTO(1,"ERROR"))
     69 .E  D
     70 ..S RESULT=WH0(1)_"^^1^"_$G(WHOTO(1,"ERROR"))
     71 ..S HLORESL="^99^"_$G(WHOTO(1,"ERROR")),ZTSTOP=1
     72 .S COUNT=1
     73 .F  S COUNT=$O(WHOTO(COUNT)) Q:'COUNT  D
     74 ..I $G(WHOTO(COUNT,"IEN")) D
     75 ...S RESULT(COUNT-1)=WHO(COUNT)_"^"_$P($G(^HLB(WHOTO(COUNT,"IEN"),0)),"^")_"^"_$S($G(WHOTO(COUNT,"QUEUED")):0,1:1)_"^"_$G(WHOTO(COUNT,"ERROR"))
     76 ..E  D
     77 ...S RESULT(COUNT-1)=WH0(COUNT)_"^^1^"_$G(WHOTO(COUNT,"ERROR"))
     78 ;
     79 E  S HLORESL="^99^Unable to send message",ZTSTOP=1,RESULT="^^"_HLORESL
     80 Q HLORESL
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOF778.m

    r613 r623  
    1 HLOF778 ;ALB/CJM-HL7 - Saving messages to file 778 ;07/10/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;
    6 SAVEMSG(HLMSTATE)       ;
    7         ;If a record has not yet been created in file 778, then it will be created. Will file any segments into 777 not yet stored.  For batch messages, will store the MSH segments in 778 as the individual messages are stored in 777.
    8         ;Input:
    9         ;  HLMSTATE (pass by reference) - contains information about the message
    10         ;    These subscripts must be defined:
    11         ;  ("BATCH")=1 if batch, 0 otherwise
    12         ;  ("BATCH","BTS")=BTS segment if end of batch reached
    13         ;  ("BODY")=ien file 777 if stored
    14         ;  ("DIRECTION")=<"IN" or "OUT">
    15         ;  ("IEN")=ien,file 778 if stored
    16         ;  ("UNSTORED LINES") - count of lines to be stored.  The lines are at the a lower subscript level <msg>,<segment>,<line>=<line to be stored>
    17         ;  ("UNSTORED MSH") For batch messages, set to 1 if there are MSH in cache. Cached MSH at ("UNSTORED MSH",<subfile ien>,<1 & 2>)
    18         ;
    19         ;Output:
    20         ;  Function - returns the ien of the msg (file 778)
    21         ;  HLMSTATE
    22         ;   ("BODY") - set to ien, file 777 if newly created
    23         ;   ("IEN") - set to ien, file 778 if newly created
    24         ;   ("UNSTORED LINES")-set to 0 as this function will store them
    25         ;   ("UNSTORED MSH")- set to 0 as this function will store it
    26         ;
    27         ;
    28         I '$D(HLMSTATE("DT/TM")) S HLMSTATE("DT/TM")=$S(HLMSTATE("DIRECTION")="IN":$$NOW^XLFDT,1:"")
    29         ;
    30         ;insure that 777 entry created & all segments stored
    31         I ('HLMSTATE("BODY"))!($G(HLMSTATE("UNSTORED LINES")))!($L($G(HLMSTATE("BATCH","BTS")))),'$$SAVEMSG^HLOF777(.HLMSTATE) Q 0
    32         ;
    33         ;insure 778 entry created
    34         I 'HLMSTATE("IEN") Q:'$$NEW^HLOF778A(.HLMSTATE) 0
    35         ;
    36         ;for batch messages, store MSH segments in 778
    37         I HLMSTATE("BATCH") D
    38         .N IEN S IEN=HLMSTATE("IEN")
    39         .;
    40         .;incoming messages cache the MSH segments in memory
    41         .I HLMSTATE("DIRECTION")="IN",HLMSTATE("UNSTORED MSH") D
    42         ..N ORDER S ORDER=0
    43         ..F  S ORDER=$O(HLMSTATE("UNSTORED MSH",ORDER)) Q:'ORDER  D
    44         ...N FS,MSGID
    45         ...S FS=$E(HLMSTATE("UNSTORED MSH",ORDER,1),4)
    46         ...S MSGID=$P(HLMSTATE("UNSTORED MSH",ORDER,2),FS,5)
    47         ...S ^HLB(IEN,3,ORDER,0)=ORDER_"^"_MSGID_"^"_$G(HLMSTATE("BATCH","ACK TO",ORDER))
    48         ...S ^HLB(IEN,3,ORDER,1)=HLMSTATE("UNSTORED MSH",ORDER,1)
    49         ...S ^HLB(IEN,3,ORDER,2)=HLMSTATE("UNSTORED MSH",ORDER,2)
    50         ...S ^HLB(IEN,3,"B",ORDER,ORDER)=""
    51         ...I MSGID]"" S ^HLB("AE",MSGID,IEN_"^"_ORDER)="" ;whole file index for individual message id
    52         ..K HLMSTATE("UNSTORED MSH") S HLMSTATE("UNSTORED MSH")=0
    53         .;
    54         .;
    55         .I HLMSTATE("DIRECTION")="OUT" D
    56         ..;must build the MSH segments!
    57         ..N HDR,FS,MSG,CS
    58         ..S FS=HLMSTATE("HDR","FIELD SEPARATOR")
    59         ..S CS=$E(HLMSTATE("HDR","ENCODING CHARACTERS"),1)
    60         ..S HLMSTATE("HDR","MESSAGE TYPE")="   "
    61         ..S HLMSTATE("HDR","EVENT")="   "
    62         ..D BUILDHDR^HLOPBLD1(.HLMSTATE,"MSH",.HDR)
    63         ..S HLMSTATE("BATCH","CURRENT MESSAGE")=$O(^HLB(HLMSTATE("IEN"),3,"B",";"),-1)
    64         ..F  Q:'$$NEXTMSG(.HLMSTATE,.MSG)  D
    65         ...N MSGID,CUR
    66         ...S CUR=HLMSTATE("BATCH","CURRENT MESSAGE")
    67         ...S MSGID=HLMSTATE("HDR","BATCH CONTROL ID")_"-"_CUR
    68         ...S $P(HDR(2),FS,4)=MSG("MESSAGE TYPE")_CS_MSG("EVENT")
    69         ...S $P(HDR(2),FS,5)=MSGID
    70         ...S ^HLB(IEN,3,CUR,0)=CUR_"^"_MSGID_"^"_$G(HLMSTATE("BATCH","ACK TO",CUR))
    71         ...S ^HLB(IEN,3,CUR,1)=HDR(1)
    72         ...S ^HLB(IEN,3,CUR,2)=HDR(2)
    73         ...S ^HLB(IEN,3,"B",CUR,CUR)=""
    74         ...S ^HLB("AE",MSGID,IEN_"^"_CUR)="" ;whole file index for individual message id
    75         ..;
    76         .;if the messages are application acks, then update the original message
    77         .N SUBIEN S SUBIEN=0
    78         .F  S SUBIEN=$O(HLMSTATE("BATCH","ACK TO",SUBIEN)) Q:'SUBIEN  I $G(HLMSTATE("BATCH","ACK TO",SUBIEN,"IEN"))]"" D
    79         ..N ACKTO
    80         ..M ACKTO=HLMSTATE("BATCH","ACK TO",SUBIEN)
    81         ..;
    82         ..;for outgoing msgs, we just created the msgid, for incoming msgs we already had it
    83         ..S:HLMSTATE("DIRECTION")="OUT" ACKTO("ACK BY")=HLMSTATE("HDR","BATCH CONTROL ID")_"-"_SUBIEN
    84         ..;
    85         ..D ACKTO(.HLMSTATE,.ACKTO)
    86         .K HLMSTATE("BATCH","ACK TO")
    87         ;
    88         ;if the msg is an app ack, update the original if not done already
    89         I $G(HLMSTATE("ACK TO","IEN"))]"",'$G(HLMSTATE("ACK TO","DONE")) D
    90         .N ACKTO
    91         .M ACKTO=HLMSTATE("ACK TO")
    92         .S ACKTO("ACK BY")=$S(HLMSTATE("BATCH"):HLMSTATE("HDR","BATCH CONTROL ID"),1:HLMSTATE("HDR","MESSAGE CONTROL ID"))
    93         .D ACKTO(.HLMSTATE,.ACKTO)
    94         .S HLMSTATE("ACK TO","DONE")=1 ;so the update isn't done again
    95         ;
    96         Q HLMSTATE("IEN")
    97         ;
    98 NEXTMSG(HLMSTATE,MSG)   ;
    99         ;Traverses file 777 to return the next message in the batch - as
    100         ;indicated by HLMSTATE("BATCH","CURRENT MESSAGE")  Set to 0 to start,
    101         ;returns 0 when there are no more messages
    102         ;
    103         ;Input:  HLMSTATE (pass by reference,required)
    104         ;Output:
    105         ;  HLMSTATE
    106         ;     ("BATCH","CURRENT MESSAGE")
    107         ;  MSG -pass by reference:
    108         ;     ("EVENT")
    109         ;     ("MESSAGE TYPE")
    110         ;
    111         ;
    112         N SUBIEN,NODE
    113         K MSG
    114         Q:'$G(HLMSTATE("BODY")) 0
    115         S SUBIEN=$O(^HLA(HLMSTATE("BODY"),2,HLMSTATE("BATCH","CURRENT MESSAGE")))
    116         Q:'SUBIEN 0
    117         S NODE=$G(^HLA(HLMSTATE("BODY"),2,SUBIEN,0))
    118         S MSG("MESSAGE TYPE")=$P(NODE,"^",2)
    119         S MSG("EVENT")=$P(NODE,"^",3)
    120         S HLMSTATE("BATCH","CURRENT MESSAGE")=SUBIEN
    121         Q SUBIEN
    122         ;
    123 ACKTO(HLMSTATE,ACKTO)   ;if this is an application ack, update the original message - but do not overlay if already valued
    124         ;ACKTO = (msgid of msg being ack'd)
    125         ;        uses these subscripts ("IEN"=ien^subien),("ACK BY"=msgid of acking msg),("STATUS"=status for the initial msg determined by the ack)
    126         ;
    127         N STATUS,IEN,SUBIEN,NODE,SKIP
    128         S SKIP=0
    129         S STATUS=$G(ACKTO("STATUS"))
    130         S IEN=+ACKTO("IEN"),SUBIEN=$P(ACKTO("IEN"),"^",2)
    131         S NODE=$G(^HLB(IEN,0))
    132         I 'SUBIEN D
    133         .;ack is to a message NOT in a batch
    134         .I $P(NODE,"^",7)'="",$P(NODE,"^",7)'=ACKTO("ACK BY") S SKIP=1 Q
    135         .I STATUS="" S STATUS="SU"
    136         .S $P(NODE,"^",7)=ACKTO("ACK BY")
    137         .S $P(NODE,"^",20)=STATUS
    138         .S $P(NODE,"^",21)=$G(ACKTO("ERROR TEXT"))
    139         .S ^HLB(IEN,0)=NODE
    140         E  D
    141         .;ack is to a message that IS in a batch
    142         .S $P(^HLB(IEN,3,SUBIEN,0),"^",4)=$G(ACKTO("ACK BY"))
    143         .S $P(^HLB(IEN,3,SUBIEN,0),"^",5)=STATUS
    144         I (STATUS="ER"),'SKIP D
    145         .N APP
    146         .S APP=HLMSTATE("HDR","RECEIVING APPLICATION")
    147         .I APP="" S APP="UNKNOWN"
    148         .S ^HLB("ERRORS",APP,$$NOW^XLFDT,ACKTO("IEN"))=""
    149         .;don't count the error - the app ack was already counted as an error.
    150         .D COUNT^HLOESTAT("IN",$G(HLMSTATE("HDR","RECEIVING APPLICATION")),$G(HLMSTATE("HDR","SENDING APPLICATION")),$S(HLMSTATE("BATCH"):"BATCH",1:$G(HLMSTATE("HDR","MESSAGE TYPE"))),$G(HLMSTATE("HDR","EVENT")))
    151         Q
     1HLOF778 ;ALB/CJM-HL7 - Saving messages to file 778 ;03/15/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ;
     6SAVEMSG(HLMSTATE) ;
     7 ;If a record has not yet been created in file 778, then it will be created. Will file any segments into 777 not yet stored.  For batch messages, will store the MSH segments in 778 as the individual messages are stored in 777.
     8 ;Input:
     9 ;  HLMSTATE (pass by reference) - contains information about the message
     10 ;    These subscripts must be defined:
     11 ;  ("BATCH")=1 if batch, 0 otherwise
     12 ;  ("BATCH","BTS")=BTS segment if end of batch reached
     13 ;  ("BODY")=ien file 777 if stored
     14 ;  ("DIRECTION")=<"IN" or "OUT">
     15 ;  ("IEN")=ien,file 778 if stored
     16 ;  ("UNSTORED LINES") - count of lines to be stored.  The lines are at the a lower subscript level <msg>,<segment>,<line>=<line to be stored>
     17 ;  ("UNSTORED MSH") For batch messages, set to 1 if there are MSH in cache. Cached MSH at ("UNSTORED MSH",<subfile ien>,<1 & 2>)
     18 ;
     19 ;Output:
     20 ;  Function - returns the ien of the msg (file 778)
     21 ;  HLMSTATE
     22 ;   ("BODY") - set to ien, file 777 if newly created
     23 ;   ("IEN") - set to ien, file 778 if newly created
     24 ;   ("UNSTORED LINES")-set to 0 as this function will store them
     25 ;   ("UNSTORED MSH")- set to 0 as this function will store it
     26 ;
     27 ;
     28 I '$D(HLMSTATE("DT/TM")) S HLMSTATE("DT/TM")=$S(HLMSTATE("DIRECTION")="IN":$$NOW^XLFDT,1:"")
     29 ;
     30 ;insure that 777 entry created & all segments stored
     31 I ('HLMSTATE("BODY"))!($G(HLMSTATE("UNSTORED LINES")))!($L($G(HLMSTATE("BATCH","BTS")))),'$$SAVEMSG^HLOF777(.HLMSTATE) Q 0
     32 ;
     33 ;insure 778 entry created
     34 I 'HLMSTATE("IEN") Q:'$$NEW^HLOF778A(.HLMSTATE) 0
     35 ;
     36 ;for batch messages, store MSH segments in 778
     37 I HLMSTATE("BATCH") D
     38 .N IEN S IEN=HLMSTATE("IEN")
     39 .;
     40 .;incoming messages cache the MSH segments in memory
     41 .I HLMSTATE("DIRECTION")="IN",HLMSTATE("UNSTORED MSH") D
     42 ..N ORDER S ORDER=0
     43 ..F  S ORDER=$O(HLMSTATE("UNSTORED MSH",ORDER)) Q:'ORDER  D
     44 ...N FS,MSGID
     45 ...S FS=$E(HLMSTATE("UNSTORED MSH",ORDER,1),4)
     46 ...S MSGID=$P(HLMSTATE("UNSTORED MSH",ORDER,2),FS,5)
     47 ...S ^HLB(IEN,3,ORDER,0)=ORDER_"^"_MSGID_"^"_$G(HLMSTATE("BATCH","ACK TO",ORDER))
     48 ...S ^HLB(IEN,3,ORDER,1)=HLMSTATE("UNSTORED MSH",ORDER,1)
     49 ...S ^HLB(IEN,3,ORDER,2)=HLMSTATE("UNSTORED MSH",ORDER,2)
     50 ...S ^HLB(IEN,3,"B",ORDER,ORDER)=""
     51 ...I MSGID]"" S ^HLB("AE",MSGID,IEN_"^"_ORDER)="" ;whole file index for individual message id
     52 ..K HLMSTATE("UNSTORED MSH") S HLMSTATE("UNSTORED MSH")=0
     53 .;
     54 .;
     55 .I HLMSTATE("DIRECTION")="OUT" D
     56 ..;must build the MSH segments!
     57 ..N HDR,FS,MSG,CS
     58 ..S FS=HLMSTATE("HDR","FIELD SEPARATOR")
     59 ..S CS=$E(HLMSTATE("HDR","ENCODING CHARACTERS"),1)
     60 ..S HLMSTATE("HDR","MESSAGE TYPE")="   "
     61 ..S HLMSTATE("HDR","EVENT")="   "
     62 ..D BUILDHDR^HLOPBLD1(.HLMSTATE,"MSH",.HDR)
     63 ..S HLMSTATE("BATCH","CURRENT MESSAGE")=$O(^HLB(HLMSTATE("IEN"),3,"B",";"),-1)
     64 ..F  Q:'$$NEXTMSG(.HLMSTATE,.MSG)  D
     65 ...N MSGID,CUR
     66 ...S CUR=HLMSTATE("BATCH","CURRENT MESSAGE")
     67 ...S MSGID=HLMSTATE("HDR","BATCH CONTROL ID")_"-"_CUR
     68 ...S $P(HDR(2),FS,4)=MSG("MESSAGE TYPE")_CS_MSG("EVENT")
     69 ...S $P(HDR(2),FS,5)=MSGID
     70 ...S ^HLB(IEN,3,CUR,0)=CUR_"^"_MSGID_"^"_$G(HLMSTATE("BATCH","ACK TO",CUR))
     71 ...S ^HLB(IEN,3,CUR,1)=HDR(1)
     72 ...S ^HLB(IEN,3,CUR,2)=HDR(2)
     73 ...S ^HLB(IEN,3,"B",CUR,CUR)=""
     74 ...S ^HLB("AE",MSGID,IEN_"^"_CUR)="" ;whole file index for individual message id
     75 ..;
     76 .;if the messages are application acks, then update the original message
     77 .N SUBIEN S SUBIEN=0
     78 .F  S SUBIEN=$O(HLMSTATE("BATCH","ACK TO",SUBIEN)) Q:'SUBIEN  I $G(HLMSTATE("BATCH","ACK TO",SUBIEN,"IEN"))]"" D
     79 ..N ACKTO
     80 ..M ACKTO=HLMSTATE("BATCH","ACK TO",SUBIEN)
     81 ..;
     82 ..;for outgoing msgs, we just created the msgid, for incoming msgs we already had it
     83 ..S:HLMSTATE("DIRECTION")="OUT" ACKTO("ACK BY")=HLMSTATE("HDR","BATCH CONTROL ID")_"-"_SUBIEN
     84 ..;
     85 ..D ACKTO(.HLMSTATE,.ACKTO)
     86 .K HLMSTATE("BATCH","ACK TO")
     87 ;
     88 ;if the msg is an app ack, update the original if not done already
     89 I $G(HLMSTATE("ACK TO","IEN"))]"",'$G(HLMSTATE("ACK TO","DONE")) D
     90 .N ACKTO
     91 .M ACKTO=HLMSTATE("ACK TO")
     92 .S ACKTO("ACK BY")=$S(HLMSTATE("BATCH"):HLMSTATE("HDR","BATCH CONTROL ID"),1:HLMSTATE("HDR","MESSAGE CONTROL ID"))
     93 .D ACKTO(.HLMSTATE,.ACKTO)
     94 .S HLMSTATE("ACK TO","DONE")=1 ;so the update isn't done again
     95 ;
     96 Q HLMSTATE("IEN")
     97 ;
     98NEXTMSG(HLMSTATE,MSG) ;
     99 ;Traverses file 777 to return the next message in the batch - as
     100 ;indicated by HLMSTATE("BATCH","CURRENT MESSAGE")  Set to 0 to start,
     101 ;returns 0 when there are no more messages
     102 ;
     103 ;Input:  HLMSTATE (pass by reference,required)
     104 ;Output:
     105 ;  HLMSTATE
     106 ;     ("BATCH","CURRENT MESSAGE")
     107 ;  MSG -pass by reference:
     108 ;     ("EVENT")
     109 ;     ("MESSAGE TYPE")
     110 ;
     111 ;
     112 N SUBIEN,NODE
     113 K MSG
     114 Q:'$G(HLMSTATE("BODY")) 0
     115 S SUBIEN=$O(^HLA(HLMSTATE("BODY"),2,HLMSTATE("BATCH","CURRENT MESSAGE")))
     116 Q:'SUBIEN 0
     117 S NODE=$G(^HLA(HLMSTATE("BODY"),2,SUBIEN,0))
     118 S MSG("MESSAGE TYPE")=$P(NODE,"^",2)
     119 S MSG("EVENT")=$P(NODE,"^",3)
     120 S HLMSTATE("BATCH","CURRENT MESSAGE")=SUBIEN
     121 Q SUBIEN
     122 ;
     123ACKTO(HLMSTATE,ACKTO) ;if this is an application ack, update the original message - but do not overlay if already valued
     124 ;ACKTO = (msgid of msg being ack'd)
     125 ;        uses these subscripts ("IEN"=ien^subien),("ACK BY"=msgid of acking msg),("STATUS"=status for the initial msg determined by the ack)
     126 ;
     127 N STATUS,IEN,SUBIEN,NODE,SKIP
     128 S SKIP=0
     129 S STATUS=$G(ACKTO("STATUS"))
     130 S IEN=+ACKTO("IEN"),SUBIEN=$P(ACKTO("IEN"),"^",2)
     131 S NODE=$G(^HLB(IEN,0))
     132 I 'SUBIEN D
     133 .;ack is to a message NOT in a batch
     134 .I $P(NODE,"^",7)'="",$P(NODE,"^",7)'=ACKTO("ACK BY") S SKIP=1 Q
     135 .I STATUS="" S STATUS="SU"
     136 .S $P(NODE,"^",7)=ACKTO("ACK BY")
     137 .S $P(NODE,"^",20)=STATUS
     138 .S $P(NODE,"^",21)=$G(ACKTO("ERROR TEXT"))
     139 .S ^HLB(IEN,0)=NODE
     140 E  D
     141 .;ack is to a message that IS in a batch
     142 .S $P(^HLB(IEN,3,SUBIEN,0),"^",4)=$G(ACKTO("ACK BY"))
     143 .S $P(^HLB(IEN,3,SUBIEN,0),"^",5)=STATUS
     144 I (STATUS="AE"),'SKIP D
     145 .N APP
     146 .S APP=HLMSTATE("HDR","SENDING APPLICATION")
     147 .I APP="" S APP="UNKNOWN"
     148 .S ^HLB("ERRORS","AE",APP,$$NOW^XLFDT,ACKTO("IEN"))=""
     149 .;don't count the error - the app ack was already counted as an error.
     150 .D COUNT^HLOESTAT("IN",$G(HLMSTATE("HDR","RECEIVING APPLICATION")),$G(HLMSTATE("HDR","SENDING APPLICATION")),$S(HLMSTATE("BATCH"):"BATCH",1:$G(HLMSTATE("HDR","MESSAGE TYPE"))),$G(HLMSTATE("HDR","EVENT")))
     151 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOF778A.m

    r613 r623  
    1 HLOF778A        ;ALB/CJM-HL7 - Saving messages to file 778 (continued) ;07/10/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;
    6 NEW(HLMSTATE)   ;
    7         ;This function creates a new entry in file 778.
    8         ;Input:
    9         ;   HLMSTATE (required, pass by reference) These subscripts are expected:
    10         ;
    11         ;Output - the function returns the ien of the newly created record
    12         ;
    13         N IEN,NODE,ID,STAT
    14         S STAT="HLMSTATE(""STATUS"")"
    15         S IEN=$$NEWIEN(HLMSTATE("DIRECTION"),$$TCP)
    16         Q:'IEN 0
    17         S HLMSTATE("IEN")=IEN
    18         ;
    19         D  ;build the message header
    20         .N HDR
    21         .;for incoming messages the header segment should already exist
    22         .;for outgoing messages must build the header segment
    23         .I HLMSTATE("DIRECTION")="OUT" D  Q
    24         ..I HLMSTATE("BATCH"),$G(HLMSTATE("ACK TO"))]"" S HLMSTATE("HDR","REFERENCE BATCH CONTROL ID")=HLMSTATE("ACK TO")
    25         ..D BUILDHDR^HLOPBLD1(.HLMSTATE,$S(HLMSTATE("BATCH"):"BHS",1:"MSH"),.HDR)
    26         ..S HLMSTATE("HDR",1)=HDR(1),HLMSTATE("HDR",2)=HDR(2)
    27         ;
    28         K ^HLB(IEN)
    29         S ID=$S(HLMSTATE("BATCH"):HLMSTATE("HDR","BATCH CONTROL ID"),1:HLMSTATE("HDR","MESSAGE CONTROL ID"))
    30         S NODE=ID_"^"_HLMSTATE("BODY")_"^"_$G(HLMSTATE("ACK TO"))_"^"_$S(HLMSTATE("DIRECTION")="IN":"I",1:"O")_"^"
    31         S $P(NODE,"^",5)=$G(@STAT@("LINK NAME"))
    32         S $P(NODE,"^",6)=$G(@STAT@("QUEUE"))
    33         S $P(NODE,"^",8)=$G(@STAT@("PORT"))
    34         S $P(NODE,"^",20)=$G(@STAT)
    35         S $P(NODE,"^",21)=$G(@STAT@("ERROR TEXT"))
    36         S $P(NODE,"^",16)=HLMSTATE("DT/TM")
    37         ;
    38         I HLMSTATE("DIRECTION")="OUT" D
    39         .S $P(NODE,"^",10)=$P($G(@STAT@("APP ACK RESPONSE")),"^")
    40         .S $P(NODE,"^",11)=$P($G(@STAT@("APP ACK RESPONSE")),"^",2)
    41         .S $P(NODE,"^",12)=$P($G(@STAT@("ACCEPT ACK RESPONSE")),"^")
    42         .S $P(NODE,"^",13)=$P($G(@STAT@("ACCEPT ACK RESPONSE")),"^",2)
    43         .S $P(NODE,"^",14)=$P($G(@STAT@("FAILURE RESPONSE")),"^")
    44         .S $P(NODE,"^",15)=$P($G(@STAT@("FAILURE RESPONSE")),"^",2)
    45         .;
    46         .;for outgoing set these x-refs now, for incoming msgs set them later
    47         .S ^HLB("B",ID,IEN)=""
    48         .S ^HLB("C",HLMSTATE("BODY"),IEN)=""
    49         .I ($G(@STAT)="ER") D
    50         ..S ^HLB("ERRORS",$S($L($G(HLMSTATE("HDR","RECEIVING APPLICATION"))):HLMSTATE("HDR","RECEIVING APPLICATION"),1:"UNKNOWN"),HLMSTATE("DT/TM CREATED"),IEN)=""
    51         ..D COUNT^HLOESTAT("OUT",$G(HLMSTATE("HDR","RECEIVING APPLICATION")),$G(HLMSTATE("HDR","SENDING APPLICATION")),$S(HLMSTATE("BATCH"):"BATCH",1:$G(HLMSTATE("HDR","MESSAGE TYPE"))),$G(HLMSTATE("HDR","EVENT")))
    52         .;
    53         .;save some space for the ack
    54         .S:($G(HLMSTATE("HDR","ACCEPT ACK TYPE"))="AL") ^HLB(IEN,4)="^^^                                                                 "
    55         I $G(HLMSTATE("STATUS","PURGE")) S $P(NODE,"^",9)=HLMSTATE("STATUS","PURGE"),^HLB("AD","OUT",HLMSTATE("STATUS","PURGE"),HLMSTATE("IEN"))=""
    56         S ^HLB(IEN,0)=NODE
    57         ;
    58         ;store the message header
    59         S ^HLB(IEN,1)=HLMSTATE("HDR",1)
    60         S ^HLB(IEN,2)=HLMSTATE("HDR",2)
    61         ;
    62         ;if the msg is an app ack, update the original msg
    63         I $G(HLMSTATE("ACK TO","IEN"))]"" D
    64         .N ACKTO
    65         .M ACKTO=HLMSTATE("ACK TO")
    66         .S ACKTO("ACK BY")=$S(HLMSTATE("BATCH"):HLMSTATE("HDR","BATCH CONTROL ID"),1:HLMSTATE("HDR","MESSAGE CONTROL ID"))
    67         .D ACKTO^HLOF778(.HLMSTATE,.ACKTO)
    68         .S HLMSTATE("ACK TO","DONE")=1 ;because the update was already done, otherwise it might be done again
    69         ;
    70         ;The "SEARCH" x-ref will be created asynchronously
    71         S ^HLTMP("PENDING SEARCH X-REF",$J,HLMSTATE("DT/TM CREATED"),IEN)=""
    72         ;
    73         ;sequence q?
    74         I HLMSTATE("DIRECTION")="OUT",$G(@STAT@("SEQUENCE QUEUE"))'="" S ^HLB(IEN,5)=@STAT@("SEQUENCE QUEUE")
    75         ;
    76         Q IEN
    77         ;
    78 NEWIEN(DIR,TCP) ;
    79         ;This function uses a counter to get the next available ien for file 778. There are 4 different counters, each assigned as range of numbers, selected via the input parameters. It does not create a record.
    80         ;Inputs:
    81         ;  DIR = "IN" or "OUT" (required)
    82         ;  TCP = 1,0 (optional)
    83         ;Output - the function returns the next available ien. Several counters are used:
    84         ;
    85         ;   <"OUT","TCP">
    86         ;   <"OUT","NOT TCP">
    87         ;   <"IN","TCP">
    88         ;   <"IN","NOT TCP">
    89         ;
    90         N IEN,COUNTER,INC
    91         I DIR="OUT" S INC=$S(+$G(TCP):0,1:100000000000)
    92         I DIR="IN" S INC=$S(+$G(TCP):200000000000,1:300000000000)
    93         S COUNTER=$NA(^HLC("FILE778",DIR,$S(+$G(TCP):"TCP",1:"NOT TCP")))
    94 AGAIN   ;
    95         S IEN=$$INC^HLOSITE(COUNTER,1)
    96         I IEN>100000000000 D
    97         .L +@COUNTER:200
    98         .I $T,@COUNTER>100000000000 S @COUNTER=1,IEN=1
    99         .L -@COUNTER
    100         I IEN>100000000000 G AGAIN
    101         Q (IEN+INC)
    102         ;
    103 TCP()   ;checks the link to see if its TCP, return 1 if yes, 0 if no or not defined
    104         N IEN,TCP
    105         S TCP=1
    106         S IEN=$G(HLMSTATE("STATUS","LINK IEN"))
    107         I IEN,$P($G(^HLCS(869.1,+$P($G(^HLCS(870,IEN,0)),"^",3),0)),"^")'="TCP" S TCP=0
    108         Q TCP
    109         ;
    110 GETWORK(WORK)   ; Used by the Process Manager.
    111         ;Are there any messages that need the "SEARCH" x-ref set?
    112         ;Inputs:
    113         ;  WORK (required, pass-by-reference)
    114         ;    ("DOLLARJ")
    115         ;    ("NOW") (required by the process manager, pass-by-reference)
    116         ;
    117         L +^HLTMP("PENDING SEARCH X-REF"):0
    118         Q:'$T 0
    119         N OLD,DOLLARJ,SUCCESS,NOW
    120         S SUCCESS=0
    121         S NOW=$$SEC^XLFDT($H)
    122         S (OLD,DOLLARJ)=$G(WORK("DOLLARJ"))
    123         F  S DOLLARJ=$O(^HLTMP("PENDING SEARCH X-REF",DOLLARJ)) Q:DOLLARJ=""  D  Q:SUCCESS
    124         .N TIME S TIME=$O(^HLTMP("PENDING SEARCH X-REF",DOLLARJ,""))
    125         .S:(NOW-$$SEC^XLFDT(TIME)>100) SUCCESS=1
    126         ;
    127         I OLD'="",'SUCCESS F  S DOLLARJ=$O(^HLTMP("PENDING SEARCH X-REF",DOLLARJ)) Q:DOLLARJ=""  Q:DOLLARJ>OLD  D  Q:SUCCESS
    128         .N TIME S TIME=$O(^HLTMP("PENDING SEARCH X-REF",DOLLARJ,""))
    129         .S:(NOW-$$SEC^XLFDT(TIME)>100) SUCCESS=1
    130         S WORK("DOLLARJ")=DOLLARJ,WORK("NOW")=NOW
    131         Q:WORK("DOLLARJ")]"" 1
    132         L -^HLTMP("PENDING SEARCH X-REF")
    133         Q 0
    134         ;
    135 DOWORK(WORK)    ;Used by the Process Manager
    136         ;Sets the "SEARCH" x-ref, running 100 seconds behind when the message record was created.
    137         ;
    138         N MSGIEN,TIME
    139         S TIME=0
    140         F  S TIME=$O(^HLTMP("PENDING SEARCH X-REF",WORK("DOLLARJ"),TIME)) Q:'TIME  Q:((WORK("NOW")-$$SEC^XLFDT(TIME))<100)  D
    141         .S MSGIEN=0
    142         .F  S MSGIEN=$O(^HLTMP("PENDING SEARCH X-REF",WORK("DOLLARJ"),TIME,MSGIEN)) Q:'MSGIEN  D
    143         ..N MSG
    144         ..I $$GETMSG^HLOMSG(MSGIEN,.MSG) D
    145         ...Q:'MSG("DT/TM CREATED")
    146         ...I MSG("BATCH") D
    147         ....N HDR
    148         ....F  Q:'$$NEXTMSG^HLOMSG(.MSG,.HDR)  S MSG("HDR",1)=HDR(1),MSG("HDR",2)=HDR(2) D SET(.MSG)
    149         ...E  D
    150         ....D SET(.MSG)
    151         ..K ^HLTMP("PENDING SEARCH X-REF",WORK("DOLLARJ"),TIME,MSGIEN)
    152         L -^HLTMP("PENDING SEARCH X-REF")
    153         Q
    154         ;
    155 SET(MSG)        ;
    156         ;sets the ^HLB("SEARCH") x-ref
    157         ;
    158         N APP,FS,CS,IEN
    159         I MSG("DIRECTION")'="IN",MSG("DIRECTION")'="OUT" Q
    160         S FS=$E(MSG("HDR",1),4)
    161         Q:FS=""
    162         S CS=$E(MSG("HDR",1),5)
    163         S APP=$S(MSG("DIRECTION")="IN":$P($P(MSG("HDR",1),FS,5),CS),1:$P($P(MSG("HDR",1),FS,3),CS))
    164         I APP="" S APP="UNKNOWN"
    165         I MSG("BATCH") D
    166         .N VALUE
    167         .S VALUE=$P(MSG("HDR",2),FS,4)
    168         .S MSG("MESSAGE TYPE")=$P(VALUE,CS)
    169         .S MSG("EVENT")=$P(VALUE,CS,2)
    170         S:MSG("MESSAGE TYPE")="" MSG("MESSAGE TYPE")="<none>"
    171         S:MSG("EVENT")="" MSG("EVENT")="<none>"
    172         S IEN=MSG("IEN")
    173         I MSG("BATCH") S IEN=IEN_"^"_MSG("BATCH","CURRENT MESSAGE")
    174         S ^HLB("SEARCH",MSG("DIRECTION"),MSG("DT/TM CREATED"),APP,MSG("MESSAGE TYPE"),MSG("EVENT"),IEN)=""
    175         Q
     1HLOF778A ;ALB/CJM-HL7 - Saving messages to file 778 (continued) ;03/07/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ;
     6NEW(HLMSTATE) ;
     7 ;This function creates a new entry in file 778.
     8 ;Input:
     9 ;   HLMSTATE (required, pass by reference) These subscripts are expected:
     10 ;
     11 ;Output - the function returns the ien of the newly created record
     12 ;
     13 N IEN,NODE,ID,STAT
     14 S STAT="HLMSTATE(""STATUS"")"
     15 S IEN=$$NEWIEN(HLMSTATE("DIRECTION"),$$TCP)
     16 Q:'IEN 0
     17 S HLMSTATE("IEN")=IEN
     18 ;
     19 D  ;build the message header
     20 .N HDR
     21 .;for incoming messages the header segment should already exist
     22 .;for outgoing messages must build the header segment
     23 .I HLMSTATE("DIRECTION")="OUT" D  Q
     24 ..I HLMSTATE("BATCH"),$G(HLMSTATE("ACK TO"))]"" S HLMSTATE("HDR","REFERENCE BATCH CONTROL ID")=HLMSTATE("ACK TO")
     25 ..D BUILDHDR^HLOPBLD1(.HLMSTATE,$S(HLMSTATE("BATCH"):"BHS",1:"MSH"),.HDR)
     26 ..S HLMSTATE("HDR",1)=HDR(1),HLMSTATE("HDR",2)=HDR(2)
     27 ;
     28 K ^HLB(IEN)
     29 S ID=$S(HLMSTATE("BATCH"):HLMSTATE("HDR","BATCH CONTROL ID"),1:HLMSTATE("HDR","MESSAGE CONTROL ID"))
     30 S NODE=ID_"^"_HLMSTATE("BODY")_"^"_$G(HLMSTATE("ACK TO"))_"^"_$S(HLMSTATE("DIRECTION")="IN":"I",1:"O")_"^"
     31 S $P(NODE,"^",5)=$G(@STAT@("LINK NAME"))
     32 S $P(NODE,"^",6)=$G(@STAT@("QUEUE"))
     33 S $P(NODE,"^",8)=$G(@STAT@("PORT"))
     34 S $P(NODE,"^",20)=$G(@STAT)
     35 S $P(NODE,"^",21)=$G(@STAT@("ERROR TEXT"))
     36 S $P(NODE,"^",16)=HLMSTATE("DT/TM")
     37 ;
     38 I HLMSTATE("DIRECTION")="OUT" D
     39 .S $P(NODE,"^",10)=$P($G(@STAT@("APP ACK RESPONSE")),"^")
     40 .S $P(NODE,"^",11)=$P($G(@STAT@("APP ACK RESPONSE")),"^",2)
     41 .S $P(NODE,"^",12)=$P($G(@STAT@("ACCEPT ACK RESPONSE")),"^")
     42 .S $P(NODE,"^",13)=$P($G(@STAT@("ACCEPT ACK RESPONSE")),"^",2)
     43 .S $P(NODE,"^",14)=$P($G(@STAT@("FAILURE RESPONSE")),"^")
     44 .S $P(NODE,"^",15)=$P($G(@STAT@("FAILURE RESPONSE")),"^",2)
     45 .;
     46 .;for outgoing set these x-refs now, for incoming msgs set them later
     47 .S ^HLB("B",ID,IEN)=""
     48 .S ^HLB("C",HLMSTATE("BODY"),IEN)=""
     49 .I ($G(@STAT)="SE") D
     50 ..S ^HLB("ERRORS","SE",$S($L($G(HLMSTATE("HDR","RECEIVING APPLICATION"))):HLMSTATE("HDR","RECEIVING APPLICATION"),1:"UNKNOWN"),HLMSTATE("DT/TM CREATED"),IEN)=""
     51 ..D COUNT^HLOESTAT("OUT",$G(HLMSTATE("HDR","RECEIVING APPLICATION")),$G(HLMSTATE("HDR","SENDING APPLICATION")),$S(HLMSTATE("BATCH"):"BATCH",1:$G(HLMSTATE("HDR","MESSAGE TYPE"))),$G(HLMSTATE("HDR","EVENT")))
     52 .;
     53 .;save some space for the ack
     54 .S:($G(HLMSTATE("HDR","ACCEPT ACK TYPE"))="AL") ^HLB(IEN,4)="^^^                                                                 "
     55 I $G(HLMSTATE("STATUS","PURGE")) S $P(NODE,"^",9)=HLMSTATE("STATUS","PURGE"),^HLB("AD","OUT",HLMSTATE("STATUS","PURGE"),HLMSTATE("IEN"))=""
     56 S ^HLB(IEN,0)=NODE
     57 ;
     58 ;store the message header
     59 S ^HLB(IEN,1)=HLMSTATE("HDR",1)
     60 S ^HLB(IEN,2)=HLMSTATE("HDR",2)
     61 ;
     62 ;if the msg is an app ack, update the original msg
     63 I $G(HLMSTATE("ACK TO","IEN"))]"" D
     64 .N ACKTO
     65 .M ACKTO=HLMSTATE("ACK TO")
     66 .S ACKTO("ACK BY")=$S(HLMSTATE("BATCH"):HLMSTATE("HDR","BATCH CONTROL ID"),1:HLMSTATE("HDR","MESSAGE CONTROL ID"))
     67 .D ACKTO^HLOF778(.HLMSTATE,.ACKTO)
     68 .S HLMSTATE("ACK TO","DONE")=1 ;because the update was already done, otherwise it might be done again
     69 ;
     70 ;The "SEARCH" x-ref will be created asynchronously
     71 S ^HLTMP("PENDING SEARCH X-REF",$J,HLMSTATE("DT/TM CREATED"),IEN)=""
     72 ;
     73 Q IEN
     74 ;
     75NEWIEN(DIR,TCP) ;
     76 ;This function uses a counter to get the next available ien for file 778. There are 4 different counters, each assigned as range of numbers, selected via the input parameters. It does not create a record.
     77 ;Inputs:
     78 ;  DIR = "IN" or "OUT" (required)
     79 ;  TCP = 1,0 (optional)
     80 ;Output - the function returns the next available ien. Several counters are used:
     81 ;
     82 ;   <"OUT","TCP">
     83 ;   <"OUT","NOT TCP">
     84 ;   <"IN","TCP">
     85 ;   <"IN","NOT TCP">
     86 ;
     87 N IEN,COUNTER,INC
     88 I DIR="OUT" S INC=$S(+$G(TCP):0,1:100000000000)
     89 I DIR="IN" S INC=$S(+$G(TCP):200000000000,1:300000000000)
     90 S COUNTER=$NA(^HLC("FILE778",DIR,$S(+$G(TCP):"TCP",1:"NOT TCP")))
     91AGAIN ;
     92 S IEN=$$INC^HLOSITE(COUNTER,1)
     93 I IEN>100000000000 D
     94 .L +@COUNTER:200
     95 .I $T,@COUNTER>100000000000 S @COUNTER=1,IEN=1
     96 .L -@COUNTER
     97 I IEN>100000000000 G AGAIN
     98 Q (IEN+INC)
     99 ;
     100TCP() ;checks the link to see if its TCP, return 1 if yes, 0 if no or not defined
     101 N IEN,TCP
     102 S TCP=1
     103 S IEN=$G(HLMSTATE("STATUS","LINK IEN"))
     104 I IEN,$P($G(^HLCS(869.1,+$P($G(^HLCS(870,IEN,0)),"^",3),0)),"^")'="TCP" S TCP=0
     105 Q TCP
     106 ;
     107GETWORK(WORK) ; Used by the Process Manager.
     108 ;Are there any messages that need the "SEARCH" x-ref set?
     109 ;Inputs:
     110 ;  WORK (required, pass-by-reference)
     111 ;    ("DOLLARJ")
     112 ;    ("NOW") (required by the process manager, pass-by-reference)
     113 ;
     114 L +^HLTMP("PENDING SEARCH X-REF"):0
     115 Q:'$T 0
     116 N OLD,DOLLARJ,SUCCESS,NOW
     117 S SUCCESS=0
     118 S NOW=$$SEC^XLFDT($H)
     119 S (OLD,DOLLARJ)=$G(WORK("DOLLARJ"))
     120 F  S DOLLARJ=$O(^HLTMP("PENDING SEARCH X-REF",DOLLARJ)) Q:DOLLARJ=""  D  Q:SUCCESS
     121 .N TIME S TIME=$O(^HLTMP("PENDING SEARCH X-REF",DOLLARJ,""))
     122 .S:(NOW-$$SEC^XLFDT(TIME)>100) SUCCESS=1
     123 ;
     124 I OLD'="",'SUCCESS F  S DOLLARJ=$O(^HLTMP("PENDING SEARCH X-REF",DOLLARJ)) Q:DOLLARJ=""  Q:DOLLARJ>OLD  D  Q:SUCCESS
     125 .N TIME S TIME=$O(^HLTMP("PENDING SEARCH X-REF",DOLLARJ,""))
     126 .S:(NOW-$$SEC^XLFDT(TIME)>100) SUCCESS=1
     127 S WORK("DOLLARJ")=DOLLARJ,WORK("NOW")=NOW
     128 Q:WORK("DOLLARJ")]"" 1
     129 L -^HLTMP("PENDING SEARCH X-REF")
     130 Q 0
     131 ;
     132DOWORK(WORK) ;Used by the Process Manager
     133 ;Sets the "SEARCH" x-ref, running 100 seconds behind when the message record was created.
     134 ;
     135 N MSGIEN,TIME
     136 S TIME=0
     137 F  S TIME=$O(^HLTMP("PENDING SEARCH X-REF",WORK("DOLLARJ"),TIME)) Q:'TIME  Q:((WORK("NOW")-$$SEC^XLFDT(TIME))<100)  D
     138 .S MSGIEN=0
     139 .F  S MSGIEN=$O(^HLTMP("PENDING SEARCH X-REF",WORK("DOLLARJ"),TIME,MSGIEN)) Q:'MSGIEN  D
     140 ..N MSG
     141 ..I $$GETMSG^HLOMSG(MSGIEN,.MSG) D
     142 ...Q:'MSG("DT/TM CREATED")
     143 ...I MSG("BATCH") D
     144 ....N HDR
     145 ....F  Q:'$$NEXTMSG^HLOMSG(.MSG,.HDR)  S MSG("HDR",1)=HDR(1),MSG("HDR",2)=HDR(2) D SET(.MSG)
     146 ...E  D
     147 ....D SET(.MSG)
     148 ..K ^HLTMP("PENDING SEARCH X-REF",WORK("DOLLARJ"),TIME,MSGIEN)
     149 L -^HLTMP("PENDING SEARCH X-REF")
     150 Q
     151 ;
     152SET(MSG) ;
     153 ;sets the ^HLB("SEARCH") x-ref
     154 ;
     155 N APP,FS,CS,IEN
     156 I MSG("DIRECTION")'="IN",MSG("DIRECTION")'="OUT" Q
     157 S FS=$E(MSG("HDR",1),4)
     158 Q:FS=""
     159 S CS=$E(MSG("HDR",1),5)
     160 S APP=$S(MSG("DIRECTION")="IN":$P($P(MSG("HDR",1),FS,5),CS),1:$P($P(MSG("HDR",1),FS,3),CS))
     161 I APP="" S APP="UNKNOWN"
     162 I MSG("BATCH") D
     163 .N VALUE
     164 .S VALUE=$P(MSG("HDR",2),FS,4)
     165 .S MSG("MESSAGE TYPE")=$P(VALUE,CS)
     166 .S MSG("EVENT")=$P(VALUE,CS,2)
     167 S:MSG("MESSAGE TYPE")="" MSG("MESSAGE TYPE")="<none>"
     168 S:MSG("EVENT")="" MSG("EVENT")="<none>"
     169 S IEN=MSG("IEN")
     170 I MSG("BATCH") S IEN=IEN_"^"_MSG("BATCH","CURRENT MESSAGE")
     171 S ^HLB("SEARCH",MSG("DIRECTION"),MSG("DT/TM CREATED"),APP,MSG("MESSAGE TYPE"),MSG("EVENT"),IEN)=""
     172 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOFILER.m

    r613 r623  
    1 HLOFILER        ;ALB/CJM- Passes messages on the incoming queue to the applications - 10/4/94 1pm ;07/10/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,131,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ;GET WORK function for the process running under the Process Manager
    6 GETWORK(QUE)    ;
    7         ;Input:
    8         ;  QUE - (pass by reference) These subscripts are used:
    9         ;    ("FROM") - sending facility last obtained
    10         ;    ("QUEUE") - name of the queue last obtained
    11         ;Output:
    12         ;  Function returns 1 if success, 0 if no more work
    13         ;  QUE-  updated to identify next queu of messages to process.
    14         ;
    15         N FROM,QUEUE
    16         I '$D(QUE("SYSTEM")) D
    17         .N SYS
    18         .D SYSPARMS^HLOSITE(.SYS)
    19         .S QUE("SYSTEM","NORMAL PURGE")=SYS("NORMAL PURGE")
    20         .S QUE("SYSTEM","ERROR PURGE")=SYS("ERROR PURGE")
    21         S FROM=$G(QUE("FROM")),QUEUE=$G(QUE("QUEUE"))
    22         I ($G(FROM)]""),($G(QUEUE)]"") D
    23         .L -^HLB("QUEUE","IN",FROM,QUEUE)
    24         .F  S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0  Q:$T
    25         I ($G(FROM)]""),($G(QUEUE)="") D
    26         .F  S FROM=$O(^HLB("QUEUE","IN",FROM)) Q:FROM=""  D  Q:($G(QUEUE)]"")
    27         ..S QUEUE="" F  S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0 Q:$T
    28         I FROM="" D
    29         .F  S FROM=$O(^HLB("QUEUE","IN",FROM)) Q:FROM=""  D  Q:($G(QUEUE)]"")
    30         ..S QUEUE="" F  S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0 Q:$T
    31         S QUE("FROM")=FROM,QUE("QUEUE")=QUEUE
    32         Q:(QUEUE]"") 1
    33         Q 0
    34         ;
    35 DOWORK(QUEUE)   ;sends the messages on the queue
    36         N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOFILER"
    37         ;
    38         N MSGIEN,DEQUE,QUE
    39         M QUE=QUEUE
    40         S DEQUE=0
    41         S MSGIEN=0
    42         ;
    43         F  S MSGIEN=$O(^HLB("QUEUE","IN",QUEUE("FROM"),QUEUE("QUEUE"),MSGIEN)) Q:'MSGIEN  D  M QUEUE=QUE
    44         .N MCODE,ACTION,QUE,PURGE,ACKTOIEN,NODE
    45         .N $ETRAP,$ESTACK S $ETRAP="G ERROR2^HLOFILER"
    46         .S NODE=$G(^HLB("QUEUE","IN",QUEUE("FROM"),QUEUE("QUEUE"),MSGIEN))
    47         .S ACTION=$P(NODE,"^",1,2)
    48         .S PURGE=$P(NODE,"^",3)
    49         .S ACKTOIEN=$P(NODE,"^",4)
    50         .D DEQUE(MSGIEN,PURGE,ACKTOIEN)
    51         .I ACTION]"" D
    52         ..N HLMSGIEN,MCODE,DEQUE,DUZ
    53         ..N $ETRAP,$ESTACK S $ETRAP="G ERROR3^HLOFILER"
    54         ..S HLMSGIEN=MSGIEN
    55         ..S MCODE="D "_ACTION
    56         ..N MSGIEN,X
    57         ..D DUZ^XUP(.5)
    58         ..X MCODE
    59         ..;kill the apps variables
    60         ..D
    61         ...N ZTSK
    62         ...D KILL^XUSCLEAN
    63         ;
    64 ENDWORK ;where the execution resumes upon an error
    65         D DEQUE()
    66         Q
    67         ;
    68 DEQUE(MSGIEN,PURGE,ACKTOIEN)    ;
    69         ;Dequeues the message.  Also sets up the purge dt/tm and the completion status.
    70         S:$G(MSGIEN) DEQUE=$G(DEQUE)+1,DEQUE(MSGIEN)=PURGE_"^"_ACKTOIEN
    71         I '$G(MSGIEN)!($G(DEQUE)>25) S MSGIEN=0 D
    72         .F  S MSGIEN=$O(DEQUE(MSGIEN)) Q:'MSGIEN  D
    73         ..N NODE,PURGE,ACKTOIEN
    74         ..S NODE=DEQUE(MSGIEN)
    75         ..S PURGE=$P(NODE,"^"),ACKTOIEN=$P(NODE,"^",2)
    76         ..D DEQUE^HLOQUE(QUEUE("FROM"),QUEUE("QUEUE"),"IN",MSGIEN)
    77         ..S NODE=$G(^HLB(MSGIEN,0))
    78         ..Q:NODE=""
    79         ..S $P(NODE,"^",19)=1 ;sets the flag to show that the app handoff was done
    80         ..D:PURGE
    81         ...N STATUS
    82         ...S STATUS=$P(NODE,"^",20)
    83         ...S:STATUS="" $P(NODE,"^",20)="SU",STATUS="SU"
    84         ...S $P(NODE,"^",9)=$$FMADD^XLFDT($$NOW^XLFDT,,$S(PURGE=2:24*QUEUE("SYSTEM","ERROR PURGE"),$D(^HLB(MSGIEN,3,1,0)):24*QUEUE("SYSTEM","ERROR PURGE"),1:QUEUE("SYSTEM","NORMAL PURGE")))
    85         ...S ^HLB("AD",$S($E($P(NODE,"^",4))="I":"IN",1:"OUT"),$P(NODE,"^",9),MSGIEN)=""
    86         ...I ACKTOIEN,$D(^HLB(ACKTOIEN,0)) S $P(^HLB(ACKTOIEN,0),"^",9)=$P(NODE,"^",9),^HLB("AD",$S($E($P(NODE,"^",4))="I":"OUT",1:"IN"),$P(NODE,"^",9),ACKTOIEN)=""
    87         ..S ^HLB(MSGIEN,0)=NODE
    88         .K DEQUE S DEQUE=0
    89         Q
    90         ;
    91 ERROR   ;error trap
    92         S $ETRAP="Q:$QUIT """" Q"
    93         N HOUR
    94         S HOUR=$E($$NOW^XLFDT,1,10)
    95         S ^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2))=$G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))+1
    96         ;
    97         D DEQUE()
    98         ;
    99         ;a lot of errors of the same type may indicate an endless loop
    100         ;return to the Process Manager error trap
    101         I ($G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))>30) Q:$QUIT "" Q
    102         ;
    103         ;while debugging quit on all errors - returns to the Process Manager error trap
    104         I $G(^HLTMP("LOG ALL ERRORS")) Q:$QUIT "" Q
    105         I $ECODE["EDITED" Q:$QUIT "" Q
    106         ;
    107         D ^%ZTER
    108         D UNWIND^%ZTER
    109         Q:$QUIT ""
    110         Q
    111         ;
    112 ERROR2  ;
    113         S $ETRAP="Q:$QUIT """" Q"
    114         ;
    115         D DEQUE()
    116         ;
    117         ;may need to change the status to Error
    118         D
    119         .N NODE,RAPP,SAPP,FS,CS,REP,ESCAPE,SUBCOMP,HDR,DIR,NOW
    120         .S NOW=$$NOW^XLFDT
    121         .S NODE=$G(^HLB(MSGIEN,0))
    122         .Q:NODE=""
    123         .Q:$P(NODE,"^",20)="ER"
    124         .S $P(NODE,"^",20)="ER",$P(NODE,"^",21)="APPLICATION ROUTINE ERROR"
    125         .S DIR=$S($E($P(NODE,"^",4))="I":"IN",1:"OUT")
    126         .I $P(NODE,"^",9) K ^HLB("AD",DIR,$P(NODE,"^",9),MSGIEN)
    127         .S $P(NODE,"^",9)=$$FMADD^XLFDT(NOW,,24*QUEUE("SYSTEM","ERROR PURGE"))
    128         .S ^HLB(MSGIEN,0)=NODE
    129         .S ^HLB("AD",DIR,$P(NODE,"^",9),MSGIEN)=""
    130         .S HDR=$G(^HLB(MSGIEN,1))
    131         .S FS=$E(HDR,4)
    132         .Q:FS=""
    133         .S CS=$E(HDR,5)
    134         .S REP=$E(HDR,6)
    135         .S ESCAPE=$E(HDR,7)
    136         .S SUBCOMP=$E(HDR,8)
    137         .S RAPP=$$DESCAPE^HLOPRS1($P($P(HDR,FS,5),CS),FS,CS,SUBCOMP,REP,ESCAPE)
    138         .I RAPP="" S RAPP="UNKNOWN"
    139         .S SAPP=$$DESCAPE^HLOPRS1($P($P(HDR,FS,3),CS),FS,CS,SUBCOMP,REP,ESCAPE)
    140         .S ^HLB("ERRORS",RAPP,NOW,MSGIEN)=""
    141         .D COUNT^HLOESTAT(DIR,RAPP,SAPP,"UNKNOWN")
    142         ;
    143         ;kill the apps variables
    144         D
    145         .N ZTSK,MSGIEN,QUEUE
    146         .D KILL^XUSCLEAN
    147         ;
    148         ;release all the locks the app may have set, except Taskman lock
    149         L:$D(ZTSK) ^%ZTSCH("TASK",ZTSK):1
    150         L:'$D(ZTSK)
    151         ;reset HLO's lock
    152         L +^HLTMP("HL7 RUNNING PROCESSES",$J):0
    153         ;return to processing the next message on the queue
    154         S $ECODE=""
    155         ;
    156         Q:$QUIT ""
    157         Q
    158 ERROR3  ;error trap for application context
    159         S $ETRAP="Q:$QUIT """" Q"
    160         D ^%ZTER
    161         S $ECODE=",UAPPLICATION ERROR,"
    162         ;
    163         ;drop to the ERROR2 error handler
    164         Q:$QUIT ""
    165         Q
     1HLOFILER ;ALB/CJM- Passes messages on the incoming queue to the applications - 10/4/94 1pm ;03/28/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,131,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ;GET WORK function for the process running under the Process Manager
     6GETWORK(QUE) ;
     7 ;Input:
     8 ;  QUE - (pass by reference) These subscripts are used:
     9 ;    ("FROM") - sending facility last obtained
     10 ;    ("QUEUE") - name of the queue last obtained
     11 ;Output:
     12 ;  Function returns 1 if success, 0 if no more work
     13 ;  QUE-  updated to identify next queu of messages to process.
     14 ;
     15 N FROM,QUEUE
     16 I '$D(QUE("SYSTEM")) D
     17 .N SYS
     18 .D SYSPARMS^HLOSITE(.SYS)
     19 .S QUE("SYSTEM","NORMAL PURGE")=SYS("NORMAL PURGE")
     20 .S QUE("SYSTEM","ERROR PURGE")=SYS("ERROR PURGE")
     21 S FROM=$G(QUE("FROM")),QUEUE=$G(QUE("QUEUE"))
     22 I ($G(FROM)]""),($G(QUEUE)]"") D
     23 .L -^HLB("QUEUE","IN",FROM,QUEUE)
     24 .F  S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0  Q:$T
     25 I ($G(FROM)]""),($G(QUEUE)="") D
     26 .F  S FROM=$O(^HLB("QUEUE","IN",FROM)) Q:FROM=""  D  Q:($G(QUEUE)]"")
     27 ..S QUEUE="" F  S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0 Q:$T
     28 I FROM="" D
     29 .F  S FROM=$O(^HLB("QUEUE","IN",FROM)) Q:FROM=""  D  Q:($G(QUEUE)]"")
     30 ..S QUEUE="" F  S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="")  I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0 Q:$T
     31 S QUE("FROM")=FROM,QUE("QUEUE")=QUEUE
     32 Q:(QUEUE]"") 1
     33 Q 0
     34 ;
     35DOWORK(QUEUE) ;sends the messages on the queue
     36 N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOFILER"
     37 ;
     38 N MSGIEN,DEQUE,QUE
     39 M QUE=QUEUE
     40 S DEQUE=0
     41 S MSGIEN=0
     42 ;
     43 F  S MSGIEN=$O(^HLB("QUEUE","IN",QUEUE("FROM"),QUEUE("QUEUE"),MSGIEN)) Q:'MSGIEN  D  M QUEUE=QUE
     44 .N MCODE,ACTION,QUE,PURGE,ACKTOIEN,NODE
     45 .N $ETRAP,$ESTACK S $ETRAP="G ERROR2^HLOFILER"
     46 .S NODE=$G(^HLB("QUEUE","IN",QUEUE("FROM"),QUEUE("QUEUE"),MSGIEN))
     47 .S ACTION=$P(NODE,"^",1,2)
     48 .S PURGE=$P(NODE,"^",3)
     49 .S ACKTOIEN=$P(NODE,"^",4)
     50 .D DEQUE(MSGIEN,PURGE,ACKTOIEN)
     51 .I ACTION]"" D
     52 ..N HLMSGIEN,MCODE,DEQUE,DUZ
     53 ..N $ETRAP,$ESTACK S $ETRAP="G ERROR3^HLOFILER"
     54 ..S HLMSGIEN=MSGIEN
     55 ..S MCODE="D "_ACTION
     56 ..N MSGIEN,X
     57 ..D DUZ^XUP(.5)
     58 ..X MCODE
     59 ..;kill the apps variables
     60 ..D
     61 ...N ZTSK
     62 ...D KILL^XUSCLEAN
     63 ;
     64ENDWORK ;where the execution resumes upon an error
     65 D DEQUE()
     66 Q
     67 ;
     68DEQUE(MSGIEN,PURGE,ACKTOIEN) ;
     69 ;Dequeues the message.  Also sets up the purge dt/tm and the completion status.
     70 S:$G(MSGIEN) DEQUE=$G(DEQUE)+1,DEQUE(MSGIEN)=PURGE_"^"_ACKTOIEN
     71 I '$G(MSGIEN)!($G(DEQUE)>25) S MSGIEN=0 D
     72 .F  S MSGIEN=$O(DEQUE(MSGIEN)) Q:'MSGIEN  D
     73 ..N NODE,PURGE,ACKTOIEN
     74 ..S NODE=DEQUE(MSGIEN)
     75 ..S PURGE=$P(NODE,"^"),ACKTOIEN=$P(NODE,"^",2)
     76 ..D DEQUE^HLOQUE(QUEUE("FROM"),QUEUE("QUEUE"),"IN",MSGIEN)
     77 ..S NODE=$G(^HLB(MSGIEN,0))
     78 ..Q:NODE=""
     79 ..S $P(NODE,"^",19)=1 ;sets the flag to show that the app handoff was done
     80 ..D:PURGE
     81 ...N STATUS
     82 ...S STATUS=$P(NODE,"^",20)
     83 ...S:STATUS="" $P(NODE,"^",20)="SU",STATUS="SU"
     84 ...S $P(NODE,"^",9)=$$FMADD^XLFDT($$NOW^XLFDT,,$S(PURGE=2:24*QUEUE("SYSTEM","ERROR PURGE"),$D(^HLB(MSGIEN,3,1,0)):24*QUEUE("SYSTEM","ERROR PURGE"),1:QUEUE("SYSTEM","NORMAL PURGE")))
     85 ...S ^HLB("AD",$S($E($P(NODE,"^",4))="I":"IN",1:"OUT"),$P(NODE,"^",9),MSGIEN)=""
     86 ...I ACKTOIEN,$D(^HLB(ACKTOIEN,0)) S $P(^HLB(ACKTOIEN,0),"^",9)=$P(NODE,"^",9),^HLB("AD",$S($E($P(NODE,"^",4))="I":"OUT",1:"IN"),$P(NODE,"^",9),ACKTOIEN)=""
     87 ..S ^HLB(MSGIEN,0)=NODE
     88 .K DEQUE S DEQUE=0
     89 Q
     90 ;
     91ERROR ;error trap
     92 S $ETRAP="Q:$QUIT """" Q"
     93 N HOUR
     94 S HOUR=$E($$NOW^XLFDT,1,10)
     95 S ^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2))=$G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))+1
     96 ;
     97 D DEQUE()
     98 ;
     99 ;a lot of errors of the same type may indicate an endless loop
     100 ;return to the Process Manager error trap
     101 I ($G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))>30) Q:$QUIT "" Q
     102 ;
     103 ;while debugging quit on all errors - returns to the Process Manager error trap
     104 I $G(^HLTMP("LOG ALL ERRORS")) Q:$QUIT "" Q
     105 I $ECODE["EDITED" Q:$QUIT "" Q
     106 ;
     107 D ^%ZTER
     108 D UNWIND^%ZTER
     109 Q:$QUIT ""
     110 Q
     111 ;
     112ERROR2 ;
     113 S $ETRAP="Q:$QUIT """" Q"
     114 ;
     115 D DEQUE()
     116 ;
     117 ;may need to change the status to Application Error
     118 D
     119 .N NODE,RAPP,SAPP,FS,CS,REP,ESCAPE,SUBCOMP,HDR,DIR,NOW
     120 .S NOW=$$NOW^XLFDT
     121 .S NODE=$G(^HLB(MSGIEN,0))
     122 .Q:NODE=""
     123 .Q:$P(NODE,"^",20)="AE"
     124 .S $P(NODE,"^",20)="AE",$P(NODE,"^",21)="APPLICATION ROUTINE ERROR"
     125 .S DIR=$S($E($P(NODE,"^",4))="I":"IN",1:"OUT")
     126 .I $P(NODE,"^",9) K ^HLB("AD",DIR,$P(NODE,"^",9),MSGIEN)
     127 .S $P(NODE,"^",9)=$$FMADD^XLFDT(NOW,,24*QUEUE("SYSTEM","ERROR PURGE"))
     128 .S ^HLB(MSGIEN,0)=NODE
     129 .S ^HLB("AD",DIR,$P(NODE,"^",9),MSGIEN)=""
     130 .S HDR=$G(^HLB(MSGIEN,1))
     131 .S FS=$E(HDR,4)
     132 .Q:FS=""
     133 .S CS=$E(HDR,5)
     134 .S REP=$E(HDR,6)
     135 .S ESCAPE=$E(HDR,7)
     136 .S SUBCOMP=$E(HDR,8)
     137 .S RAPP=$$DESCAPE^HLOPRS1($P($P(HDR,FS,5),CS),FS,CS,SUBCOMP,REP,ESCAPE)
     138 .I RAPP="" S RAPP="UNKNOWN"
     139 .S SAPP=$$DESCAPE^HLOPRS1($P($P(HDR,FS,3),CS),FS,CS,SUBCOMP,REP,ESCAPE)
     140 .S ^HLB("ERRORS","AE",RAPP,NOW,MSGIEN)=""
     141 .D COUNT^HLOESTAT(DIR,RAPP,SAPP,"UNKNOWN")
     142 ;
     143 ;kill the apps variables
     144 D
     145 .N ZTSK,MSGIEN,QUEUE
     146 .D KILL^XUSCLEAN
     147 ;
     148 ;release all the locks the app may have set, except Taskman lock
     149 L:$D(ZTSK) ^%ZTSCH("TASK",ZTSK):1
     150 L:'$D(ZTSK)
     151 ;reset HLO's lock
     152 L +^HLTMP("HL7 RUNNING PROCESSES",$J):0
     153 ;return to processing the next message on the queue
     154 S $ECODE=""
     155 ;
     156 Q:$QUIT ""
     157 Q
     158ERROR3 ;error trap for application context
     159 S $ETRAP="Q:$QUIT """" Q"
     160 D ^%ZTER
     161 S $ECODE=",UAPPLICATION ERROR,"
     162 ;
     163 ;drop to the ERROR2 error handler
     164 Q:$QUIT ""
     165 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOMSG.m

    r613 r623  
    1 HLOMSG  ;ALB/CJM-HL7 - APIs for files 777/778 ;07/25/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 GETMSG(IEN,MSG) ;
    6         ;Description: given the message ien=MSGIEN (required), it returns the MSG array containing information about the message, defined below.
    7         ;Input:
    8         ;  IEN - the ien of the message in file 778
    9         ;Output:
    10         ;  Function returns 1 on success, 0 on failure
    11         ;  MSG (pass by reference, required) These are the subscripts returned:
    12         ;
    13         ;   "ACK BY" - msg id of msg that acknowledges this one
    14         ;   "ACK BY IEN" - msg IEN of msg that acknowledges this one.  If the message is in the batch, the value is <ien>^<subien>
    15         ;   "ACK TO" - msg id of msg that this msg acknowledges
    16         ;   "ACK TO IEN" - msg IEN of msg that this msg acknowledges. If the message is in a batch, the value is <ien>^<subien>
    17         ;  "BATCH"  = 1 if this is a batch message, 0  if not
    18         ;     "CURRENT MESSAGE" - defined only for batch messages -  a counter used during building and parsing messages to indicate the current message.  It will be set to 0 initially.
    19         ;  "BODY" - ptr to file 778 which contains the body of the message.
    20         ;  "DIRECTION" - "IN" if incoming, "OUT" if outgoing
    21         ;  "DT/TM" - date/time the message was sent or received
    22         ;  "DT/TM CREATED" - date/time the record was created (.01 field, file #777)
    23         ;  "LINE COUNT" -  a counter used during building and parsing of
    24         ;     messages to indicate the current line within the message. For
    25         ;     batch messages where each message within the batch is stored
    26         ;     separately, this field indicates the position within the current
    27         ;     individual message
    28         ;  "HDR" - the header segment, NOT parsed, as HDR(1) and HDR(2)
    29         ;  "ID" - Message Control ID for an individual message, Batch Control ID for a batch message
    30         ;  "IEN" - ien, file 778
    31         ;  "EVENT" - HL7 event, only defined if NOT batch
    32         ;  "MESSAGE TYPE" - HL7 message type, only defined if NOT batch
    33         ;  "STATUS" - the completion status
    34         ;
    35         ;     These are lower level subscripts of "STATUS":
    36         ;     "ACCEPT ACK RESPONSE" - the application's <tag>^<rtn> to Xecute when the accept ack is received
    37         ;     "ACCEPT ACK'D" - 1 if an accept ack was sent or received in response to this message
    38         ;     "APP ACK RESPONSE" - the application's <tag>^<rtn> to Xecute when app ack is received
    39         ;     "APP ACK'D" - 1 if an application ack was sent or received in response to this message
    40         ;     "ERROR TEXT" - if in error status, a description of the error
    41         ;     "LINK NAME" the link the message was transmitted through
    42         ;     "PORT" - remote port over which the message was transmitted
    43         ;     "PURGE" - scheduled purge dt/tm
    44         ;     "QUEUE" - the queue that the message was placed on
    45         ;     "SEQUENCE QUEUE" - the sequence queue (optional)
    46         ;
    47         K MSG
    48         Q:'$G(IEN) 0
    49         N NODE
    50         S MSG("IEN")=IEN
    51         S NODE=$G(^HLB(IEN,0))
    52         S MSG("ID")=$P(NODE,"^")
    53         S MSG("BODY")=$P(NODE,"^",2)
    54         S MSG("DIRECTION")=$S($E($P(NODE,"^",4))="O":"OUT",$E($P(NODE,"^",4))="I":"IN",1:"")
    55         S MSG("ACK TO")=$P(NODE,"^",3)
    56         S MSG("ACK BY")=$P(NODE,"^",7)
    57         I MSG("ACK TO")]"" S MSG("ACK TO IEN")=$$ACKTOIEN^HLOMSG1($P(NODE,"^"),MSG("ACK TO"))
    58         I MSG("ACK BY")]"" S MSG("ACK BY IEN")=$$ACKBYIEN^HLOMSG1($P(NODE,"^"),MSG("ACK BY"))
    59         S MSG("DT/TM")=$P(NODE,"^",16)
    60         S MSG("STATUS")=$P(NODE,"^",20)
    61         ;
    62         D
    63         .N NODE4
    64         .S NODE4=$G(^HLB(IEN,4))
    65         .S MSG("STATUS","QUEUE")=$P(NODE,"^",6)
    66         .S MSG("STATUS","LINK NAME")=$P(NODE,"^",5)
    67         .S MSG("STATUS","PORT")=$P(NODE,"^",8)
    68         .S MSG("STATUS","PURGE")=$P(NODE,"^",9)
    69         .S MSG("STATUS","ERROR TEXT")=$P(NODE,"^",21)
    70         .S MSG("STATUS","APP ACK RESPONSE")=$P(NODE,"^",10,11)
    71         .I MSG("STATUS","APP ACK RESPONSE")="^" S MSG("STATUS","APP ACK RESPONSE")=""
    72         .S MSG("STATUS","ACCEPT ACK RESPONSE")=$P(NODE,"^",12,13)
    73         .I MSG("STATUS","ACCEPT ACK RESPONSE")="^" S MSG("STATUS","ACCEPT ACK RESPONSE")=""
    74         .S MSG("STATUS","ACCEPT ACK'D")=$P(NODE,"^",17)
    75         .S MSG("STATUS","APP ACK'D")=$P(NODE,"^",18)
    76         .S MSG("STATUS")=$P(NODE,"^",20)
    77         .S MSG("STATUS","APP HANDOFF")=$P(NODE,"^",19)
    78         .S MSG("STATUS","ACCEPT ACK DT/TM")=$P(NODE4,"^")
    79         .S MSG("STATUS","ACCEPT ACK ID")=$P(NODE4,"^",2)
    80         .S MSG("STATUS","ACCEPT ACK MSA")=$P(NODE4,"^",3,99)
    81         ;
    82         S MSG("LINE COUNT")=0
    83         S MSG("HDR",1)=$G(^HLB(IEN,1))
    84         S MSG("HDR",2)=$G(^HLB(IEN,2))
    85         I 'MSG("BODY") D  Q 0
    86         .S MSG("DT/TM CREATED")=""
    87         .S MSG("BATCH")=""
    88         .S MSG("MESSAGE TYPE")=""
    89         .S MSG("EVENT")=""
    90         ;
    91         S NODE=$G(^HLA(MSG("BODY"),0))
    92         S MSG("DT/TM CREATED")=+NODE
    93         S MSG("BATCH")=+$P(NODE,"^",2)
    94         I MSG("BATCH") S MSG("BATCH","CURRENT MESSAGE")=0
    95         I 'MSG("BATCH") D
    96         .S MSG("MESSAGE TYPE")=$P(NODE,"^",3)
    97         .S MSG("EVENT")=$P(NODE,"^",4)
    98         I MSG("DIRECTION")="OUT" D
    99         .N NODE5
    100         .S NODE5=$G(^HLB(IEN,5))
    101         .S MSG("STATUS","SEQUENCE QUEUE")=$P(NODE5,"^")
    102         .S MSG("STATUS","MOVED TO OUT QUEUE")=$P(NODE5,"^",2)
    103         .S MSG("STATUS","SEQUENCE EXCEPTION RAISED")=$P(NODE5,"^",3)
    104         Q 1
    105         ;
    106 HLNEXT(MSG,SEG) ;
    107         ;Description:  Returns the next segment as a set of lines stored in SEG.
    108         ;Input:
    109         ;  MSG (pass by reference, required)
    110         ;Output:
    111         ;  Function returns 1 on success, 0 on failure (no more segments)
    112         ;  SEG (pass by reference, required)
    113         ;
    114         K SEG
    115         Q:MSG("LINE COUNT")=-1 0
    116         I 'MSG("BATCH") D
    117         .N I,J,NODE,START
    118         .S START=0
    119         .S J=1,I=MSG("LINE COUNT")
    120         .F  S I=$O(^HLA(MSG("BODY"),1,I)) Q:'I  S NODE=$G(^HLA(MSG("BODY"),1,I,0)) Q:(START&(NODE=""))  I NODE'="" S SEG(J)=NODE,J=J+1,START=1
    121         .I 'I D
    122         ..S MSG("LINE COUNT")=-1
    123         .E  S MSG("LINE COUNT")=I
    124         I MSG("BATCH") D
    125         .N I,J,NODE,START
    126         .S J=1,I=MSG("LINE COUNT"),START=0
    127         .F  S I=$O(^HLA(MSG("BODY"),2,MSG("BATCH","CURRENT MESSAGE"),1,I)) Q:'I  S NODE=$G(^HLA(MSG("BODY"),2,MSG("BATCH","CURRENT MESSAGE"),1,I,0)) Q:(START&(NODE=""))  I NODE'="" S SEG(J)=NODE,J=J+1,START=1
    128         .I 'I D
    129         ..S MSG("LINE COUNT")=-1
    130         .E  S MSG("LINE COUNT")=I
    131         Q $S($D(SEG):1,1:0)
    132         ;
    133 NEXTMSG(MSG,HDR)        ;
    134         ;Advances to the next message in the batch
    135         ;Input:
    136         ;  MSG (pass by reference, required) - defined by $$GETMSG()
    137         ;Output:
    138         ;  Function returns 1 on success, 0 if no more messages
    139         ;  MSG - updated with current position in the message
    140         ;  HDR (pass by reference, required) returns the header as an array of lines
    141         ;
    142         ;
    143         K HDR
    144         S MSG("LINE COUNT")=0
    145         N SUBIEN,I
    146         ;
    147         ;if completed parsing, don't start over
    148         I MSG("BATCH","CURRENT MESSAGE")=-1 Q 0
    149         ;
    150         S I=$O(^HLB(MSG("IEN"),3,"B",MSG("BATCH","CURRENT MESSAGE")))
    151         I 'I S MSG("BATCH","CURRENT MESSAGE")=-1 Q 0
    152         S MSG("BATCH","CURRENT MESSAGE")=I
    153         S SUBIEN=$O(^HLB(MSG("IEN"),3,"B",I,0))
    154         S HDR(1)=$G(^HLB(MSG("IEN"),3,SUBIEN,1))
    155         S HDR(2)=$G(^HLB(MSG("IEN"),3,SUBIEN,2))
    156         Q $S($D(HDR):1,1:0)
    157         ;
    158 ADDSEG(HLMSTATE,SEG)    ;Adds a segment to the message.
    159         ;Input:
    160         ;  HLMSTATE() - (pass by reference, required)
    161         ;  SEG() - (pass by reference, required) The segment as lines SEG(<i>)
    162         ;
    163         ;Output:
    164         ;   HLMSTATE()
    165         ;
    166         N I,J S I=0
    167         S J=HLMSTATE("LINE COUNT")
    168         ;
    169         ;insure a blank line between segments
    170         I J S J=J+1,HLMSTATE("UNSTORED LINES",$S(HLMSTATE("BATCH"):HLMSTATE("BATCH","CURRENT MESSAGE"),1:1),HLMSTATE("CURRENT SEGMENT"),J)=""
    171         ;
    172         S HLMSTATE("CURRENT SEGMENT")=HLMSTATE("CURRENT SEGMENT")+1
    173         F  S I=$O(SEG(I)) Q:'I  D
    174         .S J=J+1
    175         .S HLMSTATE("UNSTORED LINES",$S(HLMSTATE("BATCH"):HLMSTATE("BATCH","CURRENT MESSAGE"),1:1),HLMSTATE("CURRENT SEGMENT"),J)=SEG(I),HLMSTATE("UNSTORED LINES")=HLMSTATE("UNSTORED LINES")+$L(SEG(I))+50
    176         .I HLMSTATE("UNSTORED LINES")>HLMSTATE("SYSTEM","BUFFER") D
    177         ..I HLMSTATE("DIRECTION")="IN",$$SAVEMSG^HLOF778(.HLMSTATE) Q
    178         ..I HLMSTATE("DIRECTION")="OUT",$$SAVEMSG^HLOF777(.HLMSTATE)
    179         ;
    180         S HLMSTATE("LINE COUNT")=J
    181         Q
    182         ;
    183 ADDMSG(HLMSTATE,PARMS)  ;
    184         ;For outgoing messages, adds a message in the batch. There is no MSH yet, just the message type and event. 
    185         ;Input:
    186         ;  HLMSTATE() - (pass by reference, required)
    187         ;  PARMS("EVENT")
    188         ;  PARMS("MESSAGE TYPE")
    189         ;
    190         ;Output:
    191         ;   HLMSTATE() - (pass by reference, required)
    192         ;
    193         N I
    194         S I=HLMSTATE("BATCH","CURRENT MESSAGE")+1,HLMSTATE("BATCH","CURRENT MESSAGE")=I
    195         S HLMSTATE("UNSTORED LINES",I)=PARMS("MESSAGE TYPE")_"^"_PARMS("EVENT")
    196         M:$G(PARMS("ACK TO"))]"" HLMSTATE("BATCH","ACK TO",I)=PARMS("ACK TO")
    197         S HLMSTATE("CURRENT SEGMENT")=0
    198         S HLMSTATE("LINE COUNT")=0
    199         S HLMSTATE("UNSTORED LINES")=HLMSTATE("UNSTORED LINES")+100
    200         Q
    201         ;
    202 ADDMSG2(HLMSTATE,MSH)   ;
    203         ;For incoming messages adds a message to the batch. This differs from ADDMSG in that the MSH segment is passed in to be stored in file 778.
    204         ;Input:
    205         ;  HLMSTATE() - (pass by reference, required)
    206         ;  MSH(<i>) - the MSH segment as a set of lines
    207         ;
    208         ;Output:
    209         ;   HLMSTATE() - (pass by reference, required)
    210         ;
    211         N FS,CS,VALUE
    212         S HLMSTATE("BATCH","CURRENT MESSAGE")=HLMSTATE("BATCH","CURRENT MESSAGE")+1
    213         S FS=$E(MSH(1),4)
    214         S CS=$E(MSH(1),5)
    215         S VALUE=$P(MSH(2),FS,4)
    216         S HLMSTATE("UNSTORED LINES",HLMSTATE("BATCH","CURRENT MESSAGE"))=$P(VALUE,CS)_"^"_$P(VALUE,CS,2)
    217         S HLMSTATE("UNSTORED MSH")=1
    218         M HLMSTATE("UNSTORED MSH",HLMSTATE("BATCH","CURRENT MESSAGE"))=MSH
    219         S HLMSTATE("CURRENT SEGMENT")=0
    220         S HLMSTATE("LINE COUNT")=0
    221         S HLMSTATE("UNSTORED LINES")=HLMSTATE("UNSTORED LINES")+200
    222         I HLMSTATE("UNSTORED LINES")>HLMSTATE("SYSTEM","BUFFER"),$$SAVEMSG^HLOF778(.HLMSTATE) ;first stores stuff in 777, then headers in file 778
    223         Q
     1HLOMSG ;ALB/CJM-HL7 - APIs for files 777/778 ;02/04/2004
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5GETMSG(IEN,MSG) ;
     6 ;Description: given the message ien=MSGIEN (required), it returns the MSG array containing information about the message, defined below.
     7 ;Input:
     8 ;  IEN - the ien of the message in file 778
     9 ;Output:
     10 ;  Function returns 1 on success, 0 on failure
     11 ;  MSG (pass by reference, required) These are the subscripts returned:
     12 ;
     13 ;   "ACK BY" - msg id of msg that acknowledges this one
     14 ;   "ACK BY IEN" - msg IEN of msg that acknowledges this one.  If the message is in the batch, the value is <ien>^<subien>
     15 ;   "ACK TO" - msg id of msg that this msg acknowledges
     16 ;   "ACK TO IEN" - msg IEN of msg that this msg acknowledges. If the message is in a batch, the value is <ien>^<subien>
     17 ;  "BATCH"  = 1 if this is a batch message, 0  if not
     18 ;     "CURRENT MESSAGE" - defined only for batch messages -  a counter used during building and parsing messages to indicate the current message.  It will be set to 0 initially.
     19 ;  "BODY" - ptr to file 778 which contains the body of the message.
     20 ;  "DIRECTION" - "IN" if incoming, "OUT" if outgoing
     21 ;  "DT/TM" - date/time the message was sent or received
     22 ;  "DT/TM CREATED" - date/time the record was created (.01 field, file #777)
     23 ;  "LINE COUNT" -  a counter used during building and parsing of
     24 ;     messages to indicate the current line within the message. For
     25 ;     batch messages where each message within the batch is stored
     26 ;     separately, this field indicates the position within the current
     27 ;     individual message
     28 ;  "HDR" - the header segment, NOT parsed, as HDR(1) and HDR(2)
     29 ;  "ID" - Message Control ID for an individual message, Batch Control ID for a batch message
     30 ;  "IEN" - ien, file 778
     31 ;  "EVENT" - HL7 event, only defined if NOT batch
     32 ;  "MESSAGE TYPE" - HL7 message type, only defined if NOT batch
     33 ;  "STATUS" - the completion status
     34 ;
     35 ;     These are lower level subscripts of "STATUS":
     36 ;     "ACCEPT ACK RESPONSE" - the application's <tag>^<rtn> to Xecute when the accept ack is received
     37 ;     "ACCEPT ACK'D" - 1 if an accept ack was sent or received in response to this message
     38 ;     "APP ACK RESPONSE" - the application's <tag>^<rtn> to Xecute when app ack is received
     39 ;     "APP ACK'D" - 1 if an application ack was sent or received in response to this message
     40 ;     "ERROR TEXT" - if in error status, a description of the error
     41 ;     "LINK NAME" the link the message was transmitted through
     42 ;     "PORT" - remote port over which the message was transmitted
     43 ;     "PURGE" - scheduled purge dt/tm
     44 ;     "QUEUE" - the queue that the message was placed on
     45 ;
     46 K MSG
     47 Q:'$G(IEN) 0
     48 N NODE
     49 S MSG("IEN")=IEN
     50 S NODE=$G(^HLB(IEN,0))
     51 S MSG("ID")=$P(NODE,"^")
     52 S MSG("BODY")=$P(NODE,"^",2)
     53 S MSG("DIRECTION")=$S($E($P(NODE,"^",4))="O":"OUT",$E($P(NODE,"^",4))="I":"IN",1:"")
     54 S MSG("ACK TO")=$P(NODE,"^",3)
     55 S MSG("ACK BY")=$P(NODE,"^",7)
     56 I MSG("ACK TO")]"" S MSG("ACK TO IEN")=$$ACKTOIEN^HLOMSG1($P(NODE,"^"),MSG("ACK TO"))
     57 I MSG("ACK BY")]"" S MSG("ACK BY IEN")=$$ACKBYIEN^HLOMSG1($P(NODE,"^"),MSG("ACK BY"))
     58 S MSG("DT/TM")=$P(NODE,"^",16)
     59 S MSG("STATUS")=$P(NODE,"^",20)
     60 ;
     61 D
     62 .N NODE4
     63 .S NODE4=$G(^HLB(IEN,4))
     64 .S MSG("STATUS","QUEUE")=$P(NODE,"^",6)
     65 .S MSG("STATUS","LINK NAME")=$P(NODE,"^",5)
     66 .S MSG("STATUS","PORT")=$P(NODE,"^",8)
     67 .S MSG("STATUS","PURGE")=$P(NODE,"^",9)
     68 .S MSG("STATUS","ERROR TEXT")=$P(NODE,"^",21)
     69 .S MSG("STATUS","APP ACK RESPONSE")=$P(NODE,"^",10,11)
     70 .I MSG("STATUS","APP ACK RESPONSE")="^" S MSG("STATUS","APP ACK RESPONSE")=""
     71 .S MSG("STATUS","ACCEPT ACK RESPONSE")=$P(NODE,"^",12,13)
     72 .I MSG("STATUS","ACCEPT ACK RESPONSE")="^" S MSG("STATUS","ACCEPT ACK RESPONSE")=""
     73 .S MSG("STATUS","ACCEPT ACK'D")=$P(NODE,"^",17)
     74 .S MSG("STATUS","APP ACK'D")=$P(NODE,"^",18)
     75 .S MSG("STATUS")=$P(NODE,"^",20)
     76 .S MSG("STATUS","APP HANDOFF")=$P(NODE,"^",19)
     77 .S MSG("STATUS","ACCEPT ACK DT/TM")=$P(NODE4,"^")
     78 .S MSG("STATUS","ACCEPT ACK ID")=$P(NODE4,"^",2)
     79 .S MSG("STATUS","ACCEPT ACK MSA")=$P(NODE4,"^",3,99)
     80 ;
     81 S MSG("LINE COUNT")=0
     82 S MSG("HDR",1)=$G(^HLB(IEN,1))
     83 S MSG("HDR",2)=$G(^HLB(IEN,2))
     84 I 'MSG("BODY") D  Q 0
     85 .S MSG("DT/TM CREATED")=""
     86 .S MSG("BATCH")=""
     87 .S MSG("MESSAGE TYPE")=""
     88 .S MSG("EVENT")=""
     89 ;
     90 S NODE=$G(^HLA(MSG("BODY"),0))
     91 S MSG("DT/TM CREATED")=+NODE
     92 S MSG("BATCH")=+$P(NODE,"^",2)
     93 I MSG("BATCH") S MSG("BATCH","CURRENT MESSAGE")=0
     94 I 'MSG("BATCH") D
     95 .S MSG("MESSAGE TYPE")=$P(NODE,"^",3)
     96 .S MSG("EVENT")=$P(NODE,"^",4)
     97 Q 1
     98 ;
     99HLNEXT(MSG,SEG) ;
     100 ;Description:  Returns the next segment as a set of lines stored in SEG.
     101 ;Input:
     102 ;  MSG (pass by reference, required)
     103 ;Output:
     104 ;  Function returns 1 on success, 0 on failure (no more segments)
     105 ;  SEG (pass by reference, required)
     106 ;
     107 K SEG
     108 Q:MSG("LINE COUNT")=-1 0
     109 I 'MSG("BATCH") D
     110 .N I,J,NODE,START
     111 .S START=0
     112 .S J=1,I=MSG("LINE COUNT")
     113 .F  S I=$O(^HLA(MSG("BODY"),1,I)) Q:'I  S NODE=$G(^HLA(MSG("BODY"),1,I,0)) Q:(START&(NODE=""))  I NODE'="" S SEG(J)=NODE,J=J+1,START=1
     114 .I 'I D
     115 ..S MSG("LINE COUNT")=-1
     116 .E  S MSG("LINE COUNT")=I
     117 I MSG("BATCH") D
     118 .N I,J,NODE,START
     119 .S J=1,I=MSG("LINE COUNT"),START=0
     120 .F  S I=$O(^HLA(MSG("BODY"),2,MSG("BATCH","CURRENT MESSAGE"),1,I)) Q:'I  S NODE=$G(^HLA(MSG("BODY"),2,MSG("BATCH","CURRENT MESSAGE"),1,I,0)) Q:(START&(NODE=""))  I NODE'="" S SEG(J)=NODE,J=J+1,START=1
     121 .I 'I D
     122 ..S MSG("LINE COUNT")=-1
     123 .E  S MSG("LINE COUNT")=I
     124 Q $S($D(SEG):1,1:0)
     125 ;
     126NEXTMSG(MSG,HDR) ;
     127 ;Advances to the next message in the batch
     128 ;Input:
     129 ;  MSG (pass by reference, required) - defined by $$GETMSG()
     130 ;Output:
     131 ;  Function returns 1 on success, 0 if no more messages
     132 ;  MSG - updated with current position in the message
     133 ;  HDR (pass by reference, required) returns the header as an array of lines
     134 ;
     135 ;
     136 K HDR
     137 S MSG("LINE COUNT")=0
     138 N SUBIEN,I
     139 ;
     140 ;if completed parsing, don't start over
     141 I MSG("BATCH","CURRENT MESSAGE")=-1 Q 0
     142 ;
     143 S I=$O(^HLB(MSG("IEN"),3,"B",MSG("BATCH","CURRENT MESSAGE")))
     144 I 'I S MSG("BATCH","CURRENT MESSAGE")=-1 Q 0
     145 S MSG("BATCH","CURRENT MESSAGE")=I
     146 S SUBIEN=$O(^HLB(MSG("IEN"),3,"B",I,0))
     147 S HDR(1)=$G(^HLB(MSG("IEN"),3,SUBIEN,1))
     148 S HDR(2)=$G(^HLB(MSG("IEN"),3,SUBIEN,2))
     149 Q $S($D(HDR):1,1:0)
     150 ;
     151ADDSEG(HLMSTATE,SEG) ;Adds a segment to the message.
     152 ;Input:
     153 ;  HLMSTATE() - (pass by reference, required)
     154 ;  SEG() - (pass by reference, required) The segment as lines SEG(<i>)
     155 ;
     156 ;Output:
     157 ;   HLMSTATE()
     158 ;
     159 N I,J S I=0
     160 S J=HLMSTATE("LINE COUNT")
     161 ;
     162 ;insure a blank line between segments
     163 I J S J=J+1,HLMSTATE("UNSTORED LINES",$S(HLMSTATE("BATCH"):HLMSTATE("BATCH","CURRENT MESSAGE"),1:1),HLMSTATE("CURRENT SEGMENT"),J)=""
     164 ;
     165 S HLMSTATE("CURRENT SEGMENT")=HLMSTATE("CURRENT SEGMENT")+1
     166 F  S I=$O(SEG(I)) Q:'I  D
     167 .S J=J+1
     168 .S HLMSTATE("UNSTORED LINES",$S(HLMSTATE("BATCH"):HLMSTATE("BATCH","CURRENT MESSAGE"),1:1),HLMSTATE("CURRENT SEGMENT"),J)=SEG(I),HLMSTATE("UNSTORED LINES")=HLMSTATE("UNSTORED LINES")+$L(SEG(I))+50
     169 .I HLMSTATE("UNSTORED LINES")>HLMSTATE("SYSTEM","BUFFER") D
     170 ..I HLMSTATE("DIRECTION")="IN",$$SAVEMSG^HLOF778(.HLMSTATE) Q
     171 ..I HLMSTATE("DIRECTION")="OUT",$$SAVEMSG^HLOF777(.HLMSTATE)
     172 ;
     173 S HLMSTATE("LINE COUNT")=J
     174 Q
     175 ;
     176ADDMSG(HLMSTATE,PARMS) ;
     177 ;For outgoing messages, adds a message in the batch. There is no MSH yet, just the message type and event. 
     178 ;Input:
     179 ;  HLMSTATE() - (pass by reference, required)
     180 ;  PARMS("EVENT")
     181 ;  PARMS("MESSAGE TYPE")
     182 ;
     183 ;Output:
     184 ;   HLMSTATE() - (pass by reference, required)
     185 ;
     186 N I
     187 S I=HLMSTATE("BATCH","CURRENT MESSAGE")+1,HLMSTATE("BATCH","CURRENT MESSAGE")=I
     188 S HLMSTATE("UNSTORED LINES",I)=PARMS("MESSAGE TYPE")_"^"_PARMS("EVENT")
     189 M:$G(PARMS("ACK TO"))]"" HLMSTATE("BATCH","ACK TO",I)=PARMS("ACK TO")
     190 S HLMSTATE("CURRENT SEGMENT")=0
     191 S HLMSTATE("LINE COUNT")=0
     192 S HLMSTATE("UNSTORED LINES")=HLMSTATE("UNSTORED LINES")+100
     193 Q
     194 ;
     195ADDMSG2(HLMSTATE,MSH) ;
     196 ;For incoming messages adds a message to the batch. This differs from ADDMSG in that the MSH segment is passed in to be stored in file 778.
     197 ;Input:
     198 ;  HLMSTATE() - (pass by reference, required)
     199 ;  MSH(<i>) - the MSH segment as a set of lines
     200 ;
     201 ;Output:
     202 ;   HLMSTATE() - (pass by reference, required)
     203 ;
     204 N FS,CS,VALUE
     205 S HLMSTATE("BATCH","CURRENT MESSAGE")=HLMSTATE("BATCH","CURRENT MESSAGE")+1
     206 S FS=$E(MSH(1),4)
     207 S CS=$E(MSH(1),5)
     208 S VALUE=$P(MSH(2),FS,4)
     209 S HLMSTATE("UNSTORED LINES",HLMSTATE("BATCH","CURRENT MESSAGE"))=$P(VALUE,CS)_"^"_$P(VALUE,CS,2)
     210 S HLMSTATE("UNSTORED MSH")=1
     211 M HLMSTATE("UNSTORED MSH",HLMSTATE("BATCH","CURRENT MESSAGE"))=MSH
     212 S HLMSTATE("CURRENT SEGMENT")=0
     213 S HLMSTATE("LINE COUNT")=0
     214 S HLMSTATE("UNSTORED LINES")=HLMSTATE("UNSTORED LINES")+200
     215 I HLMSTATE("UNSTORED LINES")>HLMSTATE("SYSTEM","BUFFER"),$$SAVEMSG^HLOF778(.HLMSTATE) ;first stores stuff in 777, then headers in file 778
     216 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOPOST.m

    r613 r623  
    1 HLOPOST ;IRMFO-ALB/CJM -Post-Install routine for HLO;03/24/2004  14:43 ;07/20/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,134,136,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         N SYSTEM,DATA,VASITE,OLDSITE
    6         D IDXLINKS
    7         D SYSPARMS^HLOSITE(.SYSTEM)
    8         S VASITE=$$SITE^VASITE
    9         S OLDSITE=$G(^HLCS(869.3,1,0))
    10         S DATA(.01)=SYSTEM("DOMAIN")
    11         I DATA(.01)="" D
    12         .I $P(OLDSITE,"^",2) S DATA(.01)="HL7."_$P($G(^DIC(4.2,$P(OLDSITE,"^",2),0)),"^")
    13         I DATA(.01)="" D
    14         .N INST,DOMAIN
    15         .S INST=$P(VASITE,"^")
    16         .Q:'INST
    17         .S DOMAIN=$P($G(^DIC(4,INST,6)),"^")
    18         .I DOMAIN S DOMAIN=$P($G(^DIC(4.2,DOMAIN,0)),"^") I DOMAIN'="" S DATA(.01)="HL7."_DOMAIN
    19         I DATA(.01)="" D BMES^XPDUTL("Post-Install failed, system missing INSTITUTION or DOMAIN file entry") Q
    20         S DATA(.02)=SYSTEM("STATION")
    21         I DATA(.02)="",$P(OLDSITE,"^",4) S DATA(.02)=$P($G(^DIC(4,$P(OLDSITE,"^",4),99)),"^")
    22         I DATA(.02)="" S DATA(.02)=$P(VASITE,"^",3)
    23         S DATA(.03)=$P(OLDSITE,"^",3)
    24         S DATA(.04)=SYSTEM("MAXSTRING")
    25         S DATA(.05)=SYSTEM("HL7 BUFFER")
    26         S DATA(.06)=SYSTEM("USER BUFFER")
    27         S DATA(.07)=SYSTEM("NORMAL PURGE")
    28         S DATA(.08)=SYSTEM("ERROR PURGE")
    29         I $D(^HLD(779.1,1,0)) D
    30         .N ERROR
    31         .I '$$UPD^HLOASUB1(779.1,1,.DATA,.ERROR) D BMES^XPDUTL("Post-Install failed -"_$G(ERROR))
    32         E  D
    33         .N ERROR
    34         .I '$$ADD^HLOASUB1(779.1,,.DATA,.ERROR,1) D BMES^XPDUTL("Post-Install failed -"_$G(ERROR))
    35         Q
    36 IDXLINKS        ;
    37         ;set the "AC" and "AD" indicies on the HL Logical Link file
    38         N DIK
    39         S DIK="^HLCS(870,"
    40         S DIK(1)=".01^AC^AD^AD1^AD2"
    41         D ENALL^DIK
    42         Q
    43         ;
    44 P134    ;
    45         N DAILY,STARTUP,IEN,DATA
    46         S DAILY=$O(^DIC(19,"B","HLO DAILY STARTUP",0))
    47         I 'DAILY D BMES^XPDUTL("Failed to schedule the HLO DAILY STARTUP option!")
    48         S STARTUP=$O(^DIC(19,"B","HLO SYSTEM STARTUP",0))
    49         I 'STARTUP D BMES^XPDUTL("Failed to schedule the HLO SYSTEM STARTUP option!")
    50         I STARTUP D
    51         .S IEN=$O(^DIC(19.2,"B",STARTUP,0))
    52         .S DATA(.01)=STARTUP
    53         .S DATA(2)=""
    54         .S DATA(6)=""
    55         .S DATA(9)=$S($P($G(^HLD(779.1,1,0)),"^",3)="P":"S",1:"")
    56         .I IEN D
    57         ..I '$$UPD^HLOASUB1(19.2,IEN,.DATA) D BMES^XPDUTL("Failed to schedule the HLO SYSTEM STARTUP option!")
    58         .E  D
    59         ..I '$$ADD^HLOASUB1(19.2,,.DATA) D BMES^XPDUTL("Failed to schedule the HLO SYSTEM STARTUP option!")
    60         I DAILY D
    61         .S IEN=$O(^DIC(19.2,"B",DAILY,0))
    62         .S DATA(.01)=DAILY
    63         .S DATA(2)=$$NOW^XLFDT
    64         .S DATA(6)="1D"
    65         .S DATA(9)=""
    66         .I IEN D
    67         ..I '$$UPD^HLOASUB1(19.2,IEN,.DATA) D BMES^XPDUTL("Failed to schedule the HLO DAILY STARTUP option!")
    68         .E  D
    69         ..I '$$ADD^HLOASUB1(19.2,,.DATA) D BMES^XPDUTL("Failed to schedule the HLO DAILY STARTUP option!")
    70         Q
    71         ;
    72 P136    ;post-install routine for HL*1.6*136
    73         N ERROR,DIFROM,IEN
    74         I $P($G(^HLD(779.1,1,0)),"^",3)="P" D
    75         .D RESCH^XUTMOPT("HLO DAILY STARTUP",$$FMADD^XLFDT($$NOW^XLFDT,,1),,"1D","L",.ERROR)
    76         .I $G(ERROR)<0 D BMES^XPDUTL("Failed to schedule the HLO DAILY STARTUP option! Please do so manually")
    77         ;
    78         S IEN=$O(^HLD(779.3,"B","PURGE OLD MESSAGES",0))
    79         Q:'IEN
    80         S ^HLD(779.3,IEN,0)="PURGE OLD MESSAGES^1^0^2^20^^5^GETWORK^HLOPURGE^DOWORK^HLOPURGE^1^0"
    81         Q
    82         ;
    83 P137    ;
    84         ;move the existing errros to the new structure
    85         N TYPE
    86         K ^TMP($J,"HLO ERRORS")
    87         F TYPE="TF","SE","AE" D
    88         .M ^TMP($J,"HLO ERRORS",TYPE)=^HLB("ERRORS",TYPE)
    89         .M ^HLB("ERRORS")=^TMP($J,"HLO ERRORS",TYPE)
    90         .K ^TMP($J,"HLO ERRORS",TYPE)
    91         .K ^HLB("ERRORS",TYPE)
    92         Q
     1HLOPOST ;IRMFO-ALB/CJM -Post-Install routine for HLO;03/24/2004  14:43 ;05/03/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,134,136**;Oct 13, 1995;Build 9
     3 ;
     4 N SYSTEM,DATA,VASITE,OLDSITE
     5 D IDXLINKS
     6 D SYSPARMS^HLOSITE(.SYSTEM)
     7 S VASITE=$$SITE^VASITE
     8 S OLDSITE=$G(^HLCS(869.3,1,0))
     9 S DATA(.01)=SYSTEM("DOMAIN")
     10 I DATA(.01)="" D
     11 .I $P(OLDSITE,"^",2) S DATA(.01)="HL7."_$P($G(^DIC(4.2,$P(OLDSITE,"^",2),0)),"^")
     12 I DATA(.01)="" D
     13 .N INST,DOMAIN
     14 .S INST=$P(VASITE,"^")
     15 .Q:'INST
     16 .S DOMAIN=$P($G(^DIC(4,INST,6)),"^")
     17 .I DOMAIN S DOMAIN=$P($G(^DIC(4.2,DOMAIN,0)),"^") I DOMAIN'="" S DATA(.01)="HL7."_DOMAIN
     18 I DATA(.01)="" D BMES^XPDUTL("Post-Install failed, system missing INSTITUTION or DOMAIN file entry") Q
     19 S DATA(.02)=SYSTEM("STATION")
     20 I DATA(.02)="",$P(OLDSITE,"^",4) S DATA(.02)=$P($G(^DIC(4,$P(OLDSITE,"^",4),99)),"^")
     21 I DATA(.02)="" S DATA(.02)=$P(VASITE,"^",3)
     22 S DATA(.03)=$P(OLDSITE,"^",3)
     23 S DATA(.04)=SYSTEM("MAXSTRING")
     24 S DATA(.05)=SYSTEM("HL7 BUFFER")
     25 S DATA(.06)=SYSTEM("USER BUFFER")
     26 S DATA(.07)=SYSTEM("NORMAL PURGE")
     27 S DATA(.08)=SYSTEM("ERROR PURGE")
     28 I $D(^HLD(779.1,1,0)) D
     29 .N ERROR
     30 .I '$$UPD^HLOASUB1(779.1,1,.DATA,.ERROR) D BMES^XPDUTL("Post-Install failed -"_$G(ERROR))
     31 E  D
     32 .N ERROR
     33 .I '$$ADD^HLOASUB1(779.1,,.DATA,.ERROR,1) D BMES^XPDUTL("Post-Install failed -"_$G(ERROR))
     34 Q
     35IDXLINKS ;
     36 ;set the "AC" and "AD" indicies on the HL Logical Link file
     37 N DIK
     38 S DIK="^HLCS(870,"
     39 S DIK(1)=".01^AC^AD^AD1^AD2"
     40 D ENALL^DIK
     41 Q
     42 ;
     43P134 ;
     44 N DAILY,STARTUP,IEN,DATA
     45 S DAILY=$O(^DIC(19,"B","HLO DAILY STARTUP",0))
     46 I 'DAILY D BMES^XPDUTL("Failed to schedule the HLO DAILY STARTUP option!")
     47 S STARTUP=$O(^DIC(19,"B","HLO SYSTEM STARTUP",0))
     48 I 'STARTUP D BMES^XPDUTL("Failed to schedule the HLO SYSTEM STARTUP option!")
     49 I STARTUP D
     50 .S IEN=$O(^DIC(19.2,"B",STARTUP,0))
     51 .S DATA(.01)=STARTUP
     52 .S DATA(2)=""
     53 .S DATA(6)=""
     54 .S DATA(9)=$S($P($G(^HLD(779.1,1,0)),"^",3)="P":"S",1:"")
     55 .I IEN D
     56 ..I '$$UPD^HLOASUB1(19.2,IEN,.DATA) D BMES^XPDUTL("Failed to schedule the HLO SYSTEM STARTUP option!")
     57 .E  D
     58 ..I '$$ADD^HLOASUB1(19.2,,.DATA) D BMES^XPDUTL("Failed to schedule the HLO SYSTEM STARTUP option!")
     59 I DAILY D
     60 .S IEN=$O(^DIC(19.2,"B",DAILY,0))
     61 .S DATA(.01)=DAILY
     62 .S DATA(2)=$$NOW^XLFDT
     63 .S DATA(6)="1D"
     64 .S DATA(9)=""
     65 .I IEN D
     66 ..I '$$UPD^HLOASUB1(19.2,IEN,.DATA) D BMES^XPDUTL("Failed to schedule the HLO DAILY STARTUP option!")
     67 .E  D
     68 ..I '$$ADD^HLOASUB1(19.2,,.DATA) D BMES^XPDUTL("Failed to schedule the HLO DAILY STARTUP option!")
     69 Q
     70 ;
     71P136 ;post-install routine for HL*1.6*136
     72 N ERROR,DIFROM,IEN
     73 I $P($G(^HLD(779.1,1,0)),"^",3)="P" D
     74 .D RESCH^XUTMOPT("HLO DAILY STARTUP",$$FMADD^XLFDT($$NOW^XLFDT,,1),,"1D","L",.ERROR)
     75 .I $G(ERROR)<0 D BMES^XPDUTL("Failed to schedule the HLO DAILY STARTUP option! Please do so manually")
     76 ;
     77 S IEN=$O(^HLD(779.3,"B","PURGE OLD MESSAGES",0))
     78 Q:'IEN
     79 S ^HLD(779.3,IEN,0)="PURGE OLD MESSAGES^1^0^2^20^^5^GETWORK^HLOPURGE^DOWORK^HLOPURGE^1^0"
     80 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOPURGE.m

    r613 r623  
    1 HLOPURGE        ;IRMFO-ALB/CJM - Purging Old Messages;03/24/2004  14:43 ;07/25/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,134,136,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 GETWORK(WORK)   ;
    6         ;
    7         N OK
    8         S OK=0
    9         I $G(WORK)]"" L -HLPURGE(WORK)
    10         F WORK="IN","OUT","OLD778","OLD777" I '$G(WORK("DONE",WORK)) S WORK("DONE",WORK)=1 L +HLPURGE(WORK):0 S OK=$T Q:OK
    11         I 'OK K WORK("DONE") S WORK=""
    12         Q OK
    13         ;
    14 DOWORK(WORK)    ;
    15         I WORK="OLD778" D OLD778
    16         I WORK="OLD777" D OLD777
    17         I (WORK="IN")!(WORK="OUT") D
    18         .N TIME,NOW
    19         .S NOW=$$NOW^XLFDT
    20         .S TIME=0
    21         .F  S TIME=$O(^HLB("AD",WORK,TIME)) Q:TIME=""  Q:TIME>NOW  D
    22         ..N MSGIEN
    23         ..S MSGIEN=0
    24         ..F  S MSGIEN=$O(^HLB("AD",WORK,TIME,MSGIEN)) Q:'MSGIEN  D
    25         ...K ^HLB("AD",WORK,TIME,MSGIEN)
    26         ...D DELETE(MSGIEN)
    27         L -HLPURGE(WORK)
    28         Q
    29 OLD778  ;
    30         N OLD,START,END,APP,TYPE,TODAY,PARMS
    31         S TODAY=$$DT^XLFDT
    32         S OLD=$$FMADD^XLFDT(TODAY,-45)
    33         F START=0,100000000000,200000000000,300000000000 D
    34         .S END=(START+100000000000)-1
    35         .N MSGIEN,QUIT
    36         .S QUIT=0
    37         .S MSGIEN=START
    38         .F  S MSGIEN=$O(^HLB(MSGIEN)) Q:'MSGIEN  Q:(MSGIEN>END)  D  Q:QUIT
    39         ..N WHEN,BODY,NODE
    40         ..S NODE=$G(^HLB(MSGIEN,0))
    41         ..S WHEN=$P(NODE,"^",16)
    42         ..I WHEN,WHEN<OLD,$P(NODE,"^",9)<TODAY D DELETE(MSGIEN) Q
    43         ..I 'WHEN D
    44         ...S BODY=$P(NODE,"^",2)
    45         ...Q:'BODY
    46         ...S WHEN=+$G(^HLA(BODY,0))
    47         ...I WHEN,WHEN<OLD D  Q
    48         ....;I've seen messages sitting on outgoing queues forever, but it should never happen for incoming
    49         ....I $E($P(NODE,"^",4))="O",$P(NODE,"^",5)]"",$P(NODE,"^",6)]"" D
    50         .....N FROM
    51         .....S FROM=$P(NODE,"^",5)
    52         .....I $P(NODE,"^",8) S FROM=FROM_":"_$P(NODE,"^",8)
    53         .....Q:'$D(^HLB("QUEUE","OUT",FROM,$P(NODE,"^",6),MSGIEN))
    54         .....D DEQUE^HLOQUE(FROM,$P(NODE,"^",6),"OUT",MSGIEN)
    55         ....D DELETE(MSGIEN) Q
    56         ...;stop looking for old records?
    57         ...I WHEN,WHEN>OLD S QUIT=1
    58         ;
    59         ;also kill old errors left lying around
    60         D SYSPARMS^HLOSITE(.PARMS)
    61         S OLD=$$FMADD^XLFDT($$DT^XLFDT,-PARMS("ERROR PURGE"))
    62         S APP=""
    63         F  S APP=$O(^HLB("ERRORS",APP)) Q:APP=""  D
    64         .N TIME
    65         .S TIME=0
    66         .F  S TIME=$O(^HLB("ERRORS",APP,TIME)) Q:'TIME  Q:TIME>OLD  K ^HLB("ERRORS",APP,TIME)
    67         Q
    68 OLD777  ;
    69         N OLD,TIME,TODAY
    70         S TODAY=$$DT^XLFDT
    71         S OLD=$$FMADD^XLFDT(TODAY,-45)
    72         S TIME=0
    73         F  S TIME=$O(^HLA("B",TIME)) Q:'TIME  Q:TIME>OLD  D
    74         .N MSGIEN
    75         .S MSGIEN=0
    76         .F  S MSGIEN=$O(^HLA("B",TIME,MSGIEN)) Q:'MSGIEN  D
    77         ..N IEN778,STOP
    78         ..S (STOP,IEN778)=0
    79         ..F  S IEN778=$O(^HLB("C",MSGIEN,IEN778)) Q:'IEN778  D
    80         ...I $P($G(^HLB(IEN778,0)),"^",9)>TODAY S STOP=1 Q
    81         ...D DELETE(IEN778,1)
    82         ..K:'STOP ^HLB("C",MSGIEN),^HLA("B",TIME,MSGIEN),^HLA(MSGIEN)
    83         Q
    84         ;
    85 DELETE(MSGIEN,FLAG)     ;
    86         ;Input:
    87         ;  MSGIEN - IEN, file 778
    88         ;  FLAG - if $G(FLAG), will not delete the pointed to record in file 777
    89         N AC,SUBIEN,RAPP,SAPP,FS,CS,MSG
    90         I '$$GETMSG^HLOMSG(MSGIEN,.MSG) ;MSG is corrupted, but there sill may be nodes to delete
    91         S (RAPP,SAPP)=""
    92         D
    93         .S FS=$E(MSG("HDR",1),4)
    94         .Q:FS=""
    95         .S CS=$E(MSG("HDR",1),5)
    96         .S SAPP=$P($P(MSG("HDR",1),FS,3),CS)
    97         .I SAPP="" S SAPP="UNKNOWN"
    98         .S RAPP=$P($P(MSG("HDR",1),FS,5),CS)
    99         .I RAPP="" S RAPP="UNKNOWN"
    100         ;
    101         I 'MSG("BATCH") D KSEARCH(.MSG,MSG("MESSAGE TYPE"),MSG("EVENT"),SAPP,RAPP,MSGIEN)
    102         ;if an error status,take care of the "ERRORS" x-ref
    103         I MSG("STATUS")'="",MSG("STATUS")'="SU",MSG("BODY") D
    104         .K ^HLB("ERRORS",RAPP,MSG("DT/TM CREATED"),MSGIEN)
    105         .I MSG("STATUS")="ER" D
    106         ..N SUB
    107         ..S SUB=MSGIEN_"^"
    108         ..K ^HLB("ERRORS",RAPP,MSG("DT/TM CREATED"),SUB)
    109         ..F  S SUB=$O(^HLB("ERRORS",RAPP,MSG("DT/TM CREATED"),SUB)) Q:SUB=""  Q:+SUB'=MSGIEN  K ^HLB("ERRORS",RAPP,MSG("DT/TM CREATED"),SUB)
    110         ;
    111         ;kill the whole-file xrefs for the message ien within a batch
    112         S SUBIEN=0
    113         F  S SUBIEN=$O(^HLB(MSGIEN,3,SUBIEN)) Q:'SUBIEN  D
    114         .N MSGID
    115         .I FS]"" D
    116         ..N VALUE,HDR2,MSGTYPE,EVENT
    117         ..S HDR2=$G(^HLB(MSGIEN,3,SUBIEN,2))
    118         ..S VALUE=$P(HDR2,FS,4)
    119         ..S MSGTYPE=$P(VALUE,CS)
    120         ..S EVENT=$P(VALUE,CS,2)
    121         ..D KSEARCH(.MSG,MSGTYPE,EVENT,SAPP,RAPP,MSGIEN_"^"_SUBIEN)
    122         .S MSGID=$P($G(^HLB(MSGIEN,3,SUBIEN,0)),"^",2)
    123         .I MSGID]"" K ^HLB("AE",MSGID,MSGIEN_"^"_SUBIEN)
    124         ;
    125         I MSG("DIRECTION")="IN" D
    126         .Q:FS=""
    127         .N VALUE,HDR
    128         .S HDR("SENDING APPLICATION")=$P(MSG("HDR",1),FS,3)
    129         .S VALUE=$P(MSG("HDR",1),FS,4)
    130         .S HDR("SENDING FACILITY",1)=$P(VALUE,CS)
    131         .S HDR("SENDING FACILITY",2)=$P(VALUE,CS,2)
    132         .S HDR("SENDING FACILITY",3)=$P(VALUE,CS,3)
    133         .S AC=$S(HDR("SENDING FACILITY",2)]"":HDR("SENDING FACILITY",2),1:HDR("SENDING FACILITY",1))_HDR("SENDING APPLICATION")_MSG("ID")
    134         K ^HLB(MSGIEN)
    135         I MSG("STATUS","PURGE"),MSG("DIRECTION")'="" K ^HLB("AD",MSG("DIRECTION"),MSG("STATUS","PURGE"),MSGIEN)
    136         K:(MSG("ID")]"") ^HLB("B",MSG("ID"),MSGIEN)
    137         I MSG("DIRECTION")="IN" D
    138         .K:($G(AC)]"") ^HLB("AC",AC,MSGIEN)
    139         .I MSG("BODY"),'$G(FLAG) D KILL777(MSG("BODY"))
    140         I MSG("DIRECTION")="OUT" D
    141         .K ^HLB("C",+MSG("BODY"),MSGIEN)
    142         .I '$G(FLAG),'$O(^HLB("C",+MSG("BODY"),0)) D KILL777(MSG("BODY"))
    143         Q
    144         ;
    145 KILL777(BODY)   ;
    146         Q:'$G(BODY)
    147         N TIME
    148         S TIME=$P($G(^HLA(BODY,0)),"^")
    149         K ^HLA(BODY)
    150         K:(TIME]"") ^HLA("B",TIME,BODY)
    151         Q
    152         ;
    153 KSEARCH(MSG,MSGTYPE,EVENT,SAPP,RAPP,IEN)        ;
    154         ;Kills the ^HLB("SEARCH") x-ref
    155         ;
    156         N APP
    157         S:MSGTYPE="" MSGTYPE="<none>"
    158         S:EVENT="" EVENT="<none>"
    159         Q:'MSG("DT/TM CREATED")
    160         I MSG("DIRECTION")'="IN",MSG("DIRECTION")'="OUT" Q
    161         S APP=$S(MSG("DIRECTION")="IN":RAPP,1:SAPP)
    162         Q:APP=""
    163         K ^HLB("SEARCH",MSG("DIRECTION"),MSG("DT/TM CREATED"),APP,MSGTYPE,EVENT,IEN)
    164         Q
     1HLOPURGE ;IRMFO-ALB/CJM - Purging Old Messages;03/24/2004  14:43 ;04/30/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,134,136**;Oct 13, 1995;Build 9
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5GETWORK(WORK) ;
     6 ;
     7 N OK
     8 S OK=0
     9 I $G(WORK)]"" L -HLPURGE(WORK)
     10 F WORK="IN","OUT","OLD778","OLD777" I '$G(WORK("DONE",WORK)) S WORK("DONE",WORK)=1 L +HLPURGE(WORK):0 S OK=$T Q:OK
     11 I 'OK K WORK("DONE") S WORK=""
     12 Q OK
     13 ;
     14DOWORK(WORK) ;
     15 I WORK="OLD778" D OLD778
     16 I WORK="OLD777" D OLD777
     17 I (WORK="IN")!(WORK="OUT") D
     18 .N TIME,NOW
     19 .S NOW=$$NOW^XLFDT
     20 .S TIME=0
     21 .F  S TIME=$O(^HLB("AD",WORK,TIME)) Q:TIME=""  Q:TIME>NOW  D
     22 ..N MSGIEN
     23 ..S MSGIEN=0
     24 ..F  S MSGIEN=$O(^HLB("AD",WORK,TIME,MSGIEN)) Q:'MSGIEN  D
     25 ...K ^HLB("AD",WORK,TIME,MSGIEN)
     26 ...D DELETE(MSGIEN)
     27 L -HLPURGE(WORK)
     28 Q
     29OLD778 ;
     30 N OLD,START,END,APP,TYPE,TODAY
     31 S TODAY=$$DT^XLFDT
     32 S OLD=$$FMADD^XLFDT(TODAY,-45)
     33 F START=0,100000000000,200000000000,300000000000 D
     34 .S END=(START+100000000000)-1
     35 .N MSGIEN,QUIT
     36 .S QUIT=0
     37 .S MSGIEN=START
     38 .F  S MSGIEN=$O(^HLB(MSGIEN)) Q:'MSGIEN  Q:(MSGIEN>END)  D  Q:QUIT
     39 ..N WHEN,BODY,NODE
     40 ..S NODE=$G(^HLB(MSGIEN,0))
     41 ..S WHEN=$P(NODE,"^",16)
     42 ..I WHEN,WHEN<OLD,$P(NODE,"^",9)<TODAY D DELETE(MSGIEN) Q
     43 ..I 'WHEN D
     44 ...S BODY=$P(NODE,"^",2)
     45 ...Q:'BODY
     46 ...S WHEN=+$G(^HLA(BODY,0))
     47 ...I WHEN,WHEN<OLD D  Q
     48 ....;I've seen messages sitting on outgoing queues forever, but it should never happen for incoming
     49 ....I $E($P(NODE,"^",4))="O",$P(NODE,"^",5)]"",$P(NODE,"^",6)]"" D
     50 .....N FROM
     51 .....S FROM=$P(NODE,"^",5)
     52 .....I $P(NODE,"^",8) S FROM=FROM_":"_$P(NODE,"^",8)
     53 .....Q:'$D(^HLB("QUEUE","OUT",FROM,$P(NODE,"^",6),MSGIEN))
     54 .....D DEQUE^HLOQUE(FROM,$P(NODE,"^",6),"OUT",MSGIEN)
     55 ....D DELETE(MSGIEN) Q
     56 ...;stop looking for old records?
     57 ...I WHEN,WHEN>OLD S QUIT=1
     58 ;
     59 ;also kill old errors left lying around
     60 F TYPE="TF","AE","SE" S APP="" F  S APP=$O(^HLB("ERRORS",TYPE,APP)) Q:APP=""  D
     61 .N TIME,PARMS
     62 .D SYSPARMS^HLOSITE(.PARMS)
     63 .S OLD=$$FMADD^XLFDT($$DT^XLFDT,-PARMS("ERROR PURGE"))
     64 .S TIME=0
     65 .F  S TIME=$O(^HLB("ERRORS",TYPE,APP,TIME)) Q:'TIME  Q:TIME>OLD  K ^HLB("ERRORS",TYPE,APP,TIME)
     66 Q
     67OLD777 ;
     68 N OLD,TIME,TODAY
     69 S TODAY=$$DT^XLFDT
     70 S OLD=$$FMADD^XLFDT(TODAY,-45)
     71 S TIME=0
     72 F  S TIME=$O(^HLA("B",TIME)) Q:'TIME  Q:TIME>OLD  D
     73 .N MSGIEN
     74 .S MSGIEN=0
     75 .F  S MSGIEN=$O(^HLA("B",TIME,MSGIEN)) Q:'MSGIEN  D
     76 ..N IEN778,STOP
     77 ..S (STOP,IEN778)=0
     78 ..F  S IEN778=$O(^HLB("C",MSGIEN,IEN778)) Q:'IEN778  D
     79 ...I $P($G(^HLB(IEN778,0)),"^",9)>TODAY S STOP=1 Q
     80 ...D DELETE(IEN778,1)
     81 ..K:'STOP ^HLB("C",MSGIEN),^HLA("B",TIME,MSGIEN),^HLA(MSGIEN)
     82 Q
     83 ;
     84DELETE(MSGIEN,FLAG) ;
     85 ;Input:
     86 ;  MSGIEN - IEN, file 778
     87 ;  FLAG - if $G(FLAG), will not delete the pointed to record in file 777
     88 N AC,SUBIEN,RAPP,SAPP,FS,CS,MSG
     89 I '$$GETMSG^HLOMSG(MSGIEN,.MSG) ;MSG is corrupted, but there sill may be nodes to delete
     90 S (RAPP,SAPP)=""
     91 D
     92 .S FS=$E(MSG("HDR",1),4)
     93 .Q:FS=""
     94 .S CS=$E(MSG("HDR",1),5)
     95 .S SAPP=$P($P(MSG("HDR",1),FS,3),CS)
     96 .I SAPP="" S SAPP="UNKNOWN"
     97 .S RAPP=$P($P(MSG("HDR",1),FS,5),CS)
     98 .I RAPP="" S RAPP="UNKNOWN"
     99 ;
     100 I 'MSG("BATCH") D KSEARCH(.MSG,MSG("MESSAGE TYPE"),MSG("EVENT"),SAPP,RAPP,MSGIEN)
     101 ;if an error status,take care of the "ERRORS" x-ref
     102 I MSG("STATUS")'="",MSG("STATUS")'="SU",MSG("BODY") D
     103 .N APP
     104 .S APP=$S(MSG("STATUS")="TF":SAPP,1:RAPP)
     105 .K ^HLB("ERRORS",MSG("STATUS"),APP,MSG("DT/TM CREATED"),MSGIEN)
     106 .I MSG("STATUS")="AE" D
     107 ..N SUB
     108 ..S SUB=MSGIEN_"^"
     109 ..K ^HLB("ERRORS","AE",APP,MSG("DT/TM CREATED"),SUB)
     110 ..F  S SUB=$O(^HLB("ERRORS","AE",APP,MSG("DT/TM CREATED"),SUB)) Q:SUB=""  Q:+SUB'=MSGIEN  K ^HLB("ERRORS","AE",APP,MSG("DT/TM CREATED"),SUB)
     111 ;
     112 ;kill the whole-file xrefs for the message ien within a batch
     113 S SUBIEN=0
     114 F  S SUBIEN=$O(^HLB(MSGIEN,3,SUBIEN)) Q:'SUBIEN  D
     115 .N MSGID
     116 .I FS]"" D
     117 ..N VALUE,HDR2,MSGTYPE,EVENT
     118 ..S HDR2=$G(^HLB(MSGIEN,3,SUBIEN,2))
     119 ..S VALUE=$P(HDR2,FS,4)
     120 ..S MSGTYPE=$P(VALUE,CS)
     121 ..S EVENT=$P(VALUE,CS,2)
     122 ..D KSEARCH(.MSG,MSGTYPE,EVENT,SAPP,RAPP,MSGIEN_"^"_SUBIEN)
     123 .S MSGID=$P($G(^HLB(MSGIEN,3,SUBIEN,0)),"^",2)
     124 .I MSGID]"" K ^HLB("AE",MSGID,MSGIEN_"^"_SUBIEN)
     125 ;
     126 I MSG("DIRECTION")="IN" D
     127 .Q:FS=""
     128 .N VALUE,HDR
     129 .S HDR("SENDING APPLICATION")=$P(MSG("HDR",1),FS,3)
     130 .S VALUE=$P(MSG("HDR",1),FS,4)
     131 .S HDR("SENDING FACILITY",1)=$P(VALUE,CS)
     132 .S HDR("SENDING FACILITY",2)=$P(VALUE,CS,2)
     133 .S HDR("SENDING FACILITY",3)=$P(VALUE,CS,3)
     134 .S AC=$S(HDR("SENDING FACILITY",2)]"":HDR("SENDING FACILITY",2),1:HDR("SENDING FACILITY",1))_HDR("SENDING APPLICATION")_MSG("ID")
     135 K ^HLB(MSGIEN)
     136 I MSG("STATUS","PURGE"),MSG("DIRECTION")'="" K ^HLB("AD",MSG("DIRECTION"),MSG("STATUS","PURGE"),MSGIEN)
     137 K:(MSG("ID")]"") ^HLB("B",MSG("ID"),MSGIEN)
     138 I MSG("DIRECTION")="IN" D
     139 .K:($G(AC)]"") ^HLB("AC",AC,MSGIEN)
     140 .I MSG("BODY"),'$G(FLAG) D KILL777(MSG("BODY"))
     141 I MSG("DIRECTION")="OUT" D
     142 .K ^HLB("C",+MSG("BODY"),MSGIEN)
     143 .I '$G(FLAG),'$O(^HLB("C",+MSG("BODY"),0)) D KILL777(MSG("BODY"))
     144 Q
     145 ;
     146KILL777(BODY) ;
     147 Q:'$G(BODY)
     148 N TIME
     149 S TIME=$P($G(^HLA(BODY,0)),"^")
     150 K ^HLA(BODY)
     151 K:(TIME]"") ^HLA("B",TIME,BODY)
     152 Q
     153 ;
     154KSEARCH(MSG,MSGTYPE,EVENT,SAPP,RAPP,IEN) ;
     155 ;Kills the ^HLB("SEARCH") x-ref
     156 ;
     157 N APP
     158 S:MSGTYPE="" MSGTYPE="<none>"
     159 S:EVENT="" EVENT="<none>"
     160 Q:'MSG("DT/TM CREATED")
     161 I MSG("DIRECTION")'="IN",MSG("DIRECTION")'="OUT" Q
     162 S APP=$S(MSG("DIRECTION")="IN":RAPP,1:SAPP)
     163 Q:APP=""
     164 K ^HLB("SEARCH",MSG("DIRECTION"),MSG("DT/TM CREATED"),APP,MSGTYPE,EVENT,IEN)
     165 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOQUE.m

    r613 r623  
    1 HLOQUE  ;ALB/CJM- HL7 QUEUE MANAGEMENT - 10/4/94 1pm ;07/31/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,132,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 INQUE(FROM,QNAME,IEN778,ACTION,PURGE)   ;
    6         ;Will place the message=IEN778 on the IN queue, incoming
    7         ;Input:
    8         ;  FROM - sending facility from message header.
    9         ;         For actions other than incoming messages, its the specified link.
    10         ;  QNAME - queue named by the application
    11         ;  IEN778 = ien of the message in file 778
    12         ;  ACTION - <tag^routine> that should be executed for the application
    13         ;  PURGE (optional) - PURGE=1 indicates that the purge dt/tm needs to be set by the infiler
    14         ;     If PURGE("ACKTOIEN") is set, it indicates that the purge dt/tm of
    15         ;     the original message to this application ack also needs to be set.
    16         ;Output: none
    17         ;
    18         I $G(FROM)="" S FROM="UNKNOWN"
    19         I '$L($G(QNAME)) S QNAME="DEFAULT"
    20         S ^HLB("QUEUE","IN",FROM,QNAME,IEN778)=ACTION_"^"_$G(PURGE)_"^"_$G(PURGE("ACKTOIEN"))
    21         I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT","IN",FROM,QNAME)))
    22         Q
    23         ;
    24 OUTQUE(LINKNAME,PORT,QNAME,IEN778)      ;
    25         ;Will place the message=IEN778 on the out-going queue
    26         ;Input:
    27         ;  LINKNAME = name of (.01) the logical link
    28         ;  PORT (optional) the port to connect to
    29         ;  QNAME - queue named by the application
    30         ;  IEN778 = ien of the message in file 778
    31         ;Output: none
    32         ;
    33         N SUB
    34         S SUB=LINKNAME
    35         I PORT S SUB=SUB_":"_PORT
    36         I '$L($G(QNAME)) S QNAME="DEFAULT"
    37         S ^HLB("QUEUE","OUT",SUB,QNAME,IEN778)=""
    38         I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT","OUT",SUB,QNAME)))
    39         Q
    40         ;
    41 DEQUE(FROMORTO,QNAME,DIR,IEN778)        ;
    42         ;This routine will remove the message=IEN778 from its queue
    43         ;Input:
    44         ;  DIR = "IN" or "OUT", denoting the direction that the message is going in
    45         ;  FROMORTO = for outgoing: the .01 field of the logical link
    46         ;         for incoming: sending facility
    47         ;  IEN778 = ien of the message in file 778
    48         ;Output: none
    49         ;
    50         Q:(FROMORTO="")
    51         I ($G(QNAME)="") S QNAME="DEFAULT"
    52         D
    53         .I $E(DIR)="I" S DIR="IN" Q
    54         .I $E(DIR)="O" S DIR="OUT" Q
    55         I DIR'="IN",DIR'="OUT" Q
    56         Q:'$G(IEN778)
    57         D:$D(^HLB("QUEUE",DIR,FROMORTO,QNAME,IEN778))
    58         .K ^HLB("QUEUE",DIR,FROMORTO,QNAME,IEN778)
    59         .;don't let the count become negative
    60         .I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT",DIR,FROMORTO,QNAME)),-1)<0,$$INC^HLOSITE($NA(^HLC("QUEUECOUNT",DIR,FROMORTO,QNAME)))
    61         Q
    62         ;
    63 STOPQUE(DIR,QUEUE)      ;
    64         ;This API is used to set a stop flag on a named queue.
    65         ;DIR=<"IN" or "OUT">
    66         ;QUEUE - the name of the queue to be stopped
    67         ;
    68         Q:$G(DIR)=""
    69         Q:$G(QUEUE)=""
    70         S ^HLTMP("STOPPED QUEUES",DIR,QUEUE)=1
    71         Q
    72 STARTQUE(DIR,QUEUE)     ;
    73         ;This API is used to REMOVE the stop flag on a named queue.
    74         ;DIR=<"IN" or "OUT">
    75         ;QUEUE - the name of the queue to be stopped
    76         ;
    77         Q:$G(DIR)=""
    78         Q:$G(QUEUE)=""
    79         K ^HLTMP("STOPPED QUEUES",DIR,QUEUE)
    80         Q
    81 STOPPED(DIR,QUEUE)      ;
    82         ;This API is used to DETERMINE if the stop flag on a named queue is set.
    83         ;Input:
    84         ;  DIR=<"IN" or "OUT">
    85         ;  QUEUE - the name of the queue to be checked
    86         ;Output:
    87         ;  Function returns 1 if the queue is stopped, 0 otherwise
    88         Q:$G(DIR)="" 0
    89         Q:$G(QUEUE)="" 0
    90         I $G(^HLTMP("STOPPED QUEUES",DIR,QUEUE)) Q 1
    91         Q 0
    92         ;
    93 SQUE(SQUE,LINKNAME,PORT,QNAME,IEN778)   ;
    94         ;Will place the message=IEN778 on the sequencing queue. This is always done in the context of the application calling an HLO API to send a message.
    95         ;Input:
    96         ;  SQUE - name of the sequencing queue
    97         ;  LINKNAME = name of (.01) the logical link
    98         ;  PORT (optional) the port to connect to
    99         ;  QNAME (optional) outgoing queue
    100         ;  IEN778 = ien of the message in file 778
    101         ;Output: 1 if placed on the outgoing queue, 0 if placed on the sequence queue
    102         ;
    103         N NEXT,MOVED
    104         S MOVED=0
    105         ;
    106         ;keep a count of messages pending on sequence queues for the HLO System Monitor
    107         I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT","SEQUENCE")))
    108         ;
    109         L +^HLB("QUEUE","SEQUENCE",SQUE):200
    110         ;
    111         S NEXT=+$G(^HLB("QUEUE","SEQUENCE",SQUE))
    112         Q:NEXT=IEN778 0  ;already queued!
    113         ;if the sequence queue is empty and not waiting on a message, then the message can be put directly on the outgoing queue, bypassing the sequence queue
    114         I '$O(^HLB("QUEUE","SEQUENCE",SQUE,0)),'NEXT D
    115         .S ^HLB("QUEUE","SEQUENCE",SQUE)=IEN778 ;to mean something moved to outgoing but not yet transmitted
    116         .L -^HLB("QUEUE","SEQUENCE",SQUE)
    117         .D OUTQUE(.LINKNAME,.PORT,.QNAME,IEN778)
    118         .S MOVED=1
    119         E  D
    120         .;Put the message on the sequence queue.
    121         .S ^HLB("QUEUE","SEQUENCE",SQUE,IEN778)=""
    122         .L -^HLB("QUEUE","SEQUENCE",SQUE)
    123         Q MOVED
    124         ;
    125 ADVANCE(SQUE,MSGIEN)    ;
    126         ;Will move the specified sequencing queue to the next message.
    127         ;Input:
    128         ;  SQUE - name of the sequencing queue
    129         ;  MSGIEN - the ien of the message upon which the sequence queue was waiting.  If it is NOT the correct ien, then the sequence queue will NOT be advance.
    130         ;Output:
    131         ;  Function - 1 if advanced, 0 if not
    132         ;
    133         N NODE,IEN778,LINKNAME,PORT,QNAME
    134         Q:'$L($G(SQUE)) 0
    135         Q:'$G(MSGIEN) 0
    136         L +^HLB("QUEUE","SEQUENCE",SQUE):200
    137         ;
    138         ;do not advance if the queue wasn't pending the message=MSGIEN
    139         I (MSGIEN'=$P($G(^HLB("QUEUE","SEQUENCE",SQUE)),"^")) L -^HLB("QUEUE","SEQUENCE",SQUE) Q 0
    140         ;
    141         I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT","SEQUENCE")),-1)<0,$$INC^HLOSITE($NA(^HLC("QUEUECOUNT","SEQUENCE"))) ;decrement the count of messages pending sequence queues
    142         ;
    143         S IEN778=0
    144         ;look for the first message on the sequence que.  Make sure its valid, if not remove the invalid entry and keep looking.
    145         F  S IEN778=$O(^HLB("QUEUE","SEQUENCE",SQUE,0)) Q:'IEN778  S NODE=$G(^HLB(IEN778,0)) Q:$L(NODE)  D
    146         .;message does not exist! Remove from queue and try again.
    147         .K ^HLB("QUEUE","SEQUENCE",SQUE,IEN778)
    148         .I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT","SEQUENCE")),-1)<0,$$INC^HLOSITE($NA(^HLC("QUEUECOUNT","SEQUENCE"))) ;decrement the count of messages pending sequence queues
    149         ;
    150         ;IEN778 is the next pending msg on this sequence queue
    151         I IEN778 D
    152         .;
    153         .;parse out info needed to move to outgoing queue
    154         .S LINKNAME=$P(NODE,"^",5),PORT=$P(NODE,"^",8),QNAME=$P(NODE,"^",6)
    155         .;
    156         .S ^HLB("QUEUE","SEQUENCE",SQUE)=IEN778 ;indicates this sequence queue is now waiting for msg=IEN778 before advancing.  The second pieces is the timer, but will not be set until the message=IEN778 is actually transmitted.
    157         .K ^HLB("QUEUE","SEQUENCE",SQUE,IEN778) ;remove from sequence queue
    158         .L -^HLB("QUEUE","SEQUENCE",SQUE)
    159         .S $P(^HLB(IEN778,5),"^",2)=1
    160         .D OUTQUE(.LINKNAME,$G(PORT),$G(QNAME),IEN778) ;move to outgoing queue
    161         E  D
    162         .K ^HLB("QUEUE","SEQUENCE",SQUE) ;this sequence queue is currently empty and not needed
    163         .L -^HLB("QUEUE","SEQUENCE",SQUE)
    164         Q 1
    165         ;
    166 SEQCHK(WORK)    ;functions under the HLO Process Manager
    167         ;check sequence queues for timeout
    168         N QUE,NOW
    169         S NOW=$$NOW^XLFDT
    170         S QUE=""
    171         F  S QUE=$O(^HLB("QUEUE","SEQUENCE",QUE)) Q:QUE=""  D
    172         .N NODE,MSGIEN,ACTION,NODE
    173         .S NODE=$G(^HLB("QUEUE","SEQUENCE",QUE))
    174         .Q:'$P(NODE,"^",2)
    175         .Q:$P(NODE,"^",2)>NOW
    176         .Q:$P(NODE,"^",3)
    177         .L +^HLB("QUEUE","SEQUENCE",QUE):2
    178         .;don't report if a lock wasn't obtained
    179         .Q:'$T
    180         .S NODE=$G(^HLB("QUEUE","SEQUENCE",QUE))
    181         .I '$P(NODE,"^",2) L -^HLB("QUEUE","SEQUENCE",QUE) Q
    182         .I ($P(NODE,"^",2)>NOW) L -^HLB("QUEUE","SEQUENCE",QUE) Q
    183         .I $P(NODE,"^",3) L -^HLB("QUEUE","SEQUENCE",QUE) Q  ;exception already raised
    184         .S MSGIEN=$P(NODE,"^")
    185         .I 'MSGIEN L -^HLB("QUEUE","SEQUENCE",QUE) Q
    186         .S ACTION=$$EXCEPT^HLOAPP($$GETSAP^HLOCLNT2(MSGIEN))
    187         .S $P(^HLB(MSGIEN,5),"^",3)=1
    188         .S $P(^HLB("QUEUE","SEQUENCE",QUE),"^",3)=1 ;indicates exception raised
    189         .L -^HLB("QUEUE","SEQUENCE",QUE)
    190         .D  ;call the application to take action
    191         ..N HLMSGIEN,MCODE,DUZ,QUE,NOW
    192         ..N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOQUE"
    193         ..S HLMSGIEN=MSGIEN
    194         ..S MCODE="D "_ACTION
    195         ..N MSGIEN,X
    196         ..D DUZ^XUP(.5)
    197         ..X MCODE
    198         ..;kill the apps variables
    199         ..D
    200         ...N ZTSK
    201         ...D KILL^XUSCLEAN
    202         Q
    203 ERROR   ;error trap for application context
    204         S $ETRAP="D UNWIND^%ZTER"
    205         D ^%ZTER
    206         S $ECODE=",UAPPLICATION ERROR,"
    207         ;
    208         ;kill the apps variables
    209         D
    210         .N ZTSK,MSGIEN,QUEUE
    211         .D KILL^XUSCLEAN
    212         ;
    213         ;release all the locks the app may have set, except Taskman lock
    214         L:$D(ZTSK) ^%ZTSCH("TASK",ZTSK):1
    215         L:'$D(ZTSK)
    216         ;reset HLO's lock
    217         L +^HLTMP("HL7 RUNNING PROCESSES",$J):0
    218         ;return to processing the next message on the queue
    219         D UNWIND^%ZTER
    220         Q
     1HLOQUE ;ALB/CJM- HL7 QUEUE MANAGEMENT - 10/4/94 1pm ;01/05/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,132,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5INQUE(FROM,QNAME,IEN778,ACTION,PURGE) ;
     6 ;Will place the message=IEN778 on the IN queue, incoming
     7 ;Input:
     8 ;  FROM - sending facility from message header.
     9 ;         For actions other than incoming messages, its the specified link.
     10 ;  QNAME - queue named by the application
     11 ;  IEN778 = ien of the message in file 778
     12 ;  ACTION - <tag^routine> that should be executed for the application
     13 ;  PURGE (optional) - PURGE=1 indicates that the purge dt/tm needs to be set by the infiler
     14 ;     If PURGE("ACKTOIEN") is set, it indicates that the purge dt/tm of
     15 ;     the original message to this application ack also needs to be set.
     16 ;Output: none
     17 ;
     18 I $G(FROM)="" S FROM="UNKNOWN"
     19 I '$L($G(QNAME)) S QNAME="DEFAULT"
     20 S ^HLB("QUEUE","IN",FROM,QNAME,IEN778)=ACTION_"^"_$G(PURGE)_"^"_$G(PURGE("ACKTOIEN"))
     21 I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT","IN",FROM,QNAME)))
     22 Q
     23 ;
     24OUTQUE(LINKNAME,PORT,QNAME,IEN778) ;
     25 ;Will place the message=IEN778 on the out-going queue
     26 ;Input:
     27 ;  LINKNAME = name of (.01) the logical link
     28 ;  PORT (optional) the port to connect to
     29 ;  QNAME - queue named by the application
     30 ;  IEN778 = ien of the message in file 778
     31 ;Output: none
     32 ;
     33 N SUB
     34 S SUB=LINKNAME
     35 I PORT S SUB=SUB_":"_PORT
     36 I '$L($G(QNAME)) S QNAME="DEFAULT"
     37 S ^HLB("QUEUE","OUT",SUB,QNAME,IEN778)=""
     38 I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT","OUT",SUB,QNAME)))
     39 Q
     40 ;
     41DEQUE(FROMORTO,QNAME,DIR,IEN778) ;
     42 ;This routine will remove the message=IEN778 from its queue
     43 ;Input:
     44 ;  DIR = "IN" or "OUT", denoting the direction that the message is going in
     45 ;  FROMORTO = for outgoing: the .01 field of the logical link
     46 ;         for incoming: sending facility
     47 ;  IEN778 = ien of the message in file 778
     48 ;Output: none
     49 ;
     50 Q:(FROMORTO="")
     51 I ($G(QNAME)="") S QNAME="DEFAULT"
     52 D
     53 .I $E(DIR)="I" S DIR="IN" Q
     54 .I $E(DIR)="O" S DIR="OUT" Q
     55 I DIR'="IN",DIR'="OUT" Q
     56 Q:'$G(IEN778)
     57 D:$D(^HLB("QUEUE",DIR,FROMORTO,QNAME,IEN778))
     58 .K ^HLB("QUEUE",DIR,FROMORTO,QNAME,IEN778)
     59 .;don't let the count become negative
     60 .I $$INC^HLOSITE($NA(^HLC("QUEUECOUNT",DIR,FROMORTO,QNAME)),-1)<0,$$INC^HLOSITE($NA(^HLC("QUEUECOUNT",DIR,FROMORTO,QNAME)))
     61 Q
     62 ;
     63STOPQUE(DIR,QUEUE) ;
     64 ;This API is used to set a stop flag on a named queue.
     65 ;DIR=<"IN" or "OUT">
     66 ;QUEUE - the name of the queue to be stopped
     67 ;
     68 Q:$G(DIR)=""
     69 Q:$G(QUEUE)=""
     70 S ^HLTMP("STOPPED QUEUES",DIR,QUEUE)=1
     71 Q
     72STARTQUE(DIR,QUEUE) ;
     73 ;This API is used to REMOVE the stop flag on a named queue.
     74 ;DIR=<"IN" or "OUT">
     75 ;QUEUE - the name of the queue to be stopped
     76 ;
     77 Q:$G(DIR)=""
     78 Q:$G(QUEUE)=""
     79 K ^HLTMP("STOPPED QUEUES",DIR,QUEUE)
     80 Q
     81STOPPED(DIR,QUEUE) ;
     82 ;This API is used to DETERMINE if the stop flag on a named queue is set.
     83 ;Input:
     84 ;  DIR=<"IN" or "OUT">
     85 ;  QUEUE - the name of the queue to be checked
     86 ;Output:
     87 ;  Function returns 1 if the queue is stopped, 0 otherwise
     88 Q:$G(DIR)="" 0
     89 Q:$G(QUEUE)="" 0
     90 I $G(^HLTMP("STOPPED QUEUES",DIR,QUEUE)) Q 1
     91 Q 0
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOSRVR.m

    r613 r623  
    1 HLOSRVR ;ALB/CJM- Server for receiving messages - 10/4/94 1pm ;07/19/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,130,131,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 GETWORK(WORK)   ;
    6         ;GET WORK function for a single server or a Taskman multi-server
    7         N LINK
    8         I '$$CHKSTOP^HLOPROC,$G(WORK("LINK"))]"",$$GETLINK^HLOTLNK(WORK("LINK"),.LINK),+LINK("SERVER") S WORK("PORT")=LINK("PORT") Q 1
    9         Q 0
    10         ;
    11 DOWORKS(WORK)   ;
    12         ;DO WORK rtn for a single server (non-concurrent)
    13         D SERVER(WORK("LINK"))
    14         Q
    15 DOWORKM(WORK)   ;
    16         ;DO WORK rtn for a Taskman multi-server (Cache systems only)
    17         D LISTEN^%ZISTCPS(WORK("PORT"),"SERVER^HLOSRVR("""_WORK("LINK")_""")")
    18         Q
    19         ;
    20 VMS2(LINKNAME)  ;called from a VMS TCP Service once a connection request has been received.  This entry point should be used only if an additional VMS TCPIP Services are being created for HLO.
    21         ;Input:
    22         ;   LINKNAME - only pass it in if an additional service is being created on a different port
    23         Q:'$L(LINKNAME)
    24         D VMS
    25         Q
    26         ;
    27 VMS     ;Called from VMS TCP Service once a connection request has been received. This entry point should be used only by the standard HLO service that runs on the standard HLO port.
    28         Q:$$CHKSTOP^HLOPROC
    29         D
    30         .Q:$L($G(LINKNAME))
    31         .;
    32         .N PROC,NODE
    33         .S PROC=$O(^HLD(779.3,"B","VMS TCP LISTENER",0))
    34         .I PROC S LINKNAME=$P($G(^HLD(779.3,PROC,0)),"^",14) Q:$L(LINKNAME)
    35         .S NODE=$G(^HLD(779.1,1,0)) I $P(NODE,"^",10) S LINKNAME=$P($G(^HLCS(870,$P(NODE,"^",10),0)),"^") Q:$L(LINKNAME)
    36         .S LINKNAME="HLO DEFAULT LISTENER"
    37         ;
    38         D SERVER(LINKNAME,"SYS$NET")
    39         Q
    40         ;
    41 SERVER(LINKNAME,LOGICAL)        ; LINKNAME identifies the logical link, which describes the communication channel to be used
    42         N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOSRVR1"
    43         N HLCSTATE,INQUE
    44         S INQUE=0
    45         Q:'$$CONNECT(.HLCSTATE,LINKNAME,.LOGICAL)
    46         K LINKNAME
    47         F  Q:'HLCSTATE("CONNECTED")  D  Q:$$CHKSTOP^HLOPROC
    48         .N HLMSTATE,SENT
    49         .;
    50         .;read msg and parse the hdr
    51         .;HLMSTATE("MSA",1) is set with type of ack to return
    52         .I $$READMSG^HLOSRVR1(.HLCSTATE,.HLMSTATE) D
    53         ..;
    54         ..;send an ack if required and save the MSA segment
    55         ..I (HLMSTATE("MSA",1)]"") S SENT=$$WRITEACK(.HLCSTATE,.HLMSTATE) D:HLMSTATE("IEN") SAVEACK(.HLMSTATE,SENT)
    56         ..D:HLMSTATE("IEN") UPDATE(.HLMSTATE,.HLCSTATE)
    57         ..D:HLCSTATE("COUNTS")>4 SAVECNTS^HLOSTAT(.HLCSTATE)
    58         ..I $G(HLMSTATE("ACK TO","IEN")),$L($G(HLMSTATE("ACK TO","SEQUENCE QUEUE"))) D ADVANCE^HLOQUE(HLMSTATE("ACK TO","SEQUENCE QUEUE"),+HLMSTATE("ACK TO","IEN"))
    59         .E  D INQUE() H:HLCSTATE("CONNECTED") 1
    60         ;
    61 END     D CLOSE^HLOT(.HLCSTATE)
    62         D INQUE()
    63         D SAVECNTS^HLOSTAT(.HLCSTATE)
    64         Q
    65         ;
    66 CONNECT(HLCSTATE,LINKNAME,LOGICAL)      ;
    67         ;sets up HLCSTATE() and opens a server connection
    68         ;
    69         N LINK,NODE
    70         S HLCSTATE("CONNECTED")=0
    71         Q:'$$GETLINK^HLOTLNK(LINKNAME,.LINK) 0
    72         Q:+LINK("SERVER")'=1 0
    73         S HLCSTATE("SERVER")=LINK("SERVER")
    74         M HLCSTATE("LINK")=LINK
    75         S HLCSTATE("READ TIMEOUT")=20
    76         S HLCSTATE("OPEN TIMEOUT")=30
    77         S HLCSTATE("READ")="" ;buffer for reads
    78         ;
    79         ;HLCSTATE("BUFFER",<seg>,<line>)  write buffer
    80         S HLCSTATE("BUFFER","BYTE COUNT")=0 ;count of bytes in buffer
    81         S HLCSTATE("BUFFER","SEGMENT COUNT")=0 ;count of segments in buffer
    82         ;
    83         S HLCSTATE("COUNTS")=0
    84         S HLCSTATE("MESSAGE ENDED")=0 ;end of message flag
    85         S NODE=^%ZOSF("OS")
    86         S HLCSTATE("SYSTEM","OS")=$S(NODE["DSM":"DSM",NODE["OpenM":"CACHE",NODE["G.TM":"G.TM",1:"")
    87         Q:HLCSTATE("SYSTEM","OS")="" 0
    88         D  ;get necessary system parameters
    89         .N SYS,SUB
    90         .D SYSPARMS^HLOSITE(.SYS)
    91         .F SUB="MAXSTRING","DOMAIN","STATION","PROCESSING ID","NORMAL PURGE","ERROR PURGE" S HLCSTATE("SYSTEM",SUB)=SYS(SUB)
    92         .S HLCSTATE("SYSTEM","BUFFER")=SYS("HL7 BUFFER")
    93         I HLCSTATE("LINK","LLP")="TCP" D
    94         .D OPEN^HLOTCP(.HLCSTATE,.LOGICAL)
    95         E  ;no other LLP implemented
    96         ;
    97         Q HLCSTATE("CONNECTED")
    98         ;
    99 INQUE(MSGIEN,PARMS)     ;
    100         ;puts received messages on the incoming queue and sets the B x-refs
    101         I $G(MSGIEN) S INQUE=INQUE+1 M INQUE(MSGIEN)=PARMS
    102         I ('$G(MSGIEN))!(INQUE>20) S MSGIEN=0 D
    103         .F  S MSGIEN=$O(INQUE(MSGIEN)) Q:'MSGIEN  D
    104         ..S ^HLB("B",INQUE(MSGIEN,"MSGID"),MSGIEN)=""
    105         ..S ^HLA("B",INQUE(MSGIEN,"DT/TM"),INQUE(MSGIEN,"BODY"))=""
    106         ..D:INQUE(MSGIEN,"PASS")
    107         ...N PURGE
    108         ...S PURGE=+$G(INQUE(MSGIEN,"PURGE"))
    109         ...S PURGE("ACKTOIEN")=$G(INQUE(MSGIEN,"ACKTOIEN"))
    110         ...D INQUE^HLOQUE(INQUE(MSGIEN,"FROM"),INQUE(MSGIEN,"QUEUE"),MSGIEN,INQUE(MSGIEN,"ACTION"),.PURGE)
    111         .K INQUE S INQUE=0
    112         Q
    113         ;
    114 SAVEACK(HLMSTATE,SENT)  ;
    115         ;Input:
    116         ;  SENT - flag = 1 if transmission of ack succeeded, 0 otherwise
    117         ;
    118         N NODE,I
    119         S $P(NODE,"^")=HLMSTATE("MSA","DT/TM OF MESSAGE")
    120         S $P(NODE,"^",2)=HLMSTATE("MSA","MESSAGE CONTROL ID")
    121         S $P(NODE,"^",3)="MSA"
    122         F I=1:1:3 S NODE=NODE_"|"_$G(HLMSTATE("MSA",I))
    123         S ^HLB(HLMSTATE("IEN"),4)=NODE
    124         S:SENT $P(^HLB(HLMSTATE("IEN"),0),"^",$S($E(HLMSTATE("MSA",1))="A":18,1:17))=1
    125         Q
    126         ;
    127 UPDATE(HLMSTATE,HLCSTATE)       ;
    128         ;Updates status and purge date when appropriate
    129         ;Also, sets the "B" xrefs, files 777,778, and places message on the incoming queue
    130         ;
    131         N PARMS,PURGE,WAIT
    132         S PARMS("PASS")=0
    133         I HLMSTATE("STATUS","ACTION")]"",HLMSTATE("STATUS")'="SE" D
    134         .N IEN
    135         .S IEN=HLMSTATE("IEN")
    136         .S PARMS("PASS")=1,$P(^HLB(IEN,0),"^",6)=HLMSTATE("STATUS","QUEUE"),$P(^HLB(IEN,0),"^",10)=$P(HLMSTATE("STATUS","ACTION"),"^"),$P(^HLB(IEN,0),"^",11)=$P(HLMSTATE("STATUS","ACTION"),"^",2)
    137         D:'PARMS("PASS")  ;if not passing to the app, set the purge date
    138         .I HLMSTATE("STATUS")="" S HLMSTATE("STATUS")="SU"
    139         .S:HLMSTATE("BATCH") WAIT=HLCSTATE("SYSTEM","ERROR PURGE")
    140         .S:'HLMSTATE("BATCH") WAIT=$S(($G(HLMSTATE("ACK TO","STATUS"))="ER"):24*HLCSTATE("SYSTEM","ERROR PURGE"),HLMSTATE("STATUS")="ER":24*HLCSTATE("SYSTEM","ERROR PURGE"),1:HLCSTATE("SYSTEM","NORMAL PURGE"))
    141         .S PURGE=$$FMADD^XLFDT($$NOW^XLFDT,,WAIT)
    142         .S $P(^HLB(HLMSTATE("IEN"),0),"^",9)=PURGE
    143         .S ^HLB("AD","IN",PURGE,HLMSTATE("IEN"))=""
    144         .;if this is an app ack, purge the original message at the same time
    145         .I $G(HLMSTATE("ACK TO","IEN")),'HLMSTATE("BATCH") D
    146         ..S $P(^HLB(+HLMSTATE("ACK TO","IEN"),0),"^",9)=PURGE
    147         ..S ^HLB("AD","IN",PURGE,+HLMSTATE("ACK TO","IEN"))=""
    148         ;
    149         ;if not waiting for an application ack, set the status now even if passing to the app - but don't set the purge until the infiler passes the message
    150         I HLMSTATE("STATUS")="",($G(HLMSTATE("ACK TO","IEN"))!HLMSTATE("HDR","APP ACK TYPE")'="AL") S HLMSTATE("STATUS")="SU"
    151         I HLMSTATE("STATUS")'="" S $P(^HLB(HLMSTATE("IEN"),0),"^",20)=HLMSTATE("STATUS") S:$G(HLMSTATE("MSA",3))]"" $P(^HLB(HLMSTATE("IEN"),0),"^",21)=HLMSTATE("MSA",3) D:HLMSTATE("STATUS")="SE"
    152         .N APP
    153         .S APP=HLMSTATE("HDR","RECEIVING APPLICATION") S:APP="" APP="UNKNOWN" S ^HLB("ERRORS",APP,HLMSTATE("DT/TM"),HLMSTATE("IEN"))=""
    154         .D COUNT^HLOESTAT("IN",$G(HLMSTATE("HDR","RECEIVING APPLICATION")),$G(HLMSTATE("HDR","SENDING APPLICATION")),$S(HLMSTATE("BATCH"):"BATCH",1:$G(HLMSTATE("HDR","MESSAGE TYPE"))),$G(HLMSTATE("HDR","EVENT")))
    155         ;
    156         ;set the necessary parms for passing the msg to the app via the infiler
    157         D:PARMS("PASS")
    158         .N I,FROM
    159         .S FROM=HLMSTATE("HDR","SENDING FACILITY",1)
    160         .I HLMSTATE("HDR","SENDING FACILITY",2)]"" S FROM=FROM_"~"_HLMSTATE("HDR","SENDING FACILITY",2)_"~"_HLMSTATE("HDR","SENDING FACILITY",3)
    161         .I FROM="" S FROM="UNKNOWN SENDING FACILITY"
    162         .S PARMS("FROM")=FROM,PARMS("QUEUE")=HLMSTATE("STATUS","QUEUE"),PARMS("ACTION")=HLMSTATE("STATUS","ACTION")
    163         .I HLMSTATE("STATUS")'="" S PARMS("PURGE")=$S(HLMSTATE("STATUS")="ER":2,$G(HLMSTATE("ACK TO","STATUS"))="ER":2,1:1)
    164         .S:$G(HLMSTATE("ACK TO","IEN")) PARMS("ACKTOIEN")=HLMSTATE("ACK TO","IEN") ;to insure that the infiler will know to set the purge date at the same time as the initial message
    165         ;
    166         S PARMS("BODY")=HLMSTATE("BODY")
    167         S PARMS("DT/TM")=HLMSTATE("DT/TM")
    168         S PARMS("MSGID")=HLMSTATE("ID")
    169         D INQUE(HLMSTATE("IEN"),.PARMS)
    170         Q
    171         ;
    172 WRITEACK(HLCSTATE,HLMSTATE)     ;
    173         ;Sends an accept ack
    174         ;
    175         ;Input:
    176         ;  HLCSTATE (pass by reference) defines the communication channel
    177         ;  HLMSTATE (pass by reference) the message being acked
    178         ;     ("MSA",1) - value for MSA-1
    179         ;     ("MSA",2) - value for MSA-2
    180         ;     ("MSA",3) - value for MSA-3
    181         ;     ("HDR") - parsed values for the message being ack'd
    182         ;Output:
    183         ;  Function returns 1 if successful, 0 otherwise
    184         ;  HLMSTATE("MSA","MESSAGE CONTROL ID") - the msg id of the ack
    185         ;  HLMSTATE(,"MSA","DT/TM OF MESSAGE") - from the ack header
    186         ;
    187         N HDR,SUB,FS,CS,MSA,ACKID,TIME
    188         ;Hard-code the delimiters, the standard requires that the receiving system accept the delimiters listed in the header
    189         S FS="|"
    190         S CS="^"
    191         S TIME=$$NOW^XLFDT
    192         S HLMSTATE("MSA","DT/TM OF MESSAGE")=TIME
    193         S ACKID=HLCSTATE("SYSTEM","STATION")_" "_$$NEWIEN^HLOF778A("OUT")
    194         S HLMSTATE("MSA","MESSAGE CONTROL ID")=ACKID
    195         ;
    196         S HDR(1)="MSH"_FS_"^~\&"_FS_HLMSTATE("HDR","RECEIVING APPLICATION")_FS_HLCSTATE("SYSTEM","STATION")_CS_HLCSTATE("SYSTEM","DOMAIN")_CS_"DNS"_FS
    197         S HDR(1)=HDR(1)_HLMSTATE("HDR","SENDING APPLICATION")_FS_HLMSTATE("HDR","SENDING FACILITY",1)_CS_HLMSTATE("HDR","SENDING FACILITY",2)_CS_HLMSTATE("HDR","SENDING FACILITY",3)
    198         ;
    199         S HDR(2)=FS_$$HLDATE^HLFNC(TIME,"TS")_FS_FS_"ACK"_FS_ACKID_FS_HLMSTATE("HDR","PROCESSING ID")_FS_"2.4"_FS_FS_FS_"NE"_FS_"NE"
    200         ;
    201         S MSA(1)="MSA"_FS
    202         F SUB=1:1:3 S MSA(1)=MSA(1)_HLMSTATE("MSA",SUB)_FS
    203         I $$WRITEHDR^HLOT(.HLCSTATE,.HDR),$$WRITESEG^HLOT(.HLCSTATE,.MSA),$$ENDMSG^HLOT(.HLCSTATE) S HLCSTATE("COUNTS","ACKS")=$G(HLCSTATE("COUNTS","ACKS"))+1 Q 1
    204         S HLMSTATE("MSA","DT/TM OF MESSAGE")=""
    205         Q 0
     1HLOSRVR ;ALB/CJM- Server for receiving messages - 10/4/94 1pm ;03/22/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,130,131,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5GETWORK(WORK) ;
     6 ;GET WORK function for a single server or a Taskman multi-server
     7 N LINK
     8 I '$$CHKSTOP^HLOPROC,$G(WORK("LINK"))]"",$$GETLINK^HLOTLNK(WORK("LINK"),.LINK),+LINK("SERVER") S WORK("PORT")=LINK("PORT") Q 1
     9 Q 0
     10 ;
     11DOWORKS(WORK) ;
     12 ;DO WORK rtn for a single server (non-concurrent)
     13 D SERVER(WORK("LINK"))
     14 Q
     15DOWORKM(WORK) ;
     16 ;DO WORK rtn for a Taskman multi-server (Cache systems only)
     17 D LISTEN^%ZISTCPS(WORK("PORT"),"SERVER^HLOSRVR("""_WORK("LINK")_""")")
     18 Q
     19 ;
     20VMS2(LINKNAME) ;called from a VMS TCP Service once a connection request has been received.  This entry point should be used only if an additional VMS TCPIP Services are being created for HLO.
     21 ;Input:
     22 ;   LINKNAME - only pass it in if an additional service is being created on a different port
     23 Q:'$L(LINKNAME)
     24 D VMS
     25 Q
     26 ;
     27VMS ;Called from VMS TCP Service once a connection request has been received. This entry point should be used only by the standard HLO service that runs on the standard HLO port.
     28 Q:$$CHKSTOP^HLOPROC
     29 D
     30 .Q:$L($G(LINKNAME))
     31 .;
     32 .N PROC,NODE
     33 .S PROC=$O(^HLD(779.3,"B","VMS TCP LISTENER",0))
     34 .I PROC S LINKNAME=$P($G(^HLD(779.3,PROC,0)),"^",14) Q:$L(LINKNAME)
     35 .S NODE=$G(^HLD(779.1,1,0)) I $P(NODE,"^",10) S LINKNAME=$P($G(^HLCS(870,$P(NODE,"^",10),0)),"^") Q:$L(LINKNAME)
     36 .S LINKNAME="HLO DEFAULT LISTENER"
     37 ;
     38 D SERVER(LINKNAME,"SYS$NET")
     39 Q
     40 ;
     41SERVER(LINKNAME,LOGICAL) ; LINKNAME identifies the logical link, which describes the communication channel to be used
     42 N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOSRVR1"
     43 N HLCSTATE,INQUE
     44 S INQUE=0
     45 Q:'$$CONNECT(.HLCSTATE,LINKNAME,.LOGICAL)
     46 K LINKNAME
     47 F  Q:'HLCSTATE("CONNECTED")  D  Q:$$CHKSTOP^HLOPROC
     48 .N HLMSTATE,SENT
     49 .;
     50 .;read msg and parse the hdr
     51 .;HLMSTATE("MSA",1) is set with type of ack to return
     52 .I $$READMSG^HLOSRVR1(.HLCSTATE,.HLMSTATE) D
     53 ..;
     54 ..;send an ack if required and save the MSA segment
     55 ..I (HLMSTATE("MSA",1)]"") S SENT=$$WRITEACK(.HLCSTATE,.HLMSTATE) D:HLMSTATE("IEN") SAVEACK(.HLMSTATE,SENT)
     56 ..D:HLMSTATE("IEN") UPDATE(.HLMSTATE,.HLCSTATE)
     57 ..D:HLCSTATE("COUNTS")>4 SAVECNTS^HLOSTAT(.HLCSTATE)
     58 .E  D INQUE() H:HLCSTATE("CONNECTED") 1
     59 ;
     60END D CLOSE^HLOT(.HLCSTATE)
     61 D INQUE()
     62 D SAVECNTS^HLOSTAT(.HLCSTATE)
     63 Q
     64 ;
     65CONNECT(HLCSTATE,LINKNAME,LOGICAL) ;
     66 ;sets up HLCSTATE() and opens a server connection
     67 ;
     68 N LINK,NODE
     69 S HLCSTATE("CONNECTED")=0
     70 Q:'$$GETLINK^HLOTLNK(LINKNAME,.LINK) 0
     71 Q:+LINK("SERVER")'=1 0
     72 S HLCSTATE("SERVER")=LINK("SERVER")
     73 M HLCSTATE("LINK")=LINK
     74 S HLCSTATE("READ TIMEOUT")=20
     75 S HLCSTATE("OPEN TIMEOUT")=30
     76 S HLCSTATE("READ")="" ;buffer for reads
     77 ;
     78 ;HLCSTATE("BUFFER",<seg>,<line>)  write buffer
     79 S HLCSTATE("BUFFER","BYTE COUNT")=0 ;count of bytes in buffer
     80 S HLCSTATE("BUFFER","SEGMENT COUNT")=0 ;count of segments in buffer
     81 ;
     82 S HLCSTATE("COUNTS")=0
     83 S HLCSTATE("MESSAGE ENDED")=0 ;end of message flag
     84 S NODE=^%ZOSF("OS")
     85 S HLCSTATE("SYSTEM","OS")=$S(NODE["DSM":"DSM",NODE["OpenM":"CACHE",NODE["G.TM":"G.TM",1:"")
     86 Q:HLCSTATE("SYSTEM","OS")="" 0
     87 D  ;get necessary system parameters
     88 .N SYS,SUB
     89 .D SYSPARMS^HLOSITE(.SYS)
     90 .F SUB="MAXSTRING","DOMAIN","STATION","PROCESSING ID","NORMAL PURGE","ERROR PURGE" S HLCSTATE("SYSTEM",SUB)=SYS(SUB)
     91 .S HLCSTATE("SYSTEM","BUFFER")=SYS("HL7 BUFFER")
     92 I HLCSTATE("LINK","LLP")="TCP" D
     93 .D OPEN^HLOTCP(.HLCSTATE,.LOGICAL)
     94 E  ;no other LLP implemented
     95 ;
     96 Q HLCSTATE("CONNECTED")
     97 ;
     98INQUE(MSGIEN,PARMS) ;
     99 ;puts received messages on the incoming queue and sets the B x-refs
     100 I $G(MSGIEN) S INQUE=INQUE+1 M INQUE(MSGIEN)=PARMS
     101 I ('$G(MSGIEN))!(INQUE>20) S MSGIEN=0 D
     102 .F  S MSGIEN=$O(INQUE(MSGIEN)) Q:'MSGIEN  D
     103 ..S ^HLB("B",INQUE(MSGIEN,"MSGID"),MSGIEN)=""
     104 ..S ^HLA("B",INQUE(MSGIEN,"DT/TM"),INQUE(MSGIEN,"BODY"))=""
     105 ..D:INQUE(MSGIEN,"PASS")
     106 ...N PURGE
     107 ...S PURGE=+$G(INQUE(MSGIEN,"PURGE"))
     108 ...S PURGE("ACKTOIEN")=$G(INQUE(MSGIEN,"ACKTOIEN"))
     109 ...D INQUE^HLOQUE(INQUE(MSGIEN,"FROM"),INQUE(MSGIEN,"QUEUE"),MSGIEN,INQUE(MSGIEN,"ACTION"),.PURGE)
     110 .K INQUE S INQUE=0
     111 Q
     112 ;
     113SAVEACK(HLMSTATE,SENT) ;
     114 ;Input:
     115 ;  SENT - flag = 1 if transmission of ack succeeded, 0 otherwise
     116 ;
     117 N NODE,I
     118 S $P(NODE,"^")=HLMSTATE("MSA","DT/TM OF MESSAGE")
     119 S $P(NODE,"^",2)=HLMSTATE("MSA","MESSAGE CONTROL ID")
     120 S $P(NODE,"^",3)="MSA"
     121 F I=1:1:3 S NODE=NODE_"|"_$G(HLMSTATE("MSA",I))
     122 S ^HLB(HLMSTATE("IEN"),4)=NODE
     123 S:SENT $P(^HLB(HLMSTATE("IEN"),0),"^",$S($E(HLMSTATE("MSA",1))="A":18,1:17))=1
     124 Q
     125 ;
     126UPDATE(HLMSTATE,HLCSTATE) ;
     127 ;Updates status and purge date when appropriate
     128 ;Also, sets the "B" xrefs, files 777,778, and places message on the incoming queue
     129 ;
     130 N PARMS,PURGE,WAIT
     131 S PARMS("PASS")=0
     132 I HLMSTATE("STATUS","ACTION")]"",HLMSTATE("STATUS")'="SE" D
     133 .N IEN
     134 .S IEN=HLMSTATE("IEN")
     135 .S PARMS("PASS")=1,$P(^HLB(IEN,0),"^",6)=HLMSTATE("STATUS","QUEUE"),$P(^HLB(IEN,0),"^",10)=$P(HLMSTATE("STATUS","ACTION"),"^"),$P(^HLB(IEN,0),"^",11)=$P(HLMSTATE("STATUS","ACTION"),"^",2)
     136 D:'PARMS("PASS")  ;if not passing to the app, set the purge date
     137 .I HLMSTATE("STATUS")="" S HLMSTATE("STATUS")="SU"
     138 .S:HLMSTATE("BATCH") WAIT=HLCSTATE("SYSTEM","ERROR PURGE")
     139 .S:'HLMSTATE("BATCH") WAIT=$S(($G(HLMSTATE("ACK TO","STATUS"))="AE"):24*HLCSTATE("SYSTEM","ERROR PURGE"),HLMSTATE("STATUS")="SE":24*HLCSTATE("SYSTEM","ERROR PURGE"),1:HLCSTATE("SYSTEM","NORMAL PURGE"))
     140 .S PURGE=$$FMADD^XLFDT($$NOW^XLFDT,,WAIT)
     141 .S $P(^HLB(HLMSTATE("IEN"),0),"^",9)=PURGE
     142 .S ^HLB("AD","IN",PURGE,HLMSTATE("IEN"))=""
     143 .;if this is an app ack, purge the original message at the same time
     144 .I $G(HLMSTATE("ACK TO","IEN")),'HLMSTATE("BATCH") D
     145 ..S $P(^HLB(+HLMSTATE("ACK TO","IEN"),0),"^",9)=PURGE
     146 ..S ^HLB("AD","IN",PURGE,+HLMSTATE("ACK TO","IEN"))=""
     147 ;
     148 ;if not waiting for an application ack, set the status now even if passing to the app - but don't set the purge until the infiler passes the message
     149 I HLMSTATE("STATUS")="",($G(HLMSTATE("ACK TO","IEN"))!HLMSTATE("HDR","APP ACK TYPE")'="AL") S HLMSTATE("STATUS")="SU"
     150 I HLMSTATE("STATUS")'="" S $P(^HLB(HLMSTATE("IEN"),0),"^",20)=HLMSTATE("STATUS") S:$G(HLMSTATE("MSA",3))]"" $P(^HLB(HLMSTATE("IEN"),0),"^",21)=HLMSTATE("MSA",3) D:HLMSTATE("STATUS")="SE"
     151 .N APP
     152 .S APP=HLMSTATE("HDR","RECEIVING APPLICATION") S:APP="" APP="UNKNOWN" S ^HLB("ERRORS","SE",APP,HLMSTATE("DT/TM"),HLMSTATE("IEN"))=""
     153 .D COUNT^HLOESTAT("IN",$G(HLMSTATE("HDR","RECEIVING APPLICATION")),$G(HLMSTATE("HDR","SENDING APPLICATION")),$S(HLMSTATE("BATCH"):"BATCH",1:$G(HLMSTATE("HDR","MESSAGE TYPE"))),$G(HLMSTATE("HDR","EVENT")))
     154 ;
     155 ;set the necessary parms for passing the msg to the app via the infiler
     156 D:PARMS("PASS")
     157 .N I,FROM
     158 .S FROM=HLMSTATE("HDR","SENDING FACILITY",1)
     159 .I HLMSTATE("HDR","SENDING FACILITY",2)]"" S FROM=FROM_"~"_HLMSTATE("HDR","SENDING FACILITY",2)_"~"_HLMSTATE("HDR","SENDING FACILITY",3)
     160 .I FROM="" S FROM="UNKNOWN SENDING FACILITY"
     161 .S PARMS("FROM")=FROM,PARMS("QUEUE")=HLMSTATE("STATUS","QUEUE"),PARMS("ACTION")=HLMSTATE("STATUS","ACTION")
     162 .I HLMSTATE("STATUS")'="" S PARMS("PURGE")=$S(HLMSTATE("STATUS")'="SU":2,$G(HLMSTATE("ACK TO","STATUS"))="AE":2,1:1)
     163 .S:$G(HLMSTATE("ACK TO","IEN")) PARMS("ACKTOIEN")=HLMSTATE("ACK TO","IEN") ;to insure that the infiler will know to set the purge date at the same time as the initial message
     164 ;
     165 S PARMS("BODY")=HLMSTATE("BODY")
     166 S PARMS("DT/TM")=HLMSTATE("DT/TM")
     167 S PARMS("MSGID")=HLMSTATE("ID")
     168 D INQUE(HLMSTATE("IEN"),.PARMS)
     169 Q
     170 ;
     171WRITEACK(HLCSTATE,HLMSTATE) ;
     172 ;Sends an accept ack
     173 ;
     174 ;Input:
     175 ;  HLCSTATE (pass by reference) defines the communication channel
     176 ;  HLMSTATE (pass by reference) the message being acked
     177 ;     ("MSA",1) - value for MSA-1
     178 ;     ("MSA",2) - value for MSA-2
     179 ;     ("MSA",3) - value for MSA-3
     180 ;     ("HDR") - parsed values for the message being ack'd
     181 ;Output:
     182 ;  Function returns 1 if successful, 0 otherwise
     183 ;  HLMSTATE("MSA","MESSAGE CONTROL ID") - the msg id of the ack
     184 ;  HLMSTATE(,"MSA","DT/TM OF MESSAGE") - from the ack header
     185 ;
     186 N HDR,SUB,FS,CS,MSA,ACKID,TIME
     187 ;Hard-code the delimiters, the standard requires that the receiving system accept the delimiters listed in the header
     188 S FS="|"
     189 S CS="^"
     190 S TIME=$$NOW^XLFDT
     191 S HLMSTATE("MSA","DT/TM OF MESSAGE")=TIME
     192 S ACKID=HLCSTATE("SYSTEM","STATION")_" "_$$NEWIEN^HLOF778A("OUT")
     193 S HLMSTATE("MSA","MESSAGE CONTROL ID")=ACKID
     194 ;
     195 S HDR(1)="MSH"_FS_"^~\&"_FS_HLMSTATE("HDR","RECEIVING APPLICATION")_FS_HLCSTATE("SYSTEM","STATION")_CS_HLCSTATE("SYSTEM","DOMAIN")_CS_"DNS"_FS
     196 S HDR(1)=HDR(1)_HLMSTATE("HDR","SENDING APPLICATION")_FS_HLMSTATE("HDR","SENDING FACILITY",1)_CS_HLMSTATE("HDR","SENDING FACILITY",2)_CS_HLMSTATE("HDR","SENDING FACILITY",3)
     197 ;
     198 S HDR(2)=FS_$$HLDATE^HLFNC(TIME,"TS")_FS_FS_"ACK"_FS_ACKID_FS_HLMSTATE("HDR","PROCESSING ID")_FS_"2.4"_FS_FS_FS_"NE"_FS_"NE"
     199 ;
     200 S MSA(1)="MSA"_FS
     201 F SUB=1:1:3 S MSA(1)=MSA(1)_HLMSTATE("MSA",SUB)_FS
     202 I $$WRITEHDR^HLOT(.HLCSTATE,.HDR),$$WRITESEG^HLOT(.HLCSTATE,.MSA),$$ENDMSG^HLOT(.HLCSTATE) S HLCSTATE("COUNTS","ACKS")=$G(HLCSTATE("COUNTS","ACKS"))+1 Q 1
     203 S HLMSTATE("MSA","DT/TM OF MESSAGE")=""
     204 Q 0
  • 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
     1HLOSRVR1 ;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 ;
     5READMSG(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 ;
     85ADDAC(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 ;
     92DUP(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 ;
     122CHECKMSG(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 ;
     170DEL777(IEN777) ;delete a record from file 777 where the read did not complete
     171 ;
     172 K ^HLA(IEN777,0)
     173 Q
     174DEL778(IEN778) ;delete a record from file 778 where the read did not complete
     175 ;
     176 K ^HLB(IEN778,0)
     177 Q
     178 ;
     179SPLITHDR(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 ;
     192SQUISH(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 ;
     211ERROR ;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
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOSRVR2.m

    r613 r623  
    1 HLOSRVR2        ;ALB/CJM-HL7 - HLO Server ;07/20/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**131,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 NEWMSG(HLCSTATE,HLMSTATE,HDR)   ;
    6         ;initialize the HLMSTATE array after reading the header
    7         ;Inputs:
    8         ;  HLCSTATE (pass by reference)
    9         ;  HDR (pass by reference) parsed header
    10         ;Output:
    11         ;  HLMSTATE (pass by reference)
    12         ;
    13         K HLMSTATE
    14         S HLMSTATE("IEN")=""
    15         S HLMSTATE("BODY")=""
    16         S HLMSTATE("DIRECTION")="IN"
    17         S HLMSTATE("CURRENT SEGMENT")=0 ;no segments in cache
    18         S HLMSTATE("UNSTORED LINES")=1 ;just the header in cache so far
    19         S HLMSTATE("LINE COUNT")=0 ;no lines within message stored to disk
    20         I HDR("SEGMENT TYPE")="BHS" D
    21         .S HLMSTATE("BATCH")=1
    22         .S HLMSTATE("ID")=HDR("BATCH CONTROL ID")
    23         .S HLMSTATE("BATCH","CURRENT MESSAGE")=0 ;no messages in batch
    24         .S HLMSTATE("UNSTORED MSH")=0
    25         E  D
    26         .S HLMSTATE("BATCH")=0
    27         .S HLMSTATE("ID")=HDR("MESSAGE CONTROL ID")
    28         M HLMSTATE("HDR")=HDR
    29         M HLMSTATE("SYSTEM")=HLCSTATE("SYSTEM")
    30         S HLMSTATE("STATUS")=""
    31         S HLMSTATE("STATUS","QUEUE")=""
    32         S HLMSTATE("STATUS","ACTION")=""
    33         S HLMSTATE("STATUS","LINK NAME")=HLCSTATE("LINK","NAME")
    34         S HLMSTATE("STATUS","PORT")=$P(HDR("SENDING FACILITY",2),":",2)
    35         ;
    36         ;if this is a batch, and it references another batch, assume it is a b.
    37         I HLMSTATE("BATCH"),HLMSTATE("ID")]"" D
    38         .N IEN
    39         .S HLMSTATE("ACK TO")=HLMSTATE("ID")
    40         .S HLMSTATE("ACK TO","STATUS")="SU"
    41         .S IEN=$O(^HLB("B",HLMSTATE("ID"),0))
    42         .I IEN S HLMSTATE("ACK TO","IEN")=IEN_"^"
    43         E  S HLMSTATE("ACK TO")=""
    44         I 'HLMSTATE("BATCH"),HDR("ACCEPT ACK TYPE")="",HDR("APP ACK TYPE")="" D
    45         .S HLMSTATE("ORIGINAL MODE")=1
    46         E  D
    47         .S HLMSTATE("ORIGINAL MODE")=0
    48         N I F I=1,3 S HLMSTATE("MSA",I)=""
    49         S HLMSTATE("MSA",2)=HLMSTATE("ID")
    50         Q
     1HLOSRVR2 ;ALB/CJM-HL7 - Sends an application ack over an open connection, for original mode ;02/04/2004
     2 ;;1.6;HEALTH LEVEL SEVEN;**131**;Oct 13, 1995;Build 10
     3 ;
     4NEWMSG(HLCSTATE,HLMSTATE,HDR) ;
     5 ;initialize the HLMSTATE array after reading the header
     6 ;Inputs:
     7 ;  HLCSTATE (pass by reference)
     8 ;  HDR (pass by reference) parsed header
     9 ;Output:
     10 ;  HLMSTATE (pass by reference)
     11 ;
     12 K HLMSTATE
     13 S HLMSTATE("IEN")=""
     14 S HLMSTATE("BODY")=""
     15 S HLMSTATE("DIRECTION")="IN"
     16 S HLMSTATE("CURRENT SEGMENT")=0 ;no segments in cache
     17 S HLMSTATE("UNSTORED LINES")=1 ;just the header in cache so far
     18 S HLMSTATE("LINE COUNT")=0 ;no lines within message stored to disk
     19 I HDR("SEGMENT TYPE")="BHS" D
     20 .S HLMSTATE("BATCH")=1
     21 .S HLMSTATE("ID")=HDR("BATCH CONTROL ID")
     22 .S HLMSTATE("BATCH","CURRENT MESSAGE")=0 ;no messages in batch
     23 .S HLMSTATE("UNSTORED MSH")=0
     24 E  D
     25 .S HLMSTATE("BATCH")=0
     26 .S HLMSTATE("ID")=HDR("MESSAGE CONTROL ID")
     27 M HLMSTATE("HDR")=HDR
     28 M HLMSTATE("SYSTEM")=HLCSTATE("SYSTEM")
     29 S HLMSTATE("STATUS")=""
     30 S HLMSTATE("STATUS","QUEUE")=""
     31 S HLMSTATE("STATUS","ACTION")=""
     32 S HLMSTATE("STATUS","LINK NAME")=HLCSTATE("LINK","NAME")
     33 S HLMSTATE("STATUS","PORT")=$P(HDR("SENDING FACILITY",2),":",2)
     34 ;
     35 ;if this is a batch, and it references another batch, assume it is a b.
     36 I HLMSTATE("BATCH"),HLMSTATE("ID")]"" D
     37 .N IEN
     38 .S HLMSTATE("ACK TO")=HLMSTATE("ID")
     39 .S HLMSTATE("ACK TO","STATUS")="SU"
     40 .S IEN=$O(^HLB("B",HLMSTATE("ID"),0))
     41 .I IEN S HLMSTATE("ACK TO","IEN")=IEN_"^"
     42 E  S HLMSTATE("ACK TO")=""
     43 I 'HLMSTATE("BATCH"),HDR("ACCEPT ACK TYPE")="",HDR("APP ACK TYPE")="" D
     44 .S HLMSTATE("ORIGINAL MODE")=1
     45 E  D
     46 .S HLMSTATE("ORIGINAL MODE")=0
     47 N I F I=1,3 S HLMSTATE("MSA",I)=""
     48 S HLMSTATE("MSA",2)=HLMSTATE("ID")
     49 Q
     50 ;
     51ACKNOW(MSG,ERROR) ;
     52 ;Sends the messge immediately if there is an open connection, otherwise
     53 ;will return an error.
     54 ;
     55 N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOSRVR2"
     56 N SENT
     57 S SENT=0,ERROR=""
     58 I '$G(HLCSTATE("CONNECTED")) D
     59 .S ERROR="NOT CONNECTED"
     60 .S MSG("STATUS")="TF"
     61 E  S MSG("STATUS")="SU"
     62 S:'$G(MSG("DT/TM CREATED")) MSG("DT/TM CREATED")=$$NOW^XLFDT
     63 S MSG("STATUS","PURGE")=$$FMADD^XLFDT(MSG("DT/TM CREATED"),$S($G(HLCSTATE("ERROR PURGE")):HLCSTATE("ERROR PURGE"),1:7))
     64 D
     65 .I $G(MSG("UNSTORED LINES")),'$$SAVEMSG^HLOF777(.MSG) S ERROR="$$SAVE^HLOF777 FAILED!" Q
     66 .I '$$SAVEMSG^HLOF778(.MSG) S ERROR="$$SAVE^HLOF778 FAILED!" Q
     67 .Q:MSG("STATUS")'="SU"
     68 .I '$$WRITEMSG^HLOCLNT1(.HLCSTATE,.MSG) S ERROR="TRANSMISSION FAILURE" Q
     69 .S SENT=1
     70 .D COUNT^HLOSTAT(.HLCSTATE,ACK("HDR","RECEIVING APPLICATION"),ACK("HDR","SENDING APPLICATION"),ACK("HDR","MESSAGE TYPE")_"~"_ACK("HDR","EVENT"))
     71 ;
     72END ;
     73 I 'SENT,MSG("STATUS")="SU",$G(MSG("IEN")) D
     74 .Q:'$D(^HLB(MSG("IEN"),0))
     75 .S MSG("STATUS")="TF"
     76 .S MSG("STATUS","ERROR TEXT")=ERROR
     77 .S $P(^HLB(MSG("IEN"),0),"^",20)=MSG("STATUS")
     78 .S $P(^HLB(MSG("IEN"),0),"^",21)=MSG("STATUS","ERROR TEXT")
     79 .S ^HLB("ERRORS","TF",$S($L($G(MSG("HDR","RECEIVING APPLICATION"))):MSG("HDR","RECEIVING APPLICATION"),1:"UNKNOWN"),MSG("DT/TM CREATED"),IEN)=""
     80 ;
     81 Q SENT
     82 ;
     83ERROR ;error trap for ACKNOW
     84 S SENT=0,ERROR="TRANSMISSION FAILURE:"_$P($ECODE,",",1,2)
     85 S $ETRAP="D UNWIND^%ZTER"
     86 ;
     87 ;don't log some common errors
     88 I ($ECODE["READ")!($ECODE["NOTOPEN")!($ECODE["DEVNOTOPN")!($ECODE["WRITE")!($ECODE["OPENERR") D
     89 .;nothing!
     90 E  D
     91 .D ^%ZTER
     92 G END^HLOSRVR2
     93 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOTCP.m

    r613 r623  
    1 HLOTCP  ;ALB/CJM- TCP/IP I/O - 10/4/94 1pm ;07/10/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,131,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 OPEN(HLCSTATE,LOGICAL)  ;
    6         ;This may be called either in the context of a client or a server.
    7         ;For the server, there are 3 situations:
    8         ; 1) The server is not concurrent.  In this case the TCP device should be opened.
    9         ; 2) The server is concurrent, but this process was spawned by the OS
    10         ;    (via a VMS TCP Service)  In this case, the device should be opened
    11         ;    via the LOGICAL that was passed in.
    12         ;  3) The server is concurrent, but this process was spawned by the
    13         ;     TaskMan multi-listener.  In this case TaskMan already opened the
    14         ;     device.  This case can be determined by the absence of the LOGICAL
    15         ;     input parameter.
    16         ;
    17         N IP,PORT,DNSFLAG
    18         ;
    19         S DNSFLAG=0 ;DNS has not been contacted for IP
    20         ;
    21         S:'$G(HLCSTATE("SERVER")) IP=HLCSTATE("LINK","IP")
    22         S PORT=HLCSTATE("LINK","PORT")
    23         S HLCSTATE("CONNECTED")=0
    24         S HLCSTATE("READ HEADER")="READHDR^HLOTCP"
    25         S HLCSTATE("WRITE HEADER")="WRITEHDR^HLOTCP"
    26         S HLCSTATE("READ SEGMENT")="READSEG^HLOTCP"
    27         S HLCSTATE("WRITE SEGMENT")="WRITESEG^HLOTCP"
    28         S HLCSTATE("END MESSAGE")="ENDMSG^HLOTCP"
    29         S HLCSTATE("CLOSE")="CLOSE^HLOTCP"
    30         ;
    31         ;spawned by TaskMan multi-listener? If so, the device has already been opened
    32         I $G(HLCSTATE("SERVER")),$G(HLCSTATE("LINK","SERVER"))="1^M",$G(LOGICAL)="" D  Q
    33         .S HLCSTATE("DEVICE")=IO(0),HLCSTATE("FLUSH")="!",HLCSTATE("TCP BUFFER SIZE")=510
    34         .S HLCSTATE("CONNECTED")=1
    35         ;
    36         ;if no IP, not a server, give DNS a shot
    37         I '$G(HLCSTATE("SERVER")),IP="" S DNSFLAG=1,IP=$$DNS(HLCSTATE("LINK","DOMAIN")),HLCSTATE("LINK","IP")=IP Q:IP=""
    38         ;
    39 RETRY   I HLCSTATE("SYSTEM","OS")="DSM" D
    40         .S HLCSTATE("TCP BUFFER SIZE")=512
    41         .I $G(LOGICAL)]"" S HLCSTATE("DEVICE")=LOGICAL
    42         .E  S HLCSTATE("DEVICE")=PORT
    43         .S HLCSTATE("FLUSH")="!"
    44         .I $G(HLCSTATE("SERVER")) D
    45         ..O:$G(LOGICAL)]"" HLCSTATE("DEVICE"):(TCPDEV,BLOCKSIZE=512):HLCSTATE("OPEN TIMEOUT")
    46         ..O:$G(LOGICAL)="" HLCSTATE("DEVICE"):(TCPCHAN,BLOCKSIZE=512):HLCSTATE("OPEN TIMEOUT")
    47         ..I $T D
    48         ...S HLCSTATE("CONNECTED")=1
    49         ...U HLCSTATE("DEVICE"):NOECHO
    50         .E  D  ;client
    51         ..O HLCSTATE("DEVICE"):(TCPCHAN,ADDRESS=IP,BLOCKSIZE=512):HLCSTATE("OPEN TIMEOUT")
    52         ..I $T D
    53         ...S HLCSTATE("CONNECTED")=1
    54         ...U HLCSTATE("DEVICE"):NOECHO
    55         E  I HLCSTATE("SYSTEM","OS")="CACHE" D
    56         .S HLCSTATE("FLUSH")="!"
    57         .I $G(LOGICAL)]"" S HLCSTATE("DEVICE")=LOGICAL
    58         .E  S HLCSTATE("DEVICE")="|TCP|"_PORT
    59         .S HLCSTATE("TCP BUFFER SIZE")=510
    60         .I $G(HLCSTATE("SERVER")) D
    61         ..I HLCSTATE("SERVER")="1^S" D  Q
    62         ...;single server (no concurrent connections)
    63         ...O HLCSTATE("DEVICE"):(:PORT:"+A-S":::):HLCSTATE("OPEN TIMEOUT")
    64         ...I $T D
    65         ....N A
    66         ....S HLCSTATE("CONNECTED")=1
    67         ....U HLCSTATE("DEVICE")
    68         ....F  R *A:HLCSTATE("READ TIMEOUT") Q:$T  I $$CHKSTOP^HLOPROC S HLCSTATE("CONNECTED")=0 D CLOSE(.HLCSTATE) Q
    69         ..;
    70         ..;multi-server spawned by OS - VMS TCP Services
    71         ..O HLCSTATE("DEVICE")::HLCSTATE("OPEN TIMEOUT") I '$T S HLCSTATE("CONNECTED")=0 Q
    72         ..S HLCSTATE("CONNECTED")=1
    73         ..U HLCSTATE("DEVICE"):(::"-S")
    74         ..;
    75         .E  D  ;client
    76         ..S HLCSTATE("TCP BUFFER SIZE")=510
    77         ..O HLCSTATE("DEVICE"):(IP:PORT:"-S":::):HLCSTATE("OPEN TIMEOUT")
    78         ..I $T D
    79         ...S HLCSTATE("CONNECTED")=1
    80         E  D  ;any other system but Cache or DSM
    81         .S HLCSTATE("TCP BUFFER SIZE")=256
    82         .D CALL^%ZISTCP(IP,PORT,HLCSTATE("OPEN TIMEOUT"))
    83         .S HLCSTATE("CONNECTED")='POP
    84         .I HLCSTATE("CONNECTED") S HLCSTATE("DEVICE")=IO
    85         ;
    86         ;if not connected, not the server, give DNS a shot if not tried already
    87         I '$G(HLCSTATE("SERVER")),'HLCSTATE("CONNECTED"),'DNSFLAG S DNSFLAG=1,IP=$$DNS(HLCSTATE("LINK","DOMAIN")) I IP]"",IP'=HLCSTATE("LINK","IP") S HLCSTATE("LINK","IP")=IP G RETRY
    88         I HLCSTATE("CONNECTED"),DNSFLAG S $P(^HLCS(870,HLCSTATE("LINK","IEN"),400),"^")=IP
    89         Q
    90         ;
    91 DNS(DOMAIN)     ;
    92         Q $P($$ADDRESS^XLFNSLK(DOMAIN),",")
    93         ;
    94 WRITEHDR(HLCSTATE,HDR)  ;
    95         ;
    96         ;insure that package buffer is empty
    97         K HLCSTATE("BUFFER")
    98         S HLCSTATE("BUFFER","BYTE COUNT")=0
    99         S HLCSTATE("BUFFER","SEGMENT COUNT")=0
    100         S HLCSTATE("FIRST WRITE")=1 ;so that FLUSH knows $X should be 0
    101         ;
    102         ;Start the message with <SB>, then write the header
    103         N SEG
    104         S SEG(1)=$C(11)_HDR(1)
    105         S SEG(2)=HDR(2)
    106         Q $$WRITESEG(.HLCSTATE,.SEG)
    107         ;
    108 WRITESEG(HLCSTATE,SEG)  ;
    109         N I,LAST
    110         S HLCSTATE("BUFFER","SEGMENT COUNT")=HLCSTATE("BUFFER","SEGMENT COUNT")+1
    111         S I=0,LAST=$O(SEG(99999),-1)
    112         F  S I=$O(SEG(I)) Q:'I  D
    113         .I HLCSTATE("BUFFER","BYTE COUNT")>HLCSTATE("SYSTEM","BUFFER") D FLUSH
    114         .I I=LAST S SEG(I)=SEG(I)_$C(13)
    115         .S HLCSTATE("BUFFER",HLCSTATE("BUFFER","SEGMENT COUNT"),I)=SEG(I),HLCSTATE("BUFFER","BYTE COUNT")=HLCSTATE("BUFFER","BYTE COUNT")+$L(SEG(I))+20
    116         Q HLCSTATE("CONNECTED")
    117         ;
    118 FLUSH   ;flushes the HL7 package buffer, and the system TCP buffer when full
    119         N SEGMENT,MAX
    120         S SEGMENT=0
    121         S MAX=HLCSTATE("TCP BUFFER SIZE")
    122         U HLCSTATE("DEVICE") I (HLCSTATE("SYSTEM","OS")="CACHE") S HLCSTATE("CONNECTED")=($ZA\8192#2) I 'HLCSTATE("CONNECTED") D CLOSE(.HLCSTATE)
    123         F  S SEGMENT=$O(HLCSTATE("BUFFER",SEGMENT)) Q:'SEGMENT  D
    124         .N I S I=0
    125         .F  S I=$O(HLCSTATE("BUFFER",SEGMENT,I)) Q:'I  D
    126         ..N LINE,J
    127         ..S J=$S(HLCSTATE("FIRST WRITE"):0,1:$X)
    128         ..S HLCSTATE("FIRST WRITE")=0
    129         ..S LINE=HLCSTATE("BUFFER",SEGMENT,I)
    130         ..F  Q:'(J+$L(LINE)>MAX)  D
    131         ...W $E(LINE,1,MAX-J),@HLCSTATE("FLUSH") S HLCSTATE("FLUSHED")=1
    132         ...S LINE=$E(LINE,(MAX-J)+1,99999)
    133         ...S J=0
    134         ..I (LINE]"") W LINE S HLCSTATE("FLUSHED")=0
    135         K HLCSTATE("BUFFER")
    136         S HLCSTATE("BUFFER","SEGMENT COUNT")=1
    137         S HLCSTATE("BUFFER","BYTE COUNT")=0
    138         S HLCSTATE("FIRST WRITE")=0
    139         Q
    140         ;
    141 READSEG(HLCSTATE,SEG)   ;
    142         ;
    143         ;Output:
    144         ;  SEG - returns the segment (pass by reference)
    145         ;  Function returns 1 on success, 0 on failure
    146         ;
    147         N SUCCESS,COUNT,BUF
    148         S (COUNT,SUCCESS)=0
    149         K SEG
    150         ;
    151         ;anything left from last read?
    152         S BUF=HLCSTATE("READ")
    153         S HLCSTATE("READ")=""
    154         I BUF]"" D  ;something was left!
    155         .S COUNT=1
    156         .I BUF[$C(13) D  Q
    157         ..S SEG(1)=$P(BUF,$C(13)),BUF=$P(BUF,$C(13),2,9999)
    158         ..S SUCCESS=1
    159         .S SEG(1)=BUF,BUF=""
    160         I 'SUCCESS U HLCSTATE("DEVICE") F  R BUF:HLCSTATE("READ TIMEOUT") Q:'$T  D  Q:SUCCESS
    161         .I BUF[$C(13) S SUCCESS=1,COUNT=COUNT+1,SEG(COUNT)=$P(BUF,$C(13)),BUF=$P(BUF,$C(13),2,9999) Q
    162         .S COUNT=COUNT+1,SEG(COUNT)=BUF
    163         ;
    164         I SUCCESS D
    165         .S HLCSTATE("READ")=BUF ;save the leftover
    166         .I COUNT>1,SEG(COUNT)="" K SEG(COUNT) S COUNT=COUNT-1
    167         ;Cache can return the connection status
    168         E  I (HLCSTATE("SYSTEM","OS")="CACHE") S HLCSTATE("CONNECTED")=($ZA\8192#2) I 'HLCSTATE("CONNECTED") D CLOSE(.HLCSTATE)
    169         ;
    170         ;if the <EB> character was encountered, then there are no more segments in the message, set the end of message flag
    171         I SUCCESS,SEG(COUNT)[$C(28) D
    172         .K SEG
    173         .S SUCCESS=0
    174         .S HLCSTATE("MESSAGE ENDED")=1
    175         Q SUCCESS
    176         ;
    177 READHDR(HLCSTATE,HDR)   ;
    178         ;reads the next header segment in the message stream, discarding everything that comes before it
    179         ;
    180         N SEG,SUCCESS,J,I
    181         S SUCCESS=0
    182         K HDR
    183         F  Q:'$$READSEG(.HLCSTATE,.SEG)  D  Q:SUCCESS
    184         .S I=0
    185         .;look for the <SB>
    186         .;perhaps the <SB> isn't in the first line
    187         .F  S I=$O(SEG(I)) Q:'I  D  Q:SUCCESS
    188         ..I (SEG(I)'[$C(11)) K SEG(I) Q
    189         ..S SEG(I)=$P(SEG(I),$C(11),2)
    190         ..S SUCCESS=1
    191         ..K:SEG(I)="" SEG(I)
    192         I SUCCESS S (I,J)=0 F  S J=$O(SEG(J)) Q:'J  S I=I+1,HDR(I)=SEG(J)
    193         Q SUCCESS
    194         ;
    195 CLOSE(HLCSTATE) ;
    196         CLOSE HLCSTATE("DEVICE")
    197         Q
    198         ;
    199 ENDMSG(HLCSTATE)               ;
    200         N SEG
    201         S SEG(1)=$C(28)
    202         I $$WRITESEG(.HLCSTATE,.SEG) D  Q 1
    203         .D FLUSH
    204         .U HLCSTATE("DEVICE")
    205         .I ('$G(HLCSTATE("FLUSHED")))!$X W @HLCSTATE("FLUSH") S HLCSTATE("FLUSHED")=1
    206         Q 0
     1HLOTCP ;ALB/CJM- TCP/IP I/O - 10/4/94 1pm ;03/22/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,131,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5OPEN(HLCSTATE,LOGICAL) ;
     6 ;This may be called either in the context of a client or a server.
     7 ;For the server, there are 3 situations:
     8 ; 1) The server is not concurrent.  In this case the TCP device should be opened.
     9 ; 2) The server is concurrent, but this process was spawned by the OS
     10 ;    (via a VMS TCP Service)  In this case, the device should be opened
     11 ;    via the LOGICAL that was passed in.
     12 ;  3) The server is concurrent, but this process was spawned by the
     13 ;     TaskMan multi-listener.  In this case TaskMan already opened the
     14 ;     device.  This case can be determined by the absence of the LOGICAL
     15 ;     input parameter.
     16 ;
     17 N IP,PORT,DNSFLAG
     18 ;
     19 S DNSFLAG=0 ;DNS has not been contacted for IP
     20 ;
     21 S:'$G(HLCSTATE("SERVER")) IP=HLCSTATE("LINK","IP")
     22 S PORT=HLCSTATE("LINK","PORT")
     23 S HLCSTATE("CONNECTED")=0
     24 S HLCSTATE("READ HEADER")="READHDR^HLOTCP"
     25 S HLCSTATE("WRITE HEADER")="WRITEHDR^HLOTCP"
     26 S HLCSTATE("READ SEGMENT")="READSEG^HLOTCP"
     27 S HLCSTATE("WRITE SEGMENT")="WRITESEG^HLOTCP"
     28 S HLCSTATE("END MESSAGE")="ENDMSG^HLOTCP"
     29 S HLCSTATE("CLOSE")="CLOSE^HLOTCP"
     30 ;
     31 ;spawned by TaskMan multi-listener? If so, the device has already been opened
     32 I $G(HLCSTATE("SERVER")),$G(HLCSTATE("LINK","SERVER"))="1^M",$G(LOGICAL)="" D  Q
     33 .S HLCSTATE("DEVICE")=IO(0),HLCSTATE("FLUSH")="!",HLCSTATE("TCP BUFFER SIZE")=510
     34 .S HLCSTATE("CONNECTED")=1
     35 ;
     36 ;if no IP, not a server, give DNS a shot
     37 I '$G(HLCSTATE("SERVER")),IP="" S DNSFLAG=1,IP=$$DNS(HLCSTATE("LINK","DOMAIN")),HLCSTATE("LINK","IP")=IP Q:IP=""
     38 ;
     39RETRY I HLCSTATE("SYSTEM","OS")="DSM" D
     40 .S HLCSTATE("TCP BUFFER SIZE")=512
     41 .I $G(LOGICAL)]"" S HLCSTATE("DEVICE")=LOGICAL
     42 .E  S HLCSTATE("DEVICE")=PORT
     43 .S HLCSTATE("FLUSH")="!"
     44 .I $G(HLCSTATE("SERVER")) D
     45 ..O:$G(LOGICAL)]"" HLCSTATE("DEVICE"):(TCPDEV,BLOCKSIZE=512):HLCSTATE("OPEN TIMEOUT")
     46 ..O:$G(LOGICAL)="" HLCSTATE("DEVICE"):(TCPCHAN,BLOCKSIZE=512):HLCSTATE("OPEN TIMEOUT")
     47 ..I $T D
     48 ...S HLCSTATE("CONNECTED")=1
     49 ...U HLCSTATE("DEVICE"):NOECHO
     50 .E  D  ;client
     51 ..O HLCSTATE("DEVICE"):(TCPCHAN,ADDRESS=IP,BLOCKSIZE=512):HLCSTATE("OPEN TIMEOUT")
     52 ..I $T D
     53 ...S HLCSTATE("CONNECTED")=1
     54 ...U HLCSTATE("DEVICE"):NOECHO
     55 E  I HLCSTATE("SYSTEM","OS")="CACHE" D
     56 .S HLCSTATE("FLUSH")="!"
     57 .I $G(LOGICAL)]"" S HLCSTATE("DEVICE")=LOGICAL
     58 .E  S HLCSTATE("DEVICE")="|TCP|"_PORT
     59 .S HLCSTATE("TCP BUFFER SIZE")=510
     60 .I $G(HLCSTATE("SERVER")) D
     61 ..I HLCSTATE("SERVER")="1^S" D  Q
     62 ...;single server (no concurrent connections)
     63 ...O HLCSTATE("DEVICE"):(:PORT:"+A-S":::):HLCSTATE("OPEN TIMEOUT")
     64 ...I $T D
     65 ....N A
     66 ....S HLCSTATE("CONNECTED")=1
     67 ....U HLCSTATE("DEVICE")
     68 ....F  R *A:HLCSTATE("READ TIMEOUT") Q:$T  I $$CHKSTOP^HLOPROC S HLCSTATE("CONNECTED")=0 D CLOSE(.HLCSTATE) Q
     69 ..;
     70 ..;multi-server spawned by OS - VMS TCP Services
     71 ..O HLCSTATE("DEVICE")::HLCSTATE("OPEN TIMEOUT") I '$T S HLCSTATE("CONNECTED")=0 Q
     72 ..S HLCSTATE("CONNECTED")=1
     73 ..U HLCSTATE("DEVICE"):(::"-S")
     74 ..;
     75 .E  D  ;client
     76 ..S HLCSTATE("TCP BUFFER SIZE")=510
     77 ..O HLCSTATE("DEVICE"):(IP:PORT:"-S":::):HLCSTATE("OPEN TIMEOUT")
     78 ..I $T D
     79 ...S HLCSTATE("CONNECTED")=1
     80 E  D  ;any other system but Cache or DSM
     81 .S HLCSTATE("TCP BUFFER SIZE")=256
     82 .D CALL^%ZISTCP(IP,PORT,HLCSTATE("OPEN TIMEOUT"))
     83 .S HLCSTATE("CONNECTED")='POP
     84 .I HLCSTATE("CONNECTED") S HLCSTATE("DEVICE")=IO
     85 ;
     86 ;if not connected, not the server, give DNS a shot if not tried already
     87 I '$G(HLCSTATE("SERVER")),'HLCSTATE("CONNECTED"),'DNSFLAG S DNSFLAG=1,IP=$$DNS(HLCSTATE("LINK","DOMAIN")) I IP]"",IP'=HLCSTATE("LINK","IP") S HLCSTATE("LINK","IP")=IP G RETRY
     88 I HLCSTATE("CONNECTED"),DNSFLAG S $P(^HLCS(870,HLCSTATE("LINK","IEN"),400),"^")=IP
     89 Q
     90 ;
     91DNS(DOMAIN) ;
     92 Q $P($$ADDRESS^XLFNSLK(DOMAIN),",")
     93 ;
     94WRITEHDR(HLCSTATE,HDR) ;
     95 ;
     96 ;insure that package buffer is empty
     97 K HLCSTATE("BUFFER")
     98 S HLCSTATE("BUFFER","BYTE COUNT")=0
     99 S HLCSTATE("BUFFER","SEGMENT COUNT")=0
     100 S HLCSTATE("FIRST WRITE")=1 ;so that FLUSH knows $X should be 0
     101 ;
     102 ;Start the message with <SB>, then write the header
     103 N SEG
     104 S SEG(1)=$C(11)_HDR(1)
     105 S SEG(2)=HDR(2)
     106 Q $$WRITESEG(.HLCSTATE,.SEG)
     107 ;
     108WRITESEG(HLCSTATE,SEG) ;
     109 N I,LAST
     110 S HLCSTATE("BUFFER","SEGMENT COUNT")=HLCSTATE("BUFFER","SEGMENT COUNT")+1
     111 S I=0,LAST=$O(SEG(99999),-1)
     112 F  S I=$O(SEG(I)) Q:'I  D
     113 .I HLCSTATE("BUFFER","BYTE COUNT")>HLCSTATE("SYSTEM","BUFFER") D FLUSH
     114 .I I=LAST S SEG(I)=SEG(I)_$C(13)
     115 .S HLCSTATE("BUFFER",HLCSTATE("BUFFER","SEGMENT COUNT"),I)=SEG(I),HLCSTATE("BUFFER","BYTE COUNT")=HLCSTATE("BUFFER","BYTE COUNT")+$L(SEG(I))+20
     116 Q HLCSTATE("CONNECTED")
     117 ;
     118FLUSH ;flushes the HL7 package buffer, and the system TCP buffer when full
     119 N SEGMENT,MAX
     120 S SEGMENT=0
     121 S MAX=HLCSTATE("TCP BUFFER SIZE")
     122 U HLCSTATE("DEVICE") I (HLCSTATE("SYSTEM","OS")="CACHE") S HLCSTATE("CONNECTED")=($ZA\8192#2) I 'HLCSTATE("CONNECTED") D CLOSE(.HLCSTATE)
     123 F  S SEGMENT=$O(HLCSTATE("BUFFER",SEGMENT)) Q:'SEGMENT  D
     124 .N I S I=0
     125 .F  S I=$O(HLCSTATE("BUFFER",SEGMENT,I)) Q:'I  D
     126 ..N LINE,J
     127 ..S J=$S(HLCSTATE("FIRST WRITE"):0,1:$X)
     128 ..S HLCSTATE("FIRST WRITE")=0
     129 ..S LINE=HLCSTATE("BUFFER",SEGMENT,I)
     130 ..F  Q:'(J+$L(LINE)>MAX)  D
     131 ...W $E(LINE,1,MAX-J),@HLCSTATE("FLUSH")
     132 ...S LINE=$E(LINE,(MAX-J)+1,99999)
     133 ...S J=0
     134 ..W:(LINE]"") LINE
     135 K HLCSTATE("BUFFER")
     136 S HLCSTATE("BUFFER","SEGMENT COUNT")=1
     137 S HLCSTATE("BUFFER","BYTE COUNT")=0
     138 S HLCSTATE("FIRST WRITE")=0
     139 Q
     140 ;
     141READSEG(HLCSTATE,SEG) ;
     142 ;
     143 ;Output:
     144 ;  SEG - returns the segment (pass by reference)
     145 ;  Function returns 1 on success, 0 on failure
     146 ;
     147 N SUCCESS,COUNT,BUF
     148 S (COUNT,SUCCESS)=0
     149 K SEG
     150 ;
     151 ;anything left from last read?
     152 S BUF=HLCSTATE("READ")
     153 S HLCSTATE("READ")=""
     154 I BUF]"" D  ;something was left!
     155 .S COUNT=1
     156 .I BUF[$C(13) D  Q
     157 ..S SEG(1)=$P(BUF,$C(13)),BUF=$P(BUF,$C(13),2,9999)
     158 ..S SUCCESS=1
     159 .S SEG(1)=BUF,BUF=""
     160 I 'SUCCESS U HLCSTATE("DEVICE") F  R BUF:HLCSTATE("READ TIMEOUT") Q:'$T  D  Q:SUCCESS
     161 .I BUF[$C(13) S SUCCESS=1,COUNT=COUNT+1,SEG(COUNT)=$P(BUF,$C(13)),BUF=$P(BUF,$C(13),2,9999) Q
     162 .S COUNT=COUNT+1,SEG(COUNT)=BUF
     163 ;
     164 I SUCCESS D
     165 .S HLCSTATE("READ")=BUF ;save the leftover
     166 .I COUNT>1,SEG(COUNT)="" K SEG(COUNT) S COUNT=COUNT-1
     167 ;Cache can return the connection status
     168 E  I (HLCSTATE("SYSTEM","OS")="CACHE") S HLCSTATE("CONNECTED")=($ZA\8192#2) I 'HLCSTATE("CONNECTED") D CLOSE(.HLCSTATE)
     169 ;
     170 ;if the <EB> character was encountered, then there are no more segments in the message, set the end of message flag
     171 I SUCCESS,SEG(COUNT)[$C(28) D
     172 .K SEG
     173 .S SUCCESS=0
     174 .S HLCSTATE("MESSAGE ENDED")=1
     175 Q SUCCESS
     176 ;
     177READHDR(HLCSTATE,HDR) ;
     178 ;reads the next header segment in the message stream, discarding everything that comes before it
     179 ;
     180 N SEG,SUCCESS,J,I
     181 S SUCCESS=0
     182 K HDR
     183 F  Q:'$$READSEG(.HLCSTATE,.SEG)  D  Q:SUCCESS
     184 .S I=0
     185 .;look for the <SB>
     186 .;perhaps the <SB> isn't in the first line
     187 .F  S I=$O(SEG(I)) Q:'I  D  Q:SUCCESS
     188 ..I (SEG(I)'[$C(11)) K SEG(I) Q
     189 ..S SEG(I)=$P(SEG(I),$C(11),2)
     190 ..S SUCCESS=1
     191 ..K:SEG(I)="" SEG(I)
     192 I SUCCESS S (I,J)=0 F  S J=$O(SEG(J)) Q:'J  S I=I+1,HDR(I)=SEG(J)
     193 Q SUCCESS
     194 ;
     195CLOSE(HLCSTATE) ;
     196 CLOSE HLCSTATE("DEVICE")
     197 Q
     198 ;
     199ENDMSG(HLCSTATE)        ;
     200 N SEG
     201 S SEG(1)=$C(28)
     202 I $$WRITESEG(.HLCSTATE,.SEG) D  Q 1
     203 .D FLUSH
     204 .U HLCSTATE("DEVICE")
     205 .W:$X @HLCSTATE("FLUSH")
     206 Q 0
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOUSR.m

    r613 r623  
    1 HLOUSR  ;ALB/CJM -ListManager Screen for viewing system status;12 JUN 1997 10:00 am ;07/30/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,130,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 EN      ;
    6         ;
    7         N HLSCREEN,TESTOPEN,HLRFRSH,HLPARMS
    8         D WAIT^DICD
    9         D EN^VALM("HLO SYSTEM MONITOR")
    10         Q
    11         ;
    12 BRIEF   ;
    13         N COUNT,LINK,QUE,FROM,TIME,STATUS,TEMP,DIR,TODAY,LIST
    14         S HLRFRSH="BRIEF^HLOUSR"
    15         S (HLSCREEN,VALMSG)="Brief System Status"
    16         S VALMCNT=16
    17         ;K @VALMAR
    18         D CLEAN^VALM10
    19         S VALMBG=1
    20         S VALMBCK="R"
    21         S VALMDDF("COL 1")="COL1^1^80^"
    22         K VALMDDF("COL 2"),VALMDDF("COL 3"),VALMDDF("COL 4"),VALMDDF("COL 5")
    23         D CHGCAP^VALM("COL 1"," Brief Operational Overview")
    24         S @VALMAR@(1,0)="SYSTEM STATUS:             "_$S($$CHKSTOP^HLOPROC:"STOPPED",1:"RUNNING")
    25         S @VALMAR@(2,0)="PROCESS MANAGER:           "_$S($$RUNNING:"RUNNING",1:"STOPPED")
    26         ;
    27         S TIME=$P($G(TESTOPEN("LISTENER")),"^",2)
    28         I TIME,$$FMDIFF^XLFDT($$NOW^XLFDT,TIME,2)<300 D
    29         .S STATUS=+TESTOPEN("LISTENER")
    30         E  D
    31         .S STATUS=0
    32         .S LINK=$P($G(^HLD(779.1,1,0)),"^",10)
    33         .I LINK S LINK=$P($G(^HLCS(870,LINK,0)),"^") Q:'$L(LINK)  S STATUS=$$IFOPEN^HLOUSR1(LINK)
    34         .S TESTOPEN("LISTENER")=STATUS_"^"_$$NOW^XLFDT
    35         ;
    36         S @VALMAR@(3,0)="STANDARD LISTENER:         "_$S(STATUS:"OPERATIONAL",1:"NOT OPERATIONAL")
    37         ;
    38         S @VALMAR@(4,0)="TASKMAN:                   "_$S($$TM^%ZTLOAD:"RUNNING",1:"NOT RUNNING")
    39         ;
    40         S (LIST,LINK)=""
    41         F  S LINK=$O(^HLTMP("FAILING LINKS",LINK)) Q:LINK=""  D  I $L(LIST)>60 S LIST=LIST_",..." Q
    42         .N TIME,QUE,LINKARY
    43         .I $$GETLINK^HLOTLNK($P(LINK,":"),.LINKARY)
    44         .S TIME=$G(^HLTMP("FAILING LINKS",LINK)) Q:TIME=""
    45         .I '$G(LINKARY("SHUTDOWN")),TIME="" Q
    46         .I '$G(LINKARY("SHUTDOWN")),($$HDIFF^XLFDT($H,TIME,2)<300) Q
    47         .S LIST=LIST_$S($L(LIST):", ",1:"")_$P(LINK,":")
    48         S @VALMAR@(5,0)="DOWN LINKS: "_LIST
    49         S @VALMAR@(6,0)="CLIENT LINK PROCESSES:     "_+$G(^HLC("HL7 PROCESS COUNTS","RUNNING","OUTGOING CLIENT LINK"))
    50         S @VALMAR@(7,0)="IN-FILER PROCESSES:        "_+$G(^HLC("HL7 PROCESS COUNTS","RUNNING","INCOMING QUEUES"))
    51         S COUNT=0,LINK=""
    52         F  S LINK=$O(^HLC("QUEUECOUNT","OUT",LINK)) Q:LINK=""  D
    53         .S QUE=""
    54         .F  S QUE=$O(^HLC("QUEUECOUNT","OUT",LINK,QUE)) Q:QUE=""  D
    55         ..S TEMP=$G(^HLC("QUEUECOUNT","OUT",LINK,QUE))
    56         ..S:TEMP>0 COUNT=COUNT+TEMP
    57         S @VALMAR@(8,0)="MESSAGES PENDING ON OUT QUEUES:    "_$$RJ(+COUNT,7)_"     ON SEQUENCE QUEUES:  "_$$RJ(+$G(^HLC("QUEUECOUNT","SEQUENCE")),7)
    58         S TEMP="STOPPED OUTGOING QUEUES: "
    59         S COUNT=0,QUE=""
    60         F  S QUE=$O(^HLTMP("STOPPED QUEUES","OUT",QUE)) Q:QUE=""  S COUNT=COUNT+1 Q:COUNT>4  S:COUNT=1 TEMP=TEMP_QUE S:"23"[COUNT TEMP=TEMP_"; "_QUE S:COUNT=4 TEMP=TEMP_" ..."
    61         S @VALMAR@(9,0)=TEMP
    62         S COUNT=0,QUE=""
    63         F  S QUE=$O(^HLC("QUEUECOUNT","IN",QUE)) Q:QUE=""  D
    64         .S FROM=""
    65         .F  S FROM=$O(^HLC("QUEUECOUNT","IN",QUE,FROM)) Q:FROM=""  D
    66         ..S TEMP=$G(^HLC("QUEUECOUNT","IN",QUE,FROM))
    67         ..S:TEMP>0 COUNT=COUNT+TEMP
    68         S @VALMAR@(10,0)="MESSAGES PENDING ON APPLICATIONS: "_$$RJ(+COUNT,7)
    69         S TEMP="STOPPED INCOMING QUEUES: "
    70         S COUNT=0,QUE=""
    71         F  S QUE=$O(^HLTMP("STOPPED QUEUES","IN",QUE)) Q:QUE=""  S COUNT=COUNT+1 Q:COUNT>4  S:COUNT=1 TEMP=TEMP_QUE S:"23"[COUNT TEMP=TEMP_"; "_QUE S:COUNT=4 TEMP=TEMP_" ..."
    72         S @VALMAR@(11,0)=TEMP
    73         S @VALMAR@(12,0)="FILE 777 RECORD COUNT:         "_$$RJ($P($G(^HLTMP("FILE 777 RECORD COUNT")),"^"),10)_"     --> as of "_$$FMTE^XLFDT($P($G(^HLTMP("FILE 777 RECORD COUNT")),"^",2))
    74         S @VALMAR@(13,0)="FILE 778 RECORD COUNT:         "_$$RJ($P($G(^HLTMP("FILE 778 RECORD COUNT")),"^"),10)_"     --> as of "_$$FMTE^XLFDT($P($G(^HLTMP("FILE 778 RECORD COUNT")),"^",2))
    75         S TODAY=$$DT^XLFDT
    76         S @VALMAR@(14,0)="MESSAGES SENT TODAY:           "_$$RJ($$ADD("OUT"),10)
    77         S @VALMAR@(15,0)="MESSAGES RECEIVED TODAY:       "_$$RJ($$ADD("IN"),10)
    78         S @VALMAR@(16,0)="MESSAGE ERRORS TODAY:          "_$$RJ($$ADD("EOUT")+$$ADD("EIN"),10)
    79         Q
    80 ADD(DIR)        ;
    81         N RAP,SAP,TIME,TOTAL
    82         S TOTAL=0
    83         S TIME=TODAY-.0001
    84         F  S TIME=$O(^HLSTATS(DIR,"HOURLY",TIME)) Q:'TIME  Q:((TIME\1)>TODAY)  D
    85         .S SAP=""
    86         .F  S SAP=$O(^HLSTATS(DIR,"HOURLY",TIME,SAP)) Q:SAP=""  D
    87         ..Q:SAP="ACCEPT ACK"
    88         ..S RAP=""
    89         ..F  S RAP=$O(^HLSTATS(DIR,"HOURLY",TIME,SAP,RAP)) Q:RAP=""  D
    90         ...S TYPE=""
    91         ...F  S TYPE=$O(^HLSTATS(DIR,"HOURLY",TIME,SAP,RAP,TYPE)) Q:TYPE=""  D
    92         ....S TOTAL=TOTAL+$G(^HLSTATS(DIR,"HOURLY",TIME,SAP,RAP,TYPE))
    93         Q TOTAL
    94         ;
    95 HELP    ;
    96         S X="?" D DISP^XQORM1 W !!
    97         Q
    98         ;
    99 EXIT    ;
    100         D CLEAN^VALM10
    101         D CLEAR^VALM1
    102         Q
    103         ;
    104 EXPND   ;
    105         Q
    106         ;
    107 PROCS   ;
    108         S HLRFRSH="PROCS^HLOUSR"
    109         ;K @VALMAR
    110         D CLEAN^VALM10
    111         S VALMCNT=0
    112         S VALMBCK="R"
    113         S VALMDDF("COL 1")="COL1^1^34^"
    114         S VALMDDF("COL 2")="COL 2^35^10^MIN^H"
    115         S VALMDDF("COL 3")="COL 3^47^10^MAX^H"
    116         S VALMDDF("COL 4")="COL 4^59^10^#RUNNING^H"
    117         S VALMDDF("COL 5")="COL 5^71^10^#QUEUED^IOBON"
    118         D CHGCAP^VALM("COL 1","Process Type")
    119         N IEN
    120         S IEN=0
    121         F  S IEN=$O(^HLD(779.3,"C",1,IEN)) Q:'IEN  D
    122         .N PROC
    123         .Q:'$$GETPROC^HLOPROC1(IEN,.PROC)
    124         .Q:PROC("NAME")="VMS TCP LISTENER"
    125         .S VALMCNT=VALMCNT+1
    126         .S @VALMAR@(VALMCNT,0)=$$LJ(PROC("NAME"),30)_$$RJ(PROC("MINIMUM"),6)_$$RJ(PROC("MAXIMUM"),12)_$$RJ(+$G(^HLC("HL7 PROCESS COUNTS","RUNNING",PROC("NAME"))),14)_$$RJ(+$G(^HLC("HL7 PROCESS COUNTS","QUEUED",PROC("NAME"))),12)
    127         S VALMCNT=VALMCNT+1,@VALMAR@(VALMCNT,0)=""
    128         S IEN=""
    129         F  S IEN=$O(^HLTMP("HL7 RUNNING PROCESSES",IEN)) Q:IEN=""  D
    130         .N NODE
    131         .S NODE=$G(^HLTMP("HL7 RUNNING PROCESSES",IEN))
    132         .Q:NODE=""
    133         .S VALMCNT=VALMCNT+1
    134         .S @VALMAR@(VALMCNT,0)="$J: "_$$LJ(IEN,9)_" ->"_$$CJ($P(NODE,"^",3),28)_"<- started at "_$$HTE^XLFDT($P(NODE,"^"))
    135         Q
    136         ;
    137 OUTQUEUE        ;
    138         N LINK
    139         D CLEAN^VALM10
    140         ;K @VALMAR
    141         S HLRFRSH="OUTQUEUE^HLOUSR"
    142         S (HLSCREEN,VALMSG)="Outgoing Queues *down links !stopped queues"
    143         S VALMCNT=0
    144         S VALMBCK="R"
    145         S VALMDDF("COL 1")="COL 1^2^20^ Link^H"
    146         S VALMDDF("COL 2")="COL 2^28^20^Queue^H"
    147         S VALMDDF("COL 3")="COL 3^50^20^Count^H"
    148         K VALMDDF("COL 4"),VALMDDF("COL 5")
    149         D CHGCAP^VALM("COL 1"," Link")
    150         S LINK=""
    151         F  S LINK=$O(^HLC("QUEUECOUNT","OUT",LINK)) Q:LINK=""  D
    152         .N COUNT,QUE,SHOW
    153         .S SHOW=LINK
    154         .I $D(^HLTMP("FAILING LINKS",SHOW)) S SHOW="*"_SHOW
    155         .S QUE=""
    156         .F  S QUE=$O(^HLC("QUEUECOUNT","OUT",LINK,QUE)) Q:QUE=""  D
    157         ..S COUNT=$G(^HLC("QUEUECOUNT","OUT",LINK,QUE))
    158         ..Q:COUNT<1
    159         ..S VALMCNT=VALMCNT+1
    160         ..I $E(SHOW)="*" D
    161         ...S @VALMAR@(VALMCNT,0)=$$LJ(SHOW,20)_$$CJ($S($$STOPPED^HLOQUE("OUT",QUE):"!",1:"")_QUE,21)_"   "_$$RJ(COUNT,10),SHOW=""
    162         ...D CNTRL^VALM10(VALMCNT,1,1,IOBON,IOBOFF)
    163         ..E  S @VALMAR@(VALMCNT,0)=$$LJ(SHOW,20)_$$CJ($S($$STOPPED^HLOQUE("OUT",QUE):"!",1:"")_QUE,21)_"   "_$$RJ(COUNT,10),SHOW=""
    164         Q
    165         ;
    166 INQUEUE ;
    167         N FROM
    168         D CLEAN^VALM10
    169         ;K @VALMAR
    170         S HLRFRSH="INQUEUE^HLOUSR"
    171         S (HLSCREEN,VALMSG)="Incoming Queues ('!' = stopped queues)"
    172         S VALMCNT=0
    173         S VALMBCK="R"
    174         S VALMDDF("COL 1")="COL 1^1^40^ From^H"
    175         S VALMDDF("COL 2")="COL 2^45^20^Queue^H"
    176         S VALMDDF("COL 3")="COL 3^70^10^Count^H"
    177         K VALMDDF("COL 4"),VALMDDF("COL 5")
    178         D CHGCAP^VALM("COL 1"," From")
    179         S FROM=""
    180         F  S FROM=$O(^HLC("QUEUECOUNT","IN",FROM)) Q:FROM=""  D
    181         .N COUNT,QUE,SHOW
    182         .S SHOW=$$LJ(FROM,40)_"  "
    183         .S QUE=""
    184         .F  S QUE=$O(^HLC("QUEUECOUNT","IN",FROM,QUE)) Q:QUE=""  D
    185         ..S COUNT=$G(^HLC("QUEUECOUNT","IN",FROM,QUE))
    186         ..Q:COUNT<0
    187         ..S VALMCNT=VALMCNT+1
    188         ..S @VALMAR@(VALMCNT,0)=SHOW_$$LJ($S($$STOPPED^HLOQUE("IN",QUE):"!",1:"")_QUE,21)_" "_$$RJ(COUNT,10)
    189         ..S SHOW=$$LJ("",40)_"  "
    190         Q
    191 VIEWLINK        ;
    192         N C,QUIT,LINK,LINKARY,TEMP
    193         S (QUIT,C,LINK)=""
    194         S VALMBCK="R"
    195         ;
    196         ;currently HL7 (Optimized) only does TCP
    197         S LINK=$$ASKLINK
    198         Q:LINK=""
    199         Q:'$$GETLINK^HLOTLNK(LINK,.LINKARY)
    200         S LINK=LINK_":"_LINKARY("PORT")
    201         W !,"Hit any key to stop...",!
    202         F  D  Q:QUIT
    203         .N COUNT,QUE
    204         .S (COUNT,QUE)=""
    205         .F  S QUE=$O(^HLC("QUEUECOUNT","OUT",LINK,QUE)) Q:QUE=""  S TEMP=$G(^HLC("QUEUECOUNT","OUT",LINK,QUE)) S:TEMP>0 COUNT=COUNT+TEMP
    206         .W $C(13),"                             ",$C(13),"MESSAGES PENDING TRANSMISSION: ",IOBON,$$RJ(+COUNT,10),IOBOFF
    207         .R *C:1 I $T S QUIT=1
    208         Q
    209         ;
    210 CJ(STRING,LEN)  ;
    211         Q $$CJ^XLFSTR($E(STRING,1,LEN),LEN)
    212 LJ(STRING,LEN)  ;
    213         Q $$LJ^XLFSTR($E(STRING,1,LEN),LEN)
    214 RJ(STRING,LEN)  ;
    215         Q $$RJ^XLFSTR($E(STRING,1,LEN),LEN)
    216         ;
    217 RUNNING()       ;Process Manager running?
    218         N RUNNING
    219         L +^HLTMP("PROCESS MANAGER"):0
    220         S RUNNING='$T
    221         I 'RUNNING L -^HLTMP("PROCESS MANAGER")
    222         Q RUNNING
    223         ;
    224 TESTLINK        ;
    225         N LINK,LINKNAME,OK
    226         S VALMBCK="R"
    227         S LINKNAME=$$ASKLINK
    228         Q:LINKNAME=""
    229         S OK=$$IFOPEN^HLOUSR1(LINKNAME)
    230         I OK W !,LINKNAME_" IS operational..."
    231         E  W !,LINKNAME_" is NOT operational..."
    232         W !,"Hit any key to continue..."
    233         R *C:DTIME
    234         Q
    235         ;
    236 ASKLINK()       ;
    237         N DIC,TCP,X,Y,DTOUT,DUOUT
    238         S DIC=870
    239         S DIC(0)="AENQ"
    240         S TCP=$O(^HLCS(869.1,"B","TCP",0))
    241         S DIC("A")="Select a TCP link:"
    242         S DIC("S")="I $P(^(0),U,3)=TCP"
    243         D FULL^VALM1
    244         D ^DIC
    245         I +Y'=-1,'$D(DTOUT),'$D(DUOUT) Q $P(Y,"^",2)
    246         Q ""
    247         ;
    248 STOP    ;
    249         I '$$ASKYESNO^HLOUSR2("Are you SURE that you want to stop sending and receiving messages","NO") S VALMBCK="" Q
    250         ;
    251         D STOPHL7^HLOPROC1
    252         S VALMBCK="R",VALMSG="HL7 (Optimized) has been stopped...."
    253         H 5
    254         D @HLRFRSH
    255         ;D:HLSCREEN="Brief System Status" BRIEF^HLOUSR
    256         ;D:HLSCREEN="Running Processes" PROCS^HLOUSR
    257         Q
    258         ;
    259 UPDMODE ;realtime
    260         Q:'$L(HLRFRSH)
    261         N TOP,BOTTOM,DX,DY,IOTM,IOBM,LINE,OLD,OLDCNT
    262         S OLDCNT=VALMCNT
    263         W !!!!!,IOINHI,"Hit any key to escape realtime display mode...",IOINORM
    264         S IOTM=20,IOBM=23 W @IOSTBM
    265         S TOP=VALMBG
    266         S BOTTOM=TOP+20
    267         F LINE=TOP:1:BOTTOM D
    268         .I LINE>VALMCNT S @VALMAR@(LINE,0)=$$LJ(" ",80) Q
    269         .S @VALMAR@(LINE,0)=$$LJ(@VALMAR@(LINE,0),80)
    270         F LINE=TOP:1:BOTTOM D
    271         .S OLD(LINE)=@VALMAR@(LINE,0)
    272         F LINE=17:1:BOTTOM D
    273         .S DX=50,DY=22 X IOXY W !
    274         .D WRITE^VALM10(LINE)
    275         D  F  R *C:4 Q:$T  D
    276         .D @HLRFRSH
    277         .F LINE=TOP:1:BOTTOM D
    278         ..I LINE>VALMCNT S @VALMAR@(LINE,0)=$$LJ(" ",80) Q
    279         ..S @VALMAR@(LINE,0)=$$LJ(@VALMAR@(LINE,0),80)
    280         .S VALMCNT=BOTTOM
    281         .F LINE=TOP:1:BOTTOM IF OLD(LINE)'=@VALMAR@(LINE,0) D
    282         ..S OLD(LINE)=@VALMAR@(LINE,0)
    283         ..S DX=50,DY=22 X IOXY W !
    284         ..D WRITE^VALM10(LINE)
    285         S VALMCNT=OLDCNT
    286         S VALMBCK="R"
    287         Q
     1HLOUSR ;ALB/CJM -ListManager Screen for viewing system status;12 JUN 1997 10:00 am ;02/07/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,130,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5EN ;
     6 ;
     7 N HLSCREEN,TESTOPEN,HLRFRSH
     8 D WAIT^DICD
     9 D EN^VALM("HLO SYSTEM MONITOR")
     10 Q
     11 ;
     12BRIEF ;Init variables and list array
     13 N COUNT,LINK,QUE,FROM,TIME,STATUS,TEMP,DIR,TODAY,LIST
     14 S HLRFRSH="BRIEF^HLOUSR"
     15 S (HLSCREEN,VALMSG)="Brief System Status"
     16 S VALMCNT=8
     17 ;K @VALMAR
     18 D CLEAN^VALM10
     19 S VALMBG=1
     20 S VALMBCK="R"
     21 K VALMDDF("COL 2"),VALMDDF("COL 3"),VALMDDF("COL 4"),VALMDDF("COL 5")
     22 D CHGCAP^VALM("COL 1","Brief Operational Overview")
     23 S @VALMAR@(1,0)="SYSTEM STATUS:             "_$S($$CHKSTOP^HLOPROC:"STOPPED",1:"RUNNING")
     24 S @VALMAR@(2,0)="PROCESS MANAGER:           "_$S($$RUNNING:"RUNNING",1:"STOPPED")
     25 ;
     26 S TIME=$P($G(TESTOPEN("LISTENER")),"^",2)
     27 I TIME,$$FMDIFF^XLFDT($$NOW^XLFDT,TIME,2)<300 D
     28 .S STATUS=+TESTOPEN("LISTENER")
     29 E  D
     30 .S STATUS=0
     31 .S LINK=$P($G(^HLD(779.1,1,0)),"^",10)
     32 .I LINK S LINK=$P($G(^HLCS(870,LINK,0)),"^") Q:'$L(LINK)  S STATUS=$$IFOPEN^HLOUSR1(LINK)
     33 .S TESTOPEN("LISTENER")=STATUS_"^"_$$NOW^XLFDT
     34 ;
     35 S @VALMAR@(3,0)="STANDARD LISTENER:         "_$S(STATUS:"OPERATIONAL",1:"NOT OPERATIONAL")
     36 ;
     37 S @VALMAR@(4,0)="TASKMAN:                   "_$S($$TM^%ZTLOAD:"RUNNING",1:"NOT RUNNING")
     38 ;
     39 S (LIST,LINK)=""
     40 F  S LINK=$O(^HLTMP("FAILING LINKS",LINK)) Q:LINK=""  D  I $L(LIST)>60 S LIST=LIST_",..." Q
     41 .N TIME,QUE,LINKARY
     42 .I $$GETLINK^HLOTLNK($P(LINK,":"),.LINKARY)
     43 .S TIME=$G(^HLTMP("FAILING LINKS",LINK)) Q:TIME=""
     44 .I '$G(LINKARY("SHUTDOWN")),TIME="" Q
     45 .I '$G(LINKARY("SHUTDOWN")),($$HDIFF^XLFDT($H,TIME,2)<300) Q
     46 .S LIST=LIST_$S($L(LIST):", ",1:"")_$P(LINK,":")
     47 S @VALMAR@(5,0)="DOWN LINKS: "_LIST
     48 S @VALMAR@(6,0)="CLIENT LINK PROCESSES:     "_+$G(^HLC("HL7 PROCESS COUNTS","RUNNING","OUTGOING CLIENT LINK"))
     49 S @VALMAR@(7,0)="IN-FILER PROCESSES:        "_+$G(^HLC("HL7 PROCESS COUNTS","RUNNING","INCOMING QUEUES"))
     50 S COUNT=0,LINK=""
     51 F  S LINK=$O(^HLC("QUEUECOUNT","OUT",LINK)) Q:LINK=""  D
     52 .S QUE=""
     53 .F  S QUE=$O(^HLC("QUEUECOUNT","OUT",LINK,QUE)) Q:QUE=""  D
     54 ..S TEMP=$G(^HLC("QUEUECOUNT","OUT",LINK,QUE))
     55 ..S:TEMP>0 COUNT=COUNT+TEMP
     56 S @VALMAR@(8,0)="MESSAGES PENDING TRANSMISSION:      "_+COUNT
     57 S TEMP="STOPPED OUTGOING QUEUES: "
     58 S COUNT=0,QUE=""
     59 F  S QUE=$O(^HLTMP("STOPPED QUEUES","OUT",QUE)) Q:QUE=""  S COUNT=COUNT+1 Q:COUNT>4  S:COUNT=1 TEMP=TEMP_QUE S:"23"[COUNT TEMP=TEMP_"; "_QUE S:COUNT=4 TEMP=TEMP_" ..."
     60 S @VALMAR@(9,0)=TEMP
     61 S COUNT=0,QUE=""
     62 F  S QUE=$O(^HLC("QUEUECOUNT","IN",QUE)) Q:QUE=""  D
     63 .S FROM=""
     64 .F  S FROM=$O(^HLC("QUEUECOUNT","IN",QUE,FROM)) Q:FROM=""  D
     65 ..S TEMP=$G(^HLC("QUEUECOUNT","IN",QUE,FROM))
     66 ..S:TEMP>0 COUNT=COUNT+TEMP
     67 S @VALMAR@(10,0)="MESSAGES PENDING ON APPLICATIONS:   "_+COUNT
     68 S TEMP="STOPPED INCOMING QUEUES: "
     69 S COUNT=0,QUE=""
     70 F  S QUE=$O(^HLTMP("STOPPED QUEUES","IN",QUE)) Q:QUE=""  S COUNT=COUNT+1 Q:COUNT>4  S:COUNT=1 TEMP=TEMP_QUE S:"23"[COUNT TEMP=TEMP_"; "_QUE S:COUNT=4 TEMP=TEMP_" ..."
     71 S @VALMAR@(11,0)=TEMP
     72 S @VALMAR@(12,0)="FILE 777 RECORD COUNT:         "_$$RJ($P($G(^HLTMP("FILE 777 RECORD COUNT")),"^"),10)_"     --> as of "_$$FMTE^XLFDT($P($G(^HLTMP("FILE 777 RECORD COUNT")),"^",2))
     73 S @VALMAR@(13,0)="FILE 778 RECORD COUNT:         "_$$RJ($P($G(^HLTMP("FILE 778 RECORD COUNT")),"^"),10)_"     --> as of "_$$FMTE^XLFDT($P($G(^HLTMP("FILE 778 RECORD COUNT")),"^",2))
     74 S TODAY=$$DT^XLFDT
     75 S @VALMAR@(14,0)="MESSAGES SENT TODAY:           "_$$RJ($$ADD("OUT"),10)
     76 S @VALMAR@(15,0)="MESSAGES RECEIVED TODAY:       "_$$RJ($$ADD("IN"),10)
     77 S @VALMAR@(16,0)="MESSAGE ERRORS TODAY:          "_$$RJ($$ADD("EOUT")+$$ADD("EIN"),10)
     78 Q
     79ADD(DIR) ;
     80 N RAP,SAP,TIME,TOTAL
     81 S TOTAL=0
     82 S TIME=TODAY-.0001
     83 F  S TIME=$O(^HLSTATS(DIR,"HOURLY",TIME)) Q:'TIME  Q:((TIME\1)>TODAY)  D
     84 .S SAP=""
     85 .F  S SAP=$O(^HLSTATS(DIR,"HOURLY",TIME,SAP)) Q:SAP=""  D
     86 ..Q:SAP="ACCEPT ACK"
     87 ..S RAP=""
     88 ..F  S RAP=$O(^HLSTATS(DIR,"HOURLY",TIME,SAP,RAP)) Q:RAP=""  D
     89 ...S TYPE=""
     90 ...F  S TYPE=$O(^HLSTATS(DIR,"HOURLY",TIME,SAP,RAP,TYPE)) Q:TYPE=""  D
     91 ....S TOTAL=TOTAL+$G(^HLSTATS(DIR,"HOURLY",TIME,SAP,RAP,TYPE))
     92 Q TOTAL
     93 ;
     94HELP ;Help code
     95 S X="?" D DISP^XQORM1 W !!
     96 Q
     97 ;
     98EXIT ;Exit code
     99 D CLEAN^VALM10
     100 D CLEAR^VALM1
     101 ;
     102 Q
     103 ;
     104EXPND ;Expand code
     105 Q
     106 ;
     107PROCS ;
     108 S HLRFRSH="PROCS^HLOUSR"
     109 ;K @VALMAR
     110 D CLEAN^VALM10
     111 S VALMCNT=0
     112 S VALMBCK="R"
     113 S VALMDDF("COL 2")="COL 2^35^10^MIN^H"
     114 S VALMDDF("COL 3")="COL 3^47^10^MAX^H"
     115 S VALMDDF("COL 4")="COL 4^59^10^#RUNNING^H"
     116 S VALMDDF("COL 5")="COL 5^71^10^#QUEUED^IOBON"
     117 D CHGCAP^VALM("COL 1","Process Type")
     118 N IEN
     119 S IEN=0
     120 F  S IEN=$O(^HLD(779.3,"C",1,IEN)) Q:'IEN  D
     121 .N PROC
     122 .Q:'$$GETPROC^HLOPROC1(IEN,.PROC)
     123 .Q:PROC("NAME")="VMS TCP LISTENER"
     124 .S VALMCNT=VALMCNT+1
     125 .S @VALMAR@(VALMCNT,0)=$$LJ(PROC("NAME"),30)_$$RJ(PROC("MINIMUM"),6)_$$RJ(PROC("MAXIMUM"),12)_$$RJ(+$G(^HLC("HL7 PROCESS COUNTS","RUNNING",PROC("NAME"))),14)_$$RJ(+$G(^HLC("HL7 PROCESS COUNTS","QUEUED",PROC("NAME"))),12)
     126 S VALMCNT=VALMCNT+1,@VALMAR@(VALMCNT,0)=""
     127 S IEN=""
     128 F  S IEN=$O(^HLTMP("HL7 RUNNING PROCESSES",IEN)) Q:IEN=""  D
     129 .N NODE
     130 .S NODE=$G(^HLTMP("HL7 RUNNING PROCESSES",IEN))
     131 .Q:NODE=""
     132 .S VALMCNT=VALMCNT+1
     133 .S @VALMAR@(VALMCNT,0)="$J: "_$$LJ(IEN,9)_" ->"_$$CJ($P(NODE,"^",3),28)_"<- started at "_$$HTE^XLFDT($P(NODE,"^"))
     134 Q
     135 ;
     136OUTQUEUE ;
     137 N LINK
     138 D CLEAN^VALM10
     139 ;K @VALMAR
     140 S HLRFRSH="OUTQUEUE^HLOUSR"
     141 S (HLSCREEN,VALMSG)="Outgoing Queues *down links !stopped queues"
     142 S VALMCNT=0
     143 S VALMBCK="R"
     144 S VALMDDF("COL 1")="COL 1^2^20^ Link^H"
     145 S VALMDDF("COL 2")="COL 2^28^20^Queue^H"
     146 S VALMDDF("COL 3")="COL 3^50^20^Count^H"
     147 K VALMDDF("COL 4"),VALMDDF("COL 5")
     148 D CHGCAP^VALM("COL 1"," Link")
     149 S LINK=""
     150 F  S LINK=$O(^HLC("QUEUECOUNT","OUT",LINK)) Q:LINK=""  D
     151 .N COUNT,QUE,SHOW
     152 .S SHOW=LINK
     153 .I $D(^HLTMP("FAILING LINKS",SHOW)) S SHOW="*"_SHOW
     154 .S QUE=""
     155 .F  S QUE=$O(^HLC("QUEUECOUNT","OUT",LINK,QUE)) Q:QUE=""  D
     156 ..S COUNT=$G(^HLC("QUEUECOUNT","OUT",LINK,QUE))
     157 ..Q:COUNT<1
     158 ..S VALMCNT=VALMCNT+1
     159 ..I $E(SHOW)="*" D
     160 ...S @VALMAR@(VALMCNT,0)=$$LJ(SHOW,20)_$$CJ($S($$STOPPED^HLOQUE("OUT",QUE):"!",1:"")_QUE,21)_"   "_$$RJ(COUNT,10),SHOW=""
     161 ...D CNTRL^VALM10(VALMCNT,1,1,IOBON,IOBOFF)
     162 ..E  S @VALMAR@(VALMCNT,0)=$$LJ(SHOW,20)_$$CJ($S($$STOPPED^HLOQUE("OUT",QUE):"!",1:"")_QUE,21)_"   "_$$RJ(COUNT,10),SHOW=""
     163 Q
     164 ;
     165INQUEUE ;
     166 N FROM
     167 D CLEAN^VALM10
     168 ;K @VALMAR
     169 S HLRFRSH="INQUEUE^HLOUSR"
     170 S (HLSCREEN,VALMSG)="Incoming Queues ('!' = stopped queues)"
     171 S VALMCNT=0
     172 S VALMBCK="R"
     173 S VALMDDF("COL 1")="COL 1^1^40^ From^H"
     174 S VALMDDF("COL 2")="COL 2^45^20^Queue^H"
     175 S VALMDDF("COL 3")="COL 3^70^10^Count^H"
     176 K VALMDDF("COL 4"),VALMDDF("COL 5")
     177 D CHGCAP^VALM("COL 1"," From")
     178 S FROM=""
     179 F  S FROM=$O(^HLC("QUEUECOUNT","IN",FROM)) Q:FROM=""  D
     180 .N COUNT,QUE,SHOW
     181 .S SHOW=$$LJ(FROM,40)_"  "
     182 .S QUE=""
     183 .F  S QUE=$O(^HLC("QUEUECOUNT","IN",FROM,QUE)) Q:QUE=""  D
     184 ..S COUNT=$G(^HLC("QUEUECOUNT","IN",FROM,QUE))
     185 ..Q:COUNT<0
     186 ..S VALMCNT=VALMCNT+1
     187 ..S @VALMAR@(VALMCNT,0)=SHOW_$$LJ($S($$STOPPED^HLOQUE("IN",QUE):"!",1:"")_QUE,21)_" "_$$RJ(COUNT,10)
     188 ..S SHOW=$$LJ("",40)_"  "
     189 Q
     190VIEWLINK ;
     191 N C,QUIT,LINK,LINKARY,TEMP
     192 S (QUIT,C,LINK)=""
     193 S VALMBCK="R"
     194 ;
     195 ;currently HL7 (Optimized) only does TCP, when serial added a change is needed here
     196 S LINK=$$ASKLINK
     197 Q:LINK=""
     198 Q:'$$GETLINK^HLOTLNK(LINK,.LINKARY)
     199 S LINK=LINK_":"_LINKARY("PORT")
     200 W !,"Hit any key to stop...",!
     201 F  D  Q:QUIT
     202 .N COUNT,QUE
     203 .S (COUNT,QUE)=""
     204 .F  S QUE=$O(^HLC("QUEUECOUNT","OUT",LINK,QUE)) Q:QUE=""  S TEMP=$G(^HLC("QUEUECOUNT","OUT",LINK,QUE)) S:TEMP>0 COUNT=COUNT+TEMP
     205 .W $C(13),"                             ",$C(13),"MESSAGES PENDING TRANSMISSION: ",IOBON,$$RJ(+COUNT,10),IOBOFF
     206 .R *C:1 I $T S QUIT=1
     207 Q
     208 ;
     209CJ(STRING,LEN) ;
     210 Q $$CJ^XLFSTR($E(STRING,1,LEN),LEN)
     211LJ(STRING,LEN) ;
     212 Q $$LJ^XLFSTR($E(STRING,1,LEN),LEN)
     213RJ(STRING,LEN) ;
     214 Q $$RJ^XLFSTR($E(STRING,1,LEN),LEN)
     215 ;
     216RUNNING() ;Is the Process Manager running?
     217 N RUNNING
     218 L +^HLTMP("PROCESS MANAGER"):0
     219 S RUNNING='$T
     220 I 'RUNNING L -^HLTMP("PROCESS MANAGER")
     221 Q RUNNING
     222 ;
     223TESTLINK ;
     224 N LINK,LINKNAME,OK
     225 S VALMBCK="R"
     226 S LINKNAME=$$ASKLINK
     227 Q:LINKNAME=""
     228 S OK=$$IFOPEN^HLOUSR1(LINKNAME)
     229 I OK W !,LINKNAME_" IS operational..."
     230 E  W !,LINKNAME_" is NOT operational..."
     231 W !,"Hit any key to continue..."
     232 R *C:DTIME
     233 Q
     234 ;
     235ASKLINK() ;
     236 N DIC,TCP,X,Y,DTOUT,DUOUT
     237 S DIC=870
     238 S DIC(0)="AENQ"
     239 S TCP=$O(^HLCS(869.1,"B","TCP",0))
     240 S DIC("A")="Select a TCP link:"
     241 S DIC("S")="I $P(^(0),U,3)=TCP"
     242 D FULL^VALM1
     243 D ^DIC
     244 I +Y'=-1,'$D(DTOUT),'$D(DUOUT) Q $P(Y,"^",2)
     245 Q ""
     246 ;
     247STOP ;
     248 I '$$ASKYESNO^HLOUSR2("Are you SURE that you want to stop sending and receiving messages","NO") S VALMBCK="" Q
     249 ;
     250 D STOPHL7^HLOPROC1
     251 S VALMBCK="R",VALMSG="HL7 (Optimized) has been stopped...."
     252 H 5
     253 D @HLRFRSH
     254 ;D:HLSCREEN="Brief System Status" BRIEF^HLOUSR
     255 ;D:HLSCREEN="Running Processes" PROCS^HLOUSR
     256 Q
     257 ;
     258UPDMODE ;update mode
     259 Q:'$L(HLRFRSH)
     260 N QUIT,NEW,TOP,BOTTOM,DX,DY,IOTM,IOBM,I
     261 W !!,IOINHI,"Hit any key to escape realtime display mode...",IOINORM
     262 S IOTM=3,IOBM=23
     263 W @IOSTBM
     264 S DX=1,DY=$S(VALMCNT<17:VALMCNT+1,1:17) X IOXY
     265 I VALMCNT>16 F I=17:1:$S(VALMCNT<22:VALMCNT,1:21) W !,@VALMAR@(I,0)
     266 S QUIT=0
     267 S TOP=VALMBG
     268 S BOTTOM=TOP+23
     269 S OLD=VALMAR
     270 S VALMAR="NEW"
     271 S VALMCNT=0
     272 F  D  Q:QUIT
     273 .N LINE
     274 .R *C:3 I $T S QUIT=1
     275 .S (VALMCNT,I)=0
     276 .D @HLRFRSH
     277 .F LINE=TOP:1:BOTTOM IF $G(@OLD@(LINE,0))'=$G(@VALMAR@(LINE,0)) D
     278 ..S:'$D(@VALMAR@(LINE,0)) @VALMAR@(LINE,0)=" "
     279 ..D WRITE^VALM10(LINE)
     280 K @OLD M @OLD=@VALMAR S VALMAR=OLD
     281 S VALMBCK="R"
     282 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOUSR1.m

    r613 r623  
    1 HLOUSR1 ;ALB/CJM -ListManager Screen for viewing messages;12 JUN 1997 10:00 am ;07/25/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 EN      ;
    6         N MSGIEN
    7         S MSGIEN=$$PICKMSG
    8         I 'MSGIEN S VALMBCK="R" Q
    9         D EN^VALM("HLO SINGLE MESSAGE DISPLAY")
    10         Q
    11         ;
    12 HDR     ;
    13         Q
    14         ;
    15 BLANK   ;
    16         S VALMCNT=0
    17         D EXIT
    18         Q
    19 DISPLAY ;
    20         K @VALMAR
    21         S VALMBCK="R"
    22         N MSG
    23         S VALMBG=1
    24         Q:'MSGIEN
    25         D SHOWMSG($P(MSGIEN,"^"),$P(MSGIEN,"^",2))
    26         Q
    27         ;
    28 PICKMSG()       ;
    29         ;ask the user to select a message & return its ien
    30         N MSGIEN,DIR,COUNT,LIST
    31         D FULL^VALM1
    32         S DIR(0)="F3:30"
    33         S DIR("A")="Message ID"
    34         S DIR("?")="Enter the full Message Control ID or Batch Control ID of the message, or '^' to exit."
    35 PICK    D ^DIR
    36         I $D(DIRUT)!(Y="") Q 0
    37         I $G(@VALMAR@("INDEX",Y)) Q $G(@VALMAR@("INDEX",Y))
    38         S COUNT=$$FINDMSG^HLOMSG1(Y,.LIST)
    39         I COUNT="0" W !!,"That message can not be found! Try Again",! G PICK
    40         I COUNT=1 Q LIST(1)
    41         I COUNT>1 D
    42         .N ITEM
    43         .W !,"There is more than one message with that ID! You must choose one to display.",1
    44         .S ITEM=0
    45         .F  S ITEM=$O(LIST(ITEM)) Q:'ITEM  D
    46         ..N MSG
    47         ..Q:'$$GETMSG^HLOMSG(+LIST(ITEM),.MSG)
    48         ..W !,"[",ITEM,"]","  DT/TM: ",$$FMTE^XLFDT(MSG("DT/TM CREATED"),2),"   STATUS: ",MSG("STATUS")
    49         .S DIR(0)="NO^1:"_COUNT,DIR("A")="Choose",DIR("?")="Choose one message from the list"
    50         .D ^DIR
    51         .I Y S Y=LIST(Y)
    52         Q Y
    53         ;
    54 HELP    ;Help code
    55         S X="?" D DISP^XQORM1 W !!
    56         Q
    57         ;
    58 EXIT    ;Exit code
    59         D CLEAN^VALM10
    60         D CLEAR^VALM1
    61         S VALMBCK="R"
    62         ;
    63         Q
    64         ;
    65 EXPND   ;Expand code
    66         Q
    67         ;
    68 CJ(STRING,LEN)  ;
    69         Q $$CJ^XLFSTR(STRING,LEN)
    70 LJ(STRING,LEN)  ;
    71         Q $$LJ^XLFSTR(STRING,LEN)
    72 SP(LEN,CHAR)    ;
    73         ;return padding - " " is the default pad character
    74         N STR
    75         S:$G(CHAR)="" CHAR=" "
    76         S $P(STR,CHAR,LEN)=CHAR
    77         Q STR
    78         ;
    79 SHOWMSG(MSGIEN,SUBIEN)  ;
    80         ;Description:
    81         ;
    82         ;Input:
    83         ;Output:
    84         ;
    85         N MSG,I,TEMP,LINE
    86         S VALMCNT=0
    87         S SUBIEN=+$G(SUBIEN)
    88         I '$$GETMSG^HLOMSG(MSGIEN,.MSG) W !,"UNABLE TO DISPLAY THE MESSAGE",!! Q
    89         I SUBIEN D GETMSGB^HLOMSG1(.MSG,SUBIEN,.MSG)
    90         ;
    91         S I=0
    92         ;** administrative information **
    93         S @VALMAR@($$I,0)=$$CJ("Administrative Information",80)
    94         D CNTRL^VALM10(VALMCNT,26,30,IORVON,IORVOFF)
    95         S LINE="MsgID: "_$$LJ(MSG("ID"),18)
    96         S LINE=LINE_"Status: "_$$LJ(MSG("STATUS"),5)
    97         S:MSG("ACK TO")]"" LINE=LINE_$$LJ(" Ack To:",14)_MSG("ACK TO")
    98         S:MSG("ACK BY")]"" LINE=LINE_$$LJ(" Ack'd By:",14)_MSG("ACK BY")
    99         S @VALMAR@($$I,0)=LINE
    100         I MSG("STATUS","ERROR TEXT")]"" S @VALMAR@($$I,0)="Error: "_"** "_MSG("STATUS","ERROR TEXT")_" **"
    101         S @VALMAR@($$I,0)="Dir:   "_$$LJ($S(MSG("DIRECTION")="IN":"INCOMING",1:"OUTGOING"),10)_$$LJ("  Trans Dt/Tm: ",12)_$$FMTE^XLFDT(MSG("DT/TM"),2)_$$LJ("  Purge DT/TM: ",8)_$$FMTE^XLFDT(MSG("STATUS","PURGE"),2)
    102         S @VALMAR@($$I,0)="Link:  "_$$LJ(MSG("STATUS","LINK NAME"),29)_"   "_$$LJ("Queue: ",13)_MSG("STATUS","QUEUE")
    103         I $L($G(MSG("STATUS","SEQUENCE QUEUE"))) D
    104         .S @VALMAR@($$I,0)="Sequence Queue: "_MSG("STATUS","SEQUENCE QUEUE")_"    Moved: "_$S(MSG("STATUS","MOVED TO OUT QUEUE"):"YES",1:"NO")
    105         I MSG("STATUS","ACCEPT ACK'D") D
    106         .S @VALMAR@($$I,0)="Accept Ack: "_$$LJ(MSG("STATUS","ACCEPT ACK ID"),26)_$$LJ(" DT/TM Ack'd: ",14)_$$FMTE^XLFDT(MSG("STATUS","ACCEPT ACK DT/TM"),2)
    107         .S @VALMAR@($$I,0)="   "_MSG("STATUS","ACCEPT ACK MSA")
    108         I MSG("DIRECTION")="IN" D
    109         .S LINE="App Response Rtn: "
    110         .I $L($G(MSG("STATUS","APP ACK RESPONSE"))) S LINE=$$LJ(LINE_MSG("STATUS","APP ACK RESPONSE"),38)_" Executed: "_$S(MSG("STATUS","APP HANDOFF"):"   YES",1:"   NO")
    111         .S @VALMAR@($$I,0)=LINE
    112         I MSG("DIRECTION")="OUT",(MSG("STATUS","APP ACK'D")!MSG("STATUS","ACCEPT ACK'D")) D
    113         .S LINE=""
    114         .I MSG("STATUS","ACCEPT ACK'D") D
    115         ..I MSG("STATUS","ACCEPT ACK RESPONSE")="" S MSG("STATUS","ACCEPT ACK RESPONSE")="n/a"
    116         ..S LINE="Accept Ack Rtn: "_MSG("STATUS","ACCEPT ACK RESPONSE")
    117         .S LINE=$$LJ(LINE,39)
    118         .I MSG("STATUS","APP ACK'D") D
    119         ..I MSG("STATUS","APP ACK RESPONSE")="" S MSG("STATUS","APP ACK RESPONSE")="n/a"
    120         ..S LINE=LINE_"App Ack Rtn: "_MSG("STATUS","APP ACK RESPONSE")
    121         .S @VALMAR@($$I,0)=LINE
    122         ;
    123         ;** the message text **
    124         S @VALMAR@($$I,0)=""
    125         I '$G(SUBIEN) D
    126         .S @VALMAR@($$I,0)=$$CJ("Message Text",80)
    127         .D CNTRL^VALM10(VALMCNT,33,16,IORVON,IORVOFF)
    128         E  D
    129         .S @VALMAR@($$I,0)=$$CJ("Individual Message Text (Batched)",80)
    130         .D CNTRL^VALM10(VALMCNT,23,35,IORVON,IORVOFF)
    131         D SHOWBODY(.MSG,$G(SUBIEN))
    132         ;
    133         ;** display its application acknowledgment **
    134         I MSG("ACK BY")]"",$$FINDMSG^HLOMSG1(MSG("ACK BY"),.TEMP)=1 S MSGIEN=TEMP(1) D
    135         .N MSG
    136         .Q:'$$GETMSG^HLOMSG(+MSGIEN,.MSG)
    137         .I $P(MSGIEN,"^",2) D GETMSGB^HLOMSG1(.MSG,$P(MSGIEN,"^",2),.MSG)
    138         .S @VALMAR@($$I,0)=""
    139         .S @VALMAR@($$I,0)=$$CJ("Application Acknowledgment",80)
    140         .D CNTRL^VALM10(VALMCNT,26,30,IORVON,IORVOFF)
    141         .D SHOWBODY(.MSG,$P(MSGIEN,"^",2))
    142         ;
    143         ;** display the original message **
    144         I MSG("ACK TO")]"",$$FINDMSG^HLOMSG1(MSG("ACK TO"),.TEMP)=1 S MSGIEN=TEMP(1) D
    145         .N MSG
    146         .Q:'$$GETMSG^HLOMSG(+MSGIEN,.MSG)
    147         .I $P(MSGIEN,"^",2) D GETMSGB^HLOMSG1(.MSG,$P(MSGIEN,"^",2),.MSG)
    148         .S @VALMAR@($$I,0)=""
    149         .S @VALMAR@($$I,0)=$$CJ("Original Message",80)
    150         .D CNTRL^VALM10(VALMCNT,26,30,IORVON,IORVOFF)
    151         .D SHOWBODY(.MSG,$P(MSGIEN,"^",2))
    152         Q
    153         ;
    154 SHOWBODY(MSG,SUBIEN)    ;
    155         N NODE,I,SEG,QUIT
    156         S QUIT=0
    157         M SEG=MSG("HDR")
    158         D ADD(.SEG)
    159         S MSG("BATCH","CURRENT MESSAGE")=0
    160         I MSG("BATCH") D
    161         .I $G(SUBIEN) D  Q
    162         ..S MSG("BATCH","CURRENT MESSAGE")=SUBIEN
    163         ..F  Q:'$$HLNEXT^HLOMSG(.MSG,.SEG)  D ADD(.SEG)
    164         .S MSG("BATCH","CURRENT MESSAGE")=0
    165         .N LAST S LAST=0
    166         .F  Q:'$$NEXTMSG^HLOMSG(.MSG,.SEG)  D  Q:QUIT
    167         ..D ADD(.SEG)
    168         ..S LAST=MSG("BATCH","CURRENT MESSAGE")
    169         ..F  Q:'$$HLNEXT^HLOMSG(.MSG,.SEG)  D ADD(.SEG)
    170         .I MSG("DIRECTION")="OUT" K SEG S SEG(1)="BTS"_$E($G(NODE(1)),4)_LAST D ADD(.SEG)
    171         E  D
    172         .F  Q:'$$HLNEXT^HLOMSG(.MSG,.SEG)  D  Q:QUIT
    173         ..D ADD(.SEG)
    174         Q
    175 I()     ;
    176         S VALMCNT=VALMCNT+1
    177         Q VALMCNT
    178 ADD(SEG)        ;
    179         N QUIT,I,J,LINE
    180         S QUIT=0
    181         S (I,J)=1
    182         S LINE(1)=$E(SEG(1),1,80),SEG(1)=$E(SEG(1),81,9999)
    183         I SEG(1)="" K SEG(1)
    184         D SHIFT(.I,.J)
    185         S @VALMAR@($$I,0)=LINE(1)
    186         S I=1
    187         F  S I=$O(LINE(I)) Q:'I  D
    188         .S @VALMAR@($$I,0)=LINE(I)
    189         .D CNTRL^VALM10(VALMCNT,1,1,IORVON,IORVOFF)
    190         Q
    191         ;
    192 SHIFT(I,J)      ;
    193         I '$D(SEG(I)) S I=$O(SEG(0)) Q:'I
    194         I $L(LINE(J))<80 D
    195         .N LEN
    196         .S LEN=$L(LINE(J))
    197         .S LINE(J)=LINE(J)_$E(SEG(I),1,80-LEN)
    198         .S SEG(I)=$E(SEG(I),81-LEN,9999)
    199         .I SEG(I)="" K SEG(I)
    200         E  D
    201         .S J=J+1
    202         .S LINE(J)="-"
    203         D SHIFT(.I,.J)
    204         Q
    205         ;
    206 SCRLMODE        ;scroll mode
    207         Q:'$L(HLRFRSH)
    208         N QUIT,IOTM,IOBM,DX,DY,LINE,IOTM,IOBM
    209         W !!,IOINHI,"Hit any key to escape scroll mode...",IOINORM
    210         S IOTM=3,IOBM=23
    211         S QUIT=0
    212         S LINE=$S(VALMCNT<17:1,1:17)
    213         W @IOSTBM
    214         S DX=1,DY=$S(VALMCNT<17:VALMCNT+1,1:17) X IOXY
    215         F I=1:1 D  Q:QUIT
    216         .;every 10 seconds refresh the data
    217         .I I>42 D @HLRFRSH S I=0
    218         .I LINE+1>VALMCNT D
    219         ..S TEMP=$G(@VALMAR@(LINE,0))
    220         ..W !,IOUON,TEMP_$$SP(80-$L(TEMP)),IOUOFF
    221         .E  W !,$G(@VALMAR@(LINE,0))
    222         .S LINE=LINE+1
    223         .I LINE>VALMCNT S LINE=1
    224         .I (I=22)!(I=43) R *C:5 I $T S QUIT=1 Q
    225         S VALMBG=LINE-23 I VALMBG<0 S VALMBG=1
    226         S VALMBCK="R"
    227         Q
    228 HLP     ;
    229         Q
    230         ;
    231 IFOPEN(LINK)    ;
    232         ;returns 1 if the link can be opened, otherwise 0
    233         ;
    234         ;Inputs:
    235         ;  LINK - name of the link (required), optionally post-fixed with ":"_<port #>, will default to that defined for link
    236         ;
    237         N LINKNAME,LINKARY,POP,IO,IOF,IOST,OPEN,PORT
    238         S OPEN=0
    239         S LINKNAME=$P(LINK,":")
    240         S PORT=$P(LINK,":",2)
    241         Q:LINKNAME="" 0
    242         Q:'$$GETLINK^HLOTLNK(LINKNAME,.LINKARY) 0
    243         S:PORT LINKARY("PORT")=PORT
    244         Q:'$G(LINKARY("PORT")) 0
    245         I LINKARY("IP")="",LINKARY("DOMAIN")="",LINKARY("LLP")="TCP",LINKARY("SERVER") D
    246         .N DATA
    247         .S LINKARY("DOMAIN")=$P($G(^HLD(779.1,1,0)),"^")
    248         .Q:LINKARY("DOMAIN")=""
    249         .S DATA(.08)=LINKARY("DOMAIN")
    250         .Q:$$UPD^HLOASUB1(870,LINKARY("IEN"),.DATA)
    251         D:$G(LINKARY("IP"))'=""
    252         .D CALL^%ZISTCP(LINKARY("IP"),LINKARY("PORT"),15)
    253         .S OPEN='POP
    254         I 'OPEN,LINKARY("DOMAIN")'="",$G(^HLTMP("DNS LAST",LINKARY("IEN")))<$$DT^XLFDT D
    255         .N IP
    256         .S ^HLTMP("DNS LAST",LINKARY("IEN"))=$$DT^XLFDT
    257         .S IP=$$DNS^HLOTCP(LINKARY("DOMAIN"))
    258         .I IP'="",IP'=LINKARY("IP") D
    259         ..N DATA
    260         ..S DATA(400.01)=IP,LINKARY("IP")=IP
    261         ..Q:$$UPD^HLOASUB1(870,LINKARY("IEN"),.DATA)
    262         ..D CALL^%ZISTCP(LINKARY("IP"),LINKARY("PORT"),15)
    263         ..S OPEN='POP
    264         C:OPEN IO
    265         ;D CLOSE^%ZISTCP
    266         Q OPEN
     1HLOUSR1 ;ALB/CJM -ListManager Screen for viewing messages;12 JUN 1997 10:00 am ;03/19/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5EN ;
     6 N MSGIEN
     7 S MSGIEN=$$PICKMSG
     8 I 'MSGIEN S VALMBCK="R" Q
     9 D EN^VALM("HLO SINGLE MESSAGE DISPLAY")
     10 Q
     11 ;
     12HDR ;
     13 Q
     14 ;
     15BLANK ;
     16 S VALMCNT=0
     17 D EXIT
     18 Q
     19DISPLAY ;
     20 K @VALMAR
     21 S VALMBCK="R"
     22 N MSG
     23 S VALMBG=1
     24 Q:'MSGIEN
     25 D SHOWMSG($P(MSGIEN,"^"),$P(MSGIEN,"^",2))
     26 Q
     27 ;
     28PICKMSG() ;
     29 ;ask the user to select a message & return its ien
     30 N MSGIEN,DIR,COUNT,LIST
     31 D FULL^VALM1
     32 S DIR(0)="F3:30"
     33 S DIR("A")="Message ID"
     34 S DIR("?")="Enter the full Message Control ID or Batch Control ID of the message, or '^' to exit."
     35PICK D ^DIR
     36 I $D(DIRUT)!(Y="") Q 0
     37 I $G(@VALMAR@("INDEX",Y)) Q $G(@VALMAR@("INDEX",Y))
     38 S COUNT=$$FINDMSG^HLOMSG1(Y,.LIST)
     39 I COUNT="0" W !!,"That message can not be found! Try Again",! G PICK
     40 I COUNT=1 Q LIST(1)
     41 I COUNT>1 D
     42 .N ITEM
     43 .W !,"There is more than one message with that ID! You must choose one to display.",1
     44 .S ITEM=0
     45 .F  S ITEM=$O(LIST(ITEM)) Q:'ITEM  D
     46 ..N MSG
     47 ..Q:'$$GETMSG^HLOMSG(+LIST(ITEM),.MSG)
     48 ..W !,"[",ITEM,"]","  DT/TM: ",$$FMTE^XLFDT(MSG("DT/TM CREATED"),2),"   STATUS: ",MSG("STATUS")
     49 .S DIR(0)="NO^1:"_COUNT,DIR("A")="Choose",DIR("?")="Choose one message from the list"
     50 .D ^DIR
     51 .I Y S Y=LIST(Y)
     52 Q Y
     53 ;
     54HELP ;Help code
     55 S X="?" D DISP^XQORM1 W !!
     56 Q
     57 ;
     58EXIT ;Exit code
     59 D CLEAN^VALM10
     60 D CLEAR^VALM1
     61 S VALMBCK="R"
     62 ;
     63 Q
     64 ;
     65EXPND ;Expand code
     66 Q
     67 ;
     68CJ(STRING,LEN) ;
     69 Q $$CJ^XLFSTR(STRING,LEN)
     70LJ(STRING,LEN) ;
     71 Q $$LJ^XLFSTR(STRING,LEN)
     72SP(LEN,CHAR) ;
     73 ;return padding - " " is the default pad character
     74 N STR
     75 S:$G(CHAR)="" CHAR=" "
     76 S $P(STR,CHAR,LEN)=CHAR
     77 Q STR
     78 ;
     79SHOWMSG(MSGIEN,SUBIEN) ;
     80 ;Description:
     81 ;
     82 ;Input:
     83 ;Output:
     84 ;
     85 N MSG,I,TEMP,LINE
     86 S VALMCNT=0
     87 S SUBIEN=+$G(SUBIEN)
     88 I '$$GETMSG^HLOMSG(MSGIEN,.MSG) W !,"UNABLE TO DISPLAY THE MESSAGE",!! Q
     89 I SUBIEN D GETMSGB^HLOMSG1(.MSG,SUBIEN,.MSG)
     90 ;
     91 S I=0
     92 ;** administrative information **
     93 S @VALMAR@($$I,0)=$$CJ("Administrative Information",80)
     94 D CNTRL^VALM10(VALMCNT,26,30,IORVON,IORVOFF)
     95 S LINE="MsgID: "_$$LJ(MSG("ID"),18)
     96 S LINE=LINE_"Status: "_$$LJ(MSG("STATUS"),5)
     97 S:MSG("ACK TO")]"" LINE=LINE_$$LJ(" Ack To:",14)_MSG("ACK TO")
     98 S:MSG("ACK BY")]"" LINE=LINE_$$LJ(" Ack'd By:",14)_MSG("ACK BY")
     99 S @VALMAR@($$I,0)=LINE
     100 I MSG("STATUS","ERROR TEXT")]"" S @VALMAR@($$I,0)="Error: "_"** "_MSG("STATUS","ERROR TEXT")_" **"
     101 S @VALMAR@($$I,0)="Dir:   "_$$LJ($S(MSG("DIRECTION")="IN":"INCOMING",1:"OUTGOING"),10)_$$LJ("  Trans Dt/Tm: ",12)_$$FMTE^XLFDT(MSG("DT/TM"),2)_$$LJ("  Purge DT/TM: ",8)_$$FMTE^XLFDT(MSG("STATUS","PURGE"),2)
     102 S @VALMAR@($$I,0)="Link:  "_$$LJ(MSG("STATUS","LINK NAME"),29)_"   "_$$LJ("Queue: ",13)_MSG("STATUS","QUEUE")
     103 I MSG("STATUS","ACCEPT ACK'D") D
     104 .S @VALMAR@($$I,0)="Accept Ack: "_$$LJ(MSG("STATUS","ACCEPT ACK ID"),26)_$$LJ(" At: ",14)_$$FMTE^XLFDT(MSG("STATUS","ACCEPT ACK DT/TM"),2)
     105 .S @VALMAR@($$I,0)="   "_MSG("STATUS","ACCEPT ACK MSA")
     106 I MSG("DIRECTION")="IN" D
     107 .S LINE="App Response Rtn: "
     108 .I $L($G(MSG("STATUS","APP ACK RESPONSE"))) S LINE=$$LJ(LINE_MSG("STATUS","APP ACK RESPONSE"),38)_" Executed: "_$S(MSG("STATUS","APP HANDOFF"):"   YES",1:"   NO")
     109 .S @VALMAR@($$I,0)=LINE
     110 I MSG("DIRECTION")="OUT",(MSG("STATUS","APP ACK'D")!MSG("STATUS","ACCEPT ACK'D")) D
     111 .S LINE=""
     112 .I MSG("STATUS","ACCEPT ACK'D") D
     113 ..I MSG("STATUS","ACCEPT ACK RESPONSE")="" S MSG("STATUS","ACCEPT ACK RESPONSE")="n/a"
     114 ..S LINE="Accept Ack Rtn: "_MSG("STATUS","ACCEPT ACK RESPONSE")
     115 .S LINE=$$LJ(LINE,39)
     116 .I MSG("STATUS","APP ACK'D") D
     117 ..I MSG("STATUS","APP ACK RESPONSE")="" S MSG("STATUS","APP ACK RESPONSE")="n/a"
     118 ..S LINE=LINE_"App Ack Rtn: "_MSG("STATUS","APP ACK RESPONSE")
     119 .S @VALMAR@($$I,0)=LINE
     120 ;
     121 ;** the message text **
     122 S @VALMAR@($$I,0)=""
     123 I '$G(SUBIEN) D
     124 .S @VALMAR@($$I,0)=$$CJ("Message Text",80)
     125 .D CNTRL^VALM10(VALMCNT,33,16,IORVON,IORVOFF)
     126 E  D
     127 .S @VALMAR@($$I,0)=$$CJ("Individual Message Text (Batched)",80)
     128 .D CNTRL^VALM10(VALMCNT,23,35,IORVON,IORVOFF)
     129 D SHOWBODY(.MSG,$G(SUBIEN))
     130 ;
     131 ;** display its application acknowledgment **
     132 I MSG("ACK BY")]"",$$FINDMSG^HLOMSG1(MSG("ACK BY"),.TEMP)=1 S MSGIEN=TEMP(1) D
     133 .N MSG
     134 .Q:'$$GETMSG^HLOMSG(+MSGIEN,.MSG)
     135 .I $P(MSGIEN,"^",2) D GETMSGB^HLOMSG1(.MSG,$P(MSGIEN,"^",2),.MSG)
     136 .S @VALMAR@($$I,0)=""
     137 .S @VALMAR@($$I,0)=$$CJ("Application Acknowledgment",80)
     138 .D CNTRL^VALM10(VALMCNT,26,30,IORVON,IORVOFF)
     139 .D SHOWBODY(.MSG,$P(MSGIEN,"^",2))
     140 ;
     141 ;** display the original message **
     142 I MSG("ACK TO")]"",$$FINDMSG^HLOMSG1(MSG("ACK TO"),.TEMP)=1 S MSGIEN=TEMP(1) D
     143 .N MSG
     144 .Q:'$$GETMSG^HLOMSG(+MSGIEN,.MSG)
     145 .I $P(MSGIEN,"^",2) D GETMSGB^HLOMSG1(.MSG,$P(MSGIEN,"^",2),.MSG)
     146 .S @VALMAR@($$I,0)=""
     147 .S @VALMAR@($$I,0)=$$CJ("Original Message",80)
     148 .D CNTRL^VALM10(VALMCNT,26,30,IORVON,IORVOFF)
     149 .D SHOWBODY(.MSG,$P(MSGIEN,"^",2))
     150 Q
     151 ;
     152SHOWBODY(MSG,SUBIEN) ;
     153 N NODE,I,SEG,QUIT
     154 S QUIT=0
     155 M SEG=MSG("HDR")
     156 D ADD(.SEG)
     157 S MSG("BATCH","CURRENT MESSAGE")=0
     158 I MSG("BATCH") D
     159 .I $G(SUBIEN) D  Q
     160 ..S MSG("BATCH","CURRENT MESSAGE")=SUBIEN
     161 ..F  Q:'$$HLNEXT^HLOMSG(.MSG,.SEG)  D ADD(.SEG)
     162 .S MSG("BATCH","CURRENT MESSAGE")=0
     163 .N LAST S LAST=0
     164 .F  Q:'$$NEXTMSG^HLOMSG(.MSG,.SEG)  D  Q:QUIT
     165 ..D ADD(.SEG)
     166 ..S LAST=MSG("BATCH","CURRENT MESSAGE")
     167 ..F  Q:'$$HLNEXT^HLOMSG(.MSG,.SEG)  D ADD(.SEG)
     168 .I MSG("DIRECTION")="OUT" K SEG S SEG(1)="BTS"_$E($G(NODE(1)),4)_LAST D ADD(.SEG)
     169 E  D
     170 .F  Q:'$$HLNEXT^HLOMSG(.MSG,.SEG)  D  Q:QUIT
     171 ..D ADD(.SEG)
     172 Q
     173I() ;
     174 S VALMCNT=VALMCNT+1
     175 Q VALMCNT
     176ADD(SEG) ;
     177 N QUIT,I,J,LINE
     178 S QUIT=0
     179 S (I,J)=1
     180 S LINE(1)=$E(SEG(1),1,80),SEG(1)=$E(SEG(1),81,9999)
     181 I SEG(1)="" K SEG(1)
     182 D SHIFT(.I,.J)
     183 S @VALMAR@($$I,0)=LINE(1)
     184 S I=1
     185 F  S I=$O(LINE(I)) Q:'I  D
     186 .S @VALMAR@($$I,0)=LINE(I)
     187 .D CNTRL^VALM10(VALMCNT,1,1,IORVON,IORVOFF)
     188 Q
     189 ;
     190SHIFT(I,J) ;
     191 I '$D(SEG(I)) S I=$O(SEG(0)) Q:'I
     192 I $L(LINE(J))<80 D
     193 .N LEN
     194 .S LEN=$L(LINE(J))
     195 .S LINE(J)=LINE(J)_$E(SEG(I),1,80-LEN)
     196 .S SEG(I)=$E(SEG(I),81-LEN,9999)
     197 .I SEG(I)="" K SEG(I)
     198 E  D
     199 .S J=J+1
     200 .S LINE(J)="-"
     201 D SHIFT(.I,.J)
     202 Q
     203 ;
     204SCRLMODE ;scroll mode
     205 Q:'$L(HLRFRSH)
     206 N QUIT,IOTM,IOBM,DX,DY,LINE,IOTM,IOBM
     207 W !!,IOINHI,"Hit any key to escape scroll mode...",IOINORM
     208 S IOTM=3,IOBM=23
     209 S QUIT=0
     210 S LINE=$S(VALMCNT<17:1,1:17)
     211 W @IOSTBM
     212 S DX=1,DY=$S(VALMCNT<17:VALMCNT+1,1:17) X IOXY
     213 F I=1:1 D  Q:QUIT
     214 .;every 10 seconds refresh the data
     215 .I I>42 D @HLRFRSH S I=0
     216 .I LINE+1>VALMCNT D
     217 ..S TEMP=$G(@VALMAR@(LINE,0))
     218 ..W !,IOUON,TEMP_$$SP(80-$L(TEMP)),IOUOFF
     219 .E  W !,$G(@VALMAR@(LINE,0))
     220 .S LINE=LINE+1
     221 .I LINE>VALMCNT S LINE=1
     222 .I (I=22)!(I=43) R *C:5 I $T S QUIT=1 Q
     223 S VALMBG=LINE-23 I VALMBG<0 S VALMBG=1
     224 S VALMBCK="R"
     225 Q
     226HLP ;
     227 Q
     228 ;
     229IFOPEN(LINK) ;
     230 ;returns 1 if the link can be opened, otherwise 0
     231 ;
     232 ;Inputs:
     233 ;  LINK - name of the link (required), optionally post-fixed with ":"_<port #>, will default to that defined for link
     234 ;
     235 N LINKNAME,LINKARY,POP,IO,IOF,IOST,OPEN,PORT
     236 S OPEN=0
     237 S LINKNAME=$P(LINK,":")
     238 S PORT=$P(LINK,":",2)
     239 Q:LINKNAME="" 0
     240 Q:'$$GETLINK^HLOTLNK(LINKNAME,.LINKARY) 0
     241 S:PORT LINKARY("PORT")=PORT
     242 Q:'$G(LINKARY("PORT")) 0
     243 I LINKARY("IP")="",LINKARY("DOMAIN")="",LINKARY("LLP")="TCP",LINKARY("SERVER") D
     244 .N DATA
     245 .S LINKARY("DOMAIN")=$P($G(^HLD(779.1,1,0)),"^")
     246 .Q:LINKARY("DOMAIN")=""
     247 .S DATA(.08)=LINKARY("DOMAIN")
     248 .Q:$$UPD^HLOASUB1(870,LINKARY("IEN"),.DATA)
     249 D:$G(LINKARY("IP"))'=""
     250 .D CALL^%ZISTCP(LINKARY("IP"),LINKARY("PORT"),15)
     251 .S OPEN='POP
     252 I 'OPEN,LINKARY("DOMAIN")'="",$G(^HLTMP("DNS LAST",LINKARY("IEN")))<$$DT^XLFDT D
     253 .N IP
     254 .S ^HLTMP("DNS LAST",LINKARY("IEN"))=$$DT^XLFDT
     255 .S IP=$$DNS^HLOTCP(LINKARY("DOMAIN"))
     256 .I IP'="",IP'=LINKARY("IP") D
     257 ..N DATA
     258 ..S DATA(400.01)=IP,LINKARY("IP")=IP
     259 ..Q:$$UPD^HLOASUB1(870,LINKARY("IEN"),.DATA)
     260 ..D CALL^%ZISTCP(LINKARY("IP"),LINKARY("PORT"),15)
     261 ..S OPEN='POP
     262 C:OPEN IO
     263 ;D CLOSE^%ZISTCP
     264 Q OPEN
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLOUSR2.m

    r613 r623  
    1 HLOUSR2 ;ALB/CJM -ListManager Screen for viewing messages(continued);12 JUN 1997 10:00 am ;07/17/2007
    2         ;;1.6;HEALTH LEVEL SEVEN;**126,134,137**;Oct 13, 1995;Build 21
    3         ;Per VHA Directive 2004-038, this routine should not be modified
    4         ;
    5 EN      ;
    6         D WAIT^DICD
    7         D EN^VALM("HLO MESSAGE VIEWER")
    8         Q
    9         ;
    10 SHOWLIST        ;
    11         N PARMS,I,ERRCOUNT
    12         S (VALMBG,VALMCNT,I,ERRCOUNT)=0
    13         D CLEAN^VALM10
    14         S VALMBG=1
    15         I '$$ASKPARMS(.PARMS) S VALMBCK="" Q
    16         I PARMS("ALL") D
    17         .N APP
    18         .S APP=""
    19         .F  S APP=$O(^HLB("ERRORS",APP)) Q:APP=""  D  Q:ERRCOUNT>PARMS("MAX")
    20         ..N TIME,IEN
    21         ..S TIME=PARMS("START")
    22         ..Q:($O(^HLB("ERRORS",APP,TIME))="")
    23         ..S @VALMAR@($$I,0)="Application: "_APP
    24         ..D CNTRL^VALM10(VALMCNT,14,$L(APP),IOINHI,IOINORM)
    25         ..F  S TIME=$O(^HLB("ERRORS",APP,TIME)) Q:'TIME  Q:ERRCOUNT>PARMS("MAX")  S IEN="" F  S IEN=$O(^HLB("ERRORS",APP,TIME,IEN)) Q:IEN=""  D ADDTO(IEN,TIME,.ERRCOUNT) Q:ERRCOUNT>PARMS("MAX")
    26         E  D
    27         .N APP
    28         .S APP=PARMS("APP")
    29         .N TIME,IEN
    30         .S TIME=PARMS("START")
    31         .Q:$O(^HLB("ERRORS",APP,TIME))=""
    32         .S @VALMAR@($$I,0)="Application: "_APP
    33         .D CNTRL^VALM10(VALMCNT,14,$L(APP),IOINHI,IOINORM)
    34         .F  S TIME=$O(^HLB("ERRORS",APP,TIME)) Q:'TIME  Q:ERRCOUNT>PARMS("MAX")  S IEN="" F  S IEN=$O(^HLB("ERRORS",APP,TIME,IEN)) Q:IEN=""  D ADDTO(IEN,TIME,.ERRCOUNT) Q:ERRCOUNT>PARMS("MAX")
    35         ;
    36 SHOW    S VALMBCK="R"
    37         ;
    38         Q
    39 ADDTO(IEN,TIME,ERRCOUNT)        ;
    40         N NODE,MSG
    41         Q:'$$GETMSG^HLOMSG(+IEN,.MSG)
    42         S ERRCOUNT=ERRCOUNT+1
    43         ;application errors could be an error to a msg within a batch
    44         ;also, need to go to the ack msg to get the error text from the MSA segment
    45         ;
    46         N SUBIEN,MSA,ERRTEXT
    47         S (ERRTEXT,MSA)=""
    48         S SUBIEN=$P(IEN,"^",2)
    49         ;within batch?
    50         D:SUBIEN GETMSGB^HLOMSG1(.MSG,SUBIEN,.MSG)
    51         S ERRTEXT=MSG("STATUS","ERROR TEXT")
    52         I ERRTEXT="",MSG("ACK BY")]"",($$FINDMSG^HLOMSG1(MSG("ACK BY"),.LIST)=1) D
    53         .N MSG,SEG,FS,AIEN
    54         .S AIEN=+LIST(1),SUBIEN=$P(LIST(1),"^",2)
    55         .Q:'$$GETMSG^HLOMSG(AIEN,.MSG)
    56         .I SUBIEN S MSG("BATCH","CURRENT MESSAGE")=SUBIEN,MSG("LINE COUNT")=0
    57         .F  Q:'$$HLNEXT^HLOMSG(.MSG,.SEG)  I $E(SEG(1),1,3)="MSA" S MSA=SEG(1),FS=$E(MSA,4),ERRTEXT=$P(MSA,FS,4) Q
    58         I ERRTEXT="",MSG("ACK BY")="" D
    59         .N FS
    60         .S FS=$E(MSG("HDR",1),4)
    61         .I $L(FS) S ERRTEXT=$P($G(MSG("STATUS","ACCEPT ACK MSA")),FS,4)
    62         S @VALMAR@($$I,0)="  "_$$LJ(MSG("ID"),15)_$$LJ(MSG("MESSAGE TYPE")_"~"_MSG("EVENT"),8)_$$LJ($$FMTE^XLFDT(MSG("DT/TM CREATED"),2),20)_$E(ERRTEXT,1,35)
    63         D CNTRL^VALM10(VALMCNT,3,15,IOINHI,IOINORM)
    64         I $L(ERRTEXT)>35 D
    65         .S @VALMAR@($$I,0)=$$RJ(" ",45)_$E(ERRTEXT,36,115)
    66         S:MSG("ID")]"" @VALMAR@("INDEX",MSG("ID"))=IEN
    67         Q
    68         ;
    69 ASKPARMS(PARMS) ;
    70         K PARMS
    71         S PARMS("START")=$$ASKBEGIN("T-1")
    72         I 'PARMS("START") Q 0
    73         S PARMS("MAX")=$$ASKMAX()
    74         Q:'(PARMS("MAX")>-1) 0
    75         S PARMS("ALL")=$$ASKYESNO("Include ALL applications","YES")
    76         I PARMS("ALL") Q 1
    77         I PARMS("ALL")="" Q 0
    78         S PARMS("APP")=$$ASKAPP
    79         I PARMS("APP")="" Q 0
    80         Q 1
    81         ;
    82 ASKMAX()               ;
    83         N DIR
    84         S DIR(0)="N^1:30000:0"
    85         S DIR("A")="Maximum List Size"
    86         S DIR("B")=1000
    87         S DIR("?",1)="In case a large number of errors meet your search criteria, what are the"
    88         S DIR("?")="maximum number of errors to display? (30,000 maximum)"
    89         D ^DIR
    90         Q:$D(DTOUT)!$D(DUOUT) -1
    91         Q X-1
    92 ASKAPP()        ;
    93         D FULL^VALM1
    94         S VALMBCK="R"
    95         N DIR
    96         S DIR(0)="F^3:60"
    97         S DIR("A")="Receiving Application"
    98         S DIR("?")="Enter the full name of the application, or '^' to exit."
    99         D ^DIR
    100         I $D(DIRUT)!(Y="") Q ""
    101         Q Y
    102         ;
    103 ASKYESNO(PROMPT,DEFAULT)        ;
    104         ;Description: Displays PROMPT, appending '?'.  Expects a YES NO response
    105         ;Input:
    106         ;   PROMPT - text to display as prompt.  Appends '?'
    107         ;   DEFAULT - (optional) YES or NO.  If not passed, defaults to YES
    108         ;Output:
    109         ;  Function value: 1 if yes, 0 if no, "" if '^' entered or timeout
    110         ;
    111         N DIR,Y
    112         S DIR(0)="Y"
    113         S DIR("A")=PROMPT
    114         S DIR("B")=$S($G(DEFAULT)="NO":"NO",1:"YES")
    115         D ^DIR
    116         Q:$D(DIRUT) ""
    117         Q Y
    118         ;
    119 STRTSTPQ        ;
    120         ;action to start or stop a queue, either incoming or outgoing
    121         ;
    122         N STOP,INOROUT,QUE
    123         S VALMBCK="R"
    124         D FULL^VALM1
    125         ;ask if stop or start
    126         D  Q:STOP=""
    127         .N DIR
    128         .S DIR(0)="S^1:START;2:STOP"
    129         .S DIR("A")="Do you want to START or STOP a queue"
    130         .S DIR("B")="1"
    131         .D ^DIR
    132         .S STOP=$S(Y=1:0,Y=2:1,1:"")
    133         ;ask if in or out
    134         D  Q:INOROUT=""
    135         .N DIR
    136         .S DIR(0)="S^I:INCOMING;O:OUTGOING"
    137         .S DIR("A")="Do you want to "_$S(STOP:"stop",1:"start")_" an incoming queue or an outgoing queue"
    138         .S DIR("B")="I"
    139         .D ^DIR
    140         .S INOROUT=$S(Y="I":"IN",Y="O":"OUT",1:"")
    141         S QUE=$$ASKQUE(INOROUT)
    142         Q:QUE=""
    143         I STOP=$$STOPPED^HLOQUE(INOROUT,QUE) D
    144         .N C
    145         .I STOP D
    146         ..W !,"That queue is already stopped!"
    147         .E  W !,"That queue is not stopped!"
    148         .W !,IOINHI,"Hit any key to continue...",IOINORM
    149         .R *C:DTIME
    150         E  D
    151         .N C
    152         .D:STOP STOPQUE^HLOQUE(INOROUT,QUE)
    153         .D:'STOP STARTQUE^HLOQUE(INOROUT,QUE)
    154         .W !,"DONE!"
    155         .W !,IOINHI,"Hit any key to continue...",IOINORM
    156         .R *C:DTIME
    157         .D @HLRFRSH
    158         Q
    159         ;
    160 ASKQUE(DIR)     ;
    161         N QUEUE
    162 AGAIN   W !,"Enter the full, exact name of queue:"
    163         S QUEUE=""
    164         R QUEUE:60 I '$T Q ""
    165         I $E(QUEUE)="?" W !,"Each message is placed on a queue that has an arbitrary name up to 20",!,"characters long." I $$ASKYESNO("Would you like to see a list of the queues that currently exist","NO") D  G AGAIN
    166         .N SUB,QUE,QUIT,COUNT
    167         .K ^TMP($J,"HLO QUEUES")
    168         .S SUB=""
    169         .F  S SUB=$O(^HLB("QUEUE",DIR,SUB)) Q:SUB=""  D
    170         ..S QUE=""
    171         ..F  S QUE=$O(^HLB("QUEUE",DIR,SUB,QUE)) Q:QUE=""  S ^TMP($J,"HLO QUEUES",QUE)=""
    172         .S QUE=""
    173         .S IOSL=$G(IOSL,20)
    174         .S (COUNT,QUIT)=0
    175         .W !
    176         .F  S QUE=$O(^TMP($J,"HLO QUEUES",QUE)) Q:QUE=""  Q:QUIT  D
    177         ..W !,QUE
    178         ..S COUNT=COUNT+1
    179         ..I COUNT>(IOSL-3) D
    180         ...N Y
    181         ...D PAUSE^VALM1
    182         ...I 'Y S QUIT=1
    183         ...S COUNT=0
    184         .W !
    185         .K ^TMP($J,"HLO QUEUES")
    186         Q:$E(QUEUE)="?" ""
    187         Q:$E(QUEUE)="^" ""
    188         Q QUEUE
    189         ;
    190 ASKBEGIN(DEFAULT)       ;
    191         ;Description: Asks the user to enter a beginning date.
    192         ;Input: DEFAULT - the suggested default dt/time (optional)
    193         ;Output: Returns the date as the function value, or 0 if the user does not select a date
    194         ;
    195         ;
    196         N %DT
    197         S %DT="AEST"
    198         S %DT("A")="Enter the beginning date/time: "
    199         S %DT("B")=$$FMTE^XLFDT($S($L($G(DEFAULT)):DEFAULT,1:$$FMADD^XLFDT(DT,-1)))
    200         S %DT(0)="-NOW"
    201         Q:$D(DTOUT) 0
    202         D ^%DT
    203         I Y=-1 Q 0
    204         Q Y
    205         ;
    206 ASKEND(BEGIN)   ;
    207         ;Description: Asks the user to enter an ending date/time
    208         ;Input: BEGIN - the earliest date/time allowed
    209         ;Output: Returns the date as the function value, or 0 if the user does not select a date/time
    210         ;
    211         N %DT
    212         S %DT="AEST"
    213         S %DT("A")="Enter the ending date/time: "
    214         S %DT("B")="NOW"
    215         S %DT(0)=BEGIN
    216         Q:$D(DTOUT) 0
    217         D ^%DT
    218         I Y=-1 Q 0
    219         Q Y
    220         ;
    221 LJ(STRING,LEN)  ;
    222         Q $$LJ^XLFSTR(STRING,LEN)
    223 RJ(STRING,LEN)  ;
    224         Q $$RJ^XLFSTR(STRING,LEN)
    225         ;
    226 I()     ;
    227         S VALMCNT=VALMCNT+1
    228         Q VALMCNT
    229         ;
    230 HEADER  ;
    231         Q
     1HLOUSR2 ;ALB/CJM -ListManager Screen for viewing messages(continued);12 JUN 1997 10:00 am ;03/19/2007
     2 ;;1.6;HEALTH LEVEL SEVEN;**126,134**;Oct 13, 1995;Build 30
     3 ;Per VHA Directive 2004-038, this routine should not be modified
     4 ;
     5EN ;
     6 D WAIT^DICD
     7 D EN^VALM("HLO MESSAGE VIEWER")
     8 Q
     9 ;
     10SHOWLIST(TYPE) ;
     11 ;TYPE= "SE", "AE", "TF"
     12 N PARMS,I,ERRCOUNT
     13 S (VALMBG,VALMCNT,I,ERRCOUNT)=0
     14 D CLEAN^VALM10
     15 S VALMBG=1
     16 I '$$ASKPARMS(.PARMS) S VALMBCK="" Q
     17 I PARMS("ALL") D
     18 .N APP
     19 .S APP=""
     20 .F  S APP=$O(^HLB("ERRORS",TYPE,APP)) Q:APP=""  D  Q:ERRCOUNT>PARMS("MAX")
     21 ..N TIME,IEN
     22 ..S TIME=PARMS("START")
     23 ..Q:($O(^HLB("ERRORS",TYPE,APP,TIME))="")
     24 ..S @VALMAR@($$I,0)="Application: "_APP
     25 ..D CNTRL^VALM10(VALMCNT,14,$L(APP),IOINHI,IOINORM)
     26 ..F  S TIME=$O(^HLB("ERRORS",TYPE,APP,TIME)) Q:'TIME  Q:ERRCOUNT>PARMS("MAX")  S IEN="" F  S IEN=$O(^HLB("ERRORS",TYPE,APP,TIME,IEN)) Q:IEN=""  D ADDTO(TYPE,IEN,TIME,.ERRCOUNT) Q:ERRCOUNT>PARMS("MAX")
     27 E  D
     28 .N APP
     29 .S APP=PARMS("APP")
     30 .N TIME,IEN
     31 .S TIME=PARMS("START")
     32 .Q:$O(^HLB("ERRORS",TYPE,APP,TIME))=""
     33 .S @VALMAR@($$I,0)="Application: "_APP
     34 .D CNTRL^VALM10(VALMCNT,14,$L(APP),IOINHI,IOINORM)
     35 .F  S TIME=$O(^HLB("ERRORS",TYPE,APP,TIME)) Q:'TIME  Q:ERRCOUNT>PARMS("MAX")  S IEN="" F  S IEN=$O(^HLB("ERRORS",TYPE,APP,TIME,IEN)) Q:IEN=""  D ADDTO(TYPE,IEN,TIME,.ERRCOUNT) Q:ERRCOUNT>PARMS("MAX")
     36 ;
     37SHOW S VALMBCK="R"
     38 ;
     39 Q
     40ADDTO(LTYPE,IEN,TIME,ERRCOUNT) ;
     41 N NODE,MSG
     42 Q:'$$GETMSG^HLOMSG(+IEN,.MSG)
     43 S ERRCOUNT=ERRCOUNT+1
     44 I LTYPE'="AE" D
     45 .N TYPE
     46 .S TYPE=$S(MSG("BATCH"):"BATCH",1:MSG("MESSAGE TYPE")_"~"_MSG("EVENT"))
     47 .S @VALMAR@($$I,0)="  "_$$LJ(MSG("ID"),15)_$$LJ(TYPE,8)_$$LJ($$FMTE^XLFDT(TIME,2),20)_MSG("STATUS","ERROR TEXT")
     48 .D CNTRL^VALM10(VALMCNT,3,15,IOINHI,IOINORM)
     49 .S:MSG("ID")]"" @VALMAR@("INDEX",MSG("ID"))=IEN
     50 E  D
     51 .;application errors - could be an error to a msg within a batch
     52 .;also, need to go to the ack msg to get the error text from the MSA segment
     53 .;
     54 .N SUBIEN,MSA,ERRTEXT
     55 .S (ERRTEXT,MSA)=""
     56 .S SUBIEN=$P(IEN,"^",2)
     57 .;within batch?
     58 .D:SUBIEN GETMSGB^HLOMSG1(.MSG,SUBIEN,.MSG)
     59 .S ERRTEXT=MSG("STATUS","ERROR TEXT")
     60 .I ERRTEXT="",MSG("ACK BY")]"",($$FINDMSG^HLOMSG1(MSG("ACK BY"),.LIST)=1) D
     61 ..N MSG,SEG,FS,AIEN
     62 ..S AIEN=+LIST(1),SUBIEN=$P(LIST(1),"^",2)
     63 ..Q:'$$GETMSG^HLOMSG(AIEN,.MSG)
     64 ..I SUBIEN S MSG("BATCH","CURRENT MESSAGE")=SUBIEN,MSG("LINE COUNT")=0
     65 ..F  Q:'$$HLNEXT^HLOMSG(.MSG,.SEG)  I $E(SEG(1),1,3)="MSA" S MSA=SEG(1),FS=$E(MSA,4),ERRTEXT=$P(MSA,FS,4) Q
     66 .S @VALMAR@($$I,0)="  "_$$LJ(MSG("ID"),15)_$$LJ(MSG("MESSAGE TYPE")_"~"_MSG("EVENT"),8)_$$LJ($$FMTE^XLFDT(MSG("DT/TM CREATED"),2),20)_$E(ERRTEXT,1,37)
     67 .D CNTRL^VALM10(VALMCNT,3,15,IOINHI,IOINORM)
     68 .I $L(ERRTEXT)>37 D
     69 ..S @VALMAR@($$I,0)="~"_$E(ERRTEXT,38,112)
     70 ..D CNTRL^VALM10(VALMCNT,1,1,IORVON,IORVOFF)
     71 .S:MSG("ID")]"" @VALMAR@("INDEX",MSG("ID"))=IEN
     72 Q
     73 ;
     74ASKPARMS(PARMS) ;
     75 K PARMS
     76 S PARMS("START")=$$ASKBEGIN("T-1")
     77 I 'PARMS("START") Q 0
     78 S PARMS("MAX")=$$ASKMAX()
     79 Q:'(PARMS("MAX")>-1) 0
     80 S PARMS("ALL")=$$ASKYESNO("Include ALL applications","YES")
     81 I PARMS("ALL") Q 1
     82 I PARMS("ALL")="" Q 0
     83 S PARMS("APP")=$$ASKAPP
     84 I PARMS("APP")="" Q 0
     85 Q 1
     86 ;
     87ASKMAX()        ;
     88 N DIR
     89 S DIR(0)="N^1:30000:0"
     90 S DIR("A")="Maximum List Size"
     91 S DIR("B")=1000
     92 S DIR("?",1)="In case a large number of errors meet your search criteria, what are the"
     93 S DIR("?")="maximum number of errors to display? (30,000 maximum)"
     94 D ^DIR
     95 Q:$D(DTOUT)!$D(DUOUT) -1
     96 Q X-1
     97ASKAPP() ;
     98 D FULL^VALM1
     99 S VALMBCK="R"
     100 N DIR
     101 S DIR(0)="F^3:60"
     102 S DIR("A")="Application"
     103 S DIR("?")="Enter the full name of the application, or '^' to exit."
     104 S DIR("?",1)="For transmission failures, enter the sending application. "
     105 S DIR("?",2)="For other errors, enter the name of the receiving application. "
     106 D ^DIR
     107 I $D(DIRUT)!(Y="") Q ""
     108 Q Y
     109 ;
     110ASKYESNO(PROMPT,DEFAULT) ;
     111 ;Description: Displays PROMPT, appending '?'.  Expects a YES NO response
     112 ;Input:
     113 ;   PROMPT - text to display as prompt.  Appends '?'
     114 ;   DEFAULT - (optional) YES or NO.  If not passed, defaults to YES
     115 ;Output:
     116 ;  Function value: 1 if yes, 0 if no, "" if '^' entered or timeout
     117 ;
     118 N DIR,Y
     119 S DIR(0)="Y"
     120 S DIR("A")=PROMPT
     121 S DIR("B")=$S($G(DEFAULT)="NO":"NO",1:"YES")
     122 D ^DIR
     123 Q:$D(DIRUT) ""
     124 Q Y
     125 ;
     126STRTSTPQ ;
     127 ;action to start or stop a queue, either incoming or outgoing
     128 ;
     129 N STOP,INOROUT,QUE
     130 S VALMBCK="R"
     131 D FULL^VALM1
     132 ;ask if stop or start
     133 D  Q:STOP=""
     134 .N DIR
     135 .S DIR(0)="S^1:START;2:STOP"
     136 .S DIR("A")="Do you want to START or STOP a queue"
     137 .S DIR("B")="1"
     138 .D ^DIR
     139 .S STOP=$S(Y=1:0,Y=2:1,1:"")
     140 ;ask if in or out
     141 D  Q:INOROUT=""
     142 .N DIR
     143 .S DIR(0)="S^I:INCOMING;O:OUTGOING"
     144 .S DIR("A")="Do you want to "_$S(STOP:"stop",1:"start")_" an incoming queue or an outgoing queue"
     145 .S DIR("B")="I"
     146 .D ^DIR
     147 .S INOROUT=$S(Y="I":"IN",Y="O":"OUT",1:"")
     148 S QUE=$$ASKQUE(INOROUT)
     149 Q:QUE=""
     150 I STOP=$$STOPPED^HLOQUE(INOROUT,QUE) D
     151 .N C
     152 .I STOP D
     153 ..W !,"That queue is already stopped!"
     154 .E  W !,"That queue is not stopped!"
     155 .W !,IOINHI,"Hit any key to continue...",IOINORM
     156 .R *C:DTIME
     157 E  D
     158 .N C
     159 .D:STOP STOPQUE^HLOQUE(INOROUT,QUE)
     160 .D:'STOP STARTQUE^HLOQUE(INOROUT,QUE)
     161 .W !,"DONE!"
     162 .W !,IOINHI,"Hit any key to continue...",IOINORM
     163 .R *C:DTIME
     164 .D @HLRFRSH
     165 Q
     166 ;
     167ASKQUE(DIR) ;
     168 N QUEUE
     169AGAIN W !,"Enter the full, exact name of queue:"
     170 S QUEUE=""
     171 R QUEUE:60 I '$T Q ""
     172 I $E(QUEUE)="?" W !,"Each message is placed on a queue that has an arbitrary name up to 20",!,"characters long." I $$ASKYESNO("Would you like to see a list of the queues that currently exist","NO") D  G AGAIN
     173 .N SUB,QUE,QUIT,COUNT
     174 .K ^TMP($J,"HLO QUEUES")
     175 .S SUB=""
     176 .F  S SUB=$O(^HLB("QUEUE",DIR,SUB)) Q:SUB=""  D
     177 ..S QUE=""
     178 ..F  S QUE=$O(^HLB("QUEUE",DIR,SUB,QUE)) Q:QUE=""  S ^TMP($J,"HLO QUEUES",QUE)=""
     179 .S QUE=""
     180 .S IOSL=$G(IOSL,20)
     181 .S (COUNT,QUIT)=0
     182 .W !
     183 .F  S QUE=$O(^TMP($J,"HLO QUEUES",QUE)) Q:QUE=""  Q:QUIT  D
     184 ..W !,QUE
     185 ..S COUNT=COUNT+1
     186 ..I COUNT>(IOSL-3) D
     187 ...N Y
     188 ...D PAUSE^VALM1
     189 ...I 'Y S QUIT=1
     190 ...S COUNT=0
     191 .W !
     192 .K ^TMP($J,"HLO QUEUES")
     193 Q:$E(QUEUE)="?" ""
     194 Q:$E(QUEUE)="^" ""
     195 Q QUEUE
     196 ;
     197ASKBEGIN(DEFAULT) ;
     198 ;Description: Asks the user to enter a beginning date.
     199 ;Input: DEFAULT - the suggested default dt/time (optional)
     200 ;Output: Returns the date as the function value, or 0 if the user does not select a date
     201 ;
     202 ;
     203 N %DT
     204 S %DT="AEST"
     205 S %DT("A")="Enter the beginning date/time: "
     206 S %DT("B")=$$FMTE^XLFDT($S($L($G(DEFAULT)):DEFAULT,1:$$FMADD^XLFDT(DT,-1)))
     207 S %DT(0)="-NOW"
     208 Q:$D(DTOUT) 0
     209 D ^%DT
     210 I Y=-1 Q 0
     211 Q Y
     212 ;
     213ASKEND(BEGIN) ;
     214 ;Description: Asks the user to enter an ending date/time
     215 ;Input: BEGIN - the earliest date/time allowed
     216 ;Output: Returns the date as the function value, or 0 if the user does not select a date/time
     217 ;
     218 N %DT
     219 S %DT="AEST"
     220 S %DT("A")="Enter the ending date/time: "
     221 S %DT("B")="NOW"
     222 S %DT(0)=BEGIN
     223 Q:$D(DTOUT) 0
     224 D ^%DT
     225 I Y=-1 Q 0
     226 Q Y
     227 ;
     228LJ(STRING,LEN) ;
     229 Q $$LJ^XLFSTR(STRING,LEN)
     230 ;
     231I() ;
     232 S VALMCNT=VALMCNT+1
     233 Q VALMCNT
     234 ;
     235HEADER ;
     236 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLTF.m

    r613 r623  
    1 HLTF    ;AISC/SAW,JRP-Create/Process Message Text File Entries ;10/17/2007  09:41
    2         ;;1.6;HEALTH LEVEL SEVEN;**1,19,43,55,109,120,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         Q
    6         ;
    7 FILE    ;Create Entries in files 772 and 773 for Version 1.5 Interface Only
    8         D CREATE(,.HLDA,.HLDT,.HLDT1)
    9         Q
    10 CREATE(HLMID,MTIEN,HLDT,HLDT1)  ;Create entries in Message Text (#772)
    11         ;
    12         ;Input  : HLMID = Variable in which value of message ID will be
    13         ;                 returned (pass by reference)
    14         ;         MTIEN = Variable in which IEN of Message Text file entry
    15         ;                 will be returned (pass by reference)
    16         ;         HLDT = Variable in which current date/time in FM internal
    17         ;                format will be returned (pass by reference)
    18         ;         HLDT1 = Variable in which current date/time in HL7 format
    19         ;                 will be returned (pass by reference)
    20         ;
    21         ;Output : See above
    22         ;
    23         ;Notes  : If HLDT has a value [upon entry], the created entries will
    24         ;         be given that value for their date/time (value of .01)
    25         ;       : Current date/time used if HLDT is not passed or invalid
    26         ;
    27         ;Make entry in Message Administration file
    28         N Y
    29         S HLDT=$G(HLDT)
    30         D MT(.HLDT)
    31         S Y=$$CHNGMID(MTIEN,.HLMID),HLDT1=$$HLDATE^HLFNC(HLDT)
    32         Q
    33 TCP(HLMID,MTIEN,HLDT)   ;create new message in 772 & 773 entries
    34         ;used for incoming messages and outgoing responses
    35         ;Input  : HLMID = Variable in which value of message ID will be
    36         ;                 returned (pass by reference)
    37         ;         MTIEN = Variable in which IEN of file 773 entry
    38         ;                 will be returned (pass by reference)
    39         ;         HLDT = Variable in which current date/time in FM internal
    40         ;                format will be returned (pass by reference)
    41         ;
    42         S HLDT=$G(HLDT),HLMID=$G(HLMID)
    43         D MT(.HLDT)
    44         S MTIEN=$$MA(MTIEN,.HLMID)
    45         Q
    46         ;
    47 MT(HLX) ;Create entry in Message Text file (#772)
    48         ;
    49         ;Input  : HLX = Date/time entry in file should be given (value of .01)
    50         ;               Defaults to current date/time
    51         ;
    52         ;Output : HLDT = Date/time of created entry (value of .01)
    53         ;       : HLDT1 = HLDT in HL7 format
    54         ;
    55         ;Notes  : HLX must be in FileMan format (default value used if not)
    56         ;       : HLDT will be in FileMan format
    57         ;       : MTIEN is ien in file 772
    58         ;
    59         ;Check for input
    60         S HLX=$G(HLX)
    61         ;Declare variables
    62         N DIC,DD,DO,HLCNT,HLJ,X,Y
    63         F HLCNT=0:1 D  Q:Y>0  H HLCNT
    64         . I (HLX'?7N.1".".6N) S HLX=$$NOW^XLFDT
    65         . S DIC="^HL(772,",DIC(0)="L",(HLDT,X)=HLX
    66         . S Y=$$STUB772(X) ; This call substituted for D FILE^DICN by HL*1.6*109
    67         . ;Entry not created - try again
    68         . I Y<0 S HLX="" Q
    69         . S MTIEN=+Y
    70         ;***If we didn't get a record in 772, need to do something
    71         I Y<0 Q
    72         S HLDT1=$$HLDATE^HLFNC(HLDT)
    73         Q
    74         ;add to Message Admin file #773
    75 MA(X,HLMID)     ;X=ien in file 772, HLMID=msg. id (passed by ref.)
    76         ;return ien in file 773
    77         ;
    78         ; patch HL*1.6*122: MPI-client/server start
    79         F  L +^HL(772,+$G(X)):10 Q:$T  H 1
    80         Q:'$G(^HL(772,X,0)) 0
    81         L -^HL(772,+$G(X))
    82         ; patch HL*1.6*122: MPI-client/server end
    83         ;
    84         N DA,DD,DO,DIC,DIE,DR,HLDA,HLCNT,HLJ,Y
    85         S DIC="^HLMA(",DIC(0)="L"
    86         F HLCNT=0:1 D  Q:Y>0  H HLCNT
    87         . S Y=$$STUB773(X) ; This call substituted for D FILE^DICN by HL*1.6*109
    88         ;***If we didn't get a record in 773, need to do something
    89         I Y<0 Q 0
    90         S HLDA=+Y,HLMID=$$MAID(HLDA,$G(HLMID))
    91         Q HLDA
    92         ;
    93 MAID(Y,HLMID)   ;Determine message ID (if needed) & store message ID
    94         ;Y=ien in 773, HLMID=id,  Output message id
    95         N HLJ
    96         ;need to have id contain institution number to make unique
    97         S:$G(HLMID)="" HLMID=+$P($$PARAM^HLCS2,U,6)_Y
    98         S HLJ(773,Y_",",2)=HLMID
    99         D FILE^HLDIE("","HLJ","","MAID","HLTF") ;HL*1.6*109
    100         Q HLMID
    101         ;
    102 CHNGMID(PTRMT,NEWID)    ;Change message ID for entry in Message Text file
    103         ;Input  : PTRMT - Pointer to entry in Message Text file (#772)
    104         ;         NEWID - New message ID
    105         ;Output : 0 = Success
    106         ;         -1^ErrorText = Error/Bad input
    107         ;
    108         ;Check input
    109         S PTRMT=+$G(PTRMT)
    110         S NEWID=$G(NEWID)
    111         Q:('$D(^HL(772,PTRMT,0))) "-1^Did not pass valid pointer to Message Text file (#772)"
    112         N HLJ
    113         I $G(NEWID)="" S NEWID=+$P($$PARAM^HLCS2,U,6)_PTRMT
    114         S HLJ(772,PTRMT_",",6)=NEWID
    115         D FILE^HLDIE("","HLJ","","CHNGMID","HLTF") ; HL*1.6*109
    116         Q 0
    117         ;
    118 OUT(HLDA,HLMID,HLMTN)   ;File Data in Message Text File for Outgoing Message
    119         ;Version 1.5 Interface Only
    120         ;
    121         ; patch HL*1.6*122: HLTF routine splitted, moves sub-routines,
    122         ; OUT, IN, and ACK to HLTF2 routine.
    123         ;
    124         D OUT^HLTF2($G(HLDA),$G(HLMID),$G(HLMTN))
    125         Q
    126         ;
    127 IN(HLMTN,HLMID,HLTIME)  ;File Data in Message Text File for Incoming Message
    128         ;Version 1.5 Interface Only
    129         ;
    130         ; patch HL*1.6*122: HLTF routine splitted, moves sub-routines,
    131         ; OUT, IN, and ACK to HLTF2 routine.
    132         ;
    133         D IN^HLTF2($G(HLMTN),$G(HLMID),$G(HLTIME))
    134         Q
    135         ;
    136 ACK(HLMSA,HLIO,HLDA)    ;Process 'ACK' Message Type - Version 1.5 Interface Only
    137         ;
    138         ; patch HL*1.6*122: HLTF routine splitted, moves sub-routines,
    139         ; OUT, IN, and ACK to HLTF2 routine.
    140         ;
    141         D ACK^HLTF2($G(HLMSA),$G(HLIO),$G(HLDA))
    142         Q
    143         ;
    144 STUB772(FLD01,OS)       ;
    145         ;This function creates a new stub record in file 772. The Stub record may consist of only the 0 node with a value of "^". If a value is passed in for the .01 field it will be included in the 0 node and its "B" x-ref set.
    146         ;Inputs:
    147         ;  OS (optional), the value of ^%ZOSF("OS")
    148         ;  FLD01 (optional), the value for the .01 field
    149         ;Output - the function returns the ien of the newly created record
    150         ;
    151         N IEN
    152         I '$L($G(OS)) N OS S OS=$G(^%ZOSF("OS"))
    153         ;
    154         I OS'["DSM",OS'["OpenM" D
    155         .F  L +^HLCS(869.3,1,772):10 S IEN=+$G(^HLCS(869.3,1,772))+1,^HLCS(869.3,1,772)=IEN S:$D(^HL(772,IEN)) IEN=0,^HLCS(869.3,1,772)=($O(^HL(772,":"),-1)\1) L -^HLCS(869.3,1,772) Q:IEN
    156         E  D
    157         .F  S IEN=$I(^HLCS(869.3,1,772),1) S:$D(^HL(772,IEN)) IEN=0,^HLCS(869.3,1,772)=($O(^HL(772,":"),-1)\1) Q:IEN
    158         ;
    159         ; patch HL*1.6*122: MPI-client/server start
    160         F  L +^HL(772,IEN):10 Q:$T  H 1
    161         S ^HL(772,IEN,0)=$G(FLD01)_"^"
    162         I $L($G(FLD01)) S ^HL(772,"B",FLD01,IEN)=""
    163         L -^HL(772,IEN)
    164         ; patch HL*1.6*122: MPI-client/server end
    165         ;
    166         Q IEN
    167         ;
    168 STUB773(FLD01,OS)       ;
    169         ;This function creates a new stub record in file 772. The Stub record may consist of only the 0 node with a value of "^". If a value is passed in for the .01 field it will be included in the 0 node and its "B" x-ref set.
    170         ;Inputs:
    171         ;  OS (optional), the value of ^%ZOSF("OS")
    172         ;  FLD01 (optional), the value for the .01 field
    173         ;Output - the function returns the ien of the newly created record
    174         ;
    175         N IEN
    176         I '$L($G(OS)) N OS S OS=$G(^%ZOSF("OS"))
    177         ;
    178         I OS'["DSM",OS'["OpenM" D
    179         .F  L +^HLCS(869.3,1,773):10 S IEN=+$G(^HLCS(869.3,1,773))+1,^HLCS(869.3,1,773)=IEN S:$D(^HLMA(IEN)) IEN=0,^HLCS(869.3,1,773)=($O(^HLMA(":"),-1)\1) L -^HLCS(869.3,1,773) Q:IEN
    180         E  D
    181         .F  S IEN=$I(^HLCS(869.3,1,773),1) S:$D(^HLMA(IEN)) IEN=0,^HLCS(869.3,1,773)=($O(^HLMA(":"),-1)\1) Q:IEN
    182         ;
    183         ; patch HL*1.6*122: MPI-client/server
    184         F  L +^HLMA(IEN):10 Q:$T  H 1
    185         S ^HLMA(IEN,0)=$G(FLD01)_"^"
    186         I $L($G(FLD01)) S ^HLMA("B",FLD01,IEN)=""
    187         L -^HLMA(IEN)
    188         ;
    189         Q IEN
     1HLTF ;AISC/SAW,JRP-Create/Process Message Text File Entries ;01/23/06  12:56
     2 ;;1.6;HEALTH LEVEL SEVEN;**1,19,43,55,109,120**;Oct 13, 1995;Build 12
     3FILE ;Create Entries in files 772 and 773 for Version 1.5 Interface Only
     4 D CREATE(,.HLDA,.HLDT,.HLDT1)
     5 Q
     6CREATE(HLMID,MTIEN,HLDT,HLDT1) ;Create entries in Message Text (#772)
     7 ;
     8 ;Input  : HLMID = Variable in which value of message ID will be
     9 ;                 returned (pass by reference)
     10 ;         MTIEN = Variable in which IEN of Message Text file entry
     11 ;                 will be returned (pass by reference)
     12 ;         HLDT = Variable in which current date/time in FM internal
     13 ;                format will be returned (pass by reference)
     14 ;         HLDT1 = Variable in which current date/time in HL7 format
     15 ;                 will be returned (pass by reference)
     16 ;
     17 ;Output : See above
     18 ;
     19 ;Notes  : If HLDT has a value [upon entry], the created entries will
     20 ;         be given that value for their date/time (value of .01)
     21 ;       : Current date/time used if HLDT is not passed or invalid
     22 ;
     23 ;Make entry in Message Administration file
     24 N Y
     25 S HLDT=$G(HLDT)
     26 D MT(.HLDT)
     27 S Y=$$CHNGMID(MTIEN,.HLMID),HLDT1=$$HLDATE^HLFNC(HLDT)
     28 Q
     29TCP(HLMID,MTIEN,HLDT) ;create new message in 772 & 773 entries
     30 ;used for incoming messages and outgoing responses
     31 ;Input  : HLMID = Variable in which value of message ID will be
     32 ;                 returned (pass by reference)
     33 ;         MTIEN = Variable in which IEN of file 773 entry
     34 ;                 will be returned (pass by reference)
     35 ;         HLDT = Variable in which current date/time in FM internal
     36 ;                format will be returned (pass by reference)
     37 ;
     38 S HLDT=$G(HLDT),HLMID=$G(HLMID)
     39 D MT(.HLDT)
     40 S MTIEN=$$MA(MTIEN,.HLMID)
     41 Q
     42 ;
     43MT(HLX) ;Create entry in Message Text file (#772)
     44 ;
     45 ;Input  : HLX = Date/time entry in file should be given (value of .01)
     46 ;               Defaults to current date/time
     47 ;
     48 ;Output : HLDT = Date/time of created entry (value of .01)
     49 ;       : HLDT1 = HLDT in HL7 format
     50 ;
     51 ;Notes  : HLX must be in FileMan format (default value used if not)
     52 ;       : HLDT will be in FileMan format
     53 ;       : MTIEN is ien in file 772
     54 ;
     55 ;Check for input
     56 S HLX=$G(HLX)
     57 ;Declare variables
     58 N DIC,DD,DO,HLCNT,HLJ,X,Y
     59 F HLCNT=0:1 D  Q:Y>0  H HLCNT
     60 . I (HLX'?7N.1".".6N) S HLX=$$NOW^XLFDT
     61 . S DIC="^HL(772,",DIC(0)="L",(HLDT,X)=HLX
     62 . S Y=$$STUB772(X) ; This call substituted for D FILE^DICN by HL*1.6*109
     63 . ;Entry not created - try again
     64 . I Y<0 S HLX="" Q
     65 . S MTIEN=+Y
     66 ;***If we didn't get a record in 772, need to do something
     67 I Y<0 Q
     68 S HLDT1=$$HLDATE^HLFNC(HLDT)
     69 Q
     70 ;add to Message Admin file #773
     71MA(X,HLMID) ;X=ien in file 772, HLMID=msg. id (passed by ref.)
     72 ;return ien in file 773
     73 Q:'$G(^HL(772,X,0)) 0
     74 N DA,DD,DO,DIC,DIE,DR,HLDA,HLCNT,HLJ,Y
     75 S DIC="^HLMA(",DIC(0)="L"
     76 F HLCNT=0:1 D  Q:Y>0  H HLCNT
     77 . S Y=$$STUB773(X) ; This call substituted for D FILE^DICN by HL*1.6*109
     78 ;***If we didn't get a record in 773, need to do something
     79 I Y<0 Q 0
     80 S HLDA=+Y,HLMID=$$MAID(HLDA,$G(HLMID))
     81 Q HLDA
     82 ;
     83MAID(Y,HLMID) ;Determine message ID (if needed) & store message ID
     84 ;Y=ien in 773, HLMID=id,  Output message id
     85 N HLJ
     86 ;need to have id contain institution number to make unique
     87 S:$G(HLMID)="" HLMID=+$P($$PARAM^HLCS2,U,6)_Y
     88 S HLJ(773,Y_",",2)=HLMID
     89 D FILE^HLDIE("","HLJ","","MAID","HLTF") ;HL*1.6*109
     90 Q HLMID
     91 ;
     92CHNGMID(PTRMT,NEWID) ;Change message ID for entry in Message Text file
     93 ;Input  : PTRMT - Pointer to entry in Message Text file (#772)
     94 ;         NEWID - New message ID
     95 ;Output : 0 = Success
     96 ;         -1^ErrorText = Error/Bad input
     97 ;
     98 ;Check input
     99 S PTRMT=+$G(PTRMT)
     100 S NEWID=$G(NEWID)
     101 Q:('$D(^HL(772,PTRMT,0))) "-1^Did not pass valid pointer to Message Text file (#772)"
     102 N HLJ
     103 I $G(NEWID)="" S NEWID=+$P($$PARAM^HLCS2,U,6)_PTRMT
     104 S HLJ(772,PTRMT_",",6)=NEWID
     105 D FILE^HLDIE("","HLJ","","CHNGMID","HLTF") ; HL*1.6*109
     106 Q 0
     107 ;
     108OUT(HLDA,HLMID,HLMTN) ;File Data in Message Text File for Outgoing Message
     109 ;Version 1.5 Interface Only
     110 Q:'$D(HLFS)
     111 ;
     112 I HLMTN="ACK"!(HLMTN="MCF")!(HLMTN="ORR") Q:'$D(HLMSA)  D ACK(HLMSA,"I") Q
     113 ;
     114 ;-- if message contained MSA find inbound message
     115 I $D(HLMSA),$D(HLNDAP),$P(HLMSA,HLFS,3)]"" D
     116 . N HLDAI
     117 . S HLDAI=0
     118 . F  S HLDAI=$O(^HL(772,"AH",+$P($G(HLNDAP0),U,12),$P(HLMSA,HLFS,3),HLDAI)) Q:'HLDAI!($P($G(^HL(772,+HLDAI,0)),U,4)="I")
     119 . I 'HLDAI K HLDAI
     120 ;
     121 D STUFF^HLTF0("O")
     122 ;
     123 N HLAC S HLAC=$S($D(HLERR):4,'$P(HLNDAP0,"^",10):1,1:2) D STATUS^HLTF0(HLDA,HLAC,$G(HLMSG))
     124 D:$D(HLCHAR) STATS^HLTF0(HLDA,HLCHAR,$G(HLEVN))
     125 ;
     126 ;-- update status if MSA and found inbound message
     127 I $D(HLMSA),$D(HLDAI) D
     128 .N HLERR,HLMSG I $P(HLMSA,HLFS,4)]"" S HLERR=$P(HLMSA,HLFS,4)
     129 .S HLAC=$P(HLMSA,HLFS,2)
     130 .I HLAC'="AA" S HLMSG=$S(HLAC="AR":"Application Reject",HLAC="AE":"Application Error",1:"")_" - "_HLERR
     131 .S HLAC=$S(HLAC'="AA":4,1:3) D STATUS^HLTF0(HLDAI,HLAC,$G(HLMSG))
     132 Q
     133 ;
     134IN(HLMTN,HLMID,HLTIME) ;File Data in Message Text File for Incoming Message
     135 ;Version 1.5 Interface Only
     136 Q:'$D(HLFS)
     137 I HLMTN="ACK"!(HLMTN="MCF")!(HLMTN="ORR") Q:'$D(HLMSA)  D ACK(HLMSA,"O",$G(HLDA)) Q
     138 ;
     139 N HLDAI S HLDA=0
     140 I $D(HLNDAP),HLMID]"" D
     141 .F  S HLDA=+$O(^HL(772,"AH",+$P($G(HLNDAP0),U,12),HLMID,HLDA)) Q:'HLDA!($P($G(^HL(772,+HLDA,0)),U,4)="I")
     142 .I HLDA D
     143 ..S HLDT=+$P($G(^HL(772,HLDA,0)),"^"),HLDT1=$$HLDATE^HLFNC(HLDT)
     144 ..K ^HL(772,HLDA,"IN")
     145 .I $D(HLMSA),$P(HLMSA,HLFS,3)]"" D
     146 ..S HLDAI=0
     147 ..F  S HLDAI=$O(^HL(772,"AH",+$P($G(HLNDAP0),U,12),$P(HLMSA,HLFS,3),HLDAI)) Q:'HLDAI!($P($G(^HL(772,+HLDAI,0)),U,4)="O")
     148 ..I 'HLDAI K HLDAI
     149 ;
     150 I 'HLDA D CREATE(.HLMID,.HLDA,.HLDT,.HLDT1) K HLZ
     151 ;
     152 D STUFF^HLTF0("I")
     153 N HLAC S HLAC=$S($D(HLERR):4,1:1) D STATUS^HLTF0(HLDA,HLAC,$G(HLMSG))
     154 ;
     155 D MERGE15^HLTF1("G",HLDA,"HLR",HLTIME)
     156 ;
     157 I '$D(HLERR),$D(HLMSA),$D(HLDAI) D
     158 .N HLAC,HLERR,HLMSG I $P(HLMSA,HLFS,4)]"" S HLERR=$P(HLMSA,HLFS,4)
     159 .S HLAC=$P(HLMSA,HLFS,2) I HLAC'="AA" S HLMSG=$S(HLAC="AR":"Application Reject",1:"Application Error")_" - "_HLERR
     160 .S HLAC=$S(HLAC'="AA":4,1:3) D STATUS^HLTF0(HLDAI,HLAC,$G(HLMSG))
     161 Q
     162 ;
     163ACK(HLMSA,HLIO,HLDA) ;Process 'ACK' Message Type - Version 1.5 Interface Only
     164 ; To determine the correct message to link the ACK, HLIO is used.
     165 ; For an ack from DHCP (original message from remote system) then
     166 ; HLIO should be "I" so that the correct inbound message is ack-ed. For
     167 ; an inbound ack (original message outbound from DHCP) HLIO should be
     168 ; "O". This distinction must be made due to the possible duplicate
     169 ; message ids from a bi-direction interface.
     170 ;
     171 ; Input : MSA - MSA from ACK message.
     172 ;         HLIO - Either "I" or "O" : See note above.
     173 ;Output : None
     174 ;
     175 N HLAC,HLMIDI
     176 ;-- set up required vars
     177 S HLAC=$P(HLMSA,HLFS,2),HLMIDI=$P(HLMSA,HLFS,3)
     178 ;-- quit
     179 Q:HLMIDI']""!(HLAC']"")!('$D(HLNDAP))
     180 ;-- find message to ack
     181 I '$G(HLDA) S HLDA=0 D
     182 . F  S HLDA=+$O(^HL(772,"AH",+$P($G(HLNDAP0),U,12),HLMIDI,HLDA)) Q:'HLDA!($P($G(^HL(772,+HLDA,0)),U,4)=HLIO)
     183 ;-- quit if no message
     184 Q:'$D(^HL(772,+HLDA,0))
     185 ;-- check for error
     186 I $P(HLMSA,HLFS,4)]"" N HLERR S HLERR=$P(HLMSA,HLFS,4)
     187 I $D(HLERR),'$D(HLMSG) N HLMSG S HLMSG="Error During Receipt of Acknowledgement Message"_$S(HLAC="AR":" - Application Reject",HLAC="AE":" - Application Error",1:"")_" - "_HLERR
     188 ;-- update status
     189 S HLAC=$S(HLMTN="MCF":2,HLAC'="AA":4,1:3)
     190 D STATUS^HLTF0(HLDA,HLAC,$G(HLMSG))
     191 Q
     192 ;
     193STUB772(FLD01,OS) ;
     194 ;This function creates a new stub record in file 772. The Stub record may consist of only the 0 node with a value of "^". If a value is passed in for the .01 field it will be included in the 0 node and its "B" x-ref set.
     195 ;Inputs:
     196 ;  OS (optional), the value of ^%ZOSF("OS")
     197 ;  FLD01 (optional), the value for the .01 field
     198 ;Output - the function returns the ien of the newly created record
     199 ;
     200 N IEN
     201 I '$L($G(OS)) N OS S OS=$G(^%ZOSF("OS"))
     202 ;
     203 ; patch HL*1.6*120, protect Else command
     204 ; I OS'["DSM",OS'["OpenM" D
     205 I OS'["DSM",OS'["OpenM" D  I 1
     206 .F  L +^HLCS(869.3,1,772):10 S IEN=+$G(^HLCS(869.3,1,772))+1,^HLCS(869.3,1,772)=IEN S:$D(^HL(772,IEN)) IEN=0,^HLCS(869.3,1,772)=($O(^HL(772,":"),-1)\1) L -^HLCS(869.3,1,772) Q:IEN
     207 E  D
     208 .F  S IEN=$I(^HLCS(869.3,1,772),1) S:$D(^HL(772,IEN)) IEN=0,^HLCS(869.3,1,772)=($O(^HL(772,":"),-1)\1) Q:IEN
     209 S ^HL(772,IEN,0)=$G(FLD01)_"^"
     210 I $L($G(FLD01)) S ^HL(772,"B",FLD01,IEN)=""
     211 Q IEN
     212 ;
     213STUB773(FLD01,OS) ;
     214 ;This function creates a new stub record in file 772. The Stub record may consist of only the 0 node with a value of "^". If a value is passed in for the .01 field it will be included in the 0 node and its "B" x-ref set.
     215 ;Inputs:
     216 ;  OS (optional), the value of ^%ZOSF("OS")
     217 ;  FLD01 (optional), the value for the .01 field
     218 ;Output - the function returns the ien of the newly created record
     219 ;
     220 N IEN
     221 I '$L($G(OS)) N OS S OS=$G(^%ZOSF("OS"))
     222 ;
     223 ; patch HL*1.6*120, protect Else command
     224 ; I OS'["DSM",OS'["OpenM" D
     225 I OS'["DSM",OS'["OpenM" D  I 1
     226 .F  L +^HLCS(869.3,1,773):10 S IEN=+$G(^HLCS(869.3,1,773))+1,^HLCS(869.3,1,773)=IEN S:$D(^HLMA(IEN)) IEN=0,^HLCS(869.3,1,773)=($O(^HLMA(":"),-1)\1) L -^HLCS(869.3,1,773) Q:IEN
     227 E  D
     228 .F  S IEN=$I(^HLCS(869.3,1,773),1) S:$D(^HLMA(IEN)) IEN=0,^HLCS(869.3,1,773)=($O(^HLMA(":"),-1)\1) Q:IEN
     229 S ^HLMA(IEN,0)=$G(FLD01)_"^"
     230 I $L($G(FLD01)) S ^HLMA("B",FLD01,IEN)=""
     231 Q IEN
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLTF1.m

    r613 r623  
    1 HLTF1   ;AISC/SAW/MTC-Process Message Text File Entries (Cont'd) ;10/17/2007  09:43
    2         ;;1.6;HEALTH LEVEL SEVEN;**5,8,22,25,19,78,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 MERGE15(ARAYTYPE,MTIEN,SUB1,SUB2)       ;Merge Local/Global Array From Application into
    6         ;Message Text File
    7         ;
    8         ;This is a routine call with parameter passing.  There are no output
    9         ;parameters returned by this call.
    10         ;
    11         ;**  Merges incoming data for v1.5 applications only **
    12         ;
    13         ;Required input parameters
    14         ;   MTIEN = The IEN from the Message Text file of the entry to be
    15         ;             updated
    16         ;  ARAYTYPE = Array type, G for global or L for local
    17         ;      SUB1 = The first level subscript of the array.  Must be
    18         ;               either HLS or HLA
    19         ;Optional input parameter
    20         ;      SUB2 = A second subscript associated with the array
    21         ;
    22         ;Check for required parameters
    23         I "GL"'[$G(ARAYTYPE)!($G(SUB1)']"")!('$G(MTIEN)) G MRGE15X
    24         ;
    25         N HLCHAR,HLEVN,HLFS,I,X,X1,X2,X3 S (HLCHAR,HLEVN,X)=0
    26         ;
    27         ;Merge data from a global array with two subscript
    28         I ARAYTYPE="G",$G(SUB2)'="" D
    29         . S X="",I=0
    30         . F  S X=$O(^TMP(SUB1,$J,SUB2,X)) Q:'X  S I=I+1,X1=^TMP(SUB1,$J,SUB2,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1
    31         ;
    32         ;Merge data from a global array with one subscripts
    33         I ARAYTYPE="G",$G(SUB2)="" D
    34         . S X="",I=0
    35         . F  S X=$O(^TMP(SUB1,$J,X)) Q:'X  S I=I+1,X1=^TMP(SUB1,$J,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1
    36         ;
    37         ;Merge data from a local array with one subscript
    38         I ARAYTYPE="L" D
    39         . S X="",I=0
    40         . F  S X=$O(HLA(SUB1,X)) Q:'X  S I=I+1,X1=HLA(SUB1,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1
    41         ;
    42         ;-- update 0 node for message text
    43         S ^HL(772,MTIEN,"IN",0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
    44         ;
    45         ;File message statistics
    46         D STATS^HLTF0(MTIEN,HLCHAR,HLEVN)
    47         ;
    48 MRGE15X ;-- exit merge
    49         Q
    50         ;
    51 MERGE(ARAYTYPE,MTIEN,SUB1,SUB2) ;Merge Local/Global Array From Application into
    52         ;Message Text File
    53         ;
    54         ;This is a routine call with parameter passing.  There are no output
    55         ;parameters returned by this call.
    56         ;
    57         ;Required input parameters
    58         ;   MTIEN = The IEN from the Message Text file of the entry to be
    59         ;             updated
    60         ;  ARAYTYPE = Array type, G for global or L for local
    61         ;      SUB1 = The first level subscript of the array.  Must be
    62         ;               either HLS or HLA
    63         ;Optional input parameter
    64         ;      SUB2 = A second subscript associated with the array
    65         ;
    66         ;Check for required parameters
    67         I "GL"'[$G(ARAYTYPE)!($G(SUB1)']"")!('$G(MTIEN)) G MERGEX
    68         ;
    69         N HLCHAR,HLEVN,HLFS,I,X,X1,X2,X3 S (HLCHAR,HLEVN,X)=0
    70         ;
    71         ; patch HL*1.6*122: MPI-client/server
    72         F  L +^HL(772,+$G(MTIEN)):10 Q:$T  H 1
    73         ;
    74         ;Merge data from a global array with two subscript
    75         I ARAYTYPE="G",$G(SUB2)'="" D
    76         . S X="",I=0
    77         . F  S X=$O(^TMP(SUB1,$J,SUB2,X)) Q:'X  S I=I+1,X1=^TMP(SUB1,$J,SUB2,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1,X2=$D(^TMP(SUB1,$J,SUB2,X)) D
    78         .. I X2=11 S X3="" F  S X3=$O(^TMP(SUB1,$J,SUB2,X,X3)) Q:'X3  D
    79         ... S I=I+1,X1=$G(^TMP(SUB1,$J,SUB2,X,X3)),HLCHAR=HLCHAR+$L(X1),^HL(772,MTIEN,"IN",I,0)=X1
    80         .. S I=I+1,^HL(772,MTIEN,"IN",I,0)="" Q
    81         ;
    82         ;Merge data from a global array with one subscripts
    83         I ARAYTYPE="G",$G(SUB2)="" D
    84         . S X="",I=0
    85         . F  S X=$O(^TMP(SUB1,$J,X)) Q:'X  S I=I+1,X1=^TMP(SUB1,$J,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1,X2=$D(^TMP(SUB1,$J,X)) D
    86         .. I X2=11 S X3="" F  S X3=$O(^TMP(SUB1,$J,X,X3)) Q:'X3  D
    87         ... S I=I+1,X1=$G(^TMP(SUB1,$J,X,X3)),HLCHAR=HLCHAR+$L(X1),^HL(772,MTIEN,"IN",I,0)=X1
    88         .. S I=I+1,^HL(772,MTIEN,"IN",I,0)="" Q
    89         ;
    90         ;Merge data from a local array with one subscript
    91         I ARAYTYPE="L" D
    92         . S X="",I=0
    93         . F  S X=$O(HLA(SUB1,X)) Q:'X  S I=I+1,X1=HLA(SUB1,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1,X2=$D(HLA(SUB1,X)) D
    94         .. I X2=11 S X3="" F  S X3=$O(HLA(SUB1,X,X3)) Q:'X3  D
    95         ... S I=I+1,X1=$G(HLA(SUB1,X,X3)),HLCHAR=HLCHAR+$L(X1),^HL(772,MTIEN,"IN",I,0)=X1
    96         .. S I=I+1,^HL(772,MTIEN,"IN",I,0)="" Q
    97         ;
    98         S:HLEVN=0 HLEVN=1
    99         ;X=ien in file 773 for TCP messages
    100         S X=+$O(^HLMA("B",MTIEN,0))
    101         ;batch message type
    102         I X,$P($G(^HLMA(X,0)),U,5)="B" D BTS
    103         I 'X,$P(^HL(772,MTIEN,0),U,8),$P(^HL(772,$P(^(0),U,8),0),U,14)="B" D BTS
    104         ;
    105         ;-- update 0 node for message text
    106         S ^HL(772,MTIEN,"IN",0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
    107         ;
    108         ; patch HL*1.6*122: MPI-client/server
    109         L -^HL(772,+$G(MTIEN))
    110         ;
    111         ;File message statistics
    112         D STATS^HLTF0(MTIEN,HLCHAR,HLEVN)
    113         ;
    114 MERGEX  ;-- exit merge
    115         Q
    116         ;
    117 BTS     ; create batch trailer seg (BTS)
    118         ;HL*1.6*78 to obtain and insert FIELD SEPARATOR, HLFS
    119         N HLFS,HLSAN
    120         S HLFS=$G(HL("FS")) ; obtain from HL array
    121         ; or obtain from sending application; default to "^"
    122         I HLFS="" D  S:HLFS="" HLFS="^"
    123         . S HLSAN=$P($G(^HL(772,MTIEN,0)),U,2)
    124         . S:HLSAN HLFS=$G(^HL(771,HLSAN,"FS"))
    125         S I=I+1,^HL(772,MTIEN,"IN",I,0)="BTS"_HLFS_HLEVN,I=I+1,^HL(772,MTIEN,"IN",I,0)=""
    126         Q
    127         ;
    128 MRGINT(MTOUT,MTIN,HDR)  ;Merge Internal to Internal Message from the
    129         ; Outbound message in 772 (MTOUT) to an Inbound entry (MTIN). The process
    130         ; will involve Moving the Header and Text into 772.
    131         ;
    132         ;Required input parameters
    133         ;  MTOUT= Internal entry number of the Outbound message
    134         ;  MTIN = Internal entry number of the Inbound  message
    135         ;  HDR  = Name of the array that contains HL7 Header segment
    136         ;         format: HLHDR - Used with indirection to build message in out
    137         ;                         queue
    138         ;  This routine will first take the header information in the array
    139         ;  specified by HDR and merge into the Message Text field of file 870.
    140         ;  Then it will move the message contained in 772 (MTIEN) into 870.
    141         ;
    142         ;Check for required parameters
    143         I '$G(MTOUT)!('$G(MTIN))!(HDR="") Q
    144         ;
    145         ;-- initilize
    146         N I,X
    147         S I=0
    148         ;
    149         ;-- move header into 772 from HDR array
    150         S X="" F  S X=$O(@HDR@(X)) Q:'X  D
    151         . S I=I+1,^HL(772,MTIN,"IN",I,0)=@HDR@(X)
    152         S I=I+1,^HL(772,MTIN,"IN",I,0)=""
    153         ;
    154         ;Move data from Message Text (MTOUT) file TO Message Text 772 (MTIN)
    155         S X=0 F  S X=$O(^HL(772,MTOUT,"IN",X)) Q:X=""  S I=I+1 D
    156         . S ^HL(772,MTIN,"IN",I,0)=$G(^HL(772,MTOUT,"IN",X,0))
    157         ;
    158         ;-- update 0 node of message and format arrays
    159         S ^HL(772,MTIN,"IN",0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
    160         ;
    161         Q
     1HLTF1 ;AISC/SAW/MTC-Process Message Text File Entries (Cont'd) ;09/10/98  11:21
     2 ;;1.6;HEALTH LEVEL SEVEN;**5,8,22,25,19,78**;Oct 13, 1995
     3MERGE15(ARAYTYPE,MTIEN,SUB1,SUB2) ;Merge Local/Global Array From Application into
     4 ;Message Text File
     5 ;
     6 ;This is a routine call with parameter passing.  There are no output
     7 ;parameters returned by this call.
     8 ;
     9 ;**  Merges incoming data for v1.5 applications only **
     10 ;
     11 ;Required input parameters
     12 ;   MTIEN = The IEN from the Message Text file of the entry to be
     13 ;             updated
     14 ;  ARAYTYPE = Array type, G for global or L for local
     15 ;      SUB1 = The first level subscript of the array.  Must be
     16 ;               either HLS or HLA
     17 ;Optional input parameter
     18 ;      SUB2 = A second subscript associated with the array
     19 ;
     20 ;Check for required parameters
     21 I "GL"'[$G(ARAYTYPE)!($G(SUB1)']"")!('$G(MTIEN)) G MRGE15X
     22 ;
     23 N HLCHAR,HLEVN,HLFS,I,X,X1,X2,X3 S (HLCHAR,HLEVN,X)=0
     24 ;
     25 ;Merge data from a global array with two subscript
     26 I ARAYTYPE="G",$G(SUB2)'="" D
     27 . S X="",I=0
     28 . F  S X=$O(^TMP(SUB1,$J,SUB2,X)) Q:'X  S I=I+1,X1=^TMP(SUB1,$J,SUB2,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1
     29 ;
     30 ;Merge data from a global array with one subscripts
     31 I ARAYTYPE="G",$G(SUB2)="" D
     32 . S X="",I=0
     33 . F  S X=$O(^TMP(SUB1,$J,X)) Q:'X  S I=I+1,X1=^TMP(SUB1,$J,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1
     34 ;
     35 ;Merge data from a local array with one subscript
     36 I ARAYTYPE="L" D
     37 . S X="",I=0
     38 . F  S X=$O(HLA(SUB1,X)) Q:'X  S I=I+1,X1=HLA(SUB1,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1
     39 ;
     40 ;-- update 0 node for message text
     41 S ^HL(772,MTIEN,"IN",0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
     42 ;
     43 ;File message statistics
     44 D STATS^HLTF0(MTIEN,HLCHAR,HLEVN)
     45 ;
     46MRGE15X ;-- exit merge
     47 Q
     48 ;
     49MERGE(ARAYTYPE,MTIEN,SUB1,SUB2) ;Merge Local/Global Array From Application into
     50 ;Message Text File
     51 ;
     52 ;This is a routine call with parameter passing.  There are no output
     53 ;parameters returned by this call.
     54 ;
     55 ;Required input parameters
     56 ;   MTIEN = The IEN from the Message Text file of the entry to be
     57 ;             updated
     58 ;  ARAYTYPE = Array type, G for global or L for local
     59 ;      SUB1 = The first level subscript of the array.  Must be
     60 ;               either HLS or HLA
     61 ;Optional input parameter
     62 ;      SUB2 = A second subscript associated with the array
     63 ;
     64 ;Check for required parameters
     65 I "GL"'[$G(ARAYTYPE)!($G(SUB1)']"")!('$G(MTIEN)) G MERGEX
     66 ;
     67 N HLCHAR,HLEVN,HLFS,I,X,X1,X2,X3 S (HLCHAR,HLEVN,X)=0
     68 ;
     69 ;Merge data from a global array with two subscript
     70 I ARAYTYPE="G",$G(SUB2)'="" D
     71 . S X="",I=0
     72 . F  S X=$O(^TMP(SUB1,$J,SUB2,X)) Q:'X  S I=I+1,X1=^TMP(SUB1,$J,SUB2,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1,X2=$D(^TMP(SUB1,$J,SUB2,X)) D
     73 .. I X2=11 S X3="" F  S X3=$O(^TMP(SUB1,$J,SUB2,X,X3)) Q:'X3  D
     74 ... S I=I+1,X1=$G(^TMP(SUB1,$J,SUB2,X,X3)),HLCHAR=HLCHAR+$L(X1),^HL(772,MTIEN,"IN",I,0)=X1
     75 .. S I=I+1,^HL(772,MTIEN,"IN",I,0)="" Q
     76 ;
     77 ;Merge data from a global array with one subscripts
     78 I ARAYTYPE="G",$G(SUB2)="" D
     79 . S X="",I=0
     80 . F  S X=$O(^TMP(SUB1,$J,X)) Q:'X  S I=I+1,X1=^TMP(SUB1,$J,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1,X2=$D(^TMP(SUB1,$J,X)) D
     81 .. I X2=11 S X3="" F  S X3=$O(^TMP(SUB1,$J,X,X3)) Q:'X3  D
     82 ... S I=I+1,X1=$G(^TMP(SUB1,$J,X,X3)),HLCHAR=HLCHAR+$L(X1),^HL(772,MTIEN,"IN",I,0)=X1
     83 .. S I=I+1,^HL(772,MTIEN,"IN",I,0)="" Q
     84 ;
     85 ;Merge data from a local array with one subscript
     86 I ARAYTYPE="L" D
     87 . S X="",I=0
     88 . F  S X=$O(HLA(SUB1,X)) Q:'X  S I=I+1,X1=HLA(SUB1,X),HLCHAR=HLCHAR+$L(X1) S:$E(X1,1,3)="MSH" HLFS=$E(X1,4),$P(X1,HLFS,8)="",HLEVN=HLEVN+1 S ^HL(772,MTIEN,"IN",I,0)=X1,X2=$D(HLA(SUB1,X)) D
     89 .. I X2=11 S X3="" F  S X3=$O(HLA(SUB1,X,X3)) Q:'X3  D
     90 ... S I=I+1,X1=$G(HLA(SUB1,X,X3)),HLCHAR=HLCHAR+$L(X1),^HL(772,MTIEN,"IN",I,0)=X1
     91 .. S I=I+1,^HL(772,MTIEN,"IN",I,0)="" Q
     92 ;
     93 S:HLEVN=0 HLEVN=1
     94 ;X=ien in file 773 for TCP messages
     95 S X=+$O(^HLMA("B",MTIEN,0))
     96 ;batch message type
     97 I X,$P($G(^HLMA(X,0)),U,5)="B" D BTS
     98 I 'X,$P(^HL(772,MTIEN,0),U,8),$P(^HL(772,$P(^(0),U,8),0),U,14)="B" D BTS
     99 ;
     100 ;-- update 0 node for message text
     101 S ^HL(772,MTIEN,"IN",0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
     102 ;
     103 ;File message statistics
     104 D STATS^HLTF0(MTIEN,HLCHAR,HLEVN)
     105 ;
     106MERGEX ;-- exit merge
     107 Q
     108 ;
     109BTS ; create batch trailer seg (BTS)
     110 ;HL*1.6*78 to obtain and insert FIELD SEPARATOR, HLFS
     111 N HLFS,HLSAN
     112 S HLFS=$G(HL("FS")) ; obtain from HL array
     113 ; or obtain from sending application; default to "^"
     114 I HLFS="" D  S:HLFS="" HLFS="^"
     115 . S HLSAN=$P($G(^HL(772,MTIEN,0)),U,2)
     116 . S:HLSAN HLFS=$G(^HL(771,HLSAN,"FS"))
     117 S I=I+1,^HL(772,MTIEN,"IN",I,0)="BTS"_HLFS_HLEVN,I=I+1,^HL(772,MTIEN,"IN",I,0)=""
     118 Q
     119 ;
     120MRGINT(MTOUT,MTIN,HDR) ;Merge Internal to Internal Message from the
     121 ; Outbound message in 772 (MTOUT) to an Inbound entry (MTIN). The process
     122 ; will involve Moving the Header and Text into 772.
     123 ;
     124 ;Required input parameters
     125 ;  MTOUT= Internal entry number of the Outbound message
     126 ;  MTIN = Internal entry number of the Inbound  message
     127 ;  HDR  = Name of the array that contains HL7 Header segment
     128 ;         format: HLHDR - Used with indirection to build message in out
     129 ;                         queue
     130 ;  This routine will first take the header information in the array
     131 ;  specified by HDR and merge into the Message Text field of file 870.
     132 ;  Then it will move the message contained in 772 (MTIEN) into 870.
     133 ;
     134 ;Check for required parameters
     135 I '$G(MTOUT)!('$G(MTIN))!(HDR="") Q
     136 ;
     137 ;-- initilize
     138 N I,X
     139 S I=0
     140 ;
     141 ;-- move header into 772 from HDR array
     142 S X="" F  S X=$O(@HDR@(X)) Q:'X  D
     143 . S I=I+1,^HL(772,MTIN,"IN",I,0)=@HDR@(X)
     144 S I=I+1,^HL(772,MTIN,"IN",I,0)=""
     145 ;
     146 ;Move data from Message Text (MTOUT) file TO Message Text 772 (MTIN)
     147 S X=0 F  S X=$O(^HL(772,MTOUT,"IN",X)) Q:X=""  S I=I+1 D
     148 . S ^HL(772,MTIN,"IN",I,0)=$G(^HL(772,MTOUT,"IN",X,0))
     149 ;
     150 ;-- update 0 node of message and format arrays
     151 S ^HL(772,MTIN,"IN",0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
     152 ;
     153 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLTF2.m

    r613 r623  
    1 HLTF2   ;AISC/SAW/MTC-Process Message Text File Entries (Cont'd) ;10/17/2007  09:44
    2         ;;1.6;HEALTH LEVEL SEVEN;**25,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5 MERGEIN(LLD0,LLD1,MTIEN,HDR,MSA)        ;Merge Data From Communication Server
    6         ;Module Logical Link File into Message Text File
    7         ;
    8         ;This is a subroutine call with parameter passing.  The output
    9         ;parameters HDR (and optionally) MSA are returned by this call.
    10         ;
    11         ;Required input parameters
    12         ;  LLD0 = Internal entry number where message is stored in Logical Link
    13         ;            file or XM if message is stored in MailMan
    14         ;  LLD1 = Internal entry number of IN QUEUE multiple entry in Logical
    15         ;           Link file (Only required for messages stored in Logical
    16         ;           Link file)
    17         ;  MTIEN = Internal entry number where message is to be copied to in
    18         ;            Message Text file
    19         ;    HDR = The variable in which the message header segment will
    20         ;            be returned
    21         ;    MSA = The variable in which the message acknowledgement segment
    22         ;            will be returned, if one exists for this message
    23         ;
    24         ;Check for required parameters
    25         I $G(LLD0)']""!('$G(MTIEN)) Q
    26         I LLD0'="XM",'$G(LLD1) Q
    27         N FLG,HLCHAR,HLEVN,HLFS,I,X,X1,HLDONE
    28         S (FLG,HLCHAR,HLEVN,X)=0
    29         ;
    30         ; patch HL*1.6*122: MPI-client/server
    31         F  L +^HL(772,+$G(MTIEN)):10 Q:$T  H 1
    32         ;
    33         ;Move data from Logical Link file to Message Text file
    34         I LLD0'="XM" D
    35         .S I=0 F  S X=$O(^HLCS(870,LLD0,1,LLD1,1,X)) Q:X'>0  S X1=$G(^(X,0)) S:"FHS,BHS,MSH"[$E(X1,1,3) FLG=1 I FLG S HLCHAR=HLCHAR+$L(X1) D
    36         ..;If header segment, process it and set HDR equal to it
    37         ..I X1'="","FHS,BHS,MSH"[$E(X1,1,3) D
    38         ...I '$D(HDR) S HDR=X1,HLFS=$E(X1,4) I $E(HDR,1,3)="BHS" S MSA="MSA"_HLFS_$P($P(HDR,HLFS,10),$E(HDR,5),1)_HLFS_$P(HDR,HLFS,12)_HLFS_$P($P(HDR,HLFS,10),$E(HDR,5),2)
    39         ...S $P(X1,HLFS,8)=""
    40         ...S:$E(X1,1,3)="MSH" HLEVN=HLEVN+1
    41         ..;If acknowledgement segment, set MSA equal to it
    42         ..I $E(X1,1,3)="MSA",'$D(MSA),$E($G(HDR),1,3)="MSH" S MSA=X1
    43         ..S I=I+1,^HL(772,MTIEN,"IN",I,0)=X1
    44         ;
    45         ;Move data from MailMan Message file to Message Text file
    46         I LLD0="XM" D
    47         .S I=0 F  X XMREC Q:XMER<0  S:"FHS,BHS,MSH"[$E(XMRG,1,3) FLG=1 I FLG S HLCHAR=HLCHAR+$L(XMRG) D  Q:XMER<0
    48         ..;If header segment, process it and set HDR equal to it
    49         ..I XMRG'="","FHS,BHS,MSH"[$E(XMRG,1,3) D
    50         ...I '$D(HDR) S HDR=XMRG,HLFS=$E(XMRG,4) I $E(HDR,1,3)="BHS" S MSA="MSA"_HLFS_$P($P(HDR,HLFS,10),$E(HDR,5),1)_HLFS_$P(HDR,HLFS,12)_HLFS_$P($P(HDR,HLFS,10),$E(HDR,5),2)
    51         ...S $P(XMRG,HLFS,8)=""
    52         ...S:$E(XMRG,1,3)="MSH" HLEVN=HLEVN+1
    53         ..;If acknowledgement segment, set MSA equal to it
    54         ..I $E(XMRG,1,3)="MSA",'$D(MSA),$E($G(HDR),1,3)="MSH" S MSA=XMRG
    55         ..S I=I+1,^HL(772,MTIEN,"IN",I,0)=XMRG
    56         S ^HL(772,MTIEN,"IN",0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
    57         ;Update statistics in Message Text file for this entry
    58         ;
    59         ; patch HL*1.6*122: MPI-client/server
    60         L -^HL(772,+$G(MTIEN))
    61         ;
    62         D STATS^HLTF0(MTIEN,HLCHAR,HLEVN)
    63         Q
    64 MERGEOUT(MTIEN,LLD0,LLD1,HDR)   ;Merge Text in Message Text File into
    65         ;Communication Server Module Logical Link File
    66         ;
    67         ;This is a routine call with parameter passing.  There are no output
    68         ;parameters returned by this call.
    69         ;
    70         ;Required input parameters
    71         ;  MTIEN = Internal entry number where message is stored in Message
    72         ;            Text file
    73         ;  LLD0 = Internal entry number where message is to be copied to in
    74         ;            Logical Link file
    75         ;  LLD1 = Internal entry number of IN QUEUE multiple entry in Logical
    76         ;          Link file
    77         ;  HDR  = Name of the array that contains HL7 Header segment
    78         ;         format: HLHDR - Used with indirection to build message in out
    79         ;                         queue
    80         ;  This routine will first take the header information in the array
    81         ;  specified by HDR and merge into the Message Text field of file 870.
    82         ;  Then it will move the message contained in 772 (MTIEN) into 870.
    83         ;
    84         ;Check for required parameters
    85         I '$G(MTIEN)!('$G(LLD0))!('$G(LLD1))!(HDR="") Q
    86         ;
    87         ;-- initilize
    88         N I,X
    89         S I=0
    90         ;
    91         ; patch HL*1.6*122: MPI-client/server
    92         F  L +^HLCS(870,+$G(LLD0),2,+$G(LLD1)):10 Q:$T  H 1
    93         ;
    94         ;-- move header into 870 from HDR array
    95         S X="" F  S X=$O(@HDR@(X)) Q:'X  D
    96         . S I=I+1,^HLCS(870,LLD0,2,LLD1,1,I,0)=@HDR@(X)
    97         S I=I+1,^HLCS(870,LLD0,2,LLD1,1,I,0)=""
    98         ;
    99         ;Move data from Message Text file to Logical Link file
    100         S X=0 F  S X=$O(^HL(772,MTIEN,"IN",X)) Q:X=""  D
    101         . S I=I+1,^HLCS(870,LLD0,2,LLD1,1,I,0)=$G(^HL(772,MTIEN,"IN",X,0))
    102         ;
    103         ;-- update 0 node of message and format arrays
    104         S ^HLCS(870,LLD0,2,LLD1,1,0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
    105         ;
    106         ; patch HL*1.6*122: MPI-client/server
    107         L -^HLCS(870,+$G(LLD0),2,+$G(LLD1))
    108         ;
    109         Q
    110 OUT(HLDA,HLMID,HLMTN)   ;File Data in Message Text File for Outgoing Message
    111         ;Version 1.5 Interface Only
    112         ;
    113         ; patch HL*1.6*122: HLTF routine splitted, moves sub-routines,
    114         ; OUT, IN, and ACK to HLTF2 routine.
    115         ;
    116         Q:'$D(HLFS)
    117         ;
    118         I HLMTN="ACK"!(HLMTN="MCF")!(HLMTN="ORR") Q:'$D(HLMSA)  D ACK(HLMSA,"I") Q
    119         ;
    120         ;-- if message contained MSA find inbound message
    121         I $D(HLMSA),$D(HLNDAP),$P(HLMSA,HLFS,3)]"" D
    122         . N HLDAI
    123         . S HLDAI=0
    124         . F  S HLDAI=$O(^HL(772,"AH",+$P($G(HLNDAP0),U,12),$P(HLMSA,HLFS,3),HLDAI)) Q:'HLDAI!($P($G(^HL(772,+HLDAI,0)),U,4)="I")
    125         . I 'HLDAI K HLDAI
    126         ;
    127         D STUFF^HLTF0("O")
    128         ;
    129         N HLAC S HLAC=$S($D(HLERR):4,'$P(HLNDAP0,"^",10):1,1:2) D STATUS^HLTF0(HLDA,HLAC,$G(HLMSG))
    130         D:$D(HLCHAR) STATS^HLTF0(HLDA,HLCHAR,$G(HLEVN))
    131         ;
    132         ;-- update status if MSA and found inbound message
    133         I $D(HLMSA),$D(HLDAI) D
    134         .N HLERR,HLMSG I $P(HLMSA,HLFS,4)]"" S HLERR=$P(HLMSA,HLFS,4)
    135         .S HLAC=$P(HLMSA,HLFS,2)
    136         .I HLAC'="AA" S HLMSG=$S(HLAC="AR":"Application Reject",HLAC="AE":"Application Error",1:"")_" - "_HLERR
    137         .S HLAC=$S(HLAC'="AA":4,1:3) D STATUS^HLTF0(HLDAI,HLAC,$G(HLMSG))
    138         Q
    139         ;
    140 IN(HLMTN,HLMID,HLTIME)  ;File Data in Message Text File for Incoming Message
    141         ;Version 1.5 Interface Only
    142         ;
    143         ; patch HL*1.6*122: HLTF routine splitted, moves sub-routines,
    144         ; OUT, IN, and ACK to HLTF2 routine.
    145         ;
    146         Q:'$D(HLFS)
    147         I HLMTN="ACK"!(HLMTN="MCF")!(HLMTN="ORR") Q:'$D(HLMSA)  D ACK(HLMSA,"O",$G(HLDA)) Q
    148         ;
    149         N HLDAI S HLDA=0
    150         I $D(HLNDAP),HLMID]"" D
    151         .F  S HLDA=+$O(^HL(772,"AH",+$P($G(HLNDAP0),U,12),HLMID,HLDA)) Q:'HLDA!($P($G(^HL(772,+HLDA,0)),U,4)="I")
    152         .I HLDA D
    153         ..S HLDT=+$P($G(^HL(772,HLDA,0)),"^"),HLDT1=$$HLDATE^HLFNC(HLDT)
    154         ..K ^HL(772,HLDA,"IN")
    155         .I $D(HLMSA),$P(HLMSA,HLFS,3)]"" D
    156         ..S HLDAI=0
    157         ..F  S HLDAI=$O(^HL(772,"AH",+$P($G(HLNDAP0),U,12),$P(HLMSA,HLFS,3),HLDAI)) Q:'HLDAI!($P($G(^HL(772,+HLDAI,0)),U,4)="O")
    158         ..I 'HLDAI K HLDAI
    159         ;
    160         ; patch HL*1.6*122: MPI-client/server
    161         ; I 'HLDA D CREATE(.HLMID,.HLDA,.HLDT,.HLDT1) K HLZ
    162         I 'HLDA D CREATE^HLTF(.HLMID,.HLDA,.HLDT,.HLDT1) K HLZ
    163         ;
    164         D STUFF^HLTF0("I")
    165         N HLAC S HLAC=$S($D(HLERR):4,1:1) D STATUS^HLTF0(HLDA,HLAC,$G(HLMSG))
    166         ;
    167         D MERGE15^HLTF1("G",HLDA,"HLR",HLTIME)
    168         ;
    169         I '$D(HLERR),$D(HLMSA),$D(HLDAI) D
    170         .N HLAC,HLERR,HLMSG I $P(HLMSA,HLFS,4)]"" S HLERR=$P(HLMSA,HLFS,4)
    171         .S HLAC=$P(HLMSA,HLFS,2) I HLAC'="AA" S HLMSG=$S(HLAC="AR":"Application Reject",1:"Application Error")_" - "_HLERR
    172         .S HLAC=$S(HLAC'="AA":4,1:3) D STATUS^HLTF0(HLDAI,HLAC,$G(HLMSG))
    173         Q
    174         ;
    175 ACK(HLMSA,HLIO,HLDA)    ;Process 'ACK' Message Type - Version 1.5 Interface Only
    176         ;
    177         ; patch HL*1.6*122: HLTF routine splitted, moves sub-routines,
    178         ; OUT, IN, and ACK to HLTF2 routine.
    179         ;
    180         ; To determine the correct message to link the ACK, HLIO is used.
    181         ; For an ack from DHCP (original message from remote system) then
    182         ; HLIO should be "I" so that the correct inbound message is ack-ed. For
    183         ; an inbound ack (original message outbound from DHCP) HLIO should be
    184         ; "O". This distinction must be made due to the possible duplicate
    185         ; message ids from a bi-direction interface.
    186         ;
    187         ; Input : MSA - MSA from ACK message.
    188         ;         HLIO - Either "I" or "O" : See note above.
    189         ;Output : None
    190         ;
    191         N HLAC,HLMIDI
    192         ;-- set up required vars
    193         S HLAC=$P(HLMSA,HLFS,2),HLMIDI=$P(HLMSA,HLFS,3)
    194         ;-- quit
    195         Q:HLMIDI']""!(HLAC']"")!('$D(HLNDAP))
    196         ;-- find message to ack
    197         I '$G(HLDA) S HLDA=0 D
    198         . F  S HLDA=+$O(^HL(772,"AH",+$P($G(HLNDAP0),U,12),HLMIDI,HLDA)) Q:'HLDA!($P($G(^HL(772,+HLDA,0)),U,4)=HLIO)
    199         ;-- quit if no message
    200         Q:'$D(^HL(772,+HLDA,0))
    201         ;-- check for error
    202         I $P(HLMSA,HLFS,4)]"" N HLERR S HLERR=$P(HLMSA,HLFS,4)
    203         I $D(HLERR),'$D(HLMSG) N HLMSG S HLMSG="Error During Receipt of Acknowledgement Message"_$S(HLAC="AR":" - Application Reject",HLAC="AE":" - Application Error",1:"")_" - "_HLERR
    204         ;-- update status
    205         S HLAC=$S(HLMTN="MCF":2,HLAC'="AA":4,1:3)
    206         D STATUS^HLTF0(HLDA,HLAC,$G(HLMSG))
    207         Q
    208         ;
     1HLTF2 ;AISC/SAW/MTC-Process Message Text File Entries (Cont'd) ;02/24/97  13:56
     2 ;;1.6;HEALTH LEVEL SEVEN;**25**;Oct 13, 1995
     3MERGEIN(LLD0,LLD1,MTIEN,HDR,MSA) ;Merge Data From Communication Server
     4 ;Module Logical Link File into Message Text File
     5 ;
     6 ;This is a subroutine call with parameter passing.  The output
     7 ;parameters HDR (and optionally) MSA are returned by this call.
     8 ;
     9 ;Required input parameters
     10 ;  LLD0 = Internal entry number where message is stored in Logical Link
     11 ;            file or XM if message is stored in MailMan
     12 ;  LLD1 = Internal entry number of IN QUEUE multiple entry in Logical
     13 ;           Link file (Only required for messages stored in Logical
     14 ;           Link file)
     15 ;  MTIEN = Internal entry number where message is to be copied to in
     16 ;            Message Text file
     17 ;    HDR = The variable in which the message header segment will
     18 ;            be returned
     19 ;    MSA = The variable in which the message acknowledgement segment
     20 ;            will be returned, if one exists for this message
     21 ;
     22 ;Check for required parameters
     23 I $G(LLD0)']""!('$G(MTIEN)) Q
     24 I LLD0'="XM",'$G(LLD1) Q
     25 N FLG,HLCHAR,HLEVN,HLFS,I,X,X1,HLDONE
     26 S (FLG,HLCHAR,HLEVN,X)=0
     27 ;
     28 ;Move data from Logical Link file to Message Text file
     29 I LLD0'="XM" D
     30 .S I=0 F  S X=$O(^HLCS(870,LLD0,1,LLD1,1,X)) Q:X'>0  S X1=$G(^(X,0)) S:"FHS,BHS,MSH"[$E(X1,1,3) FLG=1 I FLG S HLCHAR=HLCHAR+$L(X1) D
     31 ..;If header segment, process it and set HDR equal to it
     32 ..I X1'="","FHS,BHS,MSH"[$E(X1,1,3) D
     33 ...I '$D(HDR) S HDR=X1,HLFS=$E(X1,4) I $E(HDR,1,3)="BHS" S MSA="MSA"_HLFS_$P($P(HDR,HLFS,10),$E(HDR,5),1)_HLFS_$P(HDR,HLFS,12)_HLFS_$P($P(HDR,HLFS,10),$E(HDR,5),2)
     34 ...S $P(X1,HLFS,8)=""
     35 ...S:$E(X1,1,3)="MSH" HLEVN=HLEVN+1
     36 ..;If acknowledgement segment, set MSA equal to it
     37 ..I $E(X1,1,3)="MSA",'$D(MSA),$E($G(HDR),1,3)="MSH" S MSA=X1
     38 ..S I=I+1,^HL(772,MTIEN,"IN",I,0)=X1
     39 ;
     40 ;Move data from MailMan Message file to Message Text file
     41 I LLD0="XM" D
     42 .S I=0 F  X XMREC Q:XMER<0  S:"FHS,BHS,MSH"[$E(XMRG,1,3) FLG=1 I FLG S HLCHAR=HLCHAR+$L(XMRG) D  Q:XMER<0
     43 ..;If header segment, process it and set HDR equal to it
     44 ..I XMRG'="","FHS,BHS,MSH"[$E(XMRG,1,3) D
     45 ...I '$D(HDR) S HDR=XMRG,HLFS=$E(XMRG,4) I $E(HDR,1,3)="BHS" S MSA="MSA"_HLFS_$P($P(HDR,HLFS,10),$E(HDR,5),1)_HLFS_$P(HDR,HLFS,12)_HLFS_$P($P(HDR,HLFS,10),$E(HDR,5),2)
     46 ...S $P(XMRG,HLFS,8)=""
     47 ...S:$E(XMRG,1,3)="MSH" HLEVN=HLEVN+1
     48 ..;If acknowledgement segment, set MSA equal to it
     49 ..I $E(XMRG,1,3)="MSA",'$D(MSA),$E($G(HDR),1,3)="MSH" S MSA=XMRG
     50 ..S I=I+1,^HL(772,MTIEN,"IN",I,0)=XMRG
     51 S ^HL(772,MTIEN,"IN",0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
     52 ;Update statistics in Message Text file for this entry
     53 D STATS^HLTF0(MTIEN,HLCHAR,HLEVN)
     54 Q
     55MERGEOUT(MTIEN,LLD0,LLD1,HDR) ;Merge Text in Message Text File into
     56 ;Communication Server Module Logical Link File
     57 ;
     58 ;This is a routine call with parameter passing.  There are no output
     59 ;parameters returned by this call.
     60 ;
     61 ;Required input parameters
     62 ;  MTIEN = Internal entry number where message is stored in Message
     63 ;            Text file
     64 ;  LLD0 = Internal entry number where message is to be copied to in
     65 ;            Logical Link file
     66 ;  LLD1 = Internal entry number of IN QUEUE multiple entry in Logical
     67 ;          Link file
     68 ;  HDR  = Name of the array that contains HL7 Header segment
     69 ;         format: HLHDR - Used with indirection to build message in out
     70 ;                         queue
     71 ;  This routine will first take the header information in the array
     72 ;  specified by HDR and merge into the Message Text field of file 870.
     73 ;  Then it will move the message contained in 772 (MTIEN) into 870.
     74 ;
     75 ;Check for required parameters
     76 I '$G(MTIEN)!('$G(LLD0))!('$G(LLD1))!(HDR="") Q
     77 ;
     78 ;-- initilize
     79 N I,X
     80 S I=0
     81 ;
     82 ;-- move header into 870 from HDR array
     83 S X="" F  S X=$O(@HDR@(X)) Q:'X  D
     84 . S I=I+1,^HLCS(870,LLD0,2,LLD1,1,I,0)=@HDR@(X)
     85 S I=I+1,^HLCS(870,LLD0,2,LLD1,1,I,0)=""
     86 ;
     87 ;Move data from Message Text file to Logical Link file
     88 S X=0 F  S X=$O(^HL(772,MTIEN,"IN",X)) Q:X=""  D
     89 . S I=I+1,^HLCS(870,LLD0,2,LLD1,1,I,0)=$G(^HL(772,MTIEN,"IN",X,0))
     90 ;
     91 ;-- update 0 node of message and format arrays
     92 S ^HLCS(870,LLD0,2,LLD1,1,0)="^^"_I_"^"_I_"^"_$$DT^XLFDT_"^"
     93 ;
     94 Q
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLTP3.m

    r613 r623  
    1 HLTP3   ;SFIRMFO/RSD - Transaction Processor for TCP ;03/17/2008  11:26
    2         ;;1.6;HEALTH LEVEL SEVEN;**19,43,57,58,59,66,69,109,115,108,116,117,125,120,133,122,140**;Oct 13, 1995;Build 5
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         Q
    6 NEW(X)  ;process new msg. ien in 773^ien in 772
    7         ;HLMTIENS=ien in #773; HLMTIEN=ien in #772
    8         ;HLHDRO=original header;  HLHDR=response header
    9         ;set error trap
    10         N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLTP3"
    11         N HL,HLEID,HLEIDS,HLERR,HLHDR,HLHDRO,HLMTIEN,HLMTIENS,HLJ,HLMSA,HLQUIT,HLNODE,HLNEXT,HLRESLTA,HLDONE1,HLASTRSP,HLRESLT
    12         S HLRESLT=""
    13         D INIT^HLTP3A
    14         ;error with header, return commit/app reject
    15         I $G(HLRESLT) D  Q
    16         . ;set status & unlock record
    17         . D STATUS^HLTF0(HLMTIENS,4,,,1),EXIT
    18         . ;quit if no commit or app ack
    19         . I $G(HL("ACAT"))="NE",$G(HL("APAT"))="NE" Q
    20         . S X=$S($G(HL("ACAT"))="AL":"CR",1:"AR")
    21         . ;HLTCP=ien of acknowledgment msg. from ACK^HLTP4
    22         . D ACK^HLTP4(X,$P(HLRESLT,U,2)) Q:'$G(HLTCP)
    23         . ;write ack back
    24         . S X=$$WRITE^HLCSTCP2(HLTCP)
    25         . ;update counter to sent
    26         . D LLCNT^HLCSTCP(HLDP,4)
    27         . ;update status of ack
    28         . D STATUS^HLTF0(HLTCP,3,,,1)
    29         ;
    30         ;check for duplicate msg., use rec. app and msg. id x-ref
    31         ; patch HL*1.6*120
    32         I $G(HL("MID"))]"",$G(HL("RAP")) S X=$O(^HLMA("AH",HL("RAP"),HL("MID"),0)) D  Q:'$D(HLMTIENS)
    33         . ;HLASTMSG=last ien received during this connection
    34         . ;if no duplicate, save msg. ien and quit
    35         . I X=HLMTIENS!'X S HLASTMSG=HLMTIENS Q
    36         . N MSH,OIENS
    37         . S (OIENS,Y)=X D  S Y=HLMTIENS D
    38         .. ;combine MSH into single string
    39         .. S MSH(Y)="",I=0 F  S I=$O(^HLMA(Y,"MSH",I)) Q:'I  S MSH(Y)=MSH(Y)_$G(^(I,0))
    40         .; patch 117 & 125, check if identical
    41         .I MSH(HLMTIENS)'=MSH(OIENS) S HLASTMSG=HLMTIENS Q
    42         .;
    43         . ;msg is duplicate, set status
    44         . D STATUS^HLTF0(HLMTIENS,4,109,"Duplicate with ien "_OIENS,1),EXIT
    45         . ;msg was resent, ignore it.
    46         . I HLASTMSG=HLMTIENS K HLMTIENS Q
    47         . ;find original response and send back
    48         . S HLASTRSP=$O(^HLMA("AF",OIENS,OIENS))
    49         ;
    50         ;Quit if this is ack to ack
    51         I $G(HL("ACK")) D  Q
    52         . ;Update status of original ack message
    53         . D STATUS^HLTF0(HL("MTIENS"),3,,,1),STATUS^HLTF0(HLMTIENS,3,,,1)
    54         . ;unlock record
    55         . D EXIT
    56         ;
    57         ;enhance ack., send commit, quit if not an ack, msg will be processed by filer
    58         I $G(HL("ACAT"))="AL" D  Q:'$G(HL("MTIENS"))
    59         . ;msg is a resend, HLASTRSP=ien of original response
    60         .I $G(HLASTRSP) D
    61         ..S HLTCP=HLASTRSP
    62         ..D LLCNT^HLCSTCP(HLDP,3)
    63         . E  D  Q:'$G(HLTCP)
    64         ..D ACK^HLTP4("CA") ;**109** LLCNT^HLCSTCP(HLDP,3) called in ACK^HLTP4
    65         . S X=$$WRITE^HLCSTCP2(HLTCP)
    66         . D LLCNT^HLCSTCP(HLDP,4),STATUS^HLTF0(HLTCP,3,,,1):'$G(HLASTRSP)
    67         . S HLTCP=""
    68         . ;if not an ack, set status to awaiting processing **109** and put on in queue
    69         . I '$G(HL("MTIENS")),'$G(HLASTRSP) D STATUS^HLTF0(HLMTIENS,9),EXIT,SETINQUE^HLTP31
    70         ;
    71         ;enhance ack., no commit & no app ack
    72         I $G(HL("ACAT"))="NE",$G(HL("APAT"))="NE" D  Q
    73         . ;set status to awaiting processing, **109** and put on in queue
    74         . I '$G(HLASTRSP) D STATUS^HLTF0(HLMTIENS,9),EXIT,SETINQUE^HLTP31
    75         ;
    76         ; patch HL*1.6*120 start
    77         ;resending old response, msg is a resend
    78         ; do not re-send duplicate when $G(HL("ACAT"))="AL"
    79         I $G(HLASTRSP),$G(HL("ACAT"))'="AL" S HLTCP=HLASTRSP G ACK
    80         ; quit if duplicate
    81         Q:$G(HLASTRSP)
    82         ; patch HL*1.6*120 end
    83         ;
    84 CONT    ;continue processing an enhance ack msg. called from DEFACK
    85         ;Set special HL variables for processing rtn
    86         S HLQUIT=0,HLNODE="",HLNEXT="D HLNEXT^HLCSUTL"
    87         ;
    88         ; message is an acknowledgement, HLMSA=ack code^id^text
    89         I ($G(HLMSA)]"") D  Q
    90         . ;X=1 if ack ok, 0=reject of error
    91         . S X=$E(HLMSA,2)="A"
    92         . ;Update status of original message and remove it from the queue
    93         . D STATUS^HLTF0(HL("MTIENS"),$S(X:3,1:4),"",$S(X:"",1:$P(HLMSA,HL("FS"),3)),1)
    94         . D DEQUE^HLCSREP($P($G(^HLMA(HL("MTIENS"),0)),"^",7),"O",HL("MTIENS"))
    95         . D
    96         .. N HLTCP ;variable to update status in file #772.
    97         ..;
    98         ..;**108**
    99         .. N TEMP
    100         .. S TEMP=HLMTIENS
    101         .. N HLMTIENS
    102         .. S HLMTIENS=TEMP
    103         ..;**END 108**
    104         ..;
    105         .. D PROCACK^HLTP2(HLMTIEN,HL("EID"),.HLRESLT,.HL)
    106         . ;update status of incoming & unlock
    107         . D STATUS^HLTF0(HLMTIENS,$S($G(HLRESLT):4,1:3),$S($G(HLRESLT):+$G(HLRESLT),1:""),$S($G(HLRESLT):$P(HLRESLT,U,2),1:""),1),EXIT
    108         ;
    109         ;get entry action, exit action and processing routine
    110         K HLHDR,HLLD0,HLLD1,HLMSA
    111         I HL("EIDS")="",$G(HLEIDS)]"" S HL("EIDS")=HLEIDS ;**CIRN**
    112         D EVENT^HLUTIL1(HL("EIDS"),"15,20,771",.HLN)
    113         S HLENROU=$G(HLN(20)),HLEXROU=$G(HLN(15)),HLPROU=$G(HLN(771))
    114         ;quit if no processing routine,update status and quit
    115         I HLPROU']"" S HLRESLT="10^"_$G(^HL(771.7,10,0)) D STATUS^HLTF0(HLMTIENS,3,,,1),EXIT Q
    116         ;HLORNOD=subscriber protocol for Fileman auditing, ien;global ref
    117         N HLORNODD S HLORNOD=HL("EIDS")_";ORD(101,"
    118         ;Execute entry action of client protocol
    119         X:HLENROU]"" HLENROU K HLENROU,HLDONE1
    120         ;
    121         ;Execute processing routine
    122         X HLPROU S HLRESLT=0 S:($D(HLERR)) HLRESLT="9^"_HLERR
    123         ;update status of incoming to complete & unlock
    124         D STATUS^HLTF0(HLMTIENS,$S(HLRESLT:4,1:3),$S(HLRESLT:+HLRESLT,1:""),$S(HLRESLT:$P(HLRESLT,U,2),1:""),1,$S($G(HLERR("SKIP_EVENT"))=1:1,1:0)),EXIT
    125         ;HLTCPO=link open, HLTCP=ien of ack msg. from GENACK
    126 ACK     I $G(HLTCPO),$G(HLTCP) D  Q
    127         . D LLCNT^HLCSTCP(HLDP,3)
    128         . ;write ack back over open tcp link
    129         . S X=$$WRITE^HLCSTCP2(HLTCP)
    130         . ;update status of ack to complete
    131         . D:'$G(HLASTRSP) STATUS^HLTF0(HLTCP,3,,,1)
    132         . D LLCNT^HLCSTCP(HLDP,4)
    133         Q
    134         ;
    135 DEFACK(HLDP,X)  ;process the deferred application ack, called from HLCSIN
    136         ;HLDP=logical link, X=ien in file 773
    137         ;
    138         ; patch HL*1.6*120 start
    139         ; clean non-Kernel variables
    140         D
    141         . ; protect variables defined in STARTIN^HLCSIN
    142         . N HLFLG,HLEXIT,HLPTRFLR
    143         . ; protect variables defined in DEFACK^HLCSIN
    144         . N HLXX,HLD0,HLPCT
    145         . ; protect input parameters of this sub-routine
    146         . N HLDP,X
    147         . D KILL^XUSCLEAN
    148         ; patch HL*1.6*120 end
    149         ;
    150         ;set error trap
    151         N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLTP3"
    152         N HLERR     ;patch HL*1.6*109
    153         Q:'$G(HLDP)!'$G(X)  Q:'$G(^HLMA(X,0))
    154         Q:'$D(^HLMA("AC","I",HLDP,X))
    155         ;
    156         N HL,HLA,HLD0,HLEID,HLEIDS,HLHDR,HLHDRO,HLMTIEN,HLMTIENS,HLJ,HLMSA,HLN,HLQUIT,HLNODE,HLNEXT,HLRESLT,HLRESLTA,HLTCP,HLXX,Z,HLDONE1
    157         S HLMTIENS=X,X=^HLMA(HLMTIENS,0),HLMTIEN=+$P(X,U),HL("MID")=$P(X,U,2),HL("MTIENS")=$P(X,U,10),HL("LL")=$P(X,U,7),HLTCP="",HL("Q")=""""""
    158         S HL("EIDS")=$P(X,U,8),HL("SAP")=$P(X,U,11),HL("RAP")=$P(X,U,12),HL("MTP")=$P(X,U,13),HL("ETP")=$P(X,U,14)
    159         S:$P(X,U,15) HL("MTP_ETP")=$P(X,U,15)
    160         S:HL("SAP") HL("SAN")=$P($G(^HL(771,HL("SAP"),0)),U) S:HL("RAP") HL("RAN")=$P($G(^HL(771,HL("RAP"),0)),U)
    161         S:HL("MTP") HL("MTN")=$P($G(^HL(771.2,HL("MTP"),0)),U) S:HL("ETP") HL("ETN")=$P($G(^HL(779.001,HL("ETP"),0)),U)
    162         S:$G(HL("MTP_ETP")) HL("MTN_ETN")=$P($G(^HL(779.005,HL("MTP_ETP"),0)),U)
    163         S HL("EID")=$P($G(^HL(772,HLMTIEN,0)),U,10)
    164         M HLHDRO=^HLMA(HLMTIENS,"MSH")
    165         ; if no header quit
    166         Q:'$O(HLHDRO(0))
    167         ;
    168         S HL("FS")=$E(HLHDRO(1,0),4),HL("ECH")=$$P^HLTPCK2(.HLHDRO,2),HL("SFN")=$$P^HLTPCK2(.HLHDRO,4),HL("RFN")=$$P^HLTPCK2(.HLHDRO,6),HL("DTM")=$$P^HLTPCK2(.HLHDRO,7)
    169         ;
    170         ; quit if ien of #772 is not defined
    171         Q:'HLMTIEN
    172         ; quit if field separator is not defined
    173         Q:HL("FS")=""
    174         ;
    175         S X=$$P^HLTPCK2(.HLHDRO,1)
    176         ;
    177         ; patch HL*1.6*120 start
    178         I X="MSH" D
    179         . S HL("PID")=$$P^HLTPCK2(.HLHDRO,11),HL("VER")=$$P^HLTPCK2(.HLHDRO,12),HL("APAT")=$$P^HLTPCK2(.HLHDRO,16),HL("CC")=$$P^HLTPCK2(.HLHDRO,17)
    180         . ;
    181         . ; 2nd component is Processing mode
    182         . S HL("PMOD")=$P(HL("PID"),$E(HL("ECH"),1),2)
    183         . ; first component is Processing id
    184         . S HL("PID")=$P(HL("PID"),$E(HL("ECH"),1))
    185         ;
    186         I X'="MSH" D
    187         . S X=$$P^HLTPCK2(.HLHDRO,9),Z=$E(HL("ECH")),HL("PID")=$P(X,Z,2),HL("VER")=$P(X,Z,4)
    188         . ;
    189         . ; original code incorrectly treats repetition separator as
    190         . ; subcomponent separator
    191         . I $E(HL("ECH"),2)]"",X[$E(HL("ECH"),2) D
    192         .. S HL("SUB-COMPONENT")=$E(HL("ECH"),2)
    193         . ; if subcomponent separator is correctly applied
    194         . I $E(HL("ECH"),4)]"",X[$E(HL("ECH"),4) D
    195         .. S HL("SUB-COMPONENT")=$E(HL("ECH"),4)
    196         . ;
    197         . I $D(HL("SUB-COMPONENT")),HL("PID")[HL("SUB-COMPONENT") D
    198         .. ; 2nd sub-component is Processing mode
    199         .. S HL("PMOD")=$P(HL("PID"),HL("SUB-COMPONENT"),2)
    200         .. ; first sub-component is Processing id
    201         .. S HL("PID")=$P(HL("PID"),HL("SUB-COMPONENT"))
    202         . ; patch HL*1.6*120 end
    203         . ;
    204         . Q:$$P^HLTPCK2(.HLHDRO,10)=""
    205         . ;HLMSA=ack code^id^text
    206         . S HLMSA=$P($$P^HLTPCK2(.HLHDRO,10),$E(HL("ECH")),1),$P(HLMSA,HL("FS"),2)=$$P^HLTPCK2(.HLHDRO,12),$P(HLMSA,HL("FS"),3)=$P($$P^HLTPCK2(.HLHDRO,10),$E(HL("ECH")),2),HL("MSAID")=$P(HLMSA,HL("FS"),2)
    207         ;
    208         ; quit if this is a commit ack
    209         I $P($G(^HL(772,HLMTIEN,"IN",1,0)),HL("FS"),1)="MSA",$E($P($G(^HL(772,HLMTIEN,"IN",1,0)),HL("FS"),2))="C" Q
    210         ;
    211         ;**  HL*1.6*117 **
    212         K HLL("SET FOR APP ACK"),HLL("LINKS")
    213         ;
    214         D CONT
    215         Q
    216         ;
    217 MSA(Y)  ;Y=ien in 772, returns MSA segment
    218         ;ack code^msg being ack id^text
    219         ; patch HL*1.6*122
    220         ; for HL7 v2.5 and beyond with MSA as 3rd segment
    221         N X,SUBIEN,DATA,DONE
    222         S X=$G(^HL(772,Y,"IN",1,0)),X=$S($E(X,1,3)="MSA":$E(X,5,999),1:"")
    223         Q:X]"" X
    224         ;
    225         S DONE=0
    226         S SUBIEN=1
    227         F  S SUBIEN=$O(^HL(772,Y,"IN",SUBIEN)) Q:'SUBIEN  D  Q:DONE
    228         . S DATA=$G(^HL(772,Y,"IN",SUBIEN,0)) I DATA="" D
    229         .. S DONE=1
    230         .. S SUBIEN=$O(^HL(772,Y,"IN",SUBIEN)) Q:'SUBIEN
    231         .. S X=$G(^HL(772,Y,"IN",SUBIEN,0)),X=$S($E(X,1,3)="MSA":$E(X,5,999),1:"")
    232         ; patch HL*1.6*122 end
    233         ;
    234         Q X
    235         ;
    236 ERROR   ;error trap
    237         D ^%ZTER
    238         I $G(HLMTIENS),$D(^HLMA(HLMTIENS,0)) D STATUS^HLTF0(HLMTIENS,4,,,1),EXIT
    239         ; release locks created by inbound filer
    240         ; patch HL*1.6*140
    241         ; L -^HLMA("AC","I",+$G(HLXX))
    242         L -^HLMA("IN-FILER","AC","I",+$G(HLXX))
    243         G UNWIND^%ZTER
    244         ;
    245         ;
    246 EXIT    ;unlock
    247         I $G(HLMTIENS) L -^HLMA(HLMTIENS)
    248         Q
    249         ;
    250 ONAC(IEN773)    ;
    251         ;Returns 1 if the message is on the "AC","I" xref
    252         ;Returns 0 otherwise
    253         ;
    254         N LINK
    255         S LINK=$P($G(^HLMA(IEN773,0)),"^",17)
    256         Q:'LINK 0
    257         Q $D(^HLMA("AC","I",LINK,IEN773))
     1HLTP3 ;SFIRMFO/RSD - Transaction Processor for TCP ;09/13/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**19,43,57,58,59,66,69,109,115,108,116,117,125,120,133**;Oct 13, 1995;Build 13
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 Q
     6NEW(X) ;process new msg. ien in 773^msg. ien in 772
     7 ;HLMTIENS=ien in #773, msg header; HLMTIEN=ien in #772, msg text
     8 ;HLHDRO=original header;  HLHDR=response header
     9 ;set error trap
     10 N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLTP3"
     11 N HL,HLEID,HLEIDS,HLERR,HLHDR,HLHDRO,HLMTIEN,HLMTIENS,HLJ,HLMSA,HLQUIT,HLNODE,HLNEXT,HLRESLTA,HLDONE1,HLASTRSP,HLRESLT
     12 S HLRESLT=""
     13 D INIT^HLTP3A
     14 ;error with header, return commit/app reject
     15 I $G(HLRESLT) D  Q
     16 . ;set status & unlock record
     17 . D STATUS^HLTF0(HLMTIENS,4,,,1),EXIT
     18 . ;quit if no commit or app ack
     19 . I $G(HL("ACAT"))="NE",$G(HL("APAT"))="NE" Q
     20 . S X=$S($G(HL("ACAT"))="AL":"CR",1:"AR")
     21 . ;HLTCP=ien of acknowledgment msg. from ACK^HLTP4
     22 . D ACK^HLTP4(X,$P(HLRESLT,U,2)) Q:'$G(HLTCP)
     23 . ;write ack back over connection
     24 . S X=$$WRITE^HLCSTCP2(HLTCP)
     25 . ;update counter to sent
     26 . D LLCNT^HLCSTCP(HLDP,4)
     27 . ;update status of ack to complete
     28 . D STATUS^HLTF0(HLTCP,3,,,1)
     29 ;
     30 ;check for duplicate msg., use rec. app and msg. id x-ref
     31 ; patch HL*1.6*120
     32 ; I $L($G(HL("MID"))),$G(HL("RAP")) S X=$O(^HLMA("AH",HL("RAP"),HL("MID"),0)) D  Q:'$D(HLMTIENS)
     33 I $G(HL("MID"))]"",$G(HL("RAP")) S X=$O(^HLMA("AH",HL("RAP"),HL("MID"),0)) D  Q:'$D(HLMTIENS)
     34 . ;HLASTMSG=last ien received during this connection
     35 . ;if no duplicate, save msg. ien and quit
     36 . I X=HLMTIENS!'X S HLASTMSG=HLMTIENS Q
     37 . N MSH,OIENS
     38 . S (OIENS,Y)=X D  S Y=HLMTIENS D
     39 .. ;combine MSH into single string
     40 .. S MSH(Y)="",I=0 F  S I=$O(^HLMA(Y,"MSH",I)) Q:'I  S MSH(Y)=MSH(Y)_$G(^(I,0))
     41 .; patch 117 & 125, check if identical
     42 .I MSH(HLMTIENS)'=MSH(OIENS) S HLASTMSG=HLMTIENS Q
     43 .;
     44 . ;msg is duplicate, set status as duplicate
     45 . D STATUS^HLTF0(HLMTIENS,4,109,"Duplicate with ien "_OIENS,1),EXIT
     46 . ;msg was resent during this connection, ignore it.
     47 . I HLASTMSG=HLMTIENS K HLMTIENS Q
     48 . ;find original response and send back
     49 . S HLASTRSP=$O(^HLMA("AF",OIENS,OIENS))
     50 ;
     51 ;Quit if this is acknowledgment to acknowledgement message
     52 I $G(HL("ACK")) D  Q
     53 . ;Update status of original acknowledgment message to successfully
     54 . D STATUS^HLTF0(HL("MTIENS"),3,,,1),STATUS^HLTF0(HLMTIENS,3,,,1)
     55 . ;unlock record
     56 . D EXIT
     57 ;
     58 ;enhance ack., send commit, quit if not an ack, msg will be processed by filer
     59 I $G(HL("ACAT"))="AL" D  Q:'$G(HL("MTIENS"))
     60 . ;msg is a resend, HLASTRSP=ien of original response
     61 .I $G(HLASTRSP) D
     62 ..S HLTCP=HLASTRSP
     63 ..D LLCNT^HLCSTCP(HLDP,3)
     64 . E  D  Q:'$G(HLTCP)
     65 ..D ACK^HLTP4("CA") ;**109** LLCNT^HLCSTCP(HLDP,3) called in ACK^HLTP4
     66 . S X=$$WRITE^HLCSTCP2(HLTCP)
     67 . D LLCNT^HLCSTCP(HLDP,4),STATUS^HLTF0(HLTCP,3,,,1):'$G(HLASTRSP)
     68 . S HLTCP=""
     69 . ;if not an ack, set status to awaiting processing **109** and put on in queue
     70 . I '$G(HL("MTIENS")),'$G(HLASTRSP) D STATUS^HLTF0(HLMTIENS,9),EXIT,SETINQUE^HLTP31
     71 ;
     72 ;enhance ack., no commit & no app ack
     73 I $G(HL("ACAT"))="NE",$G(HL("APAT"))="NE" D  Q
     74 . ;set status to awaiting processing, **109** and put on in queue
     75 . I '$G(HLASTRSP) D STATUS^HLTF0(HLMTIENS,9),EXIT,SETINQUE^HLTP31
     76 ;
     77 ; patch HL*1.6*120 start
     78 ;resending old response, msg is a resend
     79 ; I $G(HLASTRSP) S HLTCP=HLASTRSP G ACK
     80 ; do not re-send duplicate message when $G(HL("ACAT"))="AL"
     81 I $G(HLASTRSP),$G(HL("ACAT"))'="AL" S HLTCP=HLASTRSP G ACK
     82 ; quit if duplicate
     83 Q:$G(HLASTRSP)
     84 ; patch HL*1.6*120 end
     85 ;
     86CONT ;continue processing an enhance ack msg. called from DEFACK
     87 ;Set special HL variables for processing rtn
     88 S HLQUIT=0,HLNODE="",HLNEXT="D HLNEXT^HLCSUTL"
     89 ;
     90 ; message is an acknowledgement, HLMSA=ack code^id^text
     91 I ($G(HLMSA)]"") D  Q
     92 . ;X=1 if ack ok, 0=reject of error
     93 . S X=$E(HLMSA,2)="A"
     94 . ;Update status of original subscriber message and remove it from the out-going queue
     95 . D STATUS^HLTF0(HL("MTIENS"),$S(X:3,1:4),"",$S(X:"",1:$P(HLMSA,HL("FS"),3)),1)
     96 . D DEQUE^HLCSREP($P($G(^HLMA(HL("MTIENS"),0)),"^",7),"O",HL("MTIENS"))
     97 . D
     98 .. N HLTCP ;New variable to update status in file #772.
     99 ..;
     100 ..;**108**
     101 .. N TEMP
     102 .. S TEMP=HLMTIENS
     103 .. N HLMTIENS
     104 .. S HLMTIENS=TEMP
     105 ..;**END 108**
     106 ..;
     107 .. D PROCACK^HLTP2(HLMTIEN,HL("EID"),.HLRESLT,.HL)
     108 . ;update status of incoming to complete & unlock
     109 . D STATUS^HLTF0(HLMTIENS,$S($G(HLRESLT):4,1:3),$S($G(HLRESLT):+$G(HLRESLT),1:""),$S($G(HLRESLT):$P(HLRESLT,U,2),1:""),1),EXIT
     110 ;
     111 ;get entry action, exit action and processing routine
     112 K HLHDR,HLLD0,HLLD1,HLMSA
     113 I HL("EIDS")="",$G(HLEIDS)]"" S HL("EIDS")=HLEIDS ;**CIRN**
     114 D EVENT^HLUTIL1(HL("EIDS"),"15,20,771",.HLN)
     115 S HLENROU=$G(HLN(20)),HLEXROU=$G(HLN(15)),HLPROU=$G(HLN(771))
     116 ;quit if no processing routine,update status and quit
     117 I HLPROU']"" S HLRESLT="10^"_$G(^HL(771.7,10,0)) D STATUS^HLTF0(HLMTIENS,3,,,1),EXIT Q
     118 ;HLORNOD=subscriber protocol for Fileman auditing, ien;global ref
     119 N HLORNODD S HLORNOD=HL("EIDS")_";ORD(101,"
     120 ;Execute entry action of client protocol
     121 X:HLENROU]"" HLENROU K HLENROU,HLDONE1
     122 ;
     123 ;Execute processing routine
     124 X HLPROU S HLRESLT=0 S:($D(HLERR)) HLRESLT="9^"_HLERR
     125 ;update status of incoming to complete & unlock
     126 D STATUS^HLTF0(HLMTIENS,$S(HLRESLT:4,1:3),$S(HLRESLT:+HLRESLT,1:""),$S(HLRESLT:$P(HLRESLT,U,2),1:""),1,$S($G(HLERR("SKIP_EVENT"))=1:1,1:0)),EXIT
     127 ;HLTCPO=link open, HLTCP=ien of acknowledgment msg. from GENACK
     128ACK I $G(HLTCPO),$G(HLTCP) D  Q
     129 . D LLCNT^HLCSTCP(HLDP,3)
     130 . ;write ack back over open tcp link
     131 . S X=$$WRITE^HLCSTCP2(HLTCP)
     132 . ;update status of ack to complete
     133 . D:'$G(HLASTRSP) STATUS^HLTF0(HLTCP,3,,,1)
     134 . D LLCNT^HLCSTCP(HLDP,4)
     135 Q
     136 ;
     137DEFACK(HLDP,X) ;process the deferred application ack, called from HLCSIN
     138 ;HLDP=logical link, X=ien in file 773
     139 ;
     140 ; patch HL*1.6*120 start
     141 ; clean variables except Kernel related variables
     142 D
     143 . ; protect variables defined in STARTIN^HLCSIN
     144 . N HLFLG,HLEXIT,HLPTRFLR
     145 . ; protect variables defined in DEFACK^HLCSIN
     146 . N HLXX,HLD0,HLPCT
     147 . ; protect input parameters of this sub-routine
     148 . N HLDP,X
     149 . D KILL^XUSCLEAN
     150 ; patch HL*1.6*120 end
     151 ;
     152 ;set error trap
     153 N $ETRAP,$ESTACK S $ETRAP="D ERROR^HLTP3"
     154 N HLERR     ;patch HL*1.6*109
     155 Q:'$G(HLDP)!'$G(X)  Q:'$G(^HLMA(X,0))
     156 ;**109 START**
     157 Q:'$D(^HLMA("AC","I",HLDP,X))
     158 ;**109 END**
     159 ;
     160 N HL,HLA,HLD0,HLEID,HLEIDS,HLHDR,HLHDRO,HLMTIEN,HLMTIENS,HLJ,HLMSA,HLN,HLQUIT,HLNODE,HLNEXT,HLRESLT,HLRESLTA,HLTCP,HLXX,Z,HLDONE1
     161 ;setup variables
     162 S HLMTIENS=X,X=^HLMA(HLMTIENS,0),HLMTIEN=+$P(X,U),HL("MID")=$P(X,U,2),HL("MTIENS")=$P(X,U,10),HL("LL")=$P(X,U,7),HLTCP="",HL("Q")=""""""
     163 S HL("EIDS")=$P(X,U,8),HL("SAP")=$P(X,U,11),HL("RAP")=$P(X,U,12),HL("MTP")=$P(X,U,13),HL("ETP")=$P(X,U,14)
     164 S:$P(X,U,15) HL("MTP_ETP")=$P(X,U,15)
     165 S:HL("SAP") HL("SAN")=$P($G(^HL(771,HL("SAP"),0)),U) S:HL("RAP") HL("RAN")=$P($G(^HL(771,HL("RAP"),0)),U)
     166 S:HL("MTP") HL("MTN")=$P($G(^HL(771.2,HL("MTP"),0)),U) S:HL("ETP") HL("ETN")=$P($G(^HL(779.001,HL("ETP"),0)),U)
     167 S:$G(HL("MTP_ETP")) HL("MTN_ETN")=$P($G(^HL(779.005,HL("MTP_ETP"),0)),U)
     168 S HL("EID")=$P($G(^HL(772,HLMTIEN,0)),U,10)
     169 M HLHDRO=^HLMA(HLMTIENS,"MSH")
     170 ; if no header quit
     171 ;**109**
     172 ;I '$O(HLHDRO(0)) L -^HLMA(HLMTIENS) Q
     173 Q:'$O(HLHDRO(0))
     174 ;
     175 S HL("FS")=$E(HLHDRO(1,0),4),HL("ECH")=$$P^HLTPCK2(.HLHDRO,2),HL("SFN")=$$P^HLTPCK2(.HLHDRO,4),HL("RFN")=$$P^HLTPCK2(.HLHDRO,6),HL("DTM")=$$P^HLTPCK2(.HLHDRO,7)
     176 ;
     177 ; patch HL*1.6*109 start
     178 ; quit if ien of #772 is not defined
     179 Q:'HLMTIEN
     180 ; quit if field separator is not defined
     181 Q:HL("FS")=""
     182 ; patch HL*1.6*109 end
     183 ;
     184 S X=$$P^HLTPCK2(.HLHDRO,1)
     185 ;
     186 ; patch HL*1.6*120 start
     187 I X="MSH" D
     188 . S HL("PID")=$$P^HLTPCK2(.HLHDRO,11),HL("VER")=$$P^HLTPCK2(.HLHDRO,12),HL("APAT")=$$P^HLTPCK2(.HLHDRO,16),HL("CC")=$$P^HLTPCK2(.HLHDRO,17)
     189 . ;
     190 . ; 2nd component is Processing mode
     191 . S HL("PMOD")=$P(HL("PID"),$E(HL("ECH"),1),2)
     192 . ; first component is Processing id
     193 . S HL("PID")=$P(HL("PID"),$E(HL("ECH"),1))
     194 ;
     195 I X'="MSH" D
     196 . S X=$$P^HLTPCK2(.HLHDRO,9),Z=$E(HL("ECH")),HL("PID")=$P(X,Z,2),HL("VER")=$P(X,Z,4)
     197 . ;
     198 . ; original implementation incorrectly treats repetition separator as
     199 . ; subcomponent separator
     200 . I $E(HL("ECH"),2)]"",X[$E(HL("ECH"),2) D
     201 .. S HL("SUB-COMPONENT")=$E(HL("ECH"),2)
     202 . ; if subcomponent separator is correctly applied
     203 . I $E(HL("ECH"),4)]"",X[$E(HL("ECH"),4) D
     204 .. S HL("SUB-COMPONENT")=$E(HL("ECH"),4)
     205 . ;
     206 . I $D(HL("SUB-COMPONENT")),HL("PID")[HL("SUB-COMPONENT") D
     207 .. ; 2nd sub-component is Processing mode
     208 .. S HL("PMOD")=$P(HL("PID"),HL("SUB-COMPONENT"),2)
     209 .. ; first sub-component is Processing id
     210 .. S HL("PID")=$P(HL("PID"),HL("SUB-COMPONENT"))
     211 . ; patch HL*1.6*120 end
     212 . ;
     213 . Q:$$P^HLTPCK2(.HLHDRO,10)=""
     214 . ;HLMSA=ack code^id^text
     215 . S HLMSA=$P($$P^HLTPCK2(.HLHDRO,10),$E(HL("ECH")),1),$P(HLMSA,HL("FS"),2)=$$P^HLTPCK2(.HLHDRO,12),$P(HLMSA,HL("FS"),3)=$P($$P^HLTPCK2(.HLHDRO,10),$E(HL("ECH")),2),HL("MSAID")=$P(HLMSA,HL("FS"),2)
     216 ;
     217 ; HL*1.6*108
     218 ; quit if this is a commit ack
     219 I $P($G(^HL(772,HLMTIEN,"IN",1,0)),HL("FS"),1)="MSA",$E($P($G(^HL(772,HLMTIEN,"IN",1,0)),HL("FS"),2))="C" Q
     220 ; **
     221 ;
     222 ;**  HL*1.6*117 **
     223 K HLL("SET FOR APP ACK"),HLL("LINKS")
     224 ;** END HL*1.6*117 **
     225 ;
     226 D CONT
     227 Q
     228 ;
     229MSA(Y) ;Y=ien in 772, returns MSA segment
     230 ;ack code^msg being ack id^text
     231 N X
     232 S X=$G(^HL(772,Y,"IN",1,0)),X=$S($E(X,1,3)="MSA":$E(X,5,999),1:"")
     233 Q X
     234 ;
     235ERROR ;error trap
     236 D ^%ZTER
     237 I $G(HLMTIENS),$D(^HLMA(HLMTIENS,0)) D STATUS^HLTF0(HLMTIENS,4,,,1),EXIT
     238 ;*109* release all locks created by inbound filer
     239 L -^HLMA("AC","I",+$G(HLXX))
     240 G UNWIND^%ZTER
     241 ;
     242 ;
     243EXIT ;unlock
     244 I $G(HLMTIENS) L -^HLMA(HLMTIENS)
     245 Q
     246 ;
     247ONAC(IEN773) ;
     248 ;Returns 1 if the message is on the "AC","I" xref
     249 ;Returns 0 otherwise
     250 ;
     251 N LINK
     252 S LINK=$P($G(^HLMA(IEN773,0)),"^",17)
     253 Q:'LINK 0
     254 Q $D(^HLMA("AC","I",LINK,IEN773))
  • WorldVistAEHR/trunk/r/HEALTH_LEVEL_SEVEN-HL/HLTPCK2B.m

    r613 r623  
    1 HLTPCK2B        ;OIFO-O/RJH - Message Header Validation (Con't) ;10/04/2007  16:00
    2         ;;1.6;HEALTH LEVEL SEVEN;**120,133,122**;Oct 13, 1995;Build 14
    3         ;Per VHA Directive 2004-038, this routine should not be modified.
    4         ;
    5         ; splitted from HLTPCK2A
    6         ; to be called from HLTPCK2A
    7         ;
    8 MS      ;Check for Message Structure Code
    9         I $G(ARY("MTN_ETN"))'="" D
    10         . S ARY("MTP_ETP")=0
    11         . S ARY("MTP_ETP")=+$O(^HL(779.005,"B",ARY("MTN_ETN"),0))
    12         . I ('ARY("MTP_ETP")) S:(ERR="") ERR="Invalid Message Structure Code" Q
    13         ;
    14         ;Get server and client Protocols
    15 MSA     ;if ack, then get information and quit, we don't need to respond
    16         I $G(MSA)]"" D  Q
    17         . ;Message is an acknowledgement, find original message
    18         . S ARY("MSAID")=$P(MSA,FS,2),ARY("MTIENS")=0
    19         . I ARY("MSAID")="" S:(ERR="") ERR="Invalid Message Control ID in MSA Segment - No Message ID" Q
    20         . F  S ARY("MTIENS")=+$O(^HLMA("AH",ARY("SAP"),ARY("MSAID"),ARY("MTIENS"))) Q:'ARY("MTIENS")!($P($G(^HLMA(ARY("MTIENS"),0)),U,3)="O")
    21         . I 'ARY("MTIENS") S:(ERR="") ERR="Invalid Message Control ID in MSA Segment - No message IEN in ""AH"" x-ref" Q
    22         . ;get subscriber protocol and ack. to (show if this is an ack to an ack)
    23         . S X=$G(^HLMA(ARY("MTIENS"),0)),ARY("EIDS")=$P(X,U,8),ARY("ACK")=$P(X,U,10)
    24         . ;if no subscriber protocol then response msg. is invalid
    25         . ;
    26         . ; patch HL*1.6*122 start
    27         . ; comment out the following code: for patch 109- dynamic addressing
    28         . ; I ('ARY("EIDS")) S:(ERR="") ERR="Invalid Message Control ID in MSA Segment - No Subscr. IEN in 773" Q
    29         . ;get message text ien in file 772 and server protocol, 'EID'
    30         . S ARY("MTIEN")=+X,X=$G(^HL(772,+X,0)),ARY("EID")=$P(X,U,10)
    31         . I ('ARY("EID")) S:(ERR="") ERR="Event Protocol not found" Q
    32         . ; D EVENT^HLUTIL1(ARY("EIDS"),"770,773",.HLN)
    33         . I ARY("EIDS") D EVENT^HLUTIL1(ARY("EIDS"),"770,773",.HLN)
    34         . ; patch HL*1.6*122 end
    35         ;
    36         ;Find Server Protocol - based on sending application, message type,
    37         ;event type and version ID
    38         I ARY("ETP") S ARY("EID")=+$O(^ORD(101,"AHL1",ARY("SAP"),ARY("MTP"),ARY("ETP"),ARY("VEP"),0))
    39         ;
    40         ;Find Server Protocol - based on sending application, message type,
    41         ;and version ID
    42         I 'ARY("ETP") S ARY("EID")=+$O(^ORD(101,"AHL21",ARY("SAP"),ARY("MTP"),ARY("VEP"),0))
    43         ;
    44         I ('ARY("EID")) S:(ERR="") ERR="Event Protocol not found" Q
    45         ;Find Client Protocol - in ITEM multiple of Server Protocol
    46         S ARY("EIDS")=0
    47         F  S ARY("EIDS")=+$O(^ORD(101,ARY("EID"),775,"B",ARY("EIDS"))) Q:'ARY("EIDS")!($P($G(^ORD(101,ARY("EIDS"),770)),U,2)=ARY("RAP"))
    48         I 'ARY("EIDS") S ERR="Invalid Receiving Application for this Event" Q
    49         D EVENT^HLUTIL1(ARY("EIDS"),"770,773",.HLN)
    50         ;
    51 LLP     ;Get logical link pointer
    52         S ARY("LL")=$P($G(HLN(770)),"^",7)
    53         ;
    54 FAC     ;Get sending/rec facility, validate if necessary
    55         ;
    56         S HLCS=$E(ECH,1) ;Get component separator
    57         S ARY("RAF")=$$P^HLTPCK2(.HDR,6) ;Receiving Facility
    58         S ARY("SAF")=$$P^HLTPCK2(.HDR,4) ;Sending Facility
    59         ;Get sending/receiving facility from Application Parameter file(771)
    60         S HL771SF=$P($G(^HL(771,ARY("SAP"),0)),U,3)
    61         S HL771RF=$P($G(^HL(771,ARY("RAP"),0)),U,3)
    62         ;Sending/Receiving facility required?
    63         S X=$G(^ORD(101,ARY("EIDS"),773))
    64         S HLSFREQ=+X,HLRFREQ=+$P(X,U,2)
    65 RF      ;Validate Receiving Facility
    66         I HLRFREQ D
    67         .I ARY("RAF")="" S:ERR="" ERR="Missing required receiving facility"
    68         .I HL771RF]"" D  Q
    69         ..;Facility data in 771 overrides data in site paramter file
    70         ..Q
    71         .;Check against local default value (site parameters)
    72         .Q:ARY("RAF")=(HLINSTN_HLCS_HLDOM_HLCS_"DNS")
    73         .;
    74         .; patch HL*1.6*120 start
    75         .; I $P(ARY("RAF"),HLCS)=HLINSTN,$P(ARY("RAF"),HLCS,3)="DNS" D  Q
    76         . I $P(ARY("RAF"),HLCS,3)="DNS" D  Q
    77         .. N ERROR,HLDOMP1,HLDOMP2
    78         .. ; S HLDOMP1=$P(ARY("RAF"),HLCS,2),HLDOMP1=$$FIND1^DIC(4.2,"","BMX",HLDOMP1,"B^C","","ERROR")
    79         .. S HLDOMP1=$P(ARY("RAF"),HLCS,2)
    80         .. ;
    81         .. ; assume the format is <domain>:<port #>
    82         .. I HLDOMP1[":" S ARY("RAF-PORT")=$P(HLDOMP1,":",2)
    83         .. S HLDOMP1=$P(HLDOMP1,":")
    84         .. S ARY("RAF-DOMAIN")=HLDOMP1
    85         .. ;
    86         .. ; if first piece of domain is "HL7." or "MPI.", remove it
    87         .. I ($E(HLDOMP1,1,4)="HL7.")!($E(HLDOMP1,1,4)="MPI.") D
    88         ... S HLDOMP1=$P(HLDOMP1,".",2,99)
    89         .. S HLDOMP1=$$FIND1^DIC(4.2,"","BMX",HLDOMP1,"B^C","","ERROR")
    90         .. S HLDOMP2=HLDOM,HLDOMP2=$$FIND1^DIC(4.2,"","BMX",HLDOMP2,"B^C","","ERROR")
    91         .. I HLDOMP1&HLDOMP2&(HLDOMP1=HLDOMP2) Q
    92         .. ;
    93         .. ; check DNS domain and ip address
    94         .. ;initialize variable, HLDOMP("FLAG")
    95         .. S HLDOMP("FLAG")=0
    96         .. I ARY("RAF-DOMAIN")]"" D
    97         ... ;
    98         ... ; match DNS domain
    99         ... I $D(^HLCS(870,"DNS",ARY("RAF-DOMAIN"))) D  Q
    100         .... S HLDOMP("FLAG")=1
    101         .... S ARY("RAF-LL")=+$O(^HLCS(870,"DNS",ARY("RAF-DOMAIN"),0))
    102         ... I $D(^HLCS(870,"DNS",$$UP^XLFSTR(ARY("RAF-DOMAIN")))) D  Q
    103         .... S HLDOMP("FLAG")=1
    104         .... S ARY("RAF-LL")=+$O(^HLCS(870,"DNS",$$UP^XLFSTR(ARY("RAF-DOMAIN")),0))
    105         ... I $D(^HLCS(870,"DNS",$$LOW^XLFSTR(ARY("RAF-DOMAIN")))) D  Q
    106         .... S HLDOMP("FLAG")=1
    107         .... S ARY("RAF-LL")=+$O(^HLCS(870,"DNS",$$LOW^XLFSTR(ARY("RAF-DOMAIN")),0))
    108         ... ;
    109         ... ; match ip address
    110         ... I $D(^HLCS(870,"IP",ARY("RAF-DOMAIN"))) D  Q
    111         .... S HLDOMP("FLAG")=1
    112         .... S ARY("RAF-LL")=+$O(^HLCS(870,"IP",ARY("RAF-DOMAIN"),0))
    113         .. Q:HLDOMP("FLAG")=1
    114         .. I $P(ARY("RAF"),HLCS)=HLINSTN Q
    115         .. ;
    116         .. S:ERR="" ERR="Receiving Facility mismatch."
    117         . I $P(ARY("RAF"),HLCS)=HLINSTN Q
    118         . S:ERR="" ERR="Receiving Facility mismatch."
    119         ; patch HL*1.6*120 end
    120         ;
    121 SF      ;Validate Sending Facility
    122         I HLSFREQ D
    123         .I ARY("SAF")="" S:ERR="" ERR="Missing required sending facility"
    124         .I HL771SF]"" D  Q
    125         ..;Check for facility data in 771
    126         ..Q
    127         .;If default value was sent, validate that DOMAIN RESOLVES TO LOGICAL LINK
    128         .;If so, use this instead of Protocol definition for return path
    129         .;
    130         .; patch HL*1.6*120 start
    131         . N HLDOMP
    132         . ; S HLDOMP=$P(ARY("SAF"),HLCS,2),HLDOMP=$$FIND1^DIC(4.2,"","BMX",HLDOMP,"B^C","","ERROR")
    133         . S HLDOMP=$P(ARY("SAF"),HLCS,2)
    134         . ;
    135         . ; assume the format is <domain>:<port #>
    136         . I HLDOMP[":" S ARY("SAF-PORT")=$P(HLDOMP,":",2)
    137         . S HLDOMP=$P(HLDOMP,":")
    138         . S ARY("SAF-DOMAIN")=HLDOMP
    139         . ;
    140         . ; if first piece of domain is "HL7." or "MPI.", remove it
    141         . I ($E(HLDOMP,1,4)="HL7.")!($E(HLDOMP,1,4)="MPI.") D
    142         .. S HLDOMP=$P(HLDOMP,".",2,99)
    143         . S HLDOMP=$$FIND1^DIC(4.2,"","BMX",HLDOMP,"B^C","","ERROR")
    144         .;Note: This expects a unique domain in domain file. Multiple entries will fail
    145         . ; I 'HLDOMP S:ERR="" ERR="Unrecognized/ambiguous domain in sending facility"
    146         . ;
    147         . ; check DNS domain and ip address
    148         . I 'HLDOMP D
    149         .. ;
    150         .. ;initialize variable, HLDOMP("FLAG")
    151         .. S HLDOMP("FLAG")=0
    152         .. I ARY("SAF-DOMAIN")]"" D
    153         ... ;
    154         ... ; match DNS domain
    155         ... I $D(^HLCS(870,"DNS",ARY("SAF-DOMAIN"))) D  Q
    156         .... S HLDOMP("FLAG")=1
    157         .... S ARY("SAF-LL")=+$O(^HLCS(870,"DNS",ARY("SAF-DOMAIN"),0))
    158         ... I $D(^HLCS(870,"DNS",$$UP^XLFSTR(ARY("SAF-DOMAIN")))) D  Q
    159         .... S HLDOMP("FLAG")=1
    160         .... S ARY("SAF-LL")=+$O(^HLCS(870,"DNS",$$UP^XLFSTR(ARY("SAF-DOMAIN")),0))
    161         ... I $D(^HLCS(870,"DNS",$$LOW^XLFSTR(ARY("SAF-DOMAIN")))) D  Q
    162         .... S HLDOMP("FLAG")=1
    163         .... S ARY("SAF-LL")=+$O(^HLCS(870,"DNS",$$LOW^XLFSTR(ARY("SAF-DOMAIN")),0))
    164         ... ;
    165         ... ; match ip address
    166         ... I $D(^HLCS(870,"IP",ARY("SAF-DOMAIN"))) D  Q
    167         .... S HLDOMP("FLAG")=1
    168         .... S ARY("SAF-LL")=+$O(^HLCS(870,"IP",ARY("SAF-DOMAIN"),0))
    169         .. Q:HLDOMP("FLAG")=1
    170         .. ; quit if 1st component defined
    171         .. S ARY("SAF-COMPONENT1")=$P(ARY("SAF"),HLCS,1)
    172         .. Q:ARY("SAF-COMPONENT1")]""
    173         .. S:ERR="" ERR="Receiving Facility mismatch."
    174         . ; patch HL*1.6*120 end
    175         . ;
    176         .Q:HLDOMP=$P(HLPARAM,U)  ;This is local app to app
    177         .I HLDOMP N HLNK S HLNK=+$O(^HLCS(870,"D",HLDOMP,0))
    178         .I $G(HLNK) S ARY("LL")=HLNK
    179         ;
    180 PID     ;Validate processing ID
    181         I ("DTP"'[ARY("PID")) S:(ERR="") ERR="Invalid HL7 Processing ID"
    182         S HLPID=$P(HLPARAM,U,3) ;site param
    183         S X=$G(^ORD(101,ARY("EID"),770)),X=$P(X,U,6) ;event driver
    184         ;If message is 'debug' then event driver must be 'debug.'
    185         ;If message is 'test' or 'production', then site param must match
    186         I ARY("PID")="D"&(X'="D") S:ERR="" ERR="Processing ID Mismatch with Event Driver"
    187         I ARY("PID")'="D"&(HLPID'=ARY("PID")) S:ERR="" ERR="Processing ID Mismatch with Site Parameters"
    188         ;
    189 SEC     ;Validate security field - access code and electronic signature
    190         I ($P($G(HLN(773)),"^",3)) D
    191         .S X=$P($$P^HLTPCK2(.HDR,8),$E(ECH))
    192         .S X=$$UPPER^HLFNC(X)
    193         .D ^XUSHSH
    194         .I X="",(MSA="") S:(ERR="") ERR="Invalid access code" Q
    195         .S ARY("DUZ")=0
    196         .S:(X'="") ARY("DUZ")=+$O(^VA(200,"A",X,0))
    197         .I ('ARY("DUZ")) S:(ERR="") ERR="Invalid access code" Q
    198         .I (($P($G(^VA(200,ARY("DUZ"),.1)),"^")="")&('$D(MSA))) S ARY("DUZ")=0 S:(ERR="") ERR="Invalid access code" Q
    199         .S X=$P($$P^HLTPCK2(.HDR,8),$E(ECH),3) I (X'="") D
    200         ..S X1=$G(^VA(200,ARY("DUZ"),20))
    201         ..I (X1="") S:(ERR="") ERR="No Signature Code on File" Q
    202         ..S X=$$UPPER^HLFNC(X)
    203         ..D HASH^XUSHSHP
    204         ..I ((X'=$P(X1,"^",4))!($P(X1,"^",2)="")) S:(ERR="") ERR="Invalid Electronic Signature Code" Q
    205         ..S ARY("ESIG")=$P(X1,"^",2)
    206         I $D(ARY) M HLREC=ARY
    207         Q
     1HLTPCK2B ;OIFO-O/RJH - Message Header Validation (Con't) ;09/13/2006
     2 ;;1.6;HEALTH LEVEL SEVEN;**120,133**;Oct 13, 1995;Build 13
     3 ;Per VHA Directive 2004-038, this routine should not be modified.
     4 ;
     5 ; splitted from HLTPCK2A
     6 ; to be called from HLTPCK2A
     7 ;
     8MS ;Check for Message Structure Code
     9 I $G(ARY("MTN_ETN"))'="" D
     10 . S ARY("MTP_ETP")=0
     11 . S ARY("MTP_ETP")=+$O(^HL(779.005,"B",ARY("MTN_ETN"),0))
     12 . I ('ARY("MTP_ETP")) S:(ERR="") ERR="Invalid Message Structure Code" Q
     13 ;
     14 ;Get server and client Protocols
     15MSA ;if ack, then get information and quit, we don't need to respond
     16 I $G(MSA)]"" D  Q
     17 . ;Message is an acknowledgement, find original message
     18 . S ARY("MSAID")=$P(MSA,FS,2),ARY("MTIENS")=0
     19 . I ARY("MSAID")="" S:(ERR="") ERR="Invalid Message Control ID in MSA Segment - No Message ID" Q
     20 . F  S ARY("MTIENS")=+$O(^HLMA("AH",ARY("SAP"),ARY("MSAID"),ARY("MTIENS"))) Q:'ARY("MTIENS")!($P($G(^HLMA(ARY("MTIENS"),0)),U,3)="O")
     21 . I 'ARY("MTIENS") S:(ERR="") ERR="Invalid Message Control ID in MSA Segment - No message IEN in ""AH"" x-ref" Q
     22 . ;get subscriber protocol and ack. to (show if this is an ack to an ack)
     23 . S X=$G(^HLMA(ARY("MTIENS"),0)),ARY("EIDS")=$P(X,U,8),ARY("ACK")=$P(X,U,10)
     24 . ;if no subscriber protocol then response msg. is invalid
     25 . I ('ARY("EIDS")) S:(ERR="") ERR="Invalid Message Control ID in MSA Segment - No Subscr. IEN in 773" Q
     26 . ;get message text ien in file 772 and server protocol, 'EID'
     27 . S ARY("MTIEN")=+X,X=$G(^HL(772,+X,0)),ARY("EID")=$P(X,U,10)
     28 . I ('ARY("EID")) S:(ERR="") ERR="Event Protocol not found" Q
     29 . D EVENT^HLUTIL1(ARY("EIDS"),"770,773",.HLN)
     30 ;
     31 ;Find Server Protocol - based on sending application, message type,
     32 ;event type and version ID
     33 I ARY("ETP") S ARY("EID")=+$O(^ORD(101,"AHL1",ARY("SAP"),ARY("MTP"),ARY("ETP"),ARY("VEP"),0))
     34 ;
     35 ;Find Server Protocol - based on sending application, message type,
     36 ;and version ID
     37 I 'ARY("ETP") S ARY("EID")=+$O(^ORD(101,"AHL21",ARY("SAP"),ARY("MTP"),ARY("VEP"),0))
     38 ;
     39 I ('ARY("EID")) S:(ERR="") ERR="Event Protocol not found" Q
     40 ;Find Client Protocol - in ITEM multiple of Server Protocol
     41 S ARY("EIDS")=0
     42 F  S ARY("EIDS")=+$O(^ORD(101,ARY("EID"),775,"B",ARY("EIDS"))) Q:'ARY("EIDS")!($P($G(^ORD(101,ARY("EIDS"),770)),U,2)=ARY("RAP"))
     43 I 'ARY("EIDS") S ERR="Invalid Receiving Application for this Event" Q
     44 D EVENT^HLUTIL1(ARY("EIDS"),"770,773",.HLN)
     45 ;
     46LLP ;Get logical link pointer
     47 S ARY("LL")=$P($G(HLN(770)),"^",7)
     48 ;
     49FAC ;Get sending/rec facility, validate if necessary
     50 ;
     51 S HLCS=$E(ECH,1) ;Get component separator
     52 S ARY("RAF")=$$P^HLTPCK2(.HDR,6) ;Receiving Facility
     53 S ARY("SAF")=$$P^HLTPCK2(.HDR,4) ;Sending Facility
     54 ;Get sending/receiving facility from Application Parameter file(771)
     55 S HL771SF=$P($G(^HL(771,ARY("SAP"),0)),U,3)
     56 S HL771RF=$P($G(^HL(771,ARY("RAP"),0)),U,3)
     57 ;Sending/Receiving facility required?
     58 S X=$G(^ORD(101,ARY("EIDS"),773))
     59 S HLSFREQ=+X,HLRFREQ=+$P(X,U,2)
     60RF ;Validate Receiving Facility
     61 I HLRFREQ D
     62 .I ARY("RAF")="" S:ERR="" ERR="Missing required receiving facility"
     63 .I HL771RF]"" D  Q
     64 ..;Facility data in 771 overrides data in site paramter file
     65 ..Q
     66 .;Check against local default value (site parameters)
     67 .Q:ARY("RAF")=(HLINSTN_HLCS_HLDOM_HLCS_"DNS")
     68 .;
     69 .; patch HL*1.6*120 start
     70 .; I $P(ARY("RAF"),HLCS)=HLINSTN,$P(ARY("RAF"),HLCS,3)="DNS" D  Q
     71 . I $P(ARY("RAF"),HLCS,3)="DNS" D  Q
     72 .. N ERROR,HLDOMP1,HLDOMP2
     73 .. ; S HLDOMP1=$P(ARY("RAF"),HLCS,2),HLDOMP1=$$FIND1^DIC(4.2,"","BMX",HLDOMP1,"B^C","","ERROR")
     74 .. S HLDOMP1=$P(ARY("RAF"),HLCS,2)
     75 .. ;
     76 .. ; assume the format is <domain>:<port #>
     77 .. I HLDOMP1[":" S ARY("RAF-PORT")=$P(HLDOMP1,":",2)
     78 .. S HLDOMP1=$P(HLDOMP1,":")
     79 .. S ARY("RAF-DOMAIN")=HLDOMP1
     80 .. ;
     81 .. ; if first piece of domain is "HL7." or "MPI.", remove it
     82 .. I ($E(HLDOMP1,1,4)="HL7.")!($E(HLDOMP1,1,4)="MPI.") D
     83 ... S HLDOMP1=$P(HLDOMP1,".",2,99)
     84 .. S HLDOMP1=$$FIND1^DIC(4.2,"","BMX",HLDOMP1,"B^C","","ERROR")
     85 .. S HLDOMP2=HLDOM,HLDOMP2=$$FIND1^DIC(4.2,"","BMX",HLDOMP2,"B^C","","ERROR")
     86 .. I HLDOMP1&HLDOMP2&(HLDOMP1=HLDOMP2) Q
     87 .. ;
     88 .. ; check DNS domain and ip address
     89 .. ;initialize variable, HLDOMP("FLAG")
     90 .. S HLDOMP("FLAG")=0
     91 .. I ARY("RAF-DOMAIN")]"" D
     92 ... ;
     93 ... ; match DNS domain
     94 ... I $D(^HLCS(870,"DNS",ARY("RAF-DOMAIN"))) D  Q
     95 .... S HLDOMP("FLAG")=1
     96 .... S ARY("RAF-LL")=+$O(^HLCS(870,"DNS",ARY("RAF-DOMAIN"),0))
     97 ... I $D(^HLCS(870,"DNS",$$UP^XLFSTR(ARY("RAF-DOMAIN")))) D  Q
     98 .... S HLDOMP("FLAG")=1
     99 .... S ARY("RAF-LL")=+$O(^HLCS(870,"DNS",$$UP^XLFSTR(ARY("RAF-DOMAIN")),0))
     100 ... I $D(^HLCS(870,"DNS",$$LOW^XLFSTR(ARY("RAF-DOMAIN")))) D  Q
     101 .... S HLDOMP("FLAG")=1
     102 .... S ARY("RAF-LL")=+$O(^HLCS(870,"DNS",$$LOW^XLFSTR(ARY("RAF-DOMAIN")),0))
     103 ... ;
     104 ... ; match ip address
     105 ... I $D(^HLCS(870,"IP",ARY("RAF-DOMAIN"))) D  Q
     106 .... S HLDOMP("FLAG")=1
     107 .... S ARY("RAF-LL")=+$O(^HLCS(870,"IP",ARY("RAF-DOMAIN"),0))
     108 .. Q:HLDOMP("FLAG")=1
     109 .. I $P(ARY("RAF"),HLCS)=HLINSTN Q
     110 .. ;
     111 .. S:ERR="" ERR="Receiving Facility mismatch."
     112 . I $P(ARY("RAF"),HLCS)=HLINSTN Q
     113 . S:ERR="" ERR="Receiving Facility mismatch."
     114 ; patch HL*1.6*120 end
     115 ;
     116SF ;Validate Sending Facility
     117 I HLSFREQ D
     118 .I ARY("SAF")="" S:ERR="" ERR="Missing required sending facility"
     119 .I HL771SF]"" D  Q
     120 ..;Check for facility data in 771
     121 ..Q
     122 .;If default value was sent, validate that DOMAIN RESOLVES TO LOGICAL LINK
     123 .;If so, use this instead of Protocol definition for return path
     124 .;
     125 .; patch HL*1.6*120 start
     126 . N HLDOMP
     127 . ; S HLDOMP=$P(ARY("SAF"),HLCS,2),HLDOMP=$$FIND1^DIC(4.2,"","BMX",HLDOMP,"B^C","","ERROR")
     128 . S HLDOMP=$P(ARY("SAF"),HLCS,2)
     129 . ;
     130 . ; assume the format is <domain>:<port #>
     131 . I HLDOMP[":" S ARY("SAF-PORT")=$P(HLDOMP,":",2)
     132 . S HLDOMP=$P(HLDOMP,":")
     133 . S ARY("SAF-DOMAIN")=HLDOMP
     134 . ;
     135 . ; if first piece of domain is "HL7." or "MPI.", remove it
     136 . I ($E(HLDOMP,1,4)="HL7.")!($E(HLDOMP,1,4)="MPI.") D
     137 .. S HLDOMP=$P(HLDOMP,".",2,99)
     138 . S HLDOMP=$$FIND1^DIC(4.2,"","BMX",HLDOMP,"B^C","","ERROR")
     139 .;Note: This expects a unique domain in domain file. Multiple entries will fail
     140 . ; I 'HLDOMP S:ERR="" ERR="Unrecognized/ambiguous domain in sending facility"
     141 . ;
     142 . ; check DNS domain and ip address
     143 . I 'HLDOMP D
     144 .. ;
     145 .. ;initialize variable, HLDOMP("FLAG")
     146 .. S HLDOMP("FLAG")=0
     147 .. I ARY("SAF-DOMAIN")]"" D
     148 ... ;
     149 ... ; match DNS domain
     150 ... I $D(^HLCS(870,"DNS",ARY("SAF-DOMAIN"))) D  Q
     151 .... S HLDOMP("FLAG")=1
     152 .... S ARY("SAF-LL")=+$O(^HLCS(870,"DNS",ARY("SAF-DOMAIN"),0))
     153 ... I $D(^HLCS(870,"DNS",$$UP^XLFSTR(ARY("SAF-DOMAIN")))) D  Q
     154 .... S HLDOMP("FLAG")=1
     155 .... S ARY("SAF-LL")=+$O(^HLCS(870,"DNS",$$UP^XLFSTR(ARY("SAF-DOMAIN")),0))
     156 ... I $D(^HLCS(870,"DNS",$$LOW^XLFSTR(ARY("SAF-DOMAIN")))) D  Q
     157 .... S HLDOMP("FLAG")=1
     158 .... S ARY("SAF-LL")=+$O(^HLCS(870,"DNS",$$LOW^XLFSTR(ARY("SAF-DOMAIN")),0))
     159 ... ;
     160 ... ; match ip address
     161 ... I $D(^HLCS(870,"IP",ARY("SAF-DOMAIN"))) D  Q
     162 .... S HLDOMP("FLAG")=1
     163 .... S ARY("SAF-LL")=+$O(^HLCS(870,"IP",ARY("SAF-DOMAIN"),0))
     164 .. Q:HLDOMP("FLAG")=1
     165 .. ; quit if 1st component defined
     166 .. S ARY("SAF-COMPONENT1")=$P(ARY("SAF"),HLCS,1)
     167 .. Q:ARY("SAF-COMPONENT1")]""
     168 .. S:ERR="" ERR="Receiving Facility mismatch."
     169 . ; patch HL*1.6*120 end
     170 . ;
     171 .Q:HLDOMP=$P(HLPARAM,U)  ;This is local app to app
     172 .I HLDOMP N HLNK S HLNK=+$O(^HLCS(870,"D",HLDOMP,0))
     173 .I $G(HLNK) S ARY("LL")=HLNK
     174 ;
     175PID ;Validate processing ID
     176 I ("DTP"'[ARY("PID")) S:(ERR="") ERR="Invalid HL7 Processing ID"
     177 S HLPID=$P(HLPARAM,U,3) ;site param
     178 S X=$G(^ORD(101,ARY("EID"),770)),X=$P(X,U,6) ;event driver
     179 ;If message is 'debug' then event driver must be 'debug.'
     180 ;If message is 'test' or 'production', then site param must match
     181 I ARY("PID")="D"&(X'="D") S:ERR="" ERR="Processing ID Mismatch with Event Driver"
     182 I ARY("PID")'="D"&(HLPID'=ARY("PID")) S:ERR="" ERR="Processing ID Mismatch with Site Parameters"
     183 ;
     184SEC ;Validate security field - access code and electronic signature
     185 I ($P($G(HLN(773)),"^",3)) D
     186 .S X=$P($$P^HLTPCK2(.HDR,8),$E(ECH))
     187 .S X=$$UPPER^HLFNC(X)
     188 .D ^XUSHSH
     189 .I X="",(MSA="") S:(ERR="") ERR="Invalid access code" Q
     190 .S ARY("DUZ")=0
     191 .S:(X'="") ARY("DUZ")=+$O(^VA(200,"A",X,0))
     192 .I ('ARY("DUZ")) S:(ERR="") ERR="Invalid access code" Q
     193 .I (($P($G(^VA(200,ARY("DUZ"),.1)),"^")="")&('$D(MSA))) S ARY("DUZ")=0 S:(ERR="") ERR="Invalid access code" Q
     194 .S X=$P($$P^HLTPCK2(.HDR,8),$E(ECH),3) I (X'="") D
     195 ..S X1=$G(^VA(200,ARY("DUZ"),20))
     196 ..I (X1="") S:(ERR="") ERR="No Signature Code on File" Q
     197 ..S X=$$UPPER^HLFNC(X)
     198 ..D HASH^XUSHSHP
     199 ..I ((X'=$P(X1,"^",4))!($P(X1,"^",2)="")) S:(ERR="") ERR="Invalid Electronic Signature Code" Q
     200 ..S ARY("ESIG")=$P(X1,"^",2)
     201 I $D(ARY) M HLREC=ARY
     202 Q
Note: See TracChangeset for help on using the changeset viewer.