xref: /openbmc/libmctp/tests/test_serial.c (revision 13a4041f)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 
3 #define _GNU_SOURCE
4 
5 #if HAVE_CONFIG_H
6 #include "config.h"
7 #endif
8 
9 #include "libmctp-log.h"
10 #include "libmctp-serial.h"
11 
12 #ifdef NDEBUG
13 #undef NDEBUG
14 #endif
15 
16 #include <assert.h>
17 #include <fcntl.h>
18 #include <stdbool.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <unistd.h>
22 
23 struct mctp_binding_serial_pipe {
24 	int ingress;
25 	int egress;
26 
27 	struct mctp_binding_serial *serial;
28 };
29 
30 static int mctp_binding_serial_pipe_tx(void *data, void *buf, size_t len)
31 {
32 	struct mctp_binding_serial_pipe *ctx = data;
33 	ssize_t rc;
34 
35 	rc = write(ctx->egress, buf, len);
36 	assert(rc == len);
37 }
38 
39 uint8_t mctp_msg_src[2 * MCTP_BTU];
40 
41 static bool seen;
42 
43 static void rx_message(uint8_t eid, void *data, void *msg, size_t len)
44 {
45 	uint8_t type;
46 
47 	type = *(uint8_t *)msg;
48 
49 	mctp_prdebug("MCTP message received: len %zd, type %d", len, type);
50 
51 	assert(sizeof(mctp_msg_src) == len);
52 	assert(!memcmp(mctp_msg_src, msg, len));
53 
54 	seen = true;
55 }
56 
57 struct serial_test {
58 	struct mctp_binding_serial_pipe binding;
59 	struct mctp *mctp;
60 };
61 
62 int main(void)
63 {
64 	struct serial_test scenario[2];
65 
66 	struct mctp_binding_serial_pipe *a = &scenario[0].binding;
67 	struct mctp_binding_serial_pipe *b = &scenario[1].binding;
68 	int p[2][2];
69 	int rc;
70 
71 	mctp_set_log_stdio(MCTP_LOG_DEBUG);
72 
73 	memset(&mctp_msg_src[0], 0x5a, MCTP_BTU);
74 	memset(&mctp_msg_src[MCTP_BTU], 0xa5, MCTP_BTU);
75 
76 	rc = pipe(p[0]);
77 	assert(!rc);
78 
79 	rc = pipe(p[1]);
80 	assert(!rc);
81 
82 	/* Instantiate the A side of the serial pipe */
83 	scenario[0].mctp = mctp_init();
84 	assert(scenario[0].mctp);
85 	a->serial = mctp_serial_init();
86 	assert(a->serial);
87 	a->ingress = p[0][0];
88 	a->egress = p[1][1];
89 	mctp_serial_open_fd(a->serial, a->ingress);
90 	mctp_serial_set_tx_fn(a->serial, mctp_binding_serial_pipe_tx, a);
91 	mctp_register_bus(scenario[0].mctp, mctp_binding_serial_core(a->serial), 8);
92 
93 	/* Instantiate the B side of the serial pipe */
94 	scenario[1].mctp = mctp_init();
95 	assert(scenario[1].mctp);
96 	mctp_set_rx_all(scenario[1].mctp, rx_message, NULL);
97 	b->serial = mctp_serial_init();
98 	assert(b->serial);
99 	b->ingress = p[1][0];
100 	b->egress = p[0][1];
101 	mctp_serial_open_fd(b->serial, b->ingress);
102 	mctp_serial_set_tx_fn(b->serial, mctp_binding_serial_pipe_tx, a);
103 	mctp_register_bus(scenario[1].mctp, mctp_binding_serial_core(b->serial), 9);
104 
105 	/* Transmit a message from A to B */
106 	rc = mctp_message_tx(scenario[0].mctp, 9, mctp_msg_src, sizeof(mctp_msg_src));
107 	assert(rc == 0);
108 
109 	/* Read the message at B from A */
110 	seen = false;
111 	mctp_serial_read(b->serial);
112 	assert(seen);
113 
114 	return 0;
115 }
116