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