- BOPRNEW ;IHS/ILC/ALG/CIA/PLS - ILC Listener;06-Feb-2007 21:19;SM
- ;;1.0;AUTOMATED DISPENSING INTERFACE;**1,3**;Jul 26, 2005
- Q
- DEBUG ;Call here for testing
- D DT^DICRW
- S BOPLSOC=9002,BOPDIV=1
- ;
- ;Entry used as "ZTRTN" in BOPOMTR
- GO ; EP
- I $G(BOPDIV)="" S BOPDIV=1
- ;
- ;Quit if Channel Active field set to NO for Receiving Facility
- I '$P($G(^BOP(90355,1,3,BOPDIV,0)),U,2) G QUIT
- ;Quit if STOP field set to INTERFACE STOPPED
- I $P($G(^BOP(90355,1,12)),U,1)+0>0 G QUIT
- ;
- ;Lock / Test / Quit if a job is already running
- L +^BOP(90355,"L",BOPDIV):99 E Q
- ;
- ;Listen on socket, start routine
- N %A,ZISOS,X,NIO S ZISOS=^%ZOSF("OS")
- ;IHS exemption approved on March 16, 2005
- I $$NEWERR^%ZTER() N $ETRAP S $ETRAP="D ERR^BOPRNEW"
- E S X="ERR^BOPRNEW",@^%ZOSF("TRAP")
- ;
- ;Open a channel. Parameter 1 is Socket, parameter 2 is the routine.
- ;S IO("C")=1 ; If not commented out, the channel stops after 1 message
- ;
- ;If this side is supposed to be the client, make the connection
- I $P(^BOP(90355,1,3,BOPDIV,0),U,8)="C" S X=^(0) D
- .S BOPLSOC=$P(X,U,5),X=$P(X,U,3)
- .D CALL^%ZISTCP(X,BOPLSOC) Q:POP
- .D READ
- .K BOPLSOC
- ;
- QUIT Q
- ;
- READ ;LISTEN^%ZISTCP will call here to read the message.
- S DIQUIET=1,BOPBUF="" D DT^DICRW
- ;
- LOOP U IO R X:1 H 1
- I $P($G(^BOP(90355,1,12)),U,1)+0>0 G QUIT ; all interfaces stopped
- I '$L(X) H 5 G LOOP:+$G(^BOP(90355,1,4)),QUIT
- S BOPBUF=X
- LOOP1 D RECEIVE(2)
- I $P($G(^BOP(90355,1,12)),U,1)+0>0 G QUIT ; all interfaces stopped
- I +$G(^BOP(90355,1,4)) G LOOP1:$L(BOPBUF),LOOP
- G QUIT
- ;
- RECEIVE(BOPWAIT) ;
- N I,J
- ;
- K BOPIN S BOPI=0,U="^" U IO
- ;Calculate Operating System to be able to read properly
- I '$D(BOPOS) S BOPOS=^%ZOSF("OS")
- I BOPOS["MSM" G RMSM
- G RR
- ;
- K BOPIN S BOPI=0,U="^" U IO
- ;
- RMSM ; go here if MSM
- S BOPOS("MSMVER")=$$VERSION^%ZOSV()
- S:+BOPOS("MSMVER")=0 BOPOS("MSMVER")=8
- ;
- ;Read
- ;If there are multiple records, BOPIN needs to be
- ;changed to a global array.
- ;
- RR ;
- F D R(BOPWAIT,BOPOS) Q:$S(X="":1,X=$C(28):1,1:"") D
- .I $E(X)=$C(11) S X=$E(X,2,$L(X)) Q:X=""
- .S BOPI=BOPI+1,BOPIN(BOPI)=X
- ;
- ;Quit if no data received
- Q:'$D(BOPIN)
- ;
- ;Quit if the wrong type of record
- S I=":"_$P($P(BOPIN(1),"|",9),U)_":"
- Q:":DFT:EPQ:EOQ:ETO:"'[I
- ;
- D RSET
- I BOPBUF'="" K BOPIN S BOPI=0 G RR
- Q
- ;
- RSET ; file new transaction
- ;Create NEW Record
- ;
- ;First calculate now
- S DIC="^BOP(90355.1,"
- S X=$$NOW^XLFDT()
- ;
- ;Then make sure NOW is unique in the file
- L +^BOP(90355.1,0):1
- F I=X:.000001 Q:'$D(^BOP(90355.1,"B",I))
- K DD,DO S X=I,DIC="^BOP(90355.1,",DIC(0)="F" D FILE^DICN
- L -^BOP(90355.1,0)
- ;
- ;Put data into file -- first mark it "NOT COMPLETE"
- S DIE=90355.1,DR=".1///99;.12///"_BOPDIV_";99///1;99.1///1",DA=+Y
- D ^DIE
- ;
- ;Put data into file
- S J=0 F I=0:0 S I=$O(BOPIN(I)) Q:I<1 S J=J+1,^BOP(90355.1,DA,"DATA",J,0)=BOPIN(I)
- S ^BOP(90355.1,DA,"DATA",0)=U_U_J_U_J_U_$P(^BOP(90355.1,DA,0),".")
- ;
- ;Mark transaction received and Acknowledge
- S DIE=90355.1,DR="99.1///0" D ^DIE S BOPSTOP=1
- S ^BOP(90355.1,"AC",0,DA)=""
- ; send ack back
- K OUT N A,B S A=BOPIN(1),$P(A,"|",9)="ACK"
- S B=$P(A,"|",2) S:B'["&" B=B_"&",$P(A,"|",2)=B
- S B="MSA|AA|"_DA_"|"
- S OUT(1)=$C(11)_A_$C(13),OUT(2)=B_$C(13)_$C(28)_$C(13)
- S A=0 F S A=$O(OUT(A)) Q:'A U IO W OUT(A),!
- ; keep copy in file
- S OUT(0)=$H M ^BOP(90355.1,DA,"OUT")=OUT
- K OUT,A,B
- Q
- ;
- RACK ; send ack back
- ERR ;
- G QUIT
- ;
- ;Job out at this line to start a new receiver at single division site.
- JOB N ZTIO,ZTDESC,ZTDTH,ZTRTN,ZTSAVE,ZTSK
- S ZTIO="",ZTDTH=$H,ZTRTN="JOBGO^BOPRNEW",ZTDESC="BOP LISTENER"
- D ^%ZTLOAD
- I '$G(ZTSK) D
- .W !,"BOPRNEW job startup Failed"
- Q
- JOBGO ;Start a new listener
- S X="Automated Dispense "_$J D SETENV^%ZOSV,DT^DICRW
- S I=$O(^BOP(90355,1,3,1,0)) Q:I<1 S X=^(I,0)
- S BOPLSOC=$P(X,U,5),BOPDIV=$P(X,U)
- S X="ERR^ZU",@^%ZOSF("TRAP"),ER=0
- G GO^BOPRNEW
- ;
- R(A,Z) ;Read the TCP/IP channel
- ;This module returns X each time it is called
- ;as a "line" of data (the text terminated by a $C(13)
- ;
- N BOPQ,Y
- RGO ;
- ;First look in "buffer" for a segment
- S Y=$F(BOPBUF,$C(13)),BOPQ=0
- I 'Y S BOPQ=1
- I Y S X=$E(BOPBUF,1,Y-2),BOPBUF=$E(BOPBUF,Y,9999) Q
- ;
- ;Since there was no discernable line in the buffer, read the channel
- S X="ERR^BOPRNEW",@^%ZOSF("TRAP")
- I $G(Z)["VAX" R X#200:$S($G(A):A,1:160)
- ;Compliant with M standard
- E R X:$S(A:A,1:60)
- ;
- ;Add what was read to the buffer
- I $L(X) S BOPBUF=BOPBUF_X
- ;
- ;If there was nothing in the buffer and nothing read then quit
- I BOPQ,'$L(X),$L(BOPBUF) S X=BOPBUF,BOPBUF=""
- I BOPBUF="",BOPQ Q
- S BOPQ=0 G RGO:$L(BOPBUF)
- Q
- TEST ;This is used for testing
- TSTGO ;
- W $C(11)
- W "MSH|^~\&|OMNICELLRX||PHARM||19940|260855||DFT^P03||P|2.2|",$C(13)
- W "PID|||6|6|MAQQIA^ALAN|",$C(13)
- W "PV1||NU4E^A22^Main2|",$C(13)
- W "FT1||||199401260855||V|1217712^ASPIRIN^03||OR123|1||||||||||NID^NNAME|DR123",$C(13)
- W "ZPM|V|OMNICELLRX|NUE100|3|A|12177121|ASPIRIN|U|112|112|1|NID|NNAME|WID|WNAME|222||Main2||NU4E||125|25|19940126085533||",$C(13)
- W $C(28,13),!
- H 9 R X:9
- U 0
- W !!,"Read from Channel (ACK?): "_X
- W !!,"Don't forget to close the channel."
- Q
- BOPRNEW ;IHS/ILC/ALG/CIA/PLS - ILC Listener;06-Feb-2007 21:19;SM
- +1 ;;1.0;AUTOMATED DISPENSING INTERFACE;**1,3**;Jul 26, 2005
- +2 QUIT
- DEBUG ;Call here for testing
- +1 DO DT^DICRW
- +2 SET BOPLSOC=9002
- SET BOPDIV=1
- +3 ;
- +4 ;Entry used as "ZTRTN" in BOPOMTR
- GO ; EP
- +1 IF $GET(BOPDIV)=""
- SET BOPDIV=1
- +2 ;
- +3 ;Quit if Channel Active field set to NO for Receiving Facility
- +4 IF '$PIECE($GET(^BOP(90355,1,3,BOPDIV,0)),U,2)
- GOTO QUIT
- +5 ;Quit if STOP field set to INTERFACE STOPPED
- +6 IF $PIECE($GET(^BOP(90355,1,12)),U,1)+0>0
- GOTO QUIT
- +7 ;
- +8 ;Lock / Test / Quit if a job is already running
- +9 LOCK +^BOP(90355,"L",BOPDIV):99
- IF '$TEST
- QUIT
- +10 ;
- +11 ;Listen on socket, start routine
- +12 NEW %A,ZISOS,X,NIO
- SET ZISOS=^%ZOSF("OS")
- +13 ;IHS exemption approved on March 16, 2005
- +14 IF $$NEWERR^%ZTER()
- NEW $ETRAP
- SET $ETRAP="D ERR^BOPRNEW"
- +15 IF '$TEST
- SET X="ERR^BOPRNEW"
- SET @^%ZOSF("TRAP")
- +16 ;
- +17 ;Open a channel. Parameter 1 is Socket, parameter 2 is the routine.
- +18 ;S IO("C")=1 ; If not commented out, the channel stops after 1 message
- +19 ;
- +20 ;If this side is supposed to be the client, make the connection
- +21 IF $PIECE(^BOP(90355,1,3,BOPDIV,0),U,8)="C"
- SET X=^(0)
- Begin DoDot:1
- +22 SET BOPLSOC=$PIECE(X,U,5)
- SET X=$PIECE(X,U,3)
- +23 DO CALL^%ZISTCP(X,BOPLSOC)
- IF POP
- QUIT
- +24 DO READ
- +25 KILL BOPLSOC
- End DoDot:1
- +26 ;
- QUIT QUIT
- +1 ;
- READ ;LISTEN^%ZISTCP will call here to read the message.
- +1 SET DIQUIET=1
- SET BOPBUF=""
- DO DT^DICRW
- +2 ;
- LOOP USE IO
- READ X:1
- HANG 1
- +1 ; all interfaces stopped
- IF $PIECE($GET(^BOP(90355,1,12)),U,1)+0>0
- GOTO QUIT
- +2 IF '$LENGTH(X)
- HANG 5
- IF +$GET(^BOP(90355,1,4))
- GOTO LOOP
- GOTO QUIT
- +3 SET BOPBUF=X
- LOOP1 DO RECEIVE(2)
- +1 ; all interfaces stopped
- IF $PIECE($GET(^BOP(90355,1,12)),U,1)+0>0
- GOTO QUIT
- +2 IF +$GET(^BOP(90355,1,4))
- IF $LENGTH(BOPBUF)
- GOTO LOOP1
- GOTO LOOP
- +3 GOTO QUIT
- +4 ;
- RECEIVE(BOPWAIT) ;
- +1 NEW I,J
- +2 ;
- +3 KILL BOPIN
- SET BOPI=0
- SET U="^"
- USE IO
- +4 ;Calculate Operating System to be able to read properly
- +5 IF '$DATA(BOPOS)
- SET BOPOS=^%ZOSF("OS")
- +6 IF BOPOS["MSM"
- GOTO RMSM
- +7 GOTO RR
- +8 ;
- +9 KILL BOPIN
- SET BOPI=0
- SET U="^"
- USE IO
- +10 ;
- RMSM ; go here if MSM
- +1 SET BOPOS("MSMVER")=$$VERSION^%ZOSV()
- +2 IF +BOPOS("MSMVER")=0
- SET BOPOS("MSMVER")=8
- +3 ;
- +4 ;Read
- +5 ;If there are multiple records, BOPIN needs to be
- +6 ;changed to a global array.
- +7 ;
- RR ;
- +1 FOR
- DO R(BOPWAIT,BOPOS)
- IF $SELECT(X=""
- QUIT
- Begin DoDot:1
- +2 IF $EXTRACT(X)=$CHAR(11)
- SET X=$EXTRACT(X,2,$LENGTH(X))
- IF X=""
- QUIT
- +3 SET BOPI=BOPI+1
- SET BOPIN(BOPI)=X
- End DoDot:1
- +4 ;
- +5 ;Quit if no data received
- +6 IF '$DATA(BOPIN)
- QUIT
- +7 ;
- +8 ;Quit if the wrong type of record
- +9 SET I=":"_$PIECE($PIECE(BOPIN(1),"|",9),U)_":"
- +10 IF "
- QUIT
- +11 ;
- +12 DO RSET
- +13 IF BOPBUF'=""
- KILL BOPIN
- SET BOPI=0
- GOTO RR
- +14 QUIT
- +15 ;
- RSET ; file new transaction
- +1 ;Create NEW Record
- +2 ;
- +3 ;First calculate now
- +4 SET DIC="^BOP(90355.1,"
- +5 SET X=$$NOW^XLFDT()
- +6 ;
- +7 ;Then make sure NOW is unique in the file
- +8 LOCK +^BOP(90355.1,0):1
- +9 FOR I=X:.000001
- IF '$DATA(^BOP(90355.1,"B",I))
- QUIT
- +10 KILL DD,DO
- SET X=I
- SET DIC="^BOP(90355.1,"
- SET DIC(0)="F"
- DO FILE^DICN
- +11 LOCK -^BOP(90355.1,0)
- +12 ;
- +13 ;Put data into file -- first mark it "NOT COMPLETE"
- +14 SET DIE=90355.1
- SET DR=".1///99;.12///"_BOPDIV_";99///1;99.1///1"
- SET DA=+Y
- +15 DO ^DIE
- +16 ;
- +17 ;Put data into file
- +18 SET J=0
- FOR I=0:0
- SET I=$ORDER(BOPIN(I))
- IF I<1
- QUIT
- SET J=J+1
- SET ^BOP(90355.1,DA,"DATA",J,0)=BOPIN(I)
- +19 SET ^BOP(90355.1,DA,"DATA",0)=U_U_J_U_J_U_$PIECE(^BOP(90355.1,DA,0),".")
- +20 ;
- +21 ;Mark transaction received and Acknowledge
- +22 SET DIE=90355.1
- SET DR="99.1///0"
- DO ^DIE
- SET BOPSTOP=1
- +23 SET ^BOP(90355.1,"AC",0,DA)=""
- +24 ; send ack back
- +25 KILL OUT
- NEW A,B
- SET A=BOPIN(1)
- SET $PIECE(A,"|",9)="ACK"
- +26 SET B=$PIECE(A,"|",2)
- IF B'["&"
- SET B=B_"&"
- SET $PIECE(A,"|",2)=B
- +27 SET B="MSA|AA|"_DA_"|"
- +28 SET OUT(1)=$CHAR(11)_A_$CHAR(13)
- SET OUT(2)=B_$CHAR(13)_$CHAR(28)_$CHAR(13)
- +29 SET A=0
- FOR
- SET A=$ORDER(OUT(A))
- IF 'A
- QUIT
- USE IO
- WRITE OUT(A),!
- +30 ; keep copy in file
- +31 SET OUT(0)=$HOROLOG
- MERGE ^BOP(90355.1,DA,"OUT")=OUT
- +32 KILL OUT,A,B
- +33 QUIT
- +34 ;
- RACK ; send ack back
- ERR ;
- +1 GOTO QUIT
- +2 ;
- +3 ;Job out at this line to start a new receiver at single division site.
- JOB NEW ZTIO,ZTDESC,ZTDTH,ZTRTN,ZTSAVE,ZTSK
- +1 SET ZTIO=""
- SET ZTDTH=$HOROLOG
- SET ZTRTN="JOBGO^BOPRNEW"
- SET ZTDESC="BOP LISTENER"
- +2 DO ^%ZTLOAD
- +3 IF '$GET(ZTSK)
- Begin DoDot:1
- +4 WRITE !,"BOPRNEW job startup Failed"
- End DoDot:1
- +5 QUIT
- JOBGO ;Start a new listener
- +1 SET X="Automated Dispense "_$JOB
- DO SETENV^%ZOSV
- DO DT^DICRW
- +2 SET I=$ORDER(^BOP(90355,1,3,1,0))
- IF I<1
- QUIT
- SET X=^(I,0)
- +3 SET BOPLSOC=$PIECE(X,U,5)
- SET BOPDIV=$PIECE(X,U)
- +4 SET X="ERR^ZU"
- SET @^%ZOSF("TRAP")
- SET ER=0
- +5 GOTO GO^BOPRNEW
- +6 ;
- R(A,Z) ;Read the TCP/IP channel
- +1 ;This module returns X each time it is called
- +2 ;as a "line" of data (the text terminated by a $C(13)
- +3 ;
- +4 NEW BOPQ,Y
- RGO ;
- +1 ;First look in "buffer" for a segment
- +2 SET Y=$FIND(BOPBUF,$CHAR(13))
- SET BOPQ=0
- +3 IF 'Y
- SET BOPQ=1
- +4 IF Y
- SET X=$EXTRACT(BOPBUF,1,Y-2)
- SET BOPBUF=$EXTRACT(BOPBUF,Y,9999)
- QUIT
- +5 ;
- +6 ;Since there was no discernable line in the buffer, read the channel
- +7 SET X="ERR^BOPRNEW"
- SET @^%ZOSF("TRAP")
- +8 IF $GET(Z)["VAX"
- READ X#200:$SELECT($GET(A):A,1:160)
- +9 ;Compliant with M standard
- +10 IF '$TEST
- READ X:$SELECT(A:A,1:60)
- +11 ;
- +12 ;Add what was read to the buffer
- +13 IF $LENGTH(X)
- SET BOPBUF=BOPBUF_X
- +14 ;
- +15 ;If there was nothing in the buffer and nothing read then quit
- +16 IF BOPQ
- IF '$LENGTH(X)
- IF $LENGTH(BOPBUF)
- SET X=BOPBUF
- SET BOPBUF=""
- +17 IF BOPBUF=""
- IF BOPQ
- QUIT
- +18 SET BOPQ=0
- IF $LENGTH(BOPBUF)
- GOTO RGO
- +19 QUIT
- TEST ;This is used for testing
- TSTGO ;
- +1 WRITE $CHAR(11)
- +2 WRITE "MSH|^~\&|OMNICELLRX||PHARM||19940|260855||DFT^P03||P|2.2|",$CHAR(13)
- +3 WRITE "PID|||6|6|MAQQIA^ALAN|",$CHAR(13)
- +4 WRITE "PV1||NU4E^A22^Main2|",$CHAR(13)
- +5 WRITE "FT1||||199401260855||V|1217712^ASPIRIN^03||OR123|1||||||||||NID^NNAME|DR123",$CHAR(13)
- +6 WRITE "ZPM|V|OMNICELLRX|NUE100|3|A|12177121|ASPIRIN|U|112|112|1|NID|NNAME|WID|WNAME|222||Main2||NU4E||125|25|19940126085533||",$CHAR(13)
- +7 WRITE $CHAR(28,13),!
- +8 HANG 9
- READ X:9
- +9 USE 0
- +10 WRITE !!,"Read from Channel (ACK?): "_X
- +11 WRITE !!,"Don't forget to close the channel."
- +12 QUIT