Last active
April 25, 2017 20:11
-
-
Save athoik/10c54f1856169637d973f62829c85e1d to your computer and use it in GitHub Desktop.
A small utility to test vtuner ATSC capability
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#include <sys/ioctl.h> | |
#include <linux/dvb/frontend.h> | |
#define VTUNER_GET_MESSAGE 1 | |
#define VTUNER_SET_RESPONSE 2 | |
#define VTUNER_SET_NAME 3 | |
#define VTUNER_SET_TYPE 4 | |
#define VTUNER_SET_HAS_OUTPUTS 5 | |
#define VTUNER_SET_FE_INFO 6 | |
#define VTUNER_SET_NUM_MODES 7 | |
#define VTUNER_SET_MODES 8 | |
#define VTUNER_SET_DELSYS 32 | |
#define VTUNER_SET_ADAPTER 33 | |
int setup_vtuner_dvb_s2(int fd) | |
{ | |
struct dvb_frontend_info fe_info; | |
char fe_type[8]; | |
unsigned char delsys[8]; | |
strcpy(fe_info.name, "DVB-S2 VTUNER"); | |
fe_info.type = FE_QPSK; | |
fe_info.frequency_min = 950000; | |
fe_info.frequency_max = 2150000; | |
fe_info.frequency_stepsize = 250; | |
fe_info.frequency_tolerance = 29500; | |
fe_info.symbol_rate_min = 1000000; | |
fe_info.symbol_rate_max = 45000000; | |
fe_info.caps = FE_CAN_INVERSION_AUTO | | |
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | |
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | |
FE_CAN_QPSK | | |
FE_CAN_2G_MODULATION | FE_CAN_MULTISTREAM; | |
strcpy(fe_type, "DVB-S2"); | |
ioctl(fd, VTUNER_SET_NAME, fe_info.name); | |
ioctl(fd, VTUNER_SET_TYPE, fe_type); | |
ioctl(fd, VTUNER_SET_FE_INFO, &fe_info); | |
/* set delsys */ | |
delsys[0] = SYS_DVBS2; | |
delsys[1] = SYS_DVBS; | |
delsys[2] = SYS_UNDEFINED; | |
ioctl(fd, VTUNER_SET_DELSYS, delsys); | |
/* has_outputs */ | |
ioctl(fd, VTUNER_SET_HAS_OUTPUTS, "no"); | |
return 0; | |
} | |
int setup_vtuner_dvb_c(int fd) | |
{ | |
struct dvb_frontend_info fe_info; | |
char fe_type[8]; | |
unsigned char delsys[8]; | |
strcpy(fe_info.name, "DVB-C VTUNER"); | |
fe_info.type = FE_QAM; | |
fe_info.frequency_min = 51000000; | |
fe_info.frequency_max = 858000000; | |
fe_info.frequency_stepsize = 62500; | |
fe_info.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | | |
FE_CAN_QAM_128 | FE_CAN_QAM_256 | | |
FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO; | |
strcpy(fe_type, "DVB-C"); | |
ioctl(fd, VTUNER_SET_NAME, fe_info.name); | |
ioctl(fd, VTUNER_SET_TYPE, fe_type); | |
ioctl(fd, VTUNER_SET_FE_INFO, &fe_info); | |
/* set delsys */ | |
delsys[0] = SYS_DVBC_ANNEX_A; | |
delsys[1] = SYS_DVBC_ANNEX_C; | |
delsys[2] = SYS_DVBT2; | |
delsys[3] = SYS_DVBT; | |
delsys[4] = SYS_UNDEFINED; | |
ioctl(fd, VTUNER_SET_DELSYS, delsys); | |
/* has_outputs */ | |
ioctl(fd, VTUNER_SET_HAS_OUTPUTS, "no"); | |
return 0; | |
} | |
int setup_vtuner_dvb_t2(int fd) | |
{ | |
struct dvb_frontend_info fe_info; | |
char fe_type[8]; | |
unsigned char delsys[8]; | |
strcpy(fe_info.name, "DVB-T2 VTUNER"); | |
fe_info.type = FE_OFDM; | |
fe_info.frequency_min = 0; | |
fe_info.frequency_max = 863250000; | |
fe_info.frequency_stepsize = 62500; | |
fe_info.frequency_tolerance = 0; | |
fe_info.notifier_delay = 0; | |
fe_info.caps = FE_CAN_INVERSION_AUTO | | |
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | |
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | |
FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK | | |
FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | |
FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | | |
FE_CAN_2G_MODULATION | FE_CAN_MULTISTREAM; | |
strcpy(fe_type, "DVB-T2"); | |
ioctl(fd, VTUNER_SET_NAME, fe_info.name); | |
ioctl(fd, VTUNER_SET_TYPE, fe_type); | |
ioctl(fd, VTUNER_SET_FE_INFO, &fe_info); | |
/* set delsys */ | |
delsys[0] = SYS_DVBT2; | |
delsys[1] = SYS_DVBT; | |
delsys[2] = SYS_DVBC_ANNEX_A; | |
delsys[3] = SYS_DVBC_ANNEX_C; | |
delsys[4] = SYS_UNDEFINED; | |
ioctl(fd, VTUNER_SET_DELSYS, delsys); | |
/* has_outputs */ | |
ioctl(fd, VTUNER_SET_HAS_OUTPUTS, "no"); | |
return 0; | |
} | |
int setup_vtuner_atsc(int fd) | |
{ | |
struct dvb_frontend_info fe_info; | |
char fe_type[8]; | |
unsigned char delsys[8]; | |
strcpy(fe_info.name, "ATSC VTUNER"); | |
fe_info.type = FE_ATSC; | |
fe_info.frequency_min = 54000000; | |
fe_info.frequency_max = 806000000; | |
fe_info.frequency_stepsize = 62500; | |
fe_info.frequency_tolerance = 0; | |
fe_info.notifier_delay = 0; | |
fe_info.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | | |
FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256 | | |
FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | |
FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER; | |
strcpy(fe_type, "ATSC"); | |
ioctl(fd, VTUNER_SET_NAME, fe_info.name); | |
printf("VTUNER_SET_NAME: %d %m\n", errno); | |
ioctl(fd, VTUNER_SET_TYPE, fe_type); | |
printf("VTUNER_SET_TYPE: %d %m\n", errno); | |
ioctl(fd, VTUNER_SET_FE_INFO, &fe_info); | |
printf("VTUNER_SET_FE_INFO: %d %m\n", errno); | |
/* set delsys */ | |
delsys[0] = SYS_ATSC; | |
delsys[1] = SYS_DVBC_ANNEX_B; | |
delsys[2] = SYS_UNDEFINED; | |
ioctl(fd, VTUNER_SET_DELSYS, delsys); | |
/* has_outputs */ | |
ioctl(fd, VTUNER_SET_HAS_OUTPUTS, "no"); | |
return 0; | |
} | |
const char *get_delivery_system(fe_delivery_system_t system) | |
{ | |
switch (system) { | |
case SYS_UNDEFINED: | |
return "UNDEFINED"; | |
case SYS_DVBC_ANNEX_A: | |
return "DVB-C ANNEX A"; | |
case SYS_DVBC_ANNEX_B: | |
return "DVB-C ANNEX B"; | |
case SYS_DVBC_ANNEX_C: | |
return "DVB-C ANNEX C"; | |
case SYS_DVBT: | |
return "DVB-T"; | |
case SYS_DSS: | |
return "DSS"; | |
case SYS_DVBS: | |
return "DVB-S"; | |
case SYS_DVBS2: | |
return "DVB-S2"; | |
case SYS_DVBH: | |
return "DVB-H"; | |
case SYS_ISDBT: | |
return "ISDBT"; | |
case SYS_ISDBS: | |
return "ISDBS"; | |
case SYS_ISDBC: | |
return "ISDBC"; | |
case SYS_ATSC: | |
return "ATSC"; | |
case SYS_ATSCMH: | |
return "ATSCMH"; | |
case SYS_DTMB: | |
return "DTMB"; | |
case SYS_CMMB: | |
return "CMMB"; | |
case SYS_DAB: | |
return "DAB"; | |
case SYS_DVBT2: | |
return "DVB-T2"; | |
case SYS_TURBO: | |
return "TURBO"; | |
default: | |
return "UNKNOWN"; | |
} | |
} | |
int read_delsys(int fd) | |
{ | |
struct dtv_property prop[1]; | |
struct dtv_properties props; | |
int i; | |
prop[0].cmd = DTV_ENUM_DELSYS; | |
memset(prop[0].u.buffer.data, 0, sizeof(prop[0].u.buffer.data)); | |
prop[0].u.buffer.len = 0; | |
props.props = prop; | |
props.num = 1; | |
if (ioctl(fd, FE_GET_PROPERTY, &props) < 0) { | |
fprintf(stderr, "DTV_ENUM_DELSYS failed: %m\n"); | |
return -1; | |
} | |
fprintf(stdout, "Supported delivery system%s: \n", | |
(prop[0].u.buffer.len > 1) ? "s" : ""); | |
for (i = 0; i < prop[0].u.buffer.len; i++) | |
fprintf(stdout, " [%s]\n", get_delivery_system(prop[0].u.buffer.data[i])); | |
return 0; | |
} | |
int newfrontend() | |
{ | |
int nr = 0; | |
char filename[64]; | |
while(1) | |
{ | |
sprintf(filename, "/dev/dvb/adapter0/frontend%d", nr); | |
if(access(filename, R_OK) < 0) break; | |
nr++; | |
} | |
errno = 0; | |
return nr; | |
} | |
int main(int argc, char **argv) | |
{ | |
int vtuner_fd; | |
int fe_fd; | |
char filename[64]; | |
char vtuner_type; | |
if (argc == 2) { | |
vtuner_type = argv[1][0]; | |
} | |
else { | |
fprintf(stderr, "usage %s a/t/c/s\n", argv[0]); | |
fprintf(stderr, " a = atsc\n t = dvb-t2\n c = dvb-c\n s = dvb-s2\n"); | |
return EXIT_FAILURE; | |
} | |
sprintf(filename, "/dev/dvb/adapter0/frontend%d", newfrontend()); | |
vtuner_fd = open("/dev/misc/vtuner0", O_RDWR); | |
if (vtuner_fd == -1) { | |
fprintf(stderr, "Can't open vtuner\n"); | |
return EXIT_FAILURE; | |
} | |
if (vtuner_type == 's') { | |
fprintf(stderr, "Setting DVB-S vtuner\n"); | |
setup_vtuner_dvb_s2(vtuner_fd); | |
} | |
else if (vtuner_type == 'c') { | |
fprintf(stderr, "Setting DVB-C vtuner\n"); | |
setup_vtuner_dvb_c(vtuner_fd); | |
} | |
else if (vtuner_type == 't') { | |
fprintf(stderr, "Setting DVB-T vtuner\n"); | |
setup_vtuner_dvb_t2(vtuner_fd); | |
} | |
else if (vtuner_type == 'a') { | |
fprintf(stderr, "Setting ATSC vtuner\n"); | |
setup_vtuner_atsc(vtuner_fd); | |
} | |
else { | |
fprintf(stderr, "Not a valid vtuner type"); | |
} | |
fprintf(stdout, "Displaying nim_sockets:\n"); | |
system("cat /proc/bus/nim_sockets"); | |
fprintf(stdout, "\n"); | |
fprintf(stdout, "Check device/nim_sockets and press any key...\n"); | |
getchar(); | |
fe_fd = open(filename, O_RDWR); | |
if (fe_fd == -1) { | |
fprintf(stderr, "Can't open frontend %s\n", filename); | |
return EXIT_FAILURE; | |
} | |
read_delsys(fe_fd); | |
fprintf(stdout, "About to close frontend. Press any key...\n"); | |
getchar(); | |
close(fe_fd); | |
fprintf(stdout, "About to close vtuner. Press any key...\n"); | |
getchar(); | |
close(vtuner_fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment