xref: /openbmc/libmctp/tests/test_cmds.c (revision e62b4257)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 
3 #include "test-utils.h"
4 
5 #include <stdio.h>
6 #include <string.h>
7 #include <assert.h>
8 
9 #include <libmctp.h>
10 #include <libmctp-alloc.h>
11 #include <libmctp-cmds.h>
12 
13 #ifdef NDEBUG
14 #undef NDEBUG
15 #endif
16 
17 static const mctp_eid_t eid_1 = 9;
18 static const mctp_eid_t eid_2 = 10;
19 
20 struct msg_payload {
21 	struct mctp_hdr hdr;
22 	struct mctp_ctrl_msg_hdr ctrl_hdr;
23 };
24 
25 struct callback_data {
26 	uint8_t invoked;
27 	union {
28 		uint8_t command_code;
29 		uint8_t completion_code;
30 	};
31 };
32 
33 #define __unused __attribute__((unused))
34 
35 static void control_message_transport_callback(mctp_eid_t src __unused,
36 					       void *data, void *buf,
37 					       size_t len __unused)
38 {
39 	struct callback_data *ctx = data;
40 	struct mctp_ctrl_msg_hdr *msg_hdr = buf;
41 	printf("Transport control message received - command code: 0x%X\n",
42 	       msg_hdr->command_code);
43 	ctx->invoked++;
44 	assert(msg_hdr->command_code == ctx->command_code);
45 }
46 
47 static void rcv_ctrl_msg(struct mctp_binding *b, const void *buf, size_t len)
48 {
49 	struct mctp_pktbuf *pkt = mctp_pktbuf_alloc(b, len);
50 	memcpy(mctp_pktbuf_hdr(pkt), buf, len);
51 	mctp_bus_rx(b, pkt);
52 }
53 
54 static void setup_test_binding(struct mctp_binding *test_binding,
55 			       struct mctp *test_endpoint, void *callback_ctx)
56 {
57 	assert(test_binding != NULL);
58 	assert(test_endpoint != NULL);
59 	assert(callback_ctx != NULL);
60 
61 	memset(test_binding, 0, sizeof(*test_binding));
62 	test_binding->name = "test";
63 	test_binding->version = 1;
64 	test_binding->tx = NULL;
65 	test_binding->pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
66 	test_binding->pkt_pad = 0;
67 	test_binding->control_rx = control_message_transport_callback;
68 	test_binding->control_rx_data = callback_ctx;
69 
70 	mctp_register_bus(test_endpoint, test_binding, eid_1);
71 	mctp_binding_set_tx_enabled(test_binding, true);
72 }
73 
74 static void send_transport_control_message(void)
75 {
76 	struct mctp *endpoint = mctp_init();
77 	struct mctp_binding binding;
78 	struct callback_data ctx;
79 	static const struct msg_payload send_control_message_payload = {
80 		.hdr = {
81 			.dest = eid_1,
82 			.src = eid_2,
83 			.flags_seq_tag = MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM,
84 		},
85 		.ctrl_hdr = {
86 			.ic_msg_type = MCTP_CTRL_HDR_MSG_TYPE,
87 			.rq_dgram_inst = MCTP_CTRL_HDR_FLAG_REQUEST,
88 			.command_code = 0xF2,
89 		},
90 	};
91 
92 	memset(&ctx, 0, sizeof(ctx));
93 	setup_test_binding(&binding, endpoint, &ctx);
94 	ctx.command_code = send_control_message_payload.ctrl_hdr.command_code;
95 	printf("Sending transport control message: 0x%X\n",
96 	       send_control_message_payload.ctrl_hdr.command_code);
97 	rcv_ctrl_msg(&binding, (void *)&send_control_message_payload,
98 		     sizeof(send_control_message_payload));
99 	assert(ctx.invoked == 1);
100 
101 	mctp_destroy(endpoint);
102 }
103 
104 int main(void)
105 {
106 	send_transport_control_message();
107 
108 	return EXIT_SUCCESS;
109 }
110