xref: /openbmc/libmctp/utils/mctp-pipe.c (revision 69eda31b)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 
3 #include "compiler.h"
4 #include "libmctp.h"
5 #include "libmctp-serial.h"
6 
7 #include <assert.h>
8 #include <err.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <sys/poll.h>
13 #include <sys/socket.h>
14 
15 static void rx_message(uint8_t eid __unused, bool tag_owner __unused,
16 		       uint8_t msg_tag __unused, void *data __unused, void *msg,
17 		       size_t len)
18 {
19 	ssize_t rc;
20 
21 	rc = write(STDOUT_FILENO, msg, len);
22 	if (rc < 0)
23 		warn("Write failed");
24 	else if ((size_t)rc < len)
25 		warnx("Short write of length %zd, requested %zd", rc, len);
26 }
27 
28 int main(void)
29 {
30 	struct mctp_binding_serial *serial[2];
31 	mctp_eid_t eids[] = { 8, 9 };
32 	struct pollfd pollfds[3];
33 	int rc, n, mctp_fds[2];
34 	struct mctp *mctp[2];
35 
36 	mctp[0] = mctp_init();
37 	mctp[1] = mctp_init();
38 
39 	assert(mctp[0] && mctp[1]);
40 
41 	serial[0] = mctp_serial_init();
42 	serial[1] = mctp_serial_init();
43 
44 	assert(serial[0] && serial[1]);
45 
46 	rc = socketpair(AF_UNIX, SOCK_STREAM, 0, mctp_fds);
47 	if (rc)
48 		err(EXIT_FAILURE, "Can't create sockets");
49 
50 	mctp_serial_open_fd(serial[0], mctp_fds[0]);
51 	mctp_serial_open_fd(serial[1], mctp_fds[1]);
52 
53 	mctp_register_bus(mctp[0], mctp_binding_serial_core(serial[0]),
54 			  eids[0]);
55 	mctp_register_bus(mctp[1], mctp_binding_serial_core(serial[1]),
56 			  eids[1]);
57 
58 	mctp_set_rx_all(mctp[1], rx_message, NULL);
59 
60 	pollfds[0].fd = mctp_fds[0];
61 	pollfds[0].events = POLLIN;
62 	pollfds[1].fd = mctp_fds[1];
63 	pollfds[1].events = POLLIN;
64 	pollfds[2].fd = STDIN_FILENO;
65 	pollfds[2].events = POLLIN;
66 	n = 3;
67 
68 	for (;;) {
69 		uint8_t buf[1024];
70 
71 		rc = poll(pollfds, n, -1);
72 		if (rc < 0)
73 			return EXIT_FAILURE;
74 
75 		if (pollfds[0].revents) {
76 			rc = mctp_serial_read(serial[0]);
77 			if (rc)
78 				pollfds[0].fd = -1;
79 		}
80 
81 		if (pollfds[1].revents) {
82 			rc = mctp_serial_read(serial[1]);
83 			if (rc)
84 				pollfds[1].fd = -1;
85 		}
86 
87 		if (n > 2 && pollfds[2].revents) {
88 			rc = read(STDIN_FILENO, buf, sizeof(buf));
89 			if (rc == 0) {
90 				n = 2;
91 				close(mctp_fds[0]);
92 				pollfds[0].fd = -1;
93 			} else if (rc < 0) {
94 				err(EXIT_FAILURE, "read");
95 			} else {
96 				mctp_message_tx(mctp[0], eids[1],
97 						MCTP_MESSAGE_TO_SRC, 0, buf,
98 						rc);
99 			}
100 		}
101 
102 		if (n == 2 && pollfds[0].fd < 0 && pollfds[1].fd < 0)
103 			break;
104 	}
105 
106 	return EXIT_SUCCESS;
107 }
108