aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2016-07-22 14:17:54 +0200
committerHans Verkuil <hans.verkuil@cisco.com>2016-07-22 14:17:54 +0200
commit166bdd14db919543763b10a59bed346e390762ff (patch)
tree510a40590659701afbd41fb769c122b15c5a39ed
parent09959c8d4713d4e6217d53fd3ae1196f6d3a7778 (diff)
cec-ctl: show the topology based on the physical addresses
The --show-topology never actually showed the topology. Add that. Note that there is no support yet for detecting physical addresses for unregistered devices. So switches won't show up. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
-rw-r--r--utils/cec-ctl/cec-ctl.cpp67
1 files changed, 65 insertions, 2 deletions
diff --git a/utils/cec-ctl/cec-ctl.cpp b/utils/cec-ctl/cec-ctl.cpp
index 90e4c2c0..c8ffdcad 100644
--- a/utils/cec-ctl/cec-ctl.cpp
+++ b/utils/cec-ctl/cec-ctl.cpp
@@ -31,6 +31,7 @@
#include <cerrno>
#include <string>
#include <vector>
+#include <algorithm>
#include <linux/cec-funcs.h>
#ifdef __ANDROID__
@@ -1077,6 +1078,8 @@ static void log_event(struct cec_event &ev)
(ev.ts % 1000000000) / 1000000);
}
+static __u16 phys_addrs[16];
+
static int showTopologyDevice(struct node *node, unsigned i, unsigned la)
{
struct cec_msg msg;
@@ -1105,6 +1108,7 @@ static int showTopologyDevice(struct node *node, unsigned i, unsigned la)
(phys_addr >> 4) & 0xf, phys_addr & 0xf);
printf("\t\tPrimary Device Type : %s\n",
prim_type2s(msg.msg[4]));
+ phys_addrs[i] = phys_addr;
}
cec_msg_init(&msg, la, i);
@@ -1148,6 +1152,19 @@ static int showTopologyDevice(struct node *node, unsigned i, unsigned la)
return 0;
}
+static __u16 calc_mask(__u16 pa)
+{
+ if (pa & 0xf)
+ return 0xffff;
+ if (pa & 0xff)
+ return 0xfff0;
+ if (pa & 0xfff)
+ return 0xff00;
+ if (pa & 0xffff)
+ return 0xf000;
+ return 0;
+}
+
static int showTopology(struct node *node)
{
struct cec_msg msg = { };
@@ -1172,6 +1189,48 @@ static int showTopology(struct node *node)
else if (show_info && !(msg.tx_status & CEC_TX_STATUS_MAX_RETRIES))
printf("\t\t%s for addr %d\n", status2s(msg).c_str(), i);
}
+
+ __u16 pas[16];
+
+ memcpy(pas, phys_addrs, sizeof(pas));
+ std::sort(pas, pas + 16);
+ unsigned level = 0;
+ unsigned last_pa_mask = 0;
+
+ if (pas[0] == 0xffff)
+ return 0;
+
+ printf("\n\tTopology:\n\n");
+ for (unsigned i = 0; i < 16; i++) {
+ __u16 pa = pas[i];
+ unsigned la_for_pa = 0;
+
+ if (pa == 0xffff)
+ break;
+
+ __u16 pa_mask = calc_mask(pa);
+
+ while (last_pa_mask < pa_mask) {
+ last_pa_mask = (last_pa_mask >> 4) | 0xf000;
+ level++;
+ }
+ while (last_pa_mask > pa_mask) {
+ last_pa_mask <<= 4;
+ level--;
+ }
+ printf("\t");
+ for (unsigned j = 0; j < level; j++)
+ printf(" ");
+ for (unsigned j = 0; j < 16; j++)
+ if (pa == phys_addrs[j]) {
+ la_for_pa = j;
+ break;
+ }
+ printf("%x.%x.%x.%x: %s\n",
+ pa >> 12, (pa >> 8) & 0xf,
+ (pa >> 4) & 0xf, pa & 0xf,
+ la2s(la_for_pa));
+ }
return 0;
}
@@ -1196,6 +1255,8 @@ int main(int argc, char **argv)
init_messages();
+ memset(phys_addrs, 0xff, sizeof(phys_addrs));
+
for (i = 0; long_options[i].name; i++) {
if (!isalpha(long_options[i].val))
continue;
@@ -1551,11 +1612,13 @@ int main(int argc, char **argv)
printf("\tOSD Name : '%s'\n", laddrs.osd_name);
printf("\tLogical Addresses : %u\n", laddrs.num_log_addrs);
for (unsigned i = 0; i < laddrs.num_log_addrs; i++) {
- if (laddrs.log_addr[i] == CEC_LOG_ADDR_INVALID)
+ if (laddrs.log_addr[i] == CEC_LOG_ADDR_INVALID) {
printf("\n\t Logical Address : Not Allocated\n");
- else
+ } else {
printf("\n\t Logical Address : %d (%s)\n",
laddrs.log_addr[i], la2s(laddrs.log_addr[i]));
+ phys_addrs[laddrs.log_addr[i]] = phys_addr;
+ }
printf("\t Primary Device Type : %s\n",
prim_type2s(laddrs.primary_device_type[i]));
printf("\t Logical Address Type : %s\n",

Privacy Policy