aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeborah Brouwer <deborahbrouwer3563@gmail.com>2021-06-03 19:40:53 -0700
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2021-06-04 09:10:14 +0200
commit5fc4802a70a4b8414198b516458fa7c9d44562b1 (patch)
tree407a2d634bca226e5bfcfedec34266b4a089d1a2
parentc8d617cc229c5e2862bf54509405c83d3c16f89a (diff)
downloadv4l-utils-5fc4802a70a4b8414198b516458fa7c9d44562b1.tar.gz
cec: add tests for Give Deck Status message
Test that a valid Deck Status message is received in response to Give Deck Status and that Give Deck Status automatic reporting can be turned on and off. Test that the follower returns Feature Abort for an invalid Give Deck Status operand. Signed-off-by: Deborah Brouwer <deborahbrouwer3563@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--utils/cec-compliance/cec-test.cpp72
-rw-r--r--utils/cec-follower/cec-follower.cpp2
-rw-r--r--utils/cec-follower/cec-follower.h1
-rw-r--r--utils/cec-follower/cec-processing.cpp41
4 files changed, 81 insertions, 35 deletions
diff --git a/utils/cec-compliance/cec-test.cpp b/utils/cec-compliance/cec-test.cpp
index 15f1b3c7..65a3943a 100644
--- a/utils/cec-compliance/cec-test.cpp
+++ b/utils/cec-compliance/cec-test.cpp
@@ -601,10 +601,6 @@ static const vec_remote_subtests dev_menu_ctl_subtests{
/* Deck Control */
-/*
- TODO: These are very rudimentary tests which should be expanded.
- */
-
static int deck_ctl_give_status(struct node *node, unsigned me, unsigned la, bool interactive)
{
struct cec_msg msg = {};
@@ -613,12 +609,11 @@ static int deck_ctl_give_status(struct node *node, unsigned me, unsigned la, boo
cec_msg_give_deck_status(&msg, true, CEC_OP_STATUS_REQ_ONCE);
fail_on_test(!transmit_timeout(node, &msg));
fail_on_test(timed_out(&msg));
- if (is_playback_or_rec(la)) {
- fail_on_test_v2(node->remote[la].cec_version,
- node->remote[la].has_deck_ctl && cec_msg_status_is_abort(&msg));
- fail_on_test_v2(node->remote[la].cec_version,
- !node->remote[la].has_deck_ctl && !unrecognized_op(&msg));
- }
+
+ fail_on_test_v2(node->remote[la].cec_version,
+ node->remote[la].has_deck_ctl && cec_msg_status_is_abort(&msg));
+ fail_on_test_v2(node->remote[la].cec_version,
+ !node->remote[la].has_deck_ctl && !unrecognized_op(&msg));
if (unrecognized_op(&msg))
return OK_NOT_SUPPORTED;
if (refused(&msg))
@@ -626,7 +621,51 @@ static int deck_ctl_give_status(struct node *node, unsigned me, unsigned la, boo
if (cec_msg_status_is_abort(&msg))
return OK_PRESUMED;
- return 0;
+ __u8 deck_info;
+
+ cec_ops_deck_status(&msg, &deck_info);
+ fail_on_test(deck_info < CEC_OP_DECK_INFO_PLAY || deck_info > CEC_OP_DECK_INFO_OTHER);
+
+ cec_msg_init(&msg, me, la);
+ cec_msg_give_deck_status(&msg, true, CEC_OP_STATUS_REQ_ON);
+ fail_on_test(!transmit_timeout(node, &msg));
+ fail_on_test(timed_out(&msg));
+ cec_ops_deck_status(&msg, &deck_info);
+ fail_on_test(deck_info < CEC_OP_DECK_INFO_PLAY || deck_info > CEC_OP_DECK_INFO_OTHER);
+
+ cec_msg_init(&msg, me, la);
+ cec_msg_give_deck_status(&msg, true, CEC_OP_STATUS_REQ_OFF);
+ /*
+ * Reply would not normally be expected for CEC_OP_STATUS_REQ_OFF.
+ * If a reply is received, then the follower failed to turn off
+ * status reporting as required.
+ */
+ msg.reply = CEC_MSG_DECK_STATUS;
+ fail_on_test(!transmit_timeout(node, &msg));
+ fail_on_test(!timed_out(&msg));
+
+ return OK;
+}
+
+static int deck_ctl_give_status_invalid(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+ struct cec_msg msg = {};
+
+ cec_msg_init(&msg, me, la);
+ cec_msg_give_deck_status(&msg, true, 0); /* Invalid Operand */
+ fail_on_test(!transmit_timeout(node, &msg));
+ if (unrecognized_op(&msg))
+ return OK_NOT_SUPPORTED;
+ fail_on_test(!cec_msg_status_is_abort(&msg));
+ fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
+
+ cec_msg_init(&msg, me, la);
+ cec_msg_give_deck_status(&msg, true, 4); /* Invalid Operand */
+ fail_on_test(!transmit_timeout(node, &msg));
+ fail_on_test(!cec_msg_status_is_abort(&msg));
+ fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
+
+ return OK;
}
static int deck_ctl_deck_status(struct node *node, unsigned me, unsigned la, bool interactive)
@@ -693,7 +732,16 @@ static int deck_ctl_play(struct node *node, unsigned me, unsigned la, bool inter
}
static const vec_remote_subtests deck_ctl_subtests{
- { "Give Deck Status", CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, deck_ctl_give_status },
+ {
+ "Give Deck Status",
+ CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD,
+ deck_ctl_give_status,
+ },
+ {
+ "Give Deck Status Invalid Operand",
+ CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD,
+ deck_ctl_give_status_invalid,
+ },
{ "Deck Status", CEC_LOG_ADDR_MASK_ALL, deck_ctl_deck_status },
{ "Deck Control", CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, deck_ctl_deck_ctl },
{ "Play", CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, deck_ctl_play },
diff --git a/utils/cec-follower/cec-follower.cpp b/utils/cec-follower/cec-follower.cpp
index 1f598fdf..047d7a04 100644
--- a/utils/cec-follower/cec-follower.cpp
+++ b/utils/cec-follower/cec-follower.cpp
@@ -313,6 +313,8 @@ void state_init(struct node &node)
node.state.sac_active = false;
node.state.volume = 50;
node.state.mute = false;
+ node.state.deck_report_changes = false;
+ node.state.deck_state = CEC_OP_DECK_INFO_STOP;
tuner_dev_info_init(&node.state);
node.state.last_aud_rate_rx_ts = 0;
}
diff --git a/utils/cec-follower/cec-follower.h b/utils/cec-follower/cec-follower.h
index 391b9ab4..0492faa9 100644
--- a/utils/cec-follower/cec-follower.h
+++ b/utils/cec-follower/cec-follower.h
@@ -50,6 +50,7 @@ struct state {
bool service_by_dig_id;
bool tuner_report_changes;
bool deck_report_changes;
+ __u8 deck_state;
unsigned toggle_power_status;
__u64 last_aud_rate_rx_ts;
};
diff --git a/utils/cec-follower/cec-processing.cpp b/utils/cec-follower/cec-processing.cpp
index 5b9db19f..3d2e4a2c 100644
--- a/utils/cec-follower/cec-processing.cpp
+++ b/utils/cec-follower/cec-processing.cpp
@@ -505,36 +505,31 @@ static void processMsg(struct node *node, struct cec_msg &msg, unsigned me)
break;
- /*
- Deck Control
-
- This is only a basic implementation.
-
- TODO: Device state should reflect whether we are playing,
- fast forwarding, etc.
- */
+ /* Deck Control */
case CEC_MSG_GIVE_DECK_STATUS:
- if (node->has_deck_ctl) {
- __u8 status_req;
+ if (!node->has_deck_ctl)
+ break;
- cec_ops_give_deck_status(&msg, &status_req);
- if (status_req < CEC_OP_STATUS_REQ_ON ||
- status_req > CEC_OP_STATUS_REQ_ONCE) {
- reply_feature_abort(node, &msg, CEC_OP_ABORT_INVALID_OP);
- return;
- }
- if (status_req != CEC_OP_STATUS_REQ_ONCE)
- node->state.deck_report_changes =
- status_req == CEC_OP_STATUS_REQ_ON;
- if (status_req == CEC_OP_STATUS_REQ_OFF)
- return;
+ __u8 status_req;
+ cec_ops_give_deck_status(&msg, &status_req);
+
+ switch (status_req) {
+ case CEC_OP_STATUS_REQ_ON:
+ node->state.deck_report_changes = true;
+ fallthrough;
+ case CEC_OP_STATUS_REQ_ONCE:
cec_msg_set_reply_to(&msg, &msg);
- cec_msg_deck_status(&msg, CEC_OP_DECK_INFO_STOP);
+ cec_msg_deck_status(&msg, node->state.deck_state);
transmit(node, &msg);
return;
+ case CEC_OP_STATUS_REQ_OFF:
+ node->state.deck_report_changes = false;
+ return;
+ default:
+ reply_feature_abort(node, &msg, CEC_OP_ABORT_INVALID_OP);
+ return;
}
- break;
case CEC_MSG_PLAY:
if (node->has_deck_ctl)
return;