xref: /openbmc/libmctp/tests/test_seq.c (revision e62b4257)
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