| /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| * |
| * Test host command. |
| */ |
| |
| #include "common.h" |
| #include "console.h" |
| #include "host_command.h" |
| #include "task.h" |
| #include "test_util.h" |
| #include "timer.h" |
| #include "util.h" |
| |
| struct host_packet pkt; |
| static char resp_buf[128]; |
| static char req_buf[128]; |
| struct ec_host_request *req = (struct ec_host_request *)req_buf; |
| struct ec_params_hello *p = (struct ec_params_hello *)(req_buf + sizeof(*req)); |
| struct ec_host_response *resp = (struct ec_host_response *)resp_buf; |
| struct ec_response_hello *r = |
| (struct ec_response_hello *)(resp_buf + sizeof(*resp)); |
| |
| static void hostcmd_respond(struct host_packet *pkt) |
| { |
| task_wake(TASK_ID_TEST_RUNNER); |
| } |
| |
| static char calculate_checksum(const char *buf, int size) |
| { |
| int c = 0; |
| int i; |
| |
| for (i = 0; i < size; ++i) |
| c += buf[i]; |
| |
| return -c; |
| } |
| |
| static void hostcmd_send(void) |
| { |
| req->checksum = calculate_checksum(req_buf, pkt.request_size); |
| host_packet_receive(&pkt); |
| task_wait_event(-1); |
| } |
| |
| static void hostcmd_fill_in_default(void) |
| { |
| req->struct_version = 3; |
| req->checksum = 0; |
| req->command = EC_CMD_HELLO; |
| req->command_version = 0; |
| req->reserved = 0; |
| req->data_len = 4; |
| p->in_data = 0x11223344; |
| |
| pkt.request_size = 0; |
| pkt.send_response = hostcmd_respond; |
| pkt.request = (const void *)req_buf; |
| pkt.request_max = 128; |
| pkt.request_size = sizeof(*req) + sizeof(*p); |
| pkt.response = (void *)resp_buf; |
| pkt.response_max = 128; |
| pkt.driver_result = 0; |
| } |
| |
| static int test_hostcmd_ok(void) |
| { |
| hostcmd_fill_in_default(); |
| |
| hostcmd_send(); |
| |
| TEST_ASSERT(calculate_checksum(resp_buf, |
| sizeof(*resp) + resp->data_len) == 0); |
| TEST_ASSERT(resp->result == EC_RES_SUCCESS); |
| TEST_ASSERT(r->out_data == 0x12243648); |
| |
| return EC_SUCCESS; |
| } |
| |
| static int test_hostcmd_too_short(void) |
| { |
| hostcmd_fill_in_default(); |
| |
| /* Smaller than header */ |
| pkt.request_size = sizeof(*req) - 4; |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_REQUEST_TRUNCATED); |
| |
| /* Smaller than expected data size */ |
| pkt.request_size = sizeof(*req); |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_REQUEST_TRUNCATED); |
| |
| return EC_SUCCESS; |
| } |
| |
| static int test_hostcmd_too_long(void) |
| { |
| hostcmd_fill_in_default(); |
| |
| /* Larger than request buffer */ |
| pkt.request_size = sizeof(req_buf) + 4; |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_REQUEST_TRUNCATED); |
| |
| return EC_SUCCESS; |
| } |
| |
| static int test_hostcmd_driver_error(void) |
| { |
| hostcmd_fill_in_default(); |
| |
| pkt.driver_result = EC_RES_ERROR; |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_ERROR); |
| |
| return EC_SUCCESS; |
| } |
| |
| static int test_hostcmd_invalid_command(void) |
| { |
| hostcmd_fill_in_default(); |
| |
| req->command = 0xff; |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_INVALID_COMMAND); |
| |
| return EC_SUCCESS; |
| } |
| |
| static int test_hostcmd_wrong_command_version(void) |
| { |
| hostcmd_fill_in_default(); |
| |
| req->command_version = 1; |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_INVALID_VERSION); |
| |
| return EC_SUCCESS; |
| } |
| |
| static int test_hostcmd_wrong_struct_version(void) |
| { |
| hostcmd_fill_in_default(); |
| |
| req->struct_version = 4; |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_INVALID_HEADER); |
| |
| req->struct_version = 2; |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_INVALID_HEADER); |
| |
| return EC_SUCCESS; |
| } |
| |
| static int test_hostcmd_invalid_checksum(void) |
| { |
| hostcmd_fill_in_default(); |
| |
| req->checksum++; |
| hostcmd_send(); |
| TEST_ASSERT(resp->result == EC_RES_INVALID_CHECKSUM); |
| |
| return EC_SUCCESS; |
| } |
| |
| void run_test(void) |
| { |
| wait_for_task_started(); |
| test_reset(); |
| |
| RUN_TEST(test_hostcmd_ok); |
| RUN_TEST(test_hostcmd_too_short); |
| RUN_TEST(test_hostcmd_too_long); |
| RUN_TEST(test_hostcmd_driver_error); |
| RUN_TEST(test_hostcmd_invalid_command); |
| RUN_TEST(test_hostcmd_wrong_command_version); |
| RUN_TEST(test_hostcmd_wrong_struct_version); |
| RUN_TEST(test_hostcmd_invalid_checksum); |
| |
| test_print_result(); |
| } |