Awesome! Yes it is fortran, openVMS. I am communicating with a windows box using modbus commands.
here is the write and read
65478 CONTINUE
I_STAT = SYS$QIOW( ! Issue the command
1 , %VAL( J_TCP_CHAN )
2 , %VAL( IO$_WRITEVBLK )
3 , %REF(IOSB_QIO)
4 ,
5 ,
6 , %REF( SC_DATA ) ! P1
7 , %VAL(36) ! P2
8 , ! P3
9 , ! P4
1 , ! P5
2 , ! P6
3 )
c WMC ZERO out reply message
CALL LIB$MOVC5 (0,0,0, SIZEOF (IN_CMD), IN_CMD)
c *** Modbus Command Reply, starts at byte 7 in the QIOW. These returned values should match the sent command.
c *** (7) = Modbus Slave Device (returned)
c *** (8) = Modbus Command (returned - should equal sent message)
c *** (9) = Byte Count (returned)
I_STAT = SYS$QIOW( ! get command response
1 , %VAL( J_TCP_CHAN ) ! first 6 bytes
2 , %VAL( IO$_READVBLK ) ! byte 6 is # of bytes to follow
3 , %REF(IOSB_QIO)
4 ,
5 ,
6 , %REF( IN_CMD ) ! P1
7 , %VAL(13) ! P2
8 , ! P3
9 , ! P4
1 , ! P5
1 , ! P6
2 )
here is the setup
C Setup structures for IP QIOs
I_CMD(1) = 4
I_CMD(2) = %LOC(B_CMD)
I_ADDR_PTR(1) = 8
I_ADDR_PTR(2) = %LOC(B_ADDR_BUF)
C Convert local host adapter name to an IP address
I_STAT = SYS$QIOW (
1 , %VAL( J_TCP_CHAN )
2 , %VAL( IO$_ACPCONTROL )
3 , IOSB_QIO_TCP
4 ,
5 ,
6 , I_CMD ! P1
7 , C_LCL_HOST_NAME ! P2
8 , J_ADDR_LEN ! P3
9 , I_ADDR_PTR ! P4
1 , ! P5
1 , ! P6
2 )
IF( I_STAT ) ! Was the call
1 THEN ! Good
CONTINUE
ELSE
I_RET_STAT = -20
GOTO 99000
END IF
IF( IOSB_QIO_TCP.J_COMPL_CODE ) ! Was the QIO
1 THEN ! Good
CONTINUE
ELSE
I_RET_STAT = -21
GOTO 99000
END IF ! Put data into common
LCL_HOST_ADDR.I_DATA_STR_LEN = 16 ! Len of the data structure
LCL_HOST_ADDR.I_ADDR = %LOC( LCL_SOCK_ADDR ) ! address of data structure
LCL_HOST_ADDR.I_RET_LEN_ADDR = %LOC(I_RET_LEN)
LCL_SOCK_ADDR.J_ADDR_DOMAIN = INET$C_AF_INET
J_TMP_PORT_NUM = J_LCL_PORT_NUM
LCL_SOCK_ADDR.B_PORT_NUM(1) = B_TMP_PORT_NUM(2) ! Flip for network byte order
LCL_SOCK_ADDR.B_PORT_NUM(2) = B_TMP_PORT_NUM(1)
LCL_SOCK_ADDR.B_IP_ADDR(1) = B_ADDR_BUF(1) ! IP address in
LCL_SOCK_ADDR.B_IP_ADDR(2) = B_ADDR_BUF(2) ! network byte order
LCL_SOCK_ADDR.B_IP_ADDR(3) = B_ADDR_BUF(3) ! for 165.156.6.40 for
LCL_SOCK_ADDR.B_IP_ADDR(4) = B_ADDR_BUF(4) ! HSAPRM.
C Convert remote host adapter name to an IP address
I_STAT = SYS$QIOW (
1 , %VAL( J_TCP_CHAN )
2 , %VAL( IO$_ACPCONTROL )
3 , IOSB_QIO_TCP
4 ,
5 ,
6 , I_CMD ! P1
7 , C_RMT_HOST_NAME ! P2
8 , J_ADDR_LEN ! P3
9 , I_ADDR_PTR ! P4
1 , ! P5
1 , ! P6
2 )
IF( I_STAT ) ! Was the call
1 THEN ! Good
CONTINUE
ELSE
I_RET_STAT = -30
GOTO 99000
END IF
IF( IOSB_QIO_TCP.J_COMPL_CODE ) ! Was the QIO
1 THEN ! Good
CONTINUE
ELSE
I_RET_STAT = -31
GOTO 99000
END IF ! Put data into common
RMT_HOST_ADDR.I_DATA_STR_LEN = 16 ! Len of the data structure
RMT_HOST_ADDR.I_ADDR = %LOC( RMT_SOCK_ADDR ) ! address of data structure
RMT_HOST_ADDR.I_RET_LEN_ADDR = %LOC(I_RET_LEN)
RMT_SOCK_ADDR.J_ADDR_DOMAIN = INET$C_AF_INET
J_TMP_PORT_NUM = J_RMT_PORT_NUM
RMT_SOCK_ADDR.B_PORT_NUM(1) = B_TMP_PORT_NUM(2) ! Flip for network byte order
RMT_SOCK_ADDR.B_PORT_NUM(2) = B_TMP_PORT_NUM(1)
RMT_SOCK_ADDR.B_IP_ADDR(1) = B_ADDR_BUF(1) ! IP address in
RMT_SOCK_ADDR.B_IP_ADDR(2) = B_ADDR_BUF(2) ! network byte order
RMT_SOCK_ADDR.B_IP_ADDR(3) = B_ADDR_BUF(3) ! for 165.156.6.40 for
RMT_SOCK_ADDR.B_IP_ADDR(4) = B_ADDR_BUF(4) ! HSAPRM.
C Structure for creating a local socket
C SOCK_CHAR.J_PROTOCOL_TYPE = UCX$C_TCP ! Protocol is TCP/IP
SOCK_CHAR.J_PROTOCOL_TYPE = TCPIP$C_TCP ! Protocol is TCP/IP
C SOCK_CHAR.B_SOCK_TYPE = UCX$C_STREAM ! Socket type is stream
SOCK_CHAR.B_SOCK_TYPE = TCPIP$C_STREAM ! Socket type is stream
C Structure for binding to a socket
ITEM_LIST.J_DATA_STR_LEN = 4
C ITEM_LIST.J_PARM_NAME = UCX$C_REUSEADDR
ITEM_LIST.J_PARM_NAME = TCPIP$C_REUSEADDR
ITEM_LIST.I_ADDR_PTR = %LOC(I_ON)
OPTN.J_DATA_STR_LEN = 8
C OPTN.J_PARM_NAME = UCX$C_SOCKOPT
OPTN.J_PARM_NAME = TCPIP$C_SOCKOPT
OPTN.I_ADDR_PTR = %LOC(ITEM_LIST)
I_STAT = SYS$QIOW (
1 , %VAL( J_TCP_CHAN )
2 , %VAL( IO$_SETMODE )
3 , IOSB_QIO_TCP
4 ,
5 ,
6 , %REF(SOCK_CHAR) ! P1
7 , ! P2
CCC 8 , %REF(LCL_HOST_ADDR) ! P3
9 , ! P4
1 , ! P5
1 , ! P5
1 , ! P5
C 1 %REF(OPTN), ! P6
2 )