File: intel_hdcp.c

package info (click to toggle)
intel-gpu-tools 2.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 63,360 kB
  • sloc: xml: 781,458; ansic: 360,567; python: 8,336; yacc: 2,781; perl: 1,196; sh: 1,177; lex: 487; asm: 227; lisp: 35; makefile: 30
file content (126 lines) | stat: -rw-r--r-- 2,783 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2025 Intel Corporation
 */

#include <fcntl.h>
#include <stdio.h>

#include "igt.h"

#define MAX_HDCP_BUF_LEN	5000

typedef struct data {
	int fd;
	igt_display_t display;
	struct igt_fb red, green;
	int height, width;
} data_t;

static const char *get_hdcp_version(int fd, char *connector_name)
{
	char buf[MAX_HDCP_BUF_LEN];
	int ret;

	ret = igt_debugfs_connector_dir(fd, connector_name, O_RDONLY);
	if (ret < 0) {
		fprintf(stderr, "Failed to open connector directory\n");
		return NULL;
	}

	if (is_intel_device(fd))
		igt_debugfs_simple_read(ret, "i915_hdcp_sink_capability", buf, sizeof(buf));
	else
		igt_debugfs_simple_read(ret, "hdcp_sink_capability", buf, sizeof(buf));

	close(ret);
	if (strstr(buf, "HDCP1.4") && strstr(buf, "HDCP2.2"))
		return "HDCP1.4 and HDCP2.2";
	else if (strstr(buf, "HDCP1.4"))
		return "HDCP1.4";
	else if (strstr(buf, "HDCP2.2"))
		return "HDCP2.2";
	else
		return "No HDCP support";
}

static void get_hdcp_info(data_t *data)
{
	char *output_name;
	drmModeRes *res = drmModeGetResources(data->fd);

	if (!res) {
		fprintf(stderr, "Failed to get DRM resources\n");
		return;
	}

	fprintf(stderr, "Connectors:\n");
	fprintf(stderr, "id\tencoder\tstatus\t\ttype\tHDCP\n");
	for (int i = 0; i < res->count_connectors; i++) {
		drmModeConnector *c;

		c = drmModeGetConnectorCurrent(data->fd, res->connectors[i]);

		if (!c)
			continue;

		asprintf(&output_name, "%s-%d",
			 kmstest_connector_type_str(c->connector_type),
			 c->connector_type_id);

		fprintf(stderr, "%d\t%d\t%s\t%s\t%s\n",
			c->connector_id, c->encoder_id,
			kmstest_connector_status_str(c->connection),
			kmstest_connector_type_str(c->connector_type),
			get_hdcp_version(data->fd, output_name));

		drmModeFreeConnector(c);
	}

	drmModeFreeResources(res);
}

static void print_usage(void)
{
	fprintf(stderr, "Usage: intel_hdcp [OPTIONS]\n");
	fprintf(stderr, "Options:\n");
	fprintf(stderr, "-i,	--info		Get HDCP Information\n");
	fprintf(stderr, "-h,	--help		Display this help message\n");
}

static void test_init(data_t *data)
{
	data->fd = __drm_open_driver(DRIVER_ANY);
	if (data->fd < 0) {
		fprintf(stderr, "Failed to open DRM driver\n");
		exit(EXIT_FAILURE);
	}
	igt_display_require(&data->display, data->fd);
	igt_display_require_output(&data->display);
}

int main(int argc, char **argv)
{
	data_t data;
	int option;
	static const char optstr[] = "hi";
	struct option long_opts[] = {
		{"help",	no_argument,	NULL, 'h'},
		{"info",	no_argument,	NULL, 'i'},
		{NULL,		0,		NULL,  0 }
	};

	test_init(&data);

	while ((option = getopt_long(argc, argv, optstr, long_opts, NULL)) != -1) {
		switch (option) {
		case 'i':
			get_hdcp_info(&data);
			break;
		case 'h':
		default:
			print_usage();
			break;
		}
	}
}