summaryrefslogtreecommitdiff
path: root/zephyr/test/drivers/default/src/uart_hostcmd.c
blob: 879e7348372b7b2bbbbf577f2c5e047bed106d1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/* Copyright 2022 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <zephyr/kernel.h>
#include <zephyr/ztest.h>

#include "console.h"
#include "host_command.h"
#include "uart.h"
#include "test/drivers/test_state.h"

/** Messages used in test */
static const char msg1[] = "test";
static const char msg2[] = "uart_hostcmd";
static const char msg3[] = "message3";

/** Length of message excluding NULL char at the end */
#define MSG_LEN(msg) (sizeof(msg) - 1)

/**
 * Write message 1 before first snapshot. Read everything from buffer. Create
 * second snapshot. Write message 2 after it.
 */
static void setup_snapshots_and_messages(void *unused)
{
	char response[1024];
	struct host_cmd_handler_args read_args =
		BUILD_HOST_COMMAND_RESPONSE(EC_CMD_CONSOLE_READ, 0, response);
	struct host_cmd_handler_args args =
		BUILD_HOST_COMMAND_SIMPLE(EC_CMD_CONSOLE_SNAPSHOT, 0);

	/* Set first snapshot before first message */
	zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL);
	cputs(CC_COMMAND, msg1);

	/* Read everything from buffer */
	do {
		/* Clear response size before executing command */
		read_args.response_size = 0;
		zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args),
			      NULL);
	} while (read_args.response_size != 0);

	/* Set second snapshot after first message */
	zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL);
	cputs(CC_COMMAND, msg2);
}

/**
 * Test if read next variant of console read host command is working. ver
 * argument allows to change version of command. In case of version 1, parameter
 * with sub command is provided.
 */
static void test_uart_hc_read_next(int ver)
{
	/* Should be able to read whole buffer in one command */
	char response[CONFIG_PLATFORM_EC_HOSTCMD_CONSOLE_BUF_SIZE + 1];
	struct ec_params_console_read_v1 params;
	struct host_cmd_handler_args read_args =
		BUILD_HOST_COMMAND_RESPONSE(EC_CMD_CONSOLE_READ, ver, response);
	struct host_cmd_handler_args snap_args =
		BUILD_HOST_COMMAND_SIMPLE(EC_CMD_CONSOLE_SNAPSHOT, 0);
	char *msg1_start;
	char *msg2_start;
	char *msg3_start;

	/* Set up host command parameters */
	if (ver == 1) {
		read_args.params = &params;
		read_args.params_size = sizeof(params);
		params.subcmd = CONSOLE_READ_NEXT;
	}

	read_args.response_size = 0;
	zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args), NULL);
	zassert_equal('\0', response[read_args.response_size],
		      "Last byte of response is not '\\0' (got 0x%x)",
		      response[read_args.response_size]);

	/*
	 * Whole buffer until snapshot should be in response, check if it ends
	 * with message 1 which should start at the end of response excluding
	 * NULL char.
	 */
	msg1_start = response + read_args.response_size - 1 - MSG_LEN(msg1);
	zassert_mem_equal(msg1, msg1_start, MSG_LEN(msg1),
			  "expected \"%s\", got \"%.*s\"", msg1, MSG_LEN(msg1),
			  msg1_start);

	/* Set new snapshot which should include message 2 */
	zassert_equal(EC_RES_SUCCESS, host_command_process(&snap_args), NULL);

	read_args.response_size = 0;
	zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args), NULL);
	zassert_equal('\0', response[read_args.response_size],
		      "Last byte of response is not '\\0' (got 0x%x)",
		      response[read_args.response_size]);

	/*
	 * Whole buffer should be in response, check if it ends with both
	 * messages. Message 2 should start at the end of response excluding
	 * NULL char.
	 */
	msg2_start = response + read_args.response_size - 1 - MSG_LEN(msg2);
	msg1_start = msg2_start - MSG_LEN(msg1);
	zassert_mem_equal(msg2, msg2_start, MSG_LEN(msg2),
			  "expected \"%s\", got \"%.*s\"", msg2, MSG_LEN(msg2),
			  msg2_start);
	zassert_mem_equal(msg1, msg1_start, MSG_LEN(msg1),
			  "expected \"%s\", got \"%.*s\"", msg1, MSG_LEN(msg1),
			  msg1_start);

	/* Append third message */
	cputs(CC_COMMAND, msg3);

	/* Check read next without new snapshot, no data should be read */
	read_args.response_size = 0;
	zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args), NULL);
	zassert_equal(0, read_args.response_size,
		      "expected message length 0, got %d",
		      read_args.response_size);

	/* Set new snapshot which should include message 3 */
	zassert_equal(EC_RES_SUCCESS, host_command_process(&snap_args), NULL);

	read_args.response_size = 0;
	zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args), NULL);
	zassert_equal('\0', response[read_args.response_size],
		      "Last byte of response is not '\\0' (got 0x%x)",
		      response[read_args.response_size]);

	msg3_start = response + read_args.response_size - 1 - MSG_LEN(msg3);
	msg2_start = msg3_start - MSG_LEN(msg2);
	msg1_start = msg2_start - MSG_LEN(msg1);
	zassert_mem_equal(msg3, msg3_start, MSG_LEN(msg3),
			  "expected \"%s\", got \"%.*s\"", msg3, MSG_LEN(msg3),
			  msg3_start);
	zassert_mem_equal(msg2, msg2_start, MSG_LEN(msg2),
			  "expected \"%s\", got \"%.*s\"", msg2, MSG_LEN(msg2),
			  msg2_start);
	zassert_mem_equal(msg1, msg1_start, MSG_LEN(msg1),
			  "expected \"%s\", got \"%.*s\"", msg1, MSG_LEN(msg1),
			  msg1_start);
}

