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