aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2020-09-08 17:11:47 +0200
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2020-09-08 17:11:47 +0200
commitdedeb53218d1e6b8da584a3c1aaa404f424c3647 (patch)
treef9ac5526c9b7e41e61964866a87f15e78d3c3868
parent364da216e3f8750b037fde0f83d64ced0f94a1aa (diff)
cec-ctl: improve the --phys-addr-from-edid-poll option
When --phys-addr-from-edid-poll is specified, start a background thread that does the polling. This avoids having to start one cec-ctl instance to do EDID polling, and another to start a stress test (--stress-test-power-cycle). When all other requested actions are finished, then cec-ctl will just wait for Ctrl-C when --phys-addr-from-edid-poll is specified, so this effectively keeps the old behavior as well. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--utils/cec-ctl/Makefile.am2
-rw-r--r--utils/cec-ctl/cec-ctl.1.in8
-rw-r--r--utils/cec-ctl/cec-ctl.cpp106
3 files changed, 69 insertions, 47 deletions
diff --git a/utils/cec-ctl/Makefile.am b/utils/cec-ctl/Makefile.am
index 278fcc47..de04c4de 100644
--- a/utils/cec-ctl/Makefile.am
+++ b/utils/cec-ctl/Makefile.am
@@ -3,6 +3,6 @@ man_MANS = cec-ctl.1
cec_ctl_SOURCES = cec-ctl.cpp cec-pin.cpp cec-ctl.h
cec_ctl_CPPFLAGS = -I$(top_srcdir)/utils/libcecutil $(GIT_COMMIT_CNT)
-cec_ctl_LDADD = -lrt ../libcecutil/libcecutil.la
+cec_ctl_LDADD = -lrt -lpthread ../libcecutil/libcecutil.la
EXTRA_DIST = cec-ctl.1
diff --git a/utils/cec-ctl/cec-ctl.1.in b/utils/cec-ctl/cec-ctl.1.in
index fac3a92e..aaa3157f 100644
--- a/utils/cec-ctl/cec-ctl.1.in
+++ b/utils/cec-ctl/cec-ctl.1.in
@@ -56,7 +56,7 @@ Turn on verbose reporting.
Show version information.
.TP
\fB\-w\fR, \fB\-\-wall\-clock\fR
-Show timestamps as wall-clock time. This also turns on verbose reporting.
+Show timestamps as wall-clock time. This also turns on verbose reporting.
.TP
\fB\-h\fR, \fB\-\-help\fR
Prints the help message.
@@ -79,6 +79,10 @@ EDID file every 100 ms and, if changed, update the physical address.
This provides a way for Pulse-Eight (or similar) USB CEC dongles to become
aware of HDMI disconnect and reconnect events.
+
+Polling happens in the background while cec-ctl processes other requested
+actions (i.e. transmitting messages, waiting for replies, etc.) and when that
+is all done cec-ctl will keep polling until the user kills cec-ctl (Ctrl-C).
.TP
\fB\-o\fR, \fB\-\-osd\-name\fR \fI<name>\fR
Use this OSD name. The maximum length is 14 characters.
@@ -102,7 +106,7 @@ By default when sending a CEC message that expects a reply this utility will
wait for that reply. With this option it will just send it without waiting
for the reply. This option applies to the messages following this option.
It acts as a toggle, so after you specify it a second time then the following
-messages will wait for a reply again.
+messages will wait for a reply again.
.TP
\fB\-N\fR, \fB\-\-non\-blocking\fR
Transmit messages in non-blocking mode.
diff --git a/utils/cec-ctl/cec-ctl.cpp b/utils/cec-ctl/cec-ctl.cpp
index 0cdab383..672110ab 100644
--- a/utils/cec-ctl/cec-ctl.cpp
+++ b/utils/cec-ctl/cec-ctl.cpp
@@ -21,6 +21,7 @@
#include <stdarg.h>
#include <ctime>
#include <cerrno>
+#include <pthread.h>
#include <string>
#include <vector>
#include <map>
@@ -42,6 +43,7 @@
static struct timespec start_monotonic;
static struct timeval start_timeofday;
static bool ignore_la[16];
+static const char *edid_path;
#define POLL_FAKE_OPCODE 256
static unsigned short ignore_opcode[257];
@@ -1749,6 +1751,48 @@ static __u16 parse_phys_addr_from_edid(const char *edid_path)
return pa;
}
+static void *thread_edid_poll(void *arg)
+{
+ struct node *node = static_cast<struct node *>(arg);
+ __u16 phys_addr;
+ bool has_edid;
+ char dummy;
+ int fd;
+
+ fd = open(edid_path, O_RDONLY);
+ if (fd < 0)
+ std::exit(EXIT_FAILURE);
+ lseek(fd, 0, SEEK_SET);
+ has_edid = read(fd, &dummy, 1) > 0;
+
+ if (!has_edid)
+ phys_addr = CEC_PHYS_ADDR_INVALID;
+ else
+ phys_addr = parse_phys_addr_from_edid(edid_path);
+ doioctl(node, CEC_ADAP_S_PHYS_ADDR, &phys_addr);
+ printf("Physical Address: %x.%x.%x.%x\n", cec_phys_addr_exp(phys_addr));
+
+ for (;;) {
+ bool edid;
+
+ /* Poll every 100 ms */
+ usleep(100000);
+ lseek(fd, 0, SEEK_SET);
+ edid = read(fd, &dummy, 1) > 0;
+ if (has_edid != edid) {
+ has_edid = edid;
+ if (!edid)
+ phys_addr = CEC_PHYS_ADDR_INVALID;
+ else
+ phys_addr = parse_phys_addr_from_edid(edid_path);
+ doioctl(node, CEC_ADAP_S_PHYS_ADDR, &phys_addr);
+ printf("Physical Address: %x.%x.%x.%x\n",
+ cec_phys_addr_exp(phys_addr));
+ }
+ }
+ return NULL;
+}
+
using dev_vec = std::vector<std::string>;
using dev_map = std::map<std::string, std::string>;
@@ -1763,7 +1807,7 @@ static void list_devices()
dp = opendir("/dev");
if (dp == NULL) {
- perror ("Couldn't open the directory");
+ perror("Couldn't open the directory");
return;
}
while ((ep = readdir(dp)))
@@ -1856,7 +1900,6 @@ int main(int argc, char **argv)
__u8 rc_tv = 0;
__u8 rc_src = 0;
const char *osd_name = "";
- const char *edid_path = NULL;
const char *store_pin = NULL;
const char *analyze_pin = NULL;
bool reply = true;
@@ -2580,10 +2623,19 @@ int main(int argc, char **argv)
cec_driver_info(caps, laddrs, phys_addr, conn_info);
}
+ if (options[OptPhysAddrFromEDIDPoll]) {
+ pthread_t t;
+ int ret = pthread_create(&t, NULL, thread_edid_poll, &node);
+ if (ret) {
+ fprintf(stderr, "Failed to start EDID poll thread: %s\n",
+ strerror(errno));
+ std::exit(EXIT_FAILURE);
+ }
+ }
+
if (node.num_log_addrs == 0) {
if (options[OptMonitor] || options[OptMonitorAll] ||
- options[OptMonitorPin] || options[OptStorePin] ||
- options[OptPhysAddrFromEDIDPoll])
+ options[OptMonitorPin] || options[OptStorePin])
goto skip_la;
if (warn_if_unconfigured)
fprintf(stderr, "\nAdapter is unconfigured, please configure it first.\n");
@@ -2672,49 +2724,15 @@ int main(int argc, char **argv)
stress_test_pwr_cycle_sleep_before_off);
skip_la:
- if (options[OptPhysAddrFromEDIDPoll]) {
- bool has_edid;
- char dummy;
- int fd;
-
- fd = open(edid_path, O_RDONLY);
- if (fd < 0)
- std::exit(EXIT_FAILURE);
- lseek(fd, 0, SEEK_SET);
- has_edid = read(fd, &dummy, 1) > 0;
-
- if (!has_edid)
- phys_addr = CEC_PHYS_ADDR_INVALID;
- else
- phys_addr = parse_phys_addr_from_edid(edid_path);
- doioctl(&node, CEC_ADAP_S_PHYS_ADDR, &phys_addr);
- printf("Physical Address: %x.%x.%x.%x\n", cec_phys_addr_exp(phys_addr));
-
- for (;;) {
- bool edid;
-
- /* Poll every 100 ms */
- usleep(100000);
- lseek(fd, 0, SEEK_SET);
- edid = read(fd, &dummy, 1) > 0;
- if (has_edid != edid) {
- has_edid = edid;
- if (!edid)
- phys_addr = CEC_PHYS_ADDR_INVALID;
- else
- phys_addr = parse_phys_addr_from_edid(edid_path);
- doioctl(&node, CEC_ADAP_S_PHYS_ADDR, &phys_addr);
- printf("Physical Address: %x.%x.%x.%x\n",
- cec_phys_addr_exp(phys_addr));
- }
- }
- }
-
if (options[OptMonitor] || options[OptMonitorAll] ||
- options[OptMonitorPin] || options[OptStorePin])
+ options[OptMonitorPin] || options[OptStorePin]) {
monitor(node, monitor_time, store_pin);
- else if (options[OptWaitForMsgs])
+ } else if (options[OptWaitForMsgs]) {
wait_for_msgs(node, monitor_time);
+ } else if (options[OptPhysAddrFromEDIDPoll]) {
+ printf("Press Ctrl-C to stop EDID polling.\n");
+ pause();
+ }
fflush(stdout);
close(fd);
return 0;

Privacy Policy