ZTEST_USER(uart_hostcmd, test_uart_hc_read_next_v0)
{
	test_uart_hc_read_next(0);
}

ZTEST_USER(uart_hostcmd, test_uart_hc_read_next_v1)
{
	test_uart_hc_read_next(1);
}

/** Test if read recent variant of console read host command is working */
ZTEST_USER(uart_hostcmd, test_uart_hc_read_recent_v1)
{
	/* Should be able to read whole buffer in one command */
	char response[CONFIG_PLATFORM_EC_HOSTCMD_CONSOLE_BUF_SIZE + 1];
	struct ec_params_console_read_v1 params;
	struct host_cmd_handler_args read_args =
		BUILD_HOST_COMMAND(EC_CMD_CONSOLE_READ, 1, response, params);
	struct host_cmd_handler_args snap_args =
		BUILD_HOST_COMMAND_SIMPLE(EC_CMD_CONSOLE_SNAPSHOT, 0);

	params.subcmd = CONSOLE_READ_RECENT;

	/* Only message 1 which is between two last snapshots should be read */
	read_args.response_size = 0;
	zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args), NULL);
	zassert_equal('\0', response[read_args.response_size],
		      "Last byte of response is not '\\0' (got 0x%x)",
		      response[read_args.response_size]);
	/* Account additional NULL char at the end */
	zassert_equal(MSG_LEN(msg1) + 1, read_args.response_size,
		      "expected message length %d, got %d", MSG_LEN(msg1) + 1,
		      read_args.response_size);
	zassert_mem_equal(msg1, response, MSG_LEN(msg1),
			  "expected \"%s\", got \"%.*s\"", msg1, MSG_LEN(msg1),
			  response);

	/* Set new snapshot after second message */
	zassert_equal(EC_RES_SUCCESS, host_command_process(&snap_args), NULL);

	/* Only message between two last snapshots should be read */
	read_args.response_size = 0;
	zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args), NULL);
	zassert_equal('\0', response[read_args.response_size],
		      "Last byte of response is not '\\0' (got 0x%x)",
		      response[read_args.response_size]);
	/* Account additional NULL char at the end */
	zassert_equal(MSG_LEN(msg2) + 1, read_args.response_size,
		      "expected message length %d, got %d", MSG_LEN(msg2) + 1,
		      read_args.response_size);
	zassert_mem_equal(msg2, response, MSG_LEN(msg2),
			  "expected \"%s\", got \"%.*s\"", msg2, MSG_LEN(msg2),
			  response);

	/* Append third message */
	cputs(CC_COMMAND, msg3);

	/* Check that message is not read without setting snapshot */
	read_args.response_size = 0;
	zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args), NULL);
	zassert_equal(0, read_args.response_size,
		      "expected message length 0, got %d",
		      read_args.response_size);

	/* Set new snapshot */
	zassert_equal(EC_RES_SUCCESS, host_command_process(&snap_args), NULL);

	/* This time only third message should be read */
	read_args.response_size = 0;
	zassert_equal(EC_RES_SUCCESS, host_command_process(&read_args), NULL);
	zassert_equal('\0', response[read_args.response_size],
		      "Last byte of response is not '\\0' (got 0x%x)",
		      response[read_args.response_size]);
	/* Account additional NULL char at the end */
	zassert_equal(MSG_LEN(msg3) + 1, read_args.response_size,
		      "expected message length %d, got %d", MSG_LEN(msg3) + 1,
		      read_args.response_size);
	zassert_mem_equal(msg3, response, MSG_LEN(msg3),
			  "expected \"%s\", got \"%.*s\"", msg3, MSG_LEN(msg3),
			  response);
}

ZTEST_SUITE(uart_hostcmd, drivers_predicate_post_main, NULL,
	    setup_snapshots_and_messages, NULL, NULL);