1 /* mbusio.c -- input/output through Modbus TCP */
9 #include <sys/select.h>
14 int get16 (char *msg) {
15 return ((int) msg [0]) | (((int) msg [1]) << 8);
18 void set16 (char *msg, int val) {
19 msg [0] = val & 0x00ff;
20 msg [1] = (val >> 8) & 0x00ff;
24 int main (int argc, char *argv []) {
27 if ((argc < 1) || (argc > 3)) {
28 fprintf (stderr, "Usage: %s [addr [port]]\n where addr defaults to 127.0.0.1 and port defaults to 502\nSend and receive slave+PDU over Modbus TCP, so each message is formatted\nSLAVE/8,FUNCTION/8,DATA/n\nThe TCP headering is handled by this utility\n", argv [0]);
31 char *addr = "127.0.0.1";
39 struct sockaddr_storage ss;
40 if (!socket_parse (addr, port, (struct sockaddr *) &ss)) {
41 perror ("Cannot parse address and/or port");
45 if (!socket_client ((struct sockaddr *) &ss, SOCK_STREAM, &sox)) {
46 perror ("Cannot connect to Modbus TCP");
55 if (select (sox+1, &sel, NULL, NULL, NULL) < 0) {
56 perror ("Select failed");
59 if (FD_ISSET (sox, &sel)) {
61 int len = read (sox, buf, 6+256);
63 perror ("Error reading");
66 fprintf (stderr, "MBAP header too short\n");
68 } else if (get16 (buf+0) != txnid_recv % 65536) {
69 fprintf (stderr, "MBAP txnid is bad\n");
71 } else if (get16 (buf+2) != 0) {
72 fprintf (stderr, "MBAP protoid is bad\n");
74 } else if (get16 (buf+4) != len - 7) {
75 fprintf (stderr, "MBAP length is bad\n");
77 } else if (txnid_recv >= txnid_send) {
78 fprintf (stderr, "Reply without Query\n");
81 if (write (1, buf+6, len-6) < len-6) {
82 perror ("Partial write");
88 if (FD_ISSET (0, &sel)) {
90 int len = read (0, buf+6, 256);
92 perror ("Error on stdin");
95 set16 (buf+0, txnid_send % 65536);
98 if (write (sox, buf, 6+len) < 6+len) {
99 perror ("Partial output");