aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Fjeldtvedt <jaffe1@gmail.com>2016-08-08 15:39:58 +0200
committerHans Verkuil <hans.verkuil@cisco.com>2016-08-08 16:37:59 +0200
commitfe4a1619d245971919c52b1421956537571e9937 (patch)
treec871c94fce843cc43c67ea23085fb322b6e2abef
parent8acf2767e24f8bfdaeaddb8949cbdf1cbb6999ed (diff)
add test for Tuner Control feature
This adds basic tests for the messages involved in the Tuner Control feature. cec-follower is extended to recognize those messages, and to respond to Give Tuner Device Status. Signed-off-by: Johan Fjeldtvedt <jaffe1@gmail.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
-rw-r--r--utils/cec-compliance/cec-compliance.cpp62
-rw-r--r--utils/cec-compliance/cec-compliance.h17
-rw-r--r--utils/cec-compliance/cec-test.cpp151
-rw-r--r--utils/cec-follower/cec-processing.cpp34
4 files changed, 263 insertions, 1 deletions
diff --git a/utils/cec-compliance/cec-compliance.cpp b/utils/cec-compliance/cec-compliance.cpp
index 90394879..c272dae0 100644
--- a/utils/cec-compliance/cec-compliance.cpp
+++ b/utils/cec-compliance/cec-compliance.cpp
@@ -609,6 +609,68 @@ void sad_decode(struct short_audio_desc *sad, __u32 descriptor)
}
}
+const char *bcast_system2s(__u8 bcast_system)
+{
+ switch (bcast_system) {
+ case CEC_OP_BCAST_SYSTEM_PAL_BG:
+ return "PAL B/G";
+ case CEC_OP_BCAST_SYSTEM_SECAM_LQ:
+ return "SECAM L'";
+ case CEC_OP_BCAST_SYSTEM_PAL_M:
+ return "PAL M";
+ case CEC_OP_BCAST_SYSTEM_NTSC_M:
+ return "NTSC M";
+ case CEC_OP_BCAST_SYSTEM_PAL_I:
+ return "PAL I";
+ case CEC_OP_BCAST_SYSTEM_SECAM_DK:
+ return "SECAM DK";
+ case CEC_OP_BCAST_SYSTEM_SECAM_BG:
+ return "SECAM B/G";
+ case CEC_OP_BCAST_SYSTEM_SECAM_L:
+ return "SECAM L";
+ case CEC_OP_BCAST_SYSTEM_PAL_DK:
+ return "PAL DK";
+ case 31:
+ return "Other System";
+ default:
+ return "Future use";
+ }
+}
+
+const char *dig_bcast_system2s(__u8 bcast_system)
+{
+ switch (bcast_system) {
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN:
+ return "ARIB generic";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:
+ return "ATSC generic";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN:
+ return "DVB generic";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS:
+ return "ARIB-BS";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS:
+ return "ARIB-CS";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T:
+ return "ARIB-T";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:
+ return "ATSC Cable";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:
+ return "ATSC Satellite";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T:
+ return "ATSC Terrestrial";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C:
+ return "DVB-C";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S:
+ return "DVB-S";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2:
+ return "DVB S2";
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T:
+ return "DVB-T";
+ default:
+ return "Invalid";
+ }
+}
+
int cec_named_ioctl(struct node *node, const char *name,
unsigned long int request, void *parm)
{
diff --git a/utils/cec-compliance/cec-compliance.h b/utils/cec-compliance/cec-compliance.h
index b2d95ea3..9a0f4c4d 100644
--- a/utils/cec-compliance/cec-compliance.h
+++ b/utils/cec-compliance/cec-compliance.h
@@ -148,6 +148,8 @@ struct remote {
__u8 mute;
bool has_aud_rate;
bool has_deck_ctl;
+ __u8 bcast_sys;
+ __u8 dig_bcast_sys;
};
struct node {
@@ -290,6 +292,19 @@ static inline __u8 abort_reason(const struct cec_msg *msg)
return msg->msg[3];
}
+static inline bool unrecognized_op(const struct cec_msg *msg)
+{
+ if (!cec_msg_status_is_abort(msg))
+ return false;
+ if (abort_reason(msg) == CEC_OP_ABORT_UNRECOGNIZED_OP)
+ return true;
+ if (abort_reason(msg) == CEC_OP_ABORT_REFUSED) {
+ warn("Opcode %x was refused and is treated as not supported.\n", msg->msg[2]);
+ return true;
+ }
+ return false;
+}
+
static inline bool timed_out(const struct cec_msg *msg)
{
return msg->rx_status & CEC_RX_STATUS_TIMEOUT;
@@ -343,6 +358,8 @@ std::string dev_feat2s(unsigned feat);
const char *power_status2s(__u8 power_status);
std::string short_audio_desc2s(const struct short_audio_desc &sad);
void sad_decode(struct short_audio_desc *sad, __u32 descriptor);
+const char *bcast_system2s(__u8 bcast_system);
+const char *dig_bcast_system2s(__u8 bcast_system);
int check_0(const void *p, int len);
// CEC adapter tests
diff --git a/utils/cec-compliance/cec-test.cpp b/utils/cec-compliance/cec-test.cpp
index 36f28aab..d189326c 100644
--- a/utils/cec-compliance/cec-test.cpp
+++ b/utils/cec-compliance/cec-test.cpp
@@ -273,7 +273,7 @@ static int device_osd_transfer_give(struct node *node, unsigned me, unsigned la,
static struct remote_subtest device_osd_transfer_subtests[] = {
{ "Set OSD Name", CEC_LOG_ADDR_MASK_TV, device_osd_transfer_set },
- { "Give OSD Name", CEC_LOG_ADDR_MASK_TV, device_osd_transfer_give },
+ { "Give OSD Name", CEC_LOG_ADDR_MASK_ALL, device_osd_transfer_give },
};
@@ -638,6 +638,152 @@ static struct remote_subtest deck_ctl_subtests[] = {
};
+/* Tuner Control */
+
+static int tuner_ctl_give_status(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+ struct cec_msg msg = {};
+
+ cec_msg_init(&msg, me, la);
+ cec_msg_give_tuner_device_status(&msg, true, CEC_OP_STATUS_REQ_ONCE);
+ fail_on_test(!transmit_timeout(node, &msg));
+ fail_on_test(timed_out(&msg));
+ if (cec_msg_status_is_abort(&msg))
+ return NOTSUPPORTED;
+
+ return 0;
+}
+
+static int tuner_ctl_sel_analog_service(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+ struct cec_msg msg = {};
+
+ node->remote[la].bcast_sys = ~0;
+ for (unsigned sys = 0; sys <= 8; sys++) {
+ cec_msg_init(&msg, me, la);
+ cec_msg_select_analogue_service(&msg, CEC_OP_ANA_BCAST_TYPE_CABLE,
+ 7668, sys); // 479.25 MHz analog frequency
+ fail_on_test(!transmit_timeout(node, &msg));
+ if (unrecognized_op(&msg))
+ return NOTSUPPORTED;
+ if (cec_msg_status_is_abort(&msg))
+ continue;
+ info("Tuner supports %s\n", bcast_system2s(sys));
+ node->remote[la].bcast_sys = sys;
+ }
+
+ if (node->remote[la].bcast_sys == (__u8)~0)
+ return fail("No analog broadcast format supported\n");
+
+ return PRESUMED_OK;
+}
+
+static int tuner_ctl_sel_digital_service(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+ struct cec_msg msg = {};
+ struct cec_op_digital_service_id digital_service_id = {};
+
+ digital_service_id.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL;
+ digital_service_id.channel.channel_number_fmt = CEC_OP_CHANNEL_NUMBER_FMT_1_PART;
+ digital_service_id.channel.minor = 1;
+
+ __u8 bcast_systems[] = {
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2,
+ CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T,
+ };
+
+ node->remote[la].dig_bcast_sys = ~0;
+ for (unsigned i = 0; i < ARRAY_SIZE(bcast_systems); i++) {
+ __u8 sys = bcast_systems[i];
+
+ digital_service_id.dig_bcast_system = sys;
+ cec_msg_init(&msg, me, la);
+ cec_msg_select_digital_service(&msg, &digital_service_id);
+ fail_on_test(!transmit_timeout(node, &msg));
+ if (unrecognized_op(&msg))
+ return NOTSUPPORTED;
+ if (cec_msg_status_is_abort(&msg))
+ continue;
+ info("Tuner supports %s\n", dig_bcast_system2s(sys));
+ node->remote[la].dig_bcast_sys = sys;
+ }
+
+ if (node->remote[la].dig_bcast_sys == (__u8)~0)
+ return fail("No digital broadcast system supported\n");
+
+ return PRESUMED_OK;
+}
+
+static int tuner_ctl_tuner_dev_status(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+ struct cec_msg msg = {};
+ struct cec_op_tuner_device_info tuner_dev_info = {};
+
+ tuner_dev_info.rec_flag = CEC_OP_REC_FLAG_NOT_USED;
+ tuner_dev_info.tuner_display_info = CEC_OP_TUNER_DISPLAY_INFO_NONE;
+ tuner_dev_info.is_analog = false;
+ tuner_dev_info.digital.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL;
+ tuner_dev_info.digital.dig_bcast_system = CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C;
+ tuner_dev_info.digital.channel.channel_number_fmt = CEC_OP_CHANNEL_NUMBER_FMT_1_PART;
+ tuner_dev_info.digital.channel.minor = 1;
+
+ cec_msg_init(&msg, me, la);
+
+ cec_msg_tuner_device_status(&msg, &tuner_dev_info);
+ fail_on_test(!transmit_timeout(node, &msg));
+ if (unrecognized_op(&msg))
+ return NOTSUPPORTED;
+
+ return 0;
+}
+
+static int tuner_ctl_step_dec(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+ struct cec_msg msg = {};
+
+ cec_msg_init(&msg, me, la);
+ cec_msg_tuner_step_decrement(&msg);
+ fail_on_test(!transmit_timeout(node, &msg));
+ if (unrecognized_op(&msg))
+ return NOTSUPPORTED;
+
+ return PRESUMED_OK;
+}
+
+static int tuner_ctl_step_inc(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+ struct cec_msg msg = {};
+
+ cec_msg_init(&msg, me, la);
+ cec_msg_tuner_step_increment(&msg);
+ fail_on_test(!transmit_timeout(node, &msg));
+ if (unrecognized_op(&msg))
+ return NOTSUPPORTED;
+
+ return PRESUMED_OK;
+}
+
+static struct remote_subtest tuner_ctl_subtests[] = {
+ { "Give Tuner Device Status", CEC_LOG_ADDR_MASK_TUNER, tuner_ctl_give_status },
+ { "Select Analogue Service", CEC_LOG_ADDR_MASK_TUNER, tuner_ctl_sel_analog_service },
+ { "Select Digital Service", CEC_LOG_ADDR_MASK_TUNER, tuner_ctl_sel_digital_service },
+ { "Tuner Device Status", CEC_LOG_ADDR_MASK_ALL, tuner_ctl_tuner_dev_status },
+ { "Tuner Step Decrement", CEC_LOG_ADDR_MASK_TUNER, tuner_ctl_step_dec },
+ { "Tuner Step Increment", CEC_LOG_ADDR_MASK_TUNER, tuner_ctl_step_inc },
+};
+
+
/* Post-test checks */
static int post_test_check_recognized(struct node *node, unsigned me, unsigned la, bool interactive)
@@ -689,6 +835,9 @@ static struct remote_test tests[] = {
test_case("Deck Control feature",
TAG_DECK_CONTROL,
deck_ctl_subtests),
+ test_case("Tuner Control feature",
+ TAG_TUNER_CONTROL,
+ tuner_ctl_subtests),
test_case_ext("Dynamic Auto Lipsync feature",
TAG_DYNAMIC_AUTO_LIPSYNC,
dal_subtests),
diff --git a/utils/cec-follower/cec-processing.cpp b/utils/cec-follower/cec-processing.cpp
index a2fd7e83..b66321f2 100644
--- a/utils/cec-follower/cec-processing.cpp
+++ b/utils/cec-follower/cec-processing.cpp
@@ -524,6 +524,40 @@ static void processMsg(struct node *node, struct cec_msg &msg, unsigned me)
return;
+ /* Tuner Control */
+
+ case CEC_MSG_GIVE_TUNER_DEVICE_STATUS: {
+ if (!cec_has_tuner(1 << me))
+ break;
+
+ struct cec_op_tuner_device_info tuner_dev_info = {};
+
+ cec_msg_set_reply_to(&msg, &msg);
+ tuner_dev_info.rec_flag = CEC_OP_REC_FLAG_NOT_USED;
+ tuner_dev_info.tuner_display_info = CEC_OP_TUNER_DISPLAY_INFO_NONE;
+ tuner_dev_info.is_analog = false;
+ tuner_dev_info.digital.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL;
+ tuner_dev_info.digital.dig_bcast_system = CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C;
+ tuner_dev_info.digital.channel.channel_number_fmt = CEC_OP_CHANNEL_NUMBER_FMT_1_PART;
+ tuner_dev_info.digital.channel.minor = 1;
+
+ cec_msg_tuner_device_status(&msg, &tuner_dev_info);
+ transmit(node, &msg);
+ return;
+ }
+
+ case CEC_MSG_TUNER_DEVICE_STATUS:
+ return;
+
+ case CEC_MSG_SELECT_ANALOGUE_SERVICE:
+ case CEC_MSG_SELECT_DIGITAL_SERVICE:
+ case CEC_MSG_TUNER_STEP_DECREMENT:
+ case CEC_MSG_TUNER_STEP_INCREMENT:
+ if (!cec_has_tuner(1 << me))
+ break;
+ return;
+
+
/* Dynamic Auto Lipsync */
case CEC_MSG_REQUEST_CURRENT_LATENCY: {

Privacy Policy