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 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 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 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 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