From patchwork Thu Jun 10 23:58:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deborah Brouwer X-Patchwork-Id: 12314317 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B904C48BD1 for ; Thu, 10 Jun 2021 23:59:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2A5CD613B0 for ; Thu, 10 Jun 2021 23:59:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230452AbhFKABa (ORCPT ); Thu, 10 Jun 2021 20:01:30 -0400 Received: from mail-pj1-f67.google.com ([209.85.216.67]:33608 "EHLO mail-pj1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229578AbhFKABa (ORCPT ); Thu, 10 Jun 2021 20:01:30 -0400 Received: by mail-pj1-f67.google.com with SMTP id k22-20020a17090aef16b0290163512accedso6311167pjz.0 for ; Thu, 10 Jun 2021 16:59:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WpJbMPCnqY+5cSSHltvh9VDsua5JinRzHRIGvT/ySSk=; b=oGspBHjLRQjzhSDYgAKb5wonWZuSdf1bvq7HKjqXFtBH6qXjW7XbE8Om4ENXSLx92y cDByWQ7WYOB22h01bIZNUGwGtM9bVcSatRcmesGWzVnRgZHDpHnsOw9FcuBkgsoZ7fdA okitrP9O86Z+hSopWZHQZlO7HmvHNwWn8tfdRzRrZCaY9M2K7XBEhTp4ohWUbmnhWEds BZLXwRgoztqyffUmOBjHEv4ZTEtgcASeAhtrUHnAqnWIwRv28d7NJKomey2NEywJO7DK AiFt2GkaBKwF7L5/HyFKE3VgtwJW0ybTwNQVgGpDIpkq/NWkEjdaAI0rv/cpWfLXzuey WKJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WpJbMPCnqY+5cSSHltvh9VDsua5JinRzHRIGvT/ySSk=; b=rJ96PHBHEq6MQkrhG8Ia9auE0QNbdwPTlwSZGgzgcFYSKlmLEKIxgr2SCvpUleuPCx qj9WzphZ7H8rKTIX9+l/OKhxjJVtIxVzrIXiKQWMo3MA9XTwXf8DaA6D7QImdhLPRVQm riliO94eJ+5qz+HlX+nn0dCqbU8+Wc++zKTSTIFD26rHD7E8USSUpdvtTdhJy7Tvulmj GpxjMiO0A+iG4JbGyZELI74lJUpslVXkydUA2JrwCSPx8X5/5qecB6yoF1eV5qEdzmI+ o5l4HrRp+lchWfBkx62Tm8e3WJv6WqvUJOJz4rT4I14XHAaC09poadp72F3lfWRvRqV4 gHNw== X-Gm-Message-State: AOAM533GmTA0+8AT60XfmX7FfSkXiAldSz5sAh/xEha+KLcFY6XCFqna jlsyHy87h7MygkPAqDz73ZNpi6gIeH1wCQ== X-Google-Smtp-Source: ABdhPJz/jV/uwpL1ltb63xWIj3fexKOiUd7DQ7H19SYpqikNL0LhgGF8issDVqNucGtdsag5ZJf5og== X-Received: by 2002:a17:90a:df13:: with SMTP id gp19mr1388573pjb.11.1623369499910; Thu, 10 Jun 2021 16:58:19 -0700 (PDT) Received: from ada-comp.hitronhub.home (S0106ac202ecb0523.gv.shawcable.net. [70.67.120.89]) by smtp.gmail.com with ESMTPSA id c4sm3588133pfo.189.2021.06.10.16.58.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:58:19 -0700 (PDT) From: Deborah Brouwer To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, jaffe1@gmail.com, Deborah Brouwer Subject: [PATCH v6 1/3] cec: add tests for Deck Control message Date: Thu, 10 Jun 2021 16:58:02 -0700 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 --- utils/cec-compliance/cec-compliance.h | 5 ++ utils/cec-compliance/cec-test.cpp | 111 +++++++++++++++++++++++--- utils/cec-follower/cec-follower.cpp | 2 + utils/cec-follower/cec-follower.h | 2 + utils/cec-follower/cec-processing.cpp | 70 +++++++++++++++- 5 files changed, 178 insertions(+), 12 deletions(-) diff --git a/utils/cec-compliance/cec-compliance.h b/utils/cec-compliance/cec-compliance.h index fc50e6d9..818181ab 100644 --- a/utils/cec-compliance/cec-compliance.h +++ b/utils/cec-compliance/cec-compliance.h @@ -359,6 +359,11 @@ static inline bool refused(const struct cec_msg *msg) return cec_msg_status_is_abort(msg) && abort_reason(msg) == CEC_OP_ABORT_REFUSED; } +static inline bool incorrect_mode(const struct cec_msg *msg) +{ + return cec_msg_status_is_abort(msg) && abort_reason(msg) == CEC_OP_ABORT_INCORRECT_MODE; +} + static inline bool timed_out(const struct cec_msg *msg) { return msg->rx_status & CEC_RX_STATUS_TIMEOUT; diff --git a/utils/cec-compliance/cec-test.cpp b/utils/cec-compliance/cec-test.cpp index 65a3943a..83be6b73 100644 --- a/utils/cec-compliance/cec-test.cpp +++ b/utils/cec-compliance/cec-test.cpp @@ -19,6 +19,20 @@ struct remote_test { const vec_remote_subtests &subtests; }; +static int deck_status_get(struct node *node, unsigned me, unsigned la, __u8 &deck_status) +{ + struct cec_msg msg = {}; + deck_status = 0; + + cec_msg_init(&msg, me, la); + cec_msg_give_deck_status(&msg, true, CEC_OP_STATUS_REQ_ONCE); + fail_on_test(!transmit_timeout(node, &msg)); + fail_on_test(timed_out_or_abort(&msg)); + cec_ops_deck_status(&msg, &deck_status); + + return OK; +} + /* System Information */ @@ -688,24 +702,92 @@ static int deck_ctl_deck_status(struct node *node, unsigned me, unsigned la, boo static int deck_ctl_deck_ctl(struct node *node, unsigned me, unsigned la, bool interactive) { struct cec_msg msg = {}; + __u8 deck_status; cec_msg_init(&msg, me, la); cec_msg_deck_control(&msg, CEC_OP_DECK_CTL_MODE_STOP); fail_on_test(!transmit_timeout(node, &msg)); - if (is_playback_or_rec(la)) { - 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 && !unrecognized_op(&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 && !unrecognized_op(&msg)); if (unrecognized_op(&msg)) return OK_NOT_SUPPORTED; if (refused(&msg)) return OK_REFUSED; - if (cec_msg_status_is_abort(&msg)) - return OK_PRESUMED; + fail_on_test(deck_status_get(node, me, la, deck_status)); + if (cec_msg_status_is_abort(&msg)) { + if (incorrect_mode(&msg)) { + if (deck_status == CEC_OP_DECK_INFO_NO_MEDIA) + info("Stop: no media.\n"); + else + warn("Deck has media but returned Feature Abort with Incorrect Mode."); + return OK; + } + return FAIL; + } + fail_on_test(deck_status != CEC_OP_DECK_INFO_STOP && deck_status != CEC_OP_DECK_INFO_NO_MEDIA); - return OK_PRESUMED; + cec_msg_init(&msg, me, la); + cec_msg_deck_control(&msg, CEC_OP_DECK_CTL_MODE_SKIP_FWD); + fail_on_test(!transmit_timeout(node, &msg)); + fail_on_test(deck_status_get(node, me, la, deck_status)); + /* + * If there is no media, Skip Forward should Feature Abort with Incorrect Mode + * even if Stop did not. If Skip Forward does not Feature Abort, the deck + * is assumed to have media. + */ + if (incorrect_mode(&msg)) { + fail_on_test(deck_status != CEC_OP_DECK_INFO_NO_MEDIA); + return OK; + } + fail_on_test(cec_msg_status_is_abort(&msg)); + for (unsigned i = 0; deck_status == CEC_OP_DECK_INFO_SKIP_FWD && i < long_timeout; i++) { + sleep(1); + fail_on_test(deck_status_get(node, me, la, deck_status)); + } + fail_on_test(deck_status != CEC_OP_DECK_INFO_PLAY); + + cec_msg_init(&msg, me, la); + cec_msg_deck_control(&msg, CEC_OP_DECK_CTL_MODE_SKIP_REV); + fail_on_test(!transmit_timeout(node, &msg)); + fail_on_test(cec_msg_status_is_abort(&msg)); /* Assumes deck has media. */ + fail_on_test(deck_status_get(node, me, la, deck_status)); + for (unsigned i = 0; deck_status == CEC_OP_DECK_INFO_SKIP_REV && i < long_timeout; i++) { + sleep(1); + fail_on_test(deck_status_get(node, me, la, deck_status)); + } + fail_on_test(deck_status != CEC_OP_DECK_INFO_PLAY); + + cec_msg_init(&msg, me, la); + cec_msg_deck_control(&msg, CEC_OP_DECK_CTL_MODE_EJECT); + fail_on_test(!transmit_timeout(node, &msg)); + fail_on_test(cec_msg_status_is_abort(&msg)); + fail_on_test(deck_status_get(node, me, la, deck_status)); + fail_on_test(deck_status != CEC_OP_DECK_INFO_NO_MEDIA); + + return OK; +} + +static int deck_ctl_deck_ctl_invalid(struct node *node, unsigned me, unsigned la, bool interactive) +{ + struct cec_msg msg = {}; + + cec_msg_init(&msg, me, la); + cec_msg_deck_control(&msg, 0); /* Invalid Deck Control 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_deck_control(&msg, 5); /* Invalid Deck Control 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_play(struct node *node, unsigned me, unsigned la, bool interactive) @@ -743,8 +825,17 @@ static const vec_remote_subtests deck_ctl_subtests{ 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 }, + { + "Deck Control", + CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, + deck_ctl_deck_ctl, + }, + { + "Deck Control Invalid Operand", + CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, + deck_ctl_deck_ctl_invalid, + }, }; /* Tuner Control */ diff --git a/utils/cec-follower/cec-follower.cpp b/utils/cec-follower/cec-follower.cpp index 047d7a04..ff47d698 100644 --- a/utils/cec-follower/cec-follower.cpp +++ b/utils/cec-follower/cec-follower.cpp @@ -314,7 +314,9 @@ void state_init(struct node &node) node.state.volume = 50; node.state.mute = false; node.state.deck_report_changes = false; + node.state.deck_report_changes_to = 0; node.state.deck_state = CEC_OP_DECK_INFO_STOP; + node.state.deck_skip_start = 0; 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 0492faa9..68ef222a 100644 --- a/utils/cec-follower/cec-follower.h +++ b/utils/cec-follower/cec-follower.h @@ -50,7 +50,9 @@ struct state { bool service_by_dig_id; bool tuner_report_changes; bool deck_report_changes; + __u8 deck_report_changes_to; __u8 deck_state; + __u64 deck_skip_start; 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 3d2e4a2c..4c7ba1d4 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,22 @@ static void aud_rate_msg_interval_check(struct node *node, __u64 ts_new) } } +static void update_deck_state(struct node *node, __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 = {}; + + msg.msg[0] = 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 +537,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_destination(&msg) << 4) | cec_msg_initiator(&msg); fallthrough; case CEC_OP_STATUS_REQ_ONCE: cec_msg_set_reply_to(&msg, &msg); @@ -525,6 +546,7 @@ static void processMsg(struct node *node, struct cec_msg &msg, unsigned me) return; case CEC_OP_STATUS_REQ_OFF: node->state.deck_report_changes = false; + node->state.deck_report_changes_to = 0; return; default: reply_feature_abort(node, &msg, CEC_OP_ABORT_INVALID_OP); @@ -535,9 +557,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_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; + case CEC_OP_DECK_CTL_MODE_EJECT: + deck_state = CEC_OP_DECK_INFO_NO_MEDIA; + node->state.deck_skip_start = 0; + break; + default: + cec_msg_reply_feature_abort(&msg, CEC_OP_ABORT_INVALID_OP); + transmit(node, &msg); return; - break; + } + update_deck_state(node, deck_state); + return; case CEC_MSG_DECK_STATUS: return; @@ -1034,6 +1095,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, CEC_OP_DECK_INFO_PLAY); + } } mode = CEC_MODE_INITIATOR; doioctl(node, CEC_S_MODE, &mode); From patchwork Thu Jun 10 23:58:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deborah Brouwer X-Patchwork-Id: 12314315 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8DDAC48BDF for ; Thu, 10 Jun 2021 23:58:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 95E79613B0 for ; Thu, 10 Jun 2021 23:58:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230321AbhFKAAh (ORCPT ); Thu, 10 Jun 2021 20:00:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229578AbhFKAAh (ORCPT ); Thu, 10 Jun 2021 20:00:37 -0400 Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4B89C061574 for ; Thu, 10 Jun 2021 16:58:23 -0700 (PDT) Received: by mail-pf1-x442.google.com with SMTP id y15so2950372pfl.4 for ; Thu, 10 Jun 2021 16:58:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fYF6yshbdDnOc0oeiJlzqJ9QqxQWt81AFSnSKdi8F3c=; b=IgJxC0NA80Q/bhr5i0Frc1iD+whPs25Vw+CIDPdHZi/Bv26bAGMPHpfQND0xPg8OUL AaIP8WnVCtAEbCv2vVFZECHispHmD2HOhbFWkDA17IvD5UMzSrzkG9E7rp+lYz+wmYfE uniK/SINpbAAXTa6Jqw+F+73kpid2uzcpl3ffubwyXOWKuKqeOJ2GzpjuznVrDbdjFuk iDKIm4ASa0gB32COj09/GsYlg71k0CgWthsGAhzR/DlRo+eZ0KlN2K8OKyH8eg2AgvDd ixmQPbSlU+Sx9mjnegMDZW3VBgDYBXEDZXWj+AUHomHHIspG9i3P7f1ay0Q5yNtHW50H t8kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fYF6yshbdDnOc0oeiJlzqJ9QqxQWt81AFSnSKdi8F3c=; b=Kxns13IqXgJbwCrTY6iihpQGdxX9RR8g4V/ujP4ImEatsw86MiKbTppMDgwgzKs6WQ rdayernQJpY9PCeIuFyz4kh3ryQJGV+Op+QsibXGJZ0T+bmmMz8d3V6v20X/WRe8Z92C uCsQmSdzYh3vVmuWuz6Xvk3vh0tjTuylgve5xi6HEdnkygvwxxh8wlbuzd60xauZ7fm/ 5j4vrBrjfLAR9BtXMtNBse8E80VReTzRu3J5cfRVpMEjKJsMwTPSGKkZVDWgauTVJCTf 5YyE9Aba02Oq1dryL6lZgP9ULYtuvW9K7mBFb50P+rGXAPQLtFNC4WmJxdwhSOh/nM4C FkLQ== X-Gm-Message-State: AOAM533Syv+CW/An93lpyoryY3YvNeqrw9IxIjtKvCCbi89ObSlZAh3s oBCbC9EwUKGXy8pYbB9oueOmiuC4ovfSRA== X-Google-Smtp-Source: ABdhPJyQfY0HhKcKiE/it12WlbNhi18fjJgLQ3ZP6qWIz04cshhmVWQYsRCk7V/IIRGSowz3sGzwGA== X-Received: by 2002:a63:d218:: with SMTP id a24mr831907pgg.345.1623369503431; Thu, 10 Jun 2021 16:58:23 -0700 (PDT) Received: from ada-comp.hitronhub.home (S0106ac202ecb0523.gv.shawcable.net. [70.67.120.89]) by smtp.gmail.com with ESMTPSA id c4sm3588133pfo.189.2021.06.10.16.58.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:58:22 -0700 (PDT) From: Deborah Brouwer To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, jaffe1@gmail.com, Deborah Brouwer Subject: [PATCH v6 2/3] cec: add tests for Deck Play message Date: Thu, 10 Jun 2021 16:58:03 -0700 Message-Id: <8f655634f038f312a32434e1f7c37c3720f0eb57.1623368303.git.deborahbrouwer3563@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Send all Deck Play commands and check that the follower implements them. Test that the follower returns Feature Abort for invalid Play operands. Signed-off-by: Deborah Brouwer --- utils/cec-compliance/cec-test.cpp | 100 +++++++++++++++++++++++--- utils/cec-follower/cec-processing.cpp | 70 +++++++++++++++++- 2 files changed, 156 insertions(+), 14 deletions(-) diff --git a/utils/cec-compliance/cec-test.cpp b/utils/cec-compliance/cec-test.cpp index 83be6b73..f2ec4e90 100644 --- a/utils/cec-compliance/cec-test.cpp +++ b/utils/cec-compliance/cec-test.cpp @@ -33,6 +33,20 @@ static int deck_status_get(struct node *node, unsigned me, unsigned la, __u8 &de return OK; } +static int test_play_mode(struct node *node, unsigned me, unsigned la, __u8 play_mode, __u8 expected) +{ + struct cec_msg msg = {}; + __u8 deck_status; + + cec_msg_init(&msg, me, la); + cec_msg_play(&msg, play_mode); + fail_on_test(!transmit_timeout(node, &msg)); + fail_on_test(cec_msg_status_is_abort(&msg)); /* Assumes deck has media. */ + fail_on_test(deck_status_get(node, me, la, deck_status)); + fail_on_test(deck_status != expected); + + return OK; +} /* System Information */ @@ -793,24 +807,79 @@ static int deck_ctl_deck_ctl_invalid(struct node *node, unsigned me, unsigned la static int deck_ctl_play(struct node *node, unsigned me, unsigned la, bool interactive) { struct cec_msg msg = {}; + __u8 deck_status; cec_msg_init(&msg, me, la); - cec_msg_play(&msg, CEC_OP_PLAY_MODE_PLAY_STILL); + cec_msg_play(&msg, CEC_OP_PLAY_MODE_PLAY_FWD); fail_on_test(!transmit_timeout(node, &msg)); - if (is_playback_or_rec(la)) { - 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 && !unrecognized_op(&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 && !unrecognized_op(&msg)); if (unrecognized_op(&msg)) return OK_NOT_SUPPORTED; if (refused(&msg)) return OK_REFUSED; - if (cec_msg_status_is_abort(&msg)) - return OK_PRESUMED; + fail_on_test(deck_status_get(node, me, la, deck_status)); + if (cec_msg_status_is_abort(&msg)) { + if (incorrect_mode(&msg)) { + if (deck_status == CEC_OP_DECK_INFO_NO_MEDIA) + info("Play Still: no media.\n"); + else + warn("Deck has media but returned Feature Abort with Incorrect Mode."); + return OK; + } + return FAIL; + } + fail_on_test(deck_status != CEC_OP_DECK_INFO_PLAY); - return OK_PRESUMED; + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_STILL, CEC_OP_DECK_INFO_STILL)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_REV, CEC_OP_DECK_INFO_PLAY_REV)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN, CEC_OP_DECK_INFO_FAST_FWD)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN, CEC_OP_DECK_INFO_FAST_REV)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED, CEC_OP_DECK_INFO_FAST_FWD)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED, CEC_OP_DECK_INFO_FAST_REV)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX, CEC_OP_DECK_INFO_FAST_FWD)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX, CEC_OP_DECK_INFO_FAST_REV)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN, CEC_OP_DECK_INFO_SLOW)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN, CEC_OP_DECK_INFO_SLOW_REV)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED, CEC_OP_DECK_INFO_SLOW)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED, CEC_OP_DECK_INFO_SLOW_REV)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX, CEC_OP_DECK_INFO_SLOW)); + fail_on_test(test_play_mode(node, me, la, CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX, CEC_OP_DECK_INFO_SLOW_REV)); + + cec_msg_init(&msg, me, la); + cec_msg_deck_control(&msg, CEC_OP_DECK_CTL_MODE_STOP); + fail_on_test(!transmit_timeout(node, &msg)); + + return OK; +} + +static int deck_ctl_play_invalid(struct node *node, unsigned me, unsigned la, bool interactive) +{ + struct cec_msg msg = {}; + + cec_msg_init(&msg, me, la); + cec_msg_play(&msg, 4); /* 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_play(&msg, 8); /* 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); + + cec_msg_init(&msg, me, la); + cec_msg_play(&msg, 0x26); /* 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 const vec_remote_subtests deck_ctl_subtests{ @@ -825,7 +894,6 @@ static const vec_remote_subtests deck_ctl_subtests{ deck_ctl_give_status_invalid, }, { "Deck Status", CEC_LOG_ADDR_MASK_ALL, deck_ctl_deck_status }, - { "Play", CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, deck_ctl_play }, { "Deck Control", CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, @@ -836,6 +904,16 @@ static const vec_remote_subtests deck_ctl_subtests{ CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, deck_ctl_deck_ctl_invalid, }, + { + "Play", + CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, + deck_ctl_play, + }, + { + "Play Invalid Operand", + CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, + deck_ctl_play_invalid, + }, }; /* Tuner Control */ diff --git a/utils/cec-follower/cec-processing.cpp b/utils/cec-follower/cec-processing.cpp index 4c7ba1d4..e58df85f 100644 --- a/utils/cec-follower/cec-processing.cpp +++ b/utils/cec-follower/cec-processing.cpp @@ -553,14 +553,78 @@ static void processMsg(struct node *node, struct cec_msg &msg, unsigned me) return; } case CEC_MSG_PLAY: - if (node->has_deck_ctl) + if (!node->has_deck_ctl) + break; + + __u8 deck_state; + __u8 play_mode; + + cec_ops_play(&msg, &play_mode); + + switch (play_mode) { + case CEC_OP_PLAY_MODE_PLAY_FWD: + /* Play Forward will close tray if open. */ + deck_state = CEC_OP_DECK_INFO_PLAY; + break; + case CEC_OP_PLAY_MODE_PLAY_REV: + 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_PLAY_REV; + break; + case CEC_OP_PLAY_MODE_PLAY_STILL: + /* Play Still will close tray if open. */ + deck_state = CEC_OP_DECK_INFO_STILL; + break; + case CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN: + case CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED: + case CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX: + 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_FAST_FWD; + break; + case CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN: + case CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED: + case CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX: + 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_FAST_REV; + break; + case CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN: + case CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED: + case CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX: + 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_SLOW; + break; + case CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN: + case CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED: + case CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX: + 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_SLOW_REV; + break; + default: + cec_msg_reply_feature_abort(&msg, CEC_OP_ABORT_INVALID_OP); + transmit(node, &msg); return; - break; + } + node->state.deck_skip_start = 0; + update_deck_state(node, deck_state); + return; case CEC_MSG_DECK_CONTROL: if (!node->has_deck_ctl) break; - __u8 deck_state; __u8 deck_control_mode; cec_ops_deck_control(&msg, &deck_control_mode); From patchwork Thu Jun 10 23:58:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deborah Brouwer X-Patchwork-Id: 12314319 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C057EC48BD1 for ; Thu, 10 Jun 2021 23:59:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A8C9C613D7 for ; Thu, 10 Jun 2021 23:59:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230458AbhFKABd (ORCPT ); Thu, 10 Jun 2021 20:01:33 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:41895 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229578AbhFKABc (ORCPT ); Thu, 10 Jun 2021 20:01:32 -0400 Received: by mail-pl1-f196.google.com with SMTP id e1so1892168plh.8 for ; Thu, 10 Jun 2021 16:59:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Sbj+0jWrqnwzITA5DlB3Zj2Vdv8O3eqgINtEBO7obv8=; b=raZti0gSsbKKc/0uLPS5zT0EnFfgmLy349K3UVMI8faWbSHSOsB8i3gCoNXatO5yl7 4wQU6TCFUd6TKM4WMIo6ErbMc6Bl8VMltSJIaHtDgaX3NVlapHsz7nY4wMJZJ84NI/+Q ga7+IdMkQDL1OdGq39Ec9PIEg47w8FPpRY+oTguEJJWg9fvhCn0HCsdMOWs8kK0H61Ri VJ1yvYyNCPXCMBRh80vtNRm+LYT1cLFd347V3CLeH/kh+r25IRslF6AKHgg2bfyeYbga bMeMm4kEc3zWleXm5Sseg0q7SBVhgBSEqISHq8AeTILAp0ogE2jldzKG8+aGQ/Ntf71J 2TAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Sbj+0jWrqnwzITA5DlB3Zj2Vdv8O3eqgINtEBO7obv8=; b=aFogU/klAusLr8Qgc4phIym9cIGg0FVJfRTf7iiltorrhQFp9Aope0WMlq0y0mXYmE i1WlShO9pEoFcZN3kxSqShXw8IguygN0MFEawEIxvjpZGYmoLj9TosrFamGWZsPNHQkd oBlmC1tjwEPiMHkl5idPeuI6Te+1e3Ney/trGhCeH+FgSRqg1/z/4CUHbDiowhNy3Ez7 51hwEu2httTjjj2BSUHhwimYy1YC+wNFuqTRz+URnjH6UbMhSsS1PrVawW3IOXljb83C nu/ZUAHgccJtsDf7feX8vQTSMBqjjsAP+osvDvJi66702fbI3RQDsBMzsdWtT68iQW2x uxIw== X-Gm-Message-State: AOAM532f70RUSmZYch8w5eIAsFVl4qTR9dTGVbOCqjFe1EZJXWToGcl+ 8hgXF34xXUcgpdsW6acMtYa46A0GboBPsQ== X-Google-Smtp-Source: ABdhPJyvhaNxUJywAfx8A+4Wrkeb87yUqL0Ra1yP7qGIcw/S//BN9nKbACQwvWOFk1EwI6tTSt1lWg== X-Received: by 2002:a17:90a:e94c:: with SMTP id kp12mr5903353pjb.134.1623369505327; Thu, 10 Jun 2021 16:58:25 -0700 (PDT) Received: from ada-comp.hitronhub.home (S0106ac202ecb0523.gv.shawcable.net. [70.67.120.89]) by smtp.gmail.com with ESMTPSA id c4sm3588133pfo.189.2021.06.10.16.58.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:58:24 -0700 (PDT) From: Deborah Brouwer To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, jaffe1@gmail.com, Deborah Brouwer Subject: [PATCH v6 3/3] cec-compliance: remove Deck Status test Date: Thu, 10 Jun 2021 16:58:04 -0700 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Remove the Deck Status message test because invalid Deck Status messages are already captured by cec-compliance in other tests. Signed-off-by: Deborah Brouwer --- utils/cec-compliance/cec-test.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/utils/cec-compliance/cec-test.cpp b/utils/cec-compliance/cec-test.cpp index f2ec4e90..8f2188ff 100644 --- a/utils/cec-compliance/cec-test.cpp +++ b/utils/cec-compliance/cec-test.cpp @@ -696,23 +696,6 @@ static int deck_ctl_give_status_invalid(struct node *node, unsigned me, unsigned return OK; } -static int deck_ctl_deck_status(struct node *node, unsigned me, unsigned la, bool interactive) -{ - struct cec_msg msg = {}; - - cec_msg_init(&msg, me, la); - cec_msg_deck_status(&msg, CEC_OP_DECK_INFO_STOP); - fail_on_test(!transmit_timeout(node, &msg)); - if (unrecognized_op(&msg)) - return OK_NOT_SUPPORTED; - if (refused(&msg)) - return OK_REFUSED; - if (cec_msg_status_is_abort(&msg)) - return OK_PRESUMED; - - return 0; -} - static int deck_ctl_deck_ctl(struct node *node, unsigned me, unsigned la, bool interactive) { struct cec_msg msg = {}; @@ -893,7 +876,6 @@ static const vec_remote_subtests deck_ctl_subtests{ 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,