xref: /openbmc/libmctp/tests/test_bridge.c (revision ca85ad86)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 
8 #include <libmctp.h>
9 #include <libmctp-alloc.h>
10 
11 #include "test-utils.h"
12 
13 struct mctp_binding_bridge {
14 	struct mctp_binding binding;
15 	int rx_count;
16 	int tx_count;
17 	uint8_t last_pkt_data;
18 };
19 
20 struct test_ctx {
21 	struct mctp *mctp;
22 	struct mctp_binding_bridge *bindings[2];
23 };
24 
25 static int mctp_binding_bridge_tx(struct mctp_binding *b,
26 				  struct mctp_pktbuf *pkt)
27 {
28 	struct mctp_binding_bridge *binding =
29 		container_of(b, struct mctp_binding_bridge, binding);
30 
31 	binding->tx_count++;
32 	assert(mctp_pktbuf_size(pkt) == sizeof(struct mctp_hdr) + 1);
33 	binding->last_pkt_data = *(uint8_t *)mctp_pktbuf_data(pkt);
34 
35 	return 0;
36 }
37 
38 static void mctp_binding_bridge_rx(struct mctp_binding_bridge *binding,
39 				   uint8_t key)
40 {
41 	struct mctp_pktbuf *pkt;
42 	struct mctp_hdr *hdr;
43 	uint8_t *buf;
44 
45 	pkt = mctp_pktbuf_alloc(&binding->binding, sizeof(struct mctp_hdr) + 1);
46 	assert(pkt);
47 
48 	hdr = mctp_pktbuf_hdr(pkt);
49 	hdr->flags_seq_tag = MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM;
50 
51 	/* arbitrary src/dest, as we're bridging */
52 	hdr->src = 1;
53 	hdr->dest = 2;
54 
55 	buf = mctp_pktbuf_data(pkt);
56 	*buf = key;
57 
58 	binding->rx_count++;
59 	mctp_bus_rx(&binding->binding, pkt);
60 }
61 
62 static struct mctp_binding_bridge *mctp_binding_bridge_init(char *name)
63 {
64 	struct mctp_binding_bridge *binding;
65 
66 	binding = __mctp_alloc(sizeof(*binding));
67 	memset(binding, 0, sizeof(*binding));
68 	binding->binding.name = name;
69 	binding->binding.version = 1;
70 	binding->binding.tx = mctp_binding_bridge_tx;
71 	binding->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
72 	binding->binding.pkt_header = 0;
73 	binding->binding.pkt_trailer = 0;
74 	return binding;
75 }
76 
77 int main(void)
78 {
79 	struct test_ctx _ctx, *ctx = &_ctx;
80 
81 	ctx->mctp = mctp_init();
82 
83 	ctx->bindings[0] = mctp_binding_bridge_init("binding0");
84 	ctx->bindings[1] = mctp_binding_bridge_init("binding1");
85 	mctp_bridge_busses(ctx->mctp, &ctx->bindings[0]->binding,
86 			   &ctx->bindings[1]->binding);
87 
88 	mctp_binding_set_tx_enabled(&ctx->bindings[0]->binding, true);
89 	mctp_binding_set_tx_enabled(&ctx->bindings[1]->binding, true);
90 
91 	mctp_binding_bridge_rx(ctx->bindings[0], 0xaa);
92 	assert(ctx->bindings[0]->tx_count == 0);
93 	assert(ctx->bindings[1]->tx_count == 1);
94 	assert(ctx->bindings[1]->last_pkt_data == 0xaa);
95 
96 	mctp_binding_bridge_rx(ctx->bindings[1], 0x55);
97 	assert(ctx->bindings[1]->tx_count == 1);
98 	assert(ctx->bindings[0]->tx_count == 1);
99 	assert(ctx->bindings[0]->last_pkt_data == 0x55);
100 
101 	__mctp_free(ctx->bindings[1]);
102 	__mctp_free(ctx->bindings[0]);
103 	mctp_destroy(ctx->mctp);
104 
105 	return EXIT_SUCCESS;
106 }
107