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 10 #include "test-utils.h" 11 12 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 13 14 struct test_ctx { 15 struct mctp *mctp; 16 struct mctp_binding_test *binding; 17 int rx_count; 18 uint8_t rx_data[4]; 19 size_t rx_len; 20 }; 21 22 static void test_rx(uint8_t eid, void *data, void *msg, size_t len) 23 { 24 struct test_ctx *ctx = data; 25 26 (void)eid; 27 28 ctx->rx_count++; 29 30 /* append incoming message data to the existing rx_data */ 31 assert(len <= sizeof(ctx->rx_data)); 32 assert(ctx->rx_len + len <= sizeof(ctx->rx_data)); 33 34 memcpy(ctx->rx_data + ctx->rx_len, msg, len); 35 ctx->rx_len += len; 36 } 37 38 #define SEQ(x) (x << MCTP_HDR_SEQ_SHIFT) 39 40 struct test { 41 int n_packets; 42 uint8_t flags_seq_tags[4]; 43 int exp_rx_count; 44 size_t exp_rx_len; 45 } tests[] = { 46 { 47 /* single packet */ 48 .n_packets = 1, 49 .flags_seq_tags = { 50 SEQ(1) | MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM, 51 }, 52 .exp_rx_count = 1, 53 .exp_rx_len = 1, 54 }, 55 { 56 /* two packets: one start, one end */ 57 .n_packets = 2, 58 .flags_seq_tags = { 59 SEQ(1) | MCTP_HDR_FLAG_SOM, 60 SEQ(2) | MCTP_HDR_FLAG_EOM, 61 }, 62 .exp_rx_count = 1, 63 .exp_rx_len = 2, 64 }, 65 { 66 /* three packets: one start, one no flags, one end */ 67 .n_packets = 3, 68 .flags_seq_tags = { 69 SEQ(1) | MCTP_HDR_FLAG_SOM, 70 SEQ(2), 71 SEQ(3) | MCTP_HDR_FLAG_EOM, 72 }, 73 .exp_rx_count = 1, 74 .exp_rx_len = 3, 75 }, 76 { 77 /* two packets, wrapping sequence numbers */ 78 .n_packets = 2, 79 .flags_seq_tags = { 80 SEQ(3) | MCTP_HDR_FLAG_SOM, 81 SEQ(0) | MCTP_HDR_FLAG_EOM, 82 }, 83 .exp_rx_count = 1, 84 .exp_rx_len = 2, 85 }, 86 { 87 /* two packets, invalid sequence number */ 88 .n_packets = 2, 89 .flags_seq_tags = { 90 SEQ(1) | MCTP_HDR_FLAG_SOM, 91 SEQ(3) | MCTP_HDR_FLAG_EOM, 92 }, 93 .exp_rx_count = 0, 94 .exp_rx_len = 0, 95 }, 96 }; 97 98 static void run_one_test(struct test_ctx *ctx, struct test *test) 99 { 100 const mctp_eid_t local_eid = 8; 101 const mctp_eid_t remote_eid = 9; 102 struct { 103 struct mctp_hdr hdr; 104 uint8_t payload[1]; 105 } pktbuf; 106 int i; 107 108 ctx->rx_count = 0; 109 ctx->rx_len = 0; 110 111 mctp_test_stack_init(&ctx->mctp, &ctx->binding, local_eid); 112 113 mctp_set_rx_all(ctx->mctp, test_rx, ctx); 114 115 for (i = 0; i < test->n_packets; i++) { 116 memset(&pktbuf, 0, sizeof(pktbuf)); 117 pktbuf.hdr.dest = local_eid; 118 pktbuf.hdr.src = remote_eid; 119 pktbuf.hdr.flags_seq_tag = test->flags_seq_tags[i]; 120 pktbuf.payload[0] = i; 121 122 mctp_binding_test_rx_raw(ctx->binding, 123 &pktbuf, sizeof(pktbuf)); 124 } 125 126 assert(ctx->rx_count == test->exp_rx_count); 127 assert(ctx->rx_len == test->exp_rx_len); 128 129 /* ensure the payload data was reconstructed correctly */ 130 for (i = 0; i < (int)ctx->rx_len; i++) 131 assert(ctx->rx_data[i] == i); 132 133 mctp_binding_test_destroy(ctx->binding); 134 mctp_destroy(ctx->mctp); 135 } 136 137 138 int main(void) 139 { 140 struct test_ctx ctx; 141 unsigned int i; 142 143 for (i = 0; i < ARRAY_SIZE(tests); i++) 144 run_one_test(&ctx, &tests[i]); 145 146 return EXIT_SUCCESS; 147 } 148