diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2017-09-19 16:54:54 +0200 |
---|---|---|
committer | Hans Verkuil <hans.verkuil@cisco.com> | 2017-09-19 16:54:54 +0200 |
commit | 9ee29df352dad950784f0f6f4a1bb96c0aefacc4 (patch) | |
tree | 42382aa228fb6485ebfa8bf76bac7e8cd633c460 | |
parent | 8d89a6ad9940f520ae4e816c3973551e52557d71 (diff) |
cec-compliance: various improvements for no-HPD-in-standby
The standby tests failed for TVs that disable the HPD when in
standby. One reason was a silly mistake in a condition testing
for CEC_CAP_NEEDS_HPD: a ! was missing there.
But other issues were related to the tests themselves (don't
issue an IMAGE_VIEW_ON when trying to transmit a GIVE_POWER_STATUS,
STANDBY or ACTIVE_SOURCE command since that would defeat the purpose).
Another issue that the long_timeout handling was wrong. Use time()
to determine if we timed out, that's much more reliable compared to
the old method.
Tested with a display with this 'feature'.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
-rw-r--r-- | utils/cec-compliance/cec-compliance.cpp | 9 | ||||
-rw-r--r-- | utils/cec-compliance/cec-test-power.cpp | 30 |
2 files changed, 25 insertions, 14 deletions
diff --git a/utils/cec-compliance/cec-compliance.cpp b/utils/cec-compliance/cec-compliance.cpp index 2b337231..8be8f88c 100644 --- a/utils/cec-compliance/cec-compliance.cpp +++ b/utils/cec-compliance/cec-compliance.cpp @@ -798,7 +798,8 @@ int check_0(const void *p, int len) return 0; } -#define TX_WAIT_FOR_HPD 3 +#define TX_WAIT_FOR_HPD 10 +#define TX_WAIT_FOR_HPD_RETURN 30 static bool wait_for_hpd(struct node *node, bool send_image_view_on) { @@ -845,9 +846,9 @@ static bool wait_for_hpd(struct node *node, bool send_image_view_on) send_image_view_on = false; } - if (time(NULL) - t > TX_WAIT_FOR_HPD + long_timeout) { + if (time(NULL) - t > TX_WAIT_FOR_HPD + TX_WAIT_FOR_HPD_RETURN) { fail("timed out after %d s waiting for HPD to return\n", - long_timeout); + TX_WAIT_FOR_HPD + TX_WAIT_FOR_HPD_RETURN); return false; } } @@ -876,7 +877,7 @@ retry: } warn("HPD was lost, wait for it to come up again.\n"); - if (!wait_for_hpd(node, (node->caps & CEC_CAP_NEEDS_HPD) && + if (!wait_for_hpd(node, !(node->caps & CEC_CAP_NEEDS_HPD) && cec_msg_destination(msg) == CEC_LOG_ADDR_TV)) return false; diff --git a/utils/cec-compliance/cec-test-power.cpp b/utils/cec-compliance/cec-test-power.cpp index 12f4adfe..e3360d17 100644 --- a/utils/cec-compliance/cec-test-power.cpp +++ b/utils/cec-compliance/cec-test-power.cpp @@ -37,7 +37,13 @@ static bool get_power_status(struct node *node, unsigned me, unsigned la, __u8 & cec_msg_init(&msg, me, la); cec_msg_give_device_power_status(&msg, true); - if (!transmit_timeout(node, &msg) || timed_out_or_abort(&msg)) + msg.timeout = 2000; + int res = doioctl(node, CEC_TRANSMIT, &msg); + if (res == ENONET) { + power_status = CEC_OP_POWER_STATUS_STANDBY; + return true; + } + if (res || timed_out_or_abort(&msg)) return false; cec_ops_report_power_status(&msg, &power_status); return true; @@ -259,18 +265,19 @@ static bool wait_changing_power_status(struct node *node, unsigned me, unsigned unsigned &unresponsive_time) { __u8 old_status; + time_t t = time(NULL); announce("Checking for power status change. This may take up to %u s.", long_timeout); if (!get_power_status(node, me, la, old_status)) return false; - for (unsigned i = 0; i < long_timeout / SLEEP_POLL_POWER_STATUS; i++) { + while (time(NULL) - t < long_timeout) { __u8 power_status; if (!get_power_status(node, me, la, power_status)) { /* Some TVs become completely unresponsive when transitioning between power modes. Register that this happens, but continue the test. */ - unresponsive_time = i * SLEEP_POLL_POWER_STATUS; + unresponsive_time = time(NULL) - t; } else if (old_status != power_status) { new_status = power_status; return true; @@ -286,27 +293,28 @@ static bool poll_stable_power_status(struct node *node, unsigned me, unsigned la { bool transient = false; unsigned time_to_transient = 0; + time_t t = time(NULL); /* Some devices can use several seconds to transition from one power state to another, so the power state must be repeatedly polled */ announce("Waiting for new stable power status. This may take up to %u s.", long_timeout); - for (unsigned tries = 0; tries < long_timeout / SLEEP_POLL_POWER_STATUS; tries++) { + while (time(NULL) - t < long_timeout) { __u8 power_status; if (!get_power_status(node, me, la, power_status)) { /* Some TVs become completely unresponsive when transitioning between power modes. Register that this happens, but continue the test. */ - unresponsive_time = tries * SLEEP_POLL_POWER_STATUS; + unresponsive_time = time(NULL) - t; } if (!transient && (power_status == CEC_OP_POWER_STATUS_TO_ON || power_status == CEC_OP_POWER_STATUS_TO_STANDBY)) { - time_to_transient = tries * SLEEP_POLL_POWER_STATUS; + time_to_transient = time(NULL) - t; transient = true; } if (power_status == expected_status) { announce("Transient state after %d s, stable state %s after %d s", - time_to_transient, power_status2s(power_status), tries * SLEEP_POLL_POWER_STATUS); + time_to_transient, power_status2s(power_status), (int)(time(NULL) - t)); return true; } sleep(SLEEP_POLL_POWER_STATUS); @@ -355,7 +363,8 @@ static int standby_resume_standby_toggle(struct node *node, unsigned me, unsigne announce("Sending Standby message."); cec_msg_init(&msg, me, la); cec_msg_standby(&msg); - fail_on_test(!transmit_timeout(node, &msg)); + int res = doioctl(node, CEC_TRANSMIT, &msg); + fail_on_test(res && res != ENONET); fail_on_test(cec_msg_status_is_abort(&msg)); fail_on_test(wait_changing_power_status(node, me, la, new_status, unresponsive_time)); fail_on_test(new_status != CEC_OP_POWER_STATUS_STANDBY); @@ -384,7 +393,8 @@ static int standby_resume_active_source_nowake(struct node *node, unsigned me, u announce("Sending Active Source message."); cec_msg_init(&msg, me, la); cec_msg_active_source(&msg, node->phys_addr); - fail_on_test(!transmit_timeout(node, &msg)); + int res = doioctl(node, CEC_TRANSMIT, &msg); + fail_on_test(res && res != ENONET); fail_on_test(wait_changing_power_status(node, me, la, new_status, unresponsive_time)); fail_on_test_v2_warn(node->remote[la].cec_version, new_status != CEC_OP_POWER_STATUS_STANDBY); node->remote[la].in_standby = true; @@ -450,7 +460,7 @@ static int standby_resume_wakeup(struct node *node, unsigned me, unsigned la, bo int ret; if (is_tv(la, node->remote[la].prim_type)) - ret = wakeup_tv(node, me, la); + ret = wakeup_tv(node, CEC_LOG_ADDR_UNREGISTERED, la); else ret = wakeup_source(node, me, la); if (ret) |