aboutsummaryrefslogtreecommitdiffstats
path: root/utils/cec-follower/cec-processing.cpp
diff options
context:
space:
mode:
authorDeborah Brouwer <deborahbrouwer3563@gmail.com>2021-06-11 09:45:25 -0700
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2021-06-12 10:31:36 +0200
commit29a2b3c684d5ee5258c2425a1e1877b01f3d9391 (patch)
treee09642a513c4d388be08acb52f5c107ac105bdd4 /utils/cec-follower/cec-processing.cpp
parent287ce79dc84dc09b8fd3538f4a9a372db70c3808 (diff)
cec: add tests for Deck Control message
Send all Deck Control commands Skip Forward, Skip Reverse, Stop and Eject and check the corresponding deck status. Test that the follower returns Feature Abort for invalid Deck Control operands. Signed-off-by: Deborah Brouwer <deborahbrouwer3563@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> [hverkuil: move CEC_OP_DECK_CTL_MODE_EJECT up to after MODE_STOP]
Diffstat (limited to 'utils/cec-follower/cec-processing.cpp')
-rw-r--r--utils/cec-follower/cec-processing.cpp68
1 files changed, 66 insertions, 2 deletions
diff --git a/utils/cec-follower/cec-processing.cpp b/utils/cec-follower/cec-processing.cpp
index 3d2e4a2c..4ec701d4 100644
--- a/utils/cec-follower/cec-processing.cpp
+++ b/utils/cec-follower/cec-processing.cpp
@@ -32,6 +32,9 @@
/* The maximum interval in nanoseconds between audio rate messages as defined in the spec */
#define MAX_AUD_RATE_MSG_INTERVAL_NS (2 * 1000000000ULL)
+/* The maximum interval in nanoseconds to allow a deck to skip forward/reverse */
+#define MAX_DECK_SKIP_NS (2 * 1000000000ULL)
+
struct cec_enum_values {
const char *type_name;
__u8 value;
@@ -161,6 +164,7 @@ static bool enter_standby(struct node *node)
node->state.old_power_status = node->state.power_status;
node->state.power_status = CEC_OP_POWER_STATUS_STANDBY;
node->state.power_status_changed_time = time(nullptr);
+ node->state.deck_skip_start = 0;
dev_info("Changing state to standby\n");
return true;
}
@@ -252,6 +256,21 @@ static void aud_rate_msg_interval_check(struct node *node, __u64 ts_new)
}
}
+static void update_deck_state(struct node *node, unsigned me, __u8 deck_state_new)
+{
+ if (node->state.deck_state != deck_state_new) {
+ node->state.deck_state = deck_state_new;
+
+ if (node->state.deck_report_changes) {
+ struct cec_msg msg = {};
+
+ cec_msg_init(&msg, me, node->state.deck_report_changes_to);
+ cec_msg_deck_status(&msg, node->state.deck_state);
+ transmit(node, &msg);
+ }
+ }
+}
+
static void processMsg(struct node *node, struct cec_msg &msg, unsigned me)
{
__u8 to = cec_msg_destination(&msg);
@@ -517,6 +536,7 @@ static void processMsg(struct node *node, struct cec_msg &msg, unsigned me)
switch (status_req) {
case CEC_OP_STATUS_REQ_ON:
node->state.deck_report_changes = true;
+ node->state.deck_report_changes_to = cec_msg_initiator(&msg);
fallthrough;
case CEC_OP_STATUS_REQ_ONCE:
cec_msg_set_reply_to(&msg, &msg);
@@ -535,9 +555,48 @@ static void processMsg(struct node *node, struct cec_msg &msg, unsigned me)
return;
break;
case CEC_MSG_DECK_CONTROL:
- if (node->has_deck_ctl)
+ if (!node->has_deck_ctl)
+ break;
+
+ __u8 deck_state;
+ __u8 deck_control_mode;
+
+ cec_ops_deck_control(&msg, &deck_control_mode);
+
+ switch (deck_control_mode) {
+ case CEC_OP_DECK_CTL_MODE_STOP:
+ deck_state = CEC_OP_DECK_INFO_STOP;
+ node->state.deck_skip_start = 0;
+ break;
+ case CEC_OP_DECK_CTL_MODE_EJECT:
+ deck_state = CEC_OP_DECK_INFO_NO_MEDIA;
+ node->state.deck_skip_start = 0;
+ break;
+ case CEC_OP_DECK_CTL_MODE_SKIP_FWD:
+ /* Skip Forward will not retract the deck tray. */
+ if (node->state.deck_state == CEC_OP_DECK_INFO_NO_MEDIA) {
+ reply_feature_abort(node, &msg, CEC_OP_ABORT_INCORRECT_MODE);
+ return;
+ }
+ deck_state = CEC_OP_DECK_INFO_SKIP_FWD;
+ node->state.deck_skip_start = msg.rx_ts;
+ break;
+ case CEC_OP_DECK_CTL_MODE_SKIP_REV:
+ /* Skip Reverse will not retract the deck tray. */
+ if (node->state.deck_state == CEC_OP_DECK_INFO_NO_MEDIA) {
+ reply_feature_abort(node, &msg, CEC_OP_ABORT_INCORRECT_MODE);
+ return;
+ }
+ deck_state = CEC_OP_DECK_INFO_SKIP_REV;
+ node->state.deck_skip_start = msg.rx_ts;
+ break;
+ default:
+ cec_msg_reply_feature_abort(&msg, CEC_OP_ABORT_INVALID_OP);
+ transmit(node, &msg);
return;
- break;
+ }
+ update_deck_state(node, me, deck_state);
+ return;
case CEC_MSG_DECK_STATUS:
return;
@@ -1034,6 +1093,11 @@ void testProcessing(struct node *node, bool wallclock)
if (node->has_aud_rate)
aud_rate_msg_interval_check(node, ts_now);
+
+ if (node->state.deck_skip_start && ts_now - node->state.deck_skip_start > MAX_DECK_SKIP_NS) {
+ node->state.deck_skip_start = 0;
+ update_deck_state(node, me, CEC_OP_DECK_INFO_PLAY);
+ }
}
mode = CEC_MODE_INITIATOR;
doioctl(node, CEC_S_MODE, &mode);

Privacy Policy