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 };
23
24 struct test_ctx {
25 struct mctp *mctp;
26 struct mctp_binding_bridge *bindings[2];
27 };
28
mctp_binding_bridge_tx(struct mctp_binding * b,struct mctp_pktbuf * pkt)29 static int mctp_binding_bridge_tx(struct mctp_binding *b,
30 struct mctp_pktbuf *pkt)
31 {
32 struct mctp_binding_bridge *binding =
33 container_of(b, struct mctp_binding_bridge, binding);
34
35 binding->tx_count++;
36 assert(mctp_pktbuf_size(pkt) == sizeof(struct mctp_hdr) + 1);
37 binding->last_pkt_data = *(uint8_t *)mctp_pktbuf_data(pkt);
38
39 return 0;
40 }
41
mctp_binding_bridge_rx(struct mctp_binding_bridge * binding,uint8_t key)42 static void mctp_binding_bridge_rx(struct mctp_binding_bridge *binding,
43 uint8_t key)
44 {
45 struct mctp_pktbuf *pkt;
46 struct mctp_hdr *hdr;
47 uint8_t *buf;
48
49 pkt = mctp_pktbuf_alloc(&binding->binding, sizeof(struct mctp_hdr) + 1);
50 assert(pkt);
51
52 hdr = mctp_pktbuf_hdr(pkt);
53 hdr->flags_seq_tag = MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM;
54
55 /* arbitrary src/dest, as we're bridging */
56 hdr->src = 1;
57 hdr->dest = 2;
58
59 buf = mctp_pktbuf_data(pkt);
60 *buf = key;
61
62 binding->rx_count++;
63 mctp_bus_rx(&binding->binding, pkt);
64 }
65
mctp_binding_bridge_init(char * name)66 static struct mctp_binding_bridge *mctp_binding_bridge_init(char *name)
67 {
68 struct mctp_binding_bridge *binding;
69
70 binding = __mctp_alloc(sizeof(*binding));
71 memset(binding, 0, sizeof(*binding));
72 binding->binding.name = name;
73 binding->binding.version = 1;
74 binding->binding.tx = mctp_binding_bridge_tx;
75 binding->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
76 binding->binding.pkt_header = 0;
77 binding->binding.pkt_trailer = 0;
78 return binding;
79 }
80
main(void)81 int main(void)
82 {
83 struct test_ctx _ctx, *ctx = &_ctx;
84 ctx->mctp = mctp_init();
85
86 ctx->bindings[0] = mctp_binding_bridge_init("binding0");
87 ctx->bindings[1] = mctp_binding_bridge_init("binding1");
88 mctp_bridge_busses(ctx->mctp, &ctx->bindings[0]->binding,
89 &ctx->bindings[1]->binding);
90
91 mctp_binding_set_tx_enabled(&ctx->bindings[0]->binding, true);
92 mctp_binding_set_tx_enabled(&ctx->bindings[1]->binding, true);
93
94 mctp_binding_bridge_rx(ctx->bindings[0], 0xaa);
95 assert(ctx->bindings[0]->tx_count == 0);
96 assert(ctx->bindings[1]->tx_count == 1);
97 assert(ctx->bindings[1]->last_pkt_data == 0xaa);
98
99 mctp_binding_bridge_rx(ctx->bindings[1], 0x55);
100 assert(ctx->bindings[1]->tx_count == 1);
101 assert(ctx->bindings[0]->tx_count == 1);
102 assert(ctx->bindings[0]->last_pkt_data == 0x55);
103
104 __mctp_free(ctx->bindings[1]);
105 __mctp_free(ctx->bindings[0]);
106 mctp_destroy(ctx->mctp);
107
108 return EXIT_SUCCESS;
109 }
110