diff options
Diffstat (limited to 'lib/libdvbapi')
| -rw-r--r-- | lib/libdvbapi/Makefile | 25 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbaudio.c | 50 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbaudio.h | 55 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbca.c | 159 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbca.h | 135 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbdemux.c | 255 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbdemux.h | 204 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbfe.c | 574 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbfe.h | 333 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbnet.c | 104 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbnet.h | 87 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbvideo.c | 46 | ||||
| -rw-r--r-- | lib/libdvbapi/dvbvideo.h | 46 | 
13 files changed, 2073 insertions, 0 deletions
| diff --git a/lib/libdvbapi/Makefile b/lib/libdvbapi/Makefile new file mode 100644 index 0000000..0ed96ec --- /dev/null +++ b/lib/libdvbapi/Makefile @@ -0,0 +1,25 @@ +# Makefile for linuxtv.org dvb-apps/lib/libdvbapi + +includes = dvbaudio.h \ +           dvbca.h    \ +           dvbdemux.h \ +           dvbfe.h    \ +           dvbnet.h   \ +           dvbvideo.h + +objects  = dvbaudio.o \ +           dvbca.o    \ +           dvbdemux.o \ +           dvbfe.o    \ +           dvbnet.o   \ +           dvbvideo.o + +lib_name = libdvbapi + +CPPFLAGS += -I../../lib + +.PHONY: all + +all: library + +include ../../Make.rules diff --git a/lib/libdvbapi/dvbaudio.c b/lib/libdvbapi/dvbaudio.c new file mode 100644 index 0000000..72b4d70 --- /dev/null +++ b/lib/libdvbapi/dvbaudio.c @@ -0,0 +1,50 @@ +/* + * libdvbnet - a DVB network support library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/param.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <linux/dvb/audio.h> +#include <errno.h> +#include "dvbaudio.h" + +int dvbaudio_open(int adapter, int audiodeviceid) +{ +	char filename[PATH_MAX+1]; +	int fd; + +	sprintf(filename, "/dev/dvb/adapter%i/audio%i", adapter, audiodeviceid); +	if ((fd = open(filename, O_RDWR)) < 0) { +		// if that failed, try a flat /dev structure +		sprintf(filename, "/dev/dvb%i.audio%i", adapter, audiodeviceid); +		fd = open(filename, O_RDWR); +	} + +	return fd; +} + +int dvbaudio_set_bypass(int fd, int bypass) +{ +	return ioctl(fd, AUDIO_SET_BYPASS_MODE, bypass); +} diff --git a/lib/libdvbapi/dvbaudio.h b/lib/libdvbapi/dvbaudio.h new file mode 100644 index 0000000..36f6a55 --- /dev/null +++ b/lib/libdvbapi/dvbaudio.h @@ -0,0 +1,55 @@ +/* + * libdvbnet - a DVB network support library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#ifndef LIBDVBAUDIO_H +#define LIBDVBAUDIO_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> + +/** + * Open a DVB audio device. + * + * @param adapter DVB adapter ID. + * @param audiodeviceid Id of audio device of that adapter to open. + * @return A unix file descriptor on success, or -1 on failure. + */ +extern int dvbaudio_open(int adapter, int audiodeviceid); + +/** + * Control audio bypass - i.e. output decoded audio, or the raw bitstream (e.g. AC3). + * + * @param fd Audio device opened with dvbaudio_open(). + * @param bypass 1=> enable bypass, 0=> disable. + * @return 0 on success, nonzero on failure. + */ +extern int dvbaudio_set_bypass(int fd, int bypass); + +// FIXME: this is a stub library + +#ifdef __cplusplus +} +#endif + +#endif // LIBDVBAUDIO_H diff --git a/lib/libdvbapi/dvbca.c b/lib/libdvbapi/dvbca.c new file mode 100644 index 0000000..8261cd2 --- /dev/null +++ b/lib/libdvbapi/dvbca.c @@ -0,0 +1,159 @@ +/* + * libdvbca - interface onto raw CA devices + * + * Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <unistd.h> +#include <ctype.h> +#include <errno.h> +#include <linux/dvb/ca.h> +#include "dvbca.h" + + +int dvbca_open(int adapter, int cadevice) +{ +	char filename[PATH_MAX+1]; +	int fd; + +	sprintf(filename, "/dev/dvb/adapter%i/ca%i", adapter, cadevice); +	if ((fd = open(filename, O_RDWR)) < 0) { +		// if that failed, try a flat /dev structure +		sprintf(filename, "/dev/dvb%i.ca%i", adapter, cadevice); +		fd = open(filename, O_RDWR); +	} + +	return fd; +} + +int dvbca_reset(int fd, uint8_t slot) +{ +	return ioctl(fd, CA_RESET, (1 << slot)); +} + +int dvbca_get_interface_type(int fd, uint8_t slot) +{ +	ca_slot_info_t info; + +	info.num = slot; +	if (ioctl(fd, CA_GET_SLOT_INFO, &info)) +		return -1; + +	if (info.type & CA_CI_LINK) +		return DVBCA_INTERFACE_LINK; +	if (info.type & CA_CI) +		return DVBCA_INTERFACE_HLCI; + +	return -1; +} + +int dvbca_get_cam_state(int fd, uint8_t slot) +{ +	ca_slot_info_t info; + +	info.num = slot; +	if (ioctl(fd, CA_GET_SLOT_INFO, &info)) +		return -1; + +	if (info.flags == 0) +		return DVBCA_CAMSTATE_MISSING; +	if (info.flags & CA_CI_MODULE_READY) +		return DVBCA_CAMSTATE_READY; +	if (info.flags & CA_CI_MODULE_PRESENT) +		return DVBCA_CAMSTATE_INITIALISING; + +	return -1; +} + +int dvbca_link_write(int fd, uint8_t slot, uint8_t connection_id, +		     uint8_t *data, uint16_t data_length) +{ +	uint8_t *buf = malloc(data_length + 2); +	if (buf == NULL) +		return -1; + +	buf[0] = slot; +	buf[1] = connection_id; +	memcpy(buf+2, data, data_length); + +	int result = write(fd, buf, data_length+2); +	free(buf); +	return result; +} + +int dvbca_link_read(int fd, uint8_t *slot, uint8_t *connection_id, +		     uint8_t *data, uint16_t data_length) +{ +	int size; + +	uint8_t *buf = malloc(data_length + 2); +	if (buf == NULL) +		return -1; + +	if ((size = read(fd, buf, data_length+2)) < 2) +		return -1; + +	*slot = buf[0]; +	*connection_id = buf[1]; +	memcpy(data, buf+2, size-2); +	free(buf); + +	return size - 2; +} + +int dvbca_hlci_write(int fd, uint8_t *data, uint16_t data_length) +{ +	struct ca_msg msg; + +	if (data_length > 256) { +		return -1; +	} +	memset(&msg, 0, sizeof(msg)); +	msg.length = data_length; + +	memcpy(msg.msg, data, data_length); + +	return ioctl(fd, CA_SEND_MSG, &msg); +} + +int dvbca_hlci_read(int fd, uint32_t app_tag, uint8_t *data, +		    uint16_t data_length) +{ +	struct ca_msg msg; + +	if (data_length > 256) { +		data_length = 256; +	} +	memset(&msg, 0, sizeof(msg)); +	msg.length = data_length; +	msg.msg[0] = app_tag >> 16; +	msg.msg[1] = app_tag >> 8; +	msg.msg[2] = app_tag; + +	int status = ioctl(fd, CA_GET_MSG, &msg); +	if (status < 0) return status; + +	if (msg.length > data_length) msg.length = data_length; +	memcpy(data, msg.msg, msg.length); +	return msg.length; +} diff --git a/lib/libdvbapi/dvbca.h b/lib/libdvbapi/dvbca.h new file mode 100644 index 0000000..c65423b --- /dev/null +++ b/lib/libdvbapi/dvbca.h @@ -0,0 +1,135 @@ +/* + * libdvbca - interface onto raw CA devices + * + * Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#ifndef LIBDVBCA_H +#define LIBDVBCA_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> + +/** + * The types of CA interface we support. + */ +#define DVBCA_INTERFACE_LINK 0 +#define DVBCA_INTERFACE_HLCI 1 + +/** + * States a CAM in a slot can be in. + */ +#define DVBCA_CAMSTATE_MISSING 0 +#define DVBCA_CAMSTATE_INITIALISING 1 +#define DVBCA_CAMSTATE_READY 2 + + +/** + * Open a CA device. Multiple CAMs can be accessed through a CA device. + * + * @param adapter Index of the DVB adapter. + * @param cadevice Index of the CA device on that adapter (usually 0). + * @return A unix file descriptor on success, or -1 on failure. + */ +extern int dvbca_open(int adapter, int cadevice); + +/** + * Reset a CAM. + * + * @param fd File handle opened with dvbca_open. + * @param slot Slot where the requested CAM is in. + * @return 0 on success, -1 on failure. + */ +extern int dvbca_reset(int fd, uint8_t slot); + +/** + * Get the interface type of a CAM. + * + * @param fd File handle opened with dvbca_open. + * @param slot Slot where the requested CAM is in. + * @return One of the DVBCA_INTERFACE_* values, or -1 on failure. + */ +extern int dvbca_get_interface_type(int fd, uint8_t slot); + +/** + * Get the state of a CAM. + * + * @param fd File handle opened with dvbca_open. + * @param slot Slot where the requested CAM is in. + * @return One of the DVBCA_CAMSTATE_* values, or -1 on failure. + */ +extern int dvbca_get_cam_state(int fd, uint8_t slot); + +/** + * Write a message to a CAM using a link-layer interface. + * + * @param fd File handle opened with dvbca_open. + * @param slot Slot where the requested CAM is in. + * @param connection_id Connection ID of the message. + * @param data Data to write. + * @param data_length Number of bytes to write. + * @return 0 on success, or -1 on failure. + */ +extern int dvbca_link_write(int fd, uint8_t slot, uint8_t connection_id, +			    uint8_t *data, uint16_t data_length); + +/** + * Read a message from a CAM using a link-layer interface. + * + * @param fd File handle opened with dvbca_open. + * @param slot Slot where the responding CAM is in. + * @param connection_id Destination for the connection ID the message came from. + * @param data Data that was read. + * @param data_length Max number of bytes to read. + * @return Number of bytes read on success, or -1 on failure. + */ +extern int dvbca_link_read(int fd, uint8_t *slot, uint8_t *connection_id, +			   uint8_t *data, uint16_t data_length); + +// FIXME how do we determine which CAM slot of a CA is meant? +/** + * Write a message to a CAM using an HLCI interface. + * + * @param fd File handle opened with dvbca_open. + * @param data Data to write. + * @param data_length Number of bytes to write. + * @return 0 on success, or -1 on failure. + */ +extern int dvbca_hlci_write(int fd, uint8_t *data, uint16_t data_length); + +// FIXME how do we determine which CAM slot of a CA is meant? +/** + * Read a message from a CAM using an HLCI interface. + * + * @param fd File handle opened with dvbca_open. + * @param app_tag Application layer tag giving the message type to read. + * @param data Data that was read. + * @param data_length Max number of bytes to read. + * @return Number of bytes read on success, or -1 on failure. + */ +extern int dvbca_hlci_read(int fd, uint32_t app_tag, uint8_t *data, +			   uint16_t data_length); + +#ifdef __cplusplus +} +#endif + +#endif // LIBDVBCA_H diff --git a/lib/libdvbapi/dvbdemux.c b/lib/libdvbapi/dvbdemux.c new file mode 100644 index 0000000..a882af6 --- /dev/null +++ b/lib/libdvbapi/dvbdemux.c @@ -0,0 +1,255 @@ +/* + * libdvbdemux - a DVB demux library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <unistd.h> +#include <ctype.h> +#include <errno.h> +#include <linux/dvb/dmx.h> +#include "dvbdemux.h" + + +int dvbdemux_open_demux(int adapter, int demuxdevice, int nonblocking) +{ +	char filename[PATH_MAX+1]; +	int flags = O_RDWR; +	int fd; + +	if (nonblocking) +		flags |= O_NONBLOCK; + +	sprintf(filename, "/dev/dvb/adapter%i/demux%i", adapter, demuxdevice); +	if ((fd = open(filename, flags)) < 0) { +		// if that failed, try a flat /dev structure +		sprintf(filename, "/dev/dvb%i.demux%i", adapter, demuxdevice); +		fd = open(filename, flags); +	} + +	return fd; +} + +int dvbdemux_open_dvr(int adapter, int dvrdevice, int readonly, int nonblocking) +{ +	char filename[PATH_MAX+1]; +	int flags = O_RDWR; +	int fd; + +	if (readonly) +		flags = O_RDONLY; +	if (nonblocking) +		flags |= O_NONBLOCK; + +	sprintf(filename, "/dev/dvb/adapter%i/dvr%i", adapter, dvrdevice); +	if ((fd = open(filename, flags)) < 0) { +		// if that failed, try a flat /dev structure +		sprintf(filename, "/dev/dvb%i.dvr%i", adapter, dvrdevice); +		fd = open(filename, flags); +	} + +	return fd; +} + +int dvbdemux_set_section_filter(int fd, int pid, +				uint8_t filter[18], uint8_t mask[18], +				int start, int checkcrc) +{ +	struct dmx_sct_filter_params sctfilter; + +	memset(&sctfilter, 0, sizeof(sctfilter)); +	sctfilter.pid = pid; +	memcpy(sctfilter.filter.filter, filter, 1); +	memcpy(sctfilter.filter.filter+1, filter+3, 15); +	memcpy(sctfilter.filter.mask, mask, 1); +	memcpy(sctfilter.filter.mask+1, mask+3, 15); +	memset(sctfilter.filter.mode, 0, 16); +	if (start) +		sctfilter.flags |= DMX_IMMEDIATE_START; +	if (checkcrc) +		sctfilter.flags |= DMX_CHECK_CRC; + +	return ioctl(fd, DMX_SET_FILTER, &sctfilter); +} + +int dvbdemux_set_pes_filter(int fd, int pid, +			    int input, int output, +			    int pestype, +			    int start) +{ +	struct dmx_pes_filter_params filter; + +	memset(&filter, 0, sizeof(filter)); +	filter.pid = pid; + +	switch(input) { +	case DVBDEMUX_INPUT_FRONTEND: +		filter.input = DMX_IN_FRONTEND; +		break; + +	case DVBDEMUX_INPUT_DVR: +		filter.input = DMX_IN_DVR; +		break; + +	default: +		return -EINVAL; +	} + +	switch(output) { +	case DVBDEMUX_OUTPUT_DECODER: +		filter.output = DMX_OUT_DECODER; +		break; + +	case DVBDEMUX_OUTPUT_DEMUX: +		filter.output = DMX_OUT_TAP; +		break; + +	case DVBDEMUX_OUTPUT_DVR: +		filter.output = DMX_OUT_TS_TAP; +		break; + +#ifdef DMX_OUT_TSDEMUX_TAP +	case DVBDEMUX_OUTPUT_TS_DEMUX: +		filter.output = DMX_OUT_TSDEMUX_TAP; +		break; +#endif + +	default: +		return -EINVAL; +	} + +	switch(pestype) { +	case DVBDEMUX_PESTYPE_AUDIO: +		filter.pes_type = DMX_PES_AUDIO; +		break; + +	case DVBDEMUX_PESTYPE_VIDEO: +		filter.pes_type = DMX_PES_VIDEO; +		break; + +	case DVBDEMUX_PESTYPE_TELETEXT: +		filter.pes_type = DMX_PES_TELETEXT; +		break; + +	case DVBDEMUX_PESTYPE_SUBTITLE: +		filter.pes_type = DMX_PES_SUBTITLE; +		break; + +	case DVBDEMUX_PESTYPE_PCR: +		filter.pes_type = DMX_PES_PCR; +		break; + +	default: +		return -EINVAL; +	} + +	if (start) +		filter.flags |= DMX_IMMEDIATE_START; + +	return ioctl(fd, DMX_SET_PES_FILTER, &filter); +} + +int dvbdemux_set_pid_filter(int fd, int pid, +			    int input, int output, +			    int start) +{ +	struct dmx_pes_filter_params filter; + +	memset(&filter, 0, sizeof(filter)); +	if (pid == -1) +		filter.pid = 0x2000; +	else +		filter.pid = pid; + +	switch(input) { +	case DVBDEMUX_INPUT_FRONTEND: +		filter.input = DMX_IN_FRONTEND; +		break; + +	case DVBDEMUX_INPUT_DVR: +		filter.input = DMX_IN_DVR; +		break; + +	default: +		return -EINVAL; +	} + +	switch(output) { +	case DVBDEMUX_OUTPUT_DECODER: +		filter.output = DMX_OUT_DECODER; +		break; + +	case DVBDEMUX_OUTPUT_DEMUX: +		filter.output = DMX_OUT_TAP; +		break; + +	case DVBDEMUX_OUTPUT_DVR: +		filter.output = DMX_OUT_TS_TAP; +		break; + +#ifdef DMX_OUT_TSDEMUX_TAP +	case DVBDEMUX_OUTPUT_TS_DEMUX: +		filter.output = DMX_OUT_TSDEMUX_TAP; +		break; +#endif + +	default: +		return -EINVAL; +	} + +	filter.pes_type = DMX_PES_OTHER; + +	if (start) +		filter.flags |= DMX_IMMEDIATE_START; + +	return ioctl(fd, DMX_SET_PES_FILTER, &filter); +} + +int dvbdemux_start(int fd) +{ +	return ioctl(fd, DMX_START); +} + +int dvbdemux_stop(int fd) +{ +	return ioctl(fd, DMX_STOP); +} + +int dvbdemux_get_stc(int fd, uint64_t *stc) +{ +	struct dmx_stc _stc; +	int result; + +	memset(stc, 0, sizeof(_stc)); +	if ((result = ioctl(fd, DMX_GET_STC, &_stc)) != 0) { +		return result; +	} + +	*stc = _stc.stc / _stc.base; +	return 0; +} + +int dvbdemux_set_buffer(int fd, int bufsize) +{ +	return ioctl(fd, DMX_SET_BUFFER_SIZE, bufsize); +} diff --git a/lib/libdvbapi/dvbdemux.h b/lib/libdvbapi/dvbdemux.h new file mode 100644 index 0000000..808ee80 --- /dev/null +++ b/lib/libdvbapi/dvbdemux.h @@ -0,0 +1,204 @@ +/* + * libdvbdemux - a DVB demux library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#ifndef LIBDVBDEMUX_H +#define LIBDVBDEMUX_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> + +/** + * Source of the data to be demuxed. + * + * FRONTEND. The data will be read from the frontend on the adapter. + * + * DVR. The data will be read from the DVR device of the adapter (of course, + * you need to write data TO the DVR device as well). + */ +#define DVBDEMUX_INPUT_FRONTEND 0 +#define DVBDEMUX_INPUT_DVR 1 + +/** + * Destination of the demuxed data. + * + * DECODER. Sends the data directly to a hardware decoder (if present). + * + * DEMUX. Sends the PID stream to the current demux file descriptor. HOWEVER, the + * data will be the payload *only* - transport stream headers will be stripped. + * + * DVR sends the data to the DVR device. The data will be the complete transport + * stream packets with headers intact. Note: if multiple filters specify + * DVBDEMUX_OUTPUT_DVR, the individual PID streams will be re-multiplexed + * together. + */ +#define DVBDEMUX_OUTPUT_DECODER 0 +#define DVBDEMUX_OUTPUT_DEMUX 1 +#define DVBDEMUX_OUTPUT_DVR 2 +#define DVBDEMUX_OUTPUT_TS_DEMUX 3 + +/** + * PES types. + */ +#define DVBDEMUX_PESTYPE_AUDIO 0 +#define DVBDEMUX_PESTYPE_VIDEO 1 +#define DVBDEMUX_PESTYPE_TELETEXT 2 +#define DVBDEMUX_PESTYPE_SUBTITLE 3 +#define DVBDEMUX_PESTYPE_PCR 4 + + +/** + * Open a demux device. Can be called multiple times. These let you setup a + * single filter per FD. It can can also be read() from if you use a section + * filter, or create a pes_filter or raw_filter with output DVBDEMUX_OUTPUT_DEMUX. + * + * @param adapter Index of the DVB adapter. + * @param demuxdevice Index of the demux device on that adapter (usually 0). + * @param nonblocking If 1, frontend will be opened in nonblocking mode. + * @return A unix file descriptor on success, or -1 on failure. + */ +extern int dvbdemux_open_demux(int adapter, int demuxdevice, int nonblocking); + +/** + * Open a DVR device. May be opened for writing or reading once. + * It is used to either write() transport stream data to be demuxed + * (if input == DVBDEMUX_INPUT_DVR), or to read() a stream of demuxed data + * (if output == DVBDEMUX_OUTPUT_DVR). + * + * Note, all demux filters with output set to DVBDEMUX_OUTPUT_DVR will be + * multiplexed together and output their data on this device. + * + * @param adapter Index of the DVB adapter. + * @param dvrdevice Index of the dvr device on that adapter (usually 0) + * @param readonly If 1, frontend will be opened in readonly mode only. + * @param nonblocking If 1, frontend will be opened in nonblocking mode. + * @return A unix file descriptor on success, or -1 on failure. + */ +extern int dvbdemux_open_dvr(int adapter, int dvrdevice, int readonly, int nonblocking); + +/** + * Set filter for the first 18 bytes of decoded SI table sections. Note that + * bytes 1 and 2 are _not_ filtered since they contain the length field. + * + * Conceptually, the driver computes the following for each filtered bit. + * + * (filter[X].bit[Y] & mask[X].bit[Y]) == (header[X].bit[Y] & mask[X].bit[Y]) + * + * Any sections which do not match this criteria for every bit will be discarded. + * + * The SI data is always read from the frontend, and is always returned by + * read()ing the demux fd. FIXME: check this statement! + * + * @param fd FD as opened with dvbdemux_open_demux() above. + * @param pid PID of the stream. + * @param filter The filter values of the first 18 bytes of the desired sections. + * @param mask Bitmask indicating which bits in the filter array should be tested + * (if a bit is 1, it will be tested). + * @param start If 1, the filter will be started immediately. Otherwise you must + * call dvbdemux_start() manually. + * @param checkcrc If 1, the driver will check the CRC on the table sections. + * Any bad sections will be dropped. + * @return 0 on success, nonzero on failure. + */ +extern int dvbdemux_set_section_filter(int fd, int pid, +                                       uint8_t filter[18], uint8_t mask[18], +                                       int start, int checkcrc); + +/** + * Set filter for a stream of PES data. This call can only used for cards + * equipped with a hardware decoder. + * + * @param fd FD as opened with dvbdemux_open_demux() above. + * @param pid PID of the stream. + * @param input One of DVBDEMUX_INPUT_*. + * @param output One of DVBDEMUX_OUTPUT_*. + * @param pestype One of DVBDEMUX_PESTYPE_* - this tells the decoder the type + * of data in this stream. + * @param start If 1, the filter will be started immediately. Otherwise you must + * call dvbdemux_start() manually. + * @return 0 on success, nonzero on failure. + */ +extern int dvbdemux_set_pes_filter(int fd, int pid, +                                   int input, int output, +                                   int pestype, +                                   int start); + +/** + * Create a pid filter - this will extract transport stream packets for a + * specified PID. + * + * Note: The wildcard PID can only be used on "budget" cards. + * + * @param fd FD as opened with dvbdemux_open_demux() above. + * @param pid PID to retrieve, or use -1 as a wildcard for ALL PIDs. + * @param input One of DVBDEMUX_INPUT_*. + * @param output One of DVBDEMUX_OUTPUT_*. + * @param start If 1, the filter will be started immediately. Otherwise you must + * call dvbdemux_start() manually. + * @return 0 on success, nonzero on failure. + */ +extern int dvbdemux_set_pid_filter(int fd, int pid, +                                   int input, int output, +                                   int start); + +/** + * Start a demux going. + * + * @param fd FD as opened with dvbdemux_open_demux() above. + * @return 0 on success, nonzero on failure. + */ +extern int dvbdemux_start(int fd); + +/** + * Stop a demux. + * + * @param fd FD as opened with dvbdemux_open_demux() above. + * @return 0 on success, nonzero on failure. + */ +extern int dvbdemux_stop(int fd); + +/** + * Retrieve the current STC from the demux. This call can only used for cards + * equipped with a hardware decoder. + * + * @param fd FD as opened with dvbdemux_open_demux() above. + * @param stc Where to put the retrieved STC value (in 90kHz clock). + * @return 0 on success, nonzero on failure. + */ +extern int dvbdemux_get_stc(int fd, uint64_t *stc); + +/** + * Change the internal buffer size used by the demuxer. The default buffer size + * is 8192 bytes. Can only be used if the demux in question is stopped. + * + * @param fd FD as opened with dvbdemux_open_demux() above. + * @param bufsize New buffer size to use. + * @return 0 on success, nonzero on failure. + */ +extern int dvbdemux_set_buffer(int fd, int bufsize); + +#ifdef __cplusplus +} +#endif + +#endif // LIBDVBDEMUX_H diff --git a/lib/libdvbapi/dvbfe.c b/lib/libdvbapi/dvbfe.c new file mode 100644 index 0000000..98104c9 --- /dev/null +++ b/lib/libdvbapi/dvbfe.c @@ -0,0 +1,574 @@ +/* + * libdvbfe - a DVB frontend library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com> + * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#define _GNU_SOURCE +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/poll.h> +#include <fcntl.h> +#include <unistd.h> +#include <ctype.h> +#include <errno.h> +#include <linux/dvb/frontend.h> +#include <libdvbmisc/dvbmisc.h> +#include "dvbfe.h" + +int verbose = 0; + +static int dvbfe_spectral_inversion_to_kapi[][2] = +{ +	{ DVBFE_INVERSION_OFF, INVERSION_OFF }, +	{ DVBFE_INVERSION_ON, INVERSION_ON }, +	{ DVBFE_INVERSION_AUTO, INVERSION_AUTO }, +	{ -1, -1 } +}; + +static int dvbfe_code_rate_to_kapi[][2] = +{ +	{ DVBFE_FEC_NONE, FEC_NONE }, +	{ DVBFE_FEC_1_2, FEC_1_2 }, +	{ DVBFE_FEC_2_3, FEC_2_3 }, +	{ DVBFE_FEC_3_4, FEC_3_4 }, +	{ DVBFE_FEC_4_5, FEC_4_5 }, +	{ DVBFE_FEC_5_6, FEC_5_6 }, +	{ DVBFE_FEC_6_7, FEC_6_7 }, +	{ DVBFE_FEC_7_8, FEC_7_8 }, +	{ DVBFE_FEC_8_9, FEC_8_9 }, +	{ DVBFE_FEC_AUTO, FEC_AUTO }, +	{ -1, -1 } +}; + +static int dvbfe_dvbt_const_to_kapi[][2] = +{ +	{ DVBFE_DVBT_CONST_QPSK, FE_QPSK }, +	{ DVBFE_DVBT_CONST_QAM_16, QAM_16 }, +	{ DVBFE_DVBT_CONST_QAM_32, QAM_32 }, +	{ DVBFE_DVBT_CONST_QAM_64, QAM_64 }, +	{ DVBFE_DVBT_CONST_QAM_128, QAM_128 }, +	{ DVBFE_DVBT_CONST_QAM_256, QAM_256 }, +	{ DVBFE_DVBT_CONST_AUTO, QAM_AUTO }, +	{ -1, -1 } +}; + +static int dvbfe_dvbc_mod_to_kapi[][2] = +{ +	{ DVBFE_DVBC_MOD_QAM_16, QAM_16 }, +	{ DVBFE_DVBC_MOD_QAM_32, QAM_32 }, +	{ DVBFE_DVBC_MOD_QAM_64, QAM_64 }, +	{ DVBFE_DVBC_MOD_QAM_128, QAM_128 }, +	{ DVBFE_DVBC_MOD_QAM_256, QAM_256 }, +	{ DVBFE_DVBC_MOD_AUTO, QAM_AUTO }, +	{ -1, -1 } +}; + +static int dvbfe_atsc_mod_to_kapi[][2] = +{ +	{ DVBFE_ATSC_MOD_QAM_64, QAM_64 }, +	{ DVBFE_ATSC_MOD_QAM_256, QAM_256 }, +	{ DVBFE_ATSC_MOD_VSB_8, VSB_8 }, +	{ DVBFE_ATSC_MOD_VSB_16, VSB_16 }, +	{ DVBFE_ATSC_MOD_AUTO, QAM_AUTO }, +	{ -1, -1 } +}; + +static int dvbfe_dvbt_transmit_mode_to_kapi[][2] = +{ +	{ DVBFE_DVBT_TRANSMISSION_MODE_2K, TRANSMISSION_MODE_2K }, +	{ DVBFE_DVBT_TRANSMISSION_MODE_8K, TRANSMISSION_MODE_8K }, +	{ DVBFE_DVBT_TRANSMISSION_MODE_AUTO, TRANSMISSION_MODE_AUTO }, +	{ -1, -1 } +}; + +static int dvbfe_dvbt_bandwidth_to_kapi[][2] = +{ +	{ DVBFE_DVBT_BANDWIDTH_8_MHZ, BANDWIDTH_8_MHZ }, +	{ DVBFE_DVBT_BANDWIDTH_7_MHZ, BANDWIDTH_7_MHZ }, +	{ DVBFE_DVBT_BANDWIDTH_6_MHZ, BANDWIDTH_6_MHZ }, +	{ DVBFE_DVBT_BANDWIDTH_AUTO, BANDWIDTH_AUTO }, +	{ -1, -1 } +}; + +static int dvbfe_dvbt_guard_interval_to_kapi[][2] = +{ +	{ DVBFE_DVBT_GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_32}, +	{ DVBFE_DVBT_GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_16}, +	{ DVBFE_DVBT_GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_8}, +	{ DVBFE_DVBT_GUARD_INTERVAL_1_4, GUARD_INTERVAL_1_4}, +	{ DVBFE_DVBT_GUARD_INTERVAL_AUTO, GUARD_INTERVAL_AUTO}, +	{ -1, -1 } +}; + +static int dvbfe_dvbt_hierarchy_to_kapi[][2] = +{ +	{ DVBFE_DVBT_HIERARCHY_NONE, HIERARCHY_NONE }, +	{ DVBFE_DVBT_HIERARCHY_1, HIERARCHY_1 }, +	{ DVBFE_DVBT_HIERARCHY_2, HIERARCHY_2 }, +	{ DVBFE_DVBT_HIERARCHY_4, HIERARCHY_4 }, +	{ DVBFE_DVBT_HIERARCHY_AUTO, HIERARCHY_AUTO }, +	{ -1, -1 } +}; + + +static int lookupval(int val, int reverse, int table[][2]) +{ +	int i =0; + +	while(table[i][0] != -1) { +		if (!reverse) { +			if (val == table[i][0]) { +				return table[i][1]; +			} +		} else { +			if (val == table[i][1]) { +				return table[i][0]; +			} +		} +		i++; +	} + +	return -1; +} + + +struct dvbfe_handle { +	int fd; +	enum dvbfe_type type; +	char *name; +}; + +struct dvbfe_handle *dvbfe_open(int adapter, int frontend, int readonly) +{ +	char filename[PATH_MAX+1]; +	struct dvbfe_handle *fehandle; +	int fd; +	struct dvb_frontend_info info; + +	//  flags +	int flags = O_RDWR; +	if (readonly) { +		flags = O_RDONLY; +	} + +	// open it (try normal /dev structure first) +	sprintf(filename, "/dev/dvb/adapter%i/frontend%i", adapter, frontend); +	if ((fd = open(filename, flags)) < 0) { +		// if that failed, try a flat /dev structure +		sprintf(filename, "/dev/dvb%i.frontend%i", adapter, frontend); +		if ((fd = open(filename, flags)) < 0) { +			return NULL; +		} +	} + +	// determine fe type +	if (ioctl(fd, FE_GET_INFO, &info)) { +		close(fd); +		return NULL; +	} + +	// setup structure +	fehandle = (struct dvbfe_handle*) malloc(sizeof(struct dvbfe_handle)); +	memset(fehandle, 0, sizeof(struct dvbfe_handle)); +	fehandle->fd = fd; +	switch(info.type) { +	case FE_QPSK: +		fehandle->type = DVBFE_TYPE_DVBS; +		break; + +	case FE_QAM: +		fehandle->type = DVBFE_TYPE_DVBC; +		break; + +	case FE_OFDM: +		fehandle->type = DVBFE_TYPE_DVBT; +		break; + +	case FE_ATSC: +		fehandle->type = DVBFE_TYPE_ATSC; +		break; +	} +	fehandle->name = strndup(info.name, sizeof(info.name)); + +	// done +	return fehandle; +} + +void dvbfe_close(struct dvbfe_handle *fehandle) +{ +	close(fehandle->fd); +	free(fehandle->name); +	free(fehandle); +} + +extern int dvbfe_get_info(struct dvbfe_handle *fehandle, +			  enum dvbfe_info_mask querymask, +			  struct dvbfe_info *result, +			  enum dvbfe_info_querytype querytype, +			  int timeout) +{ +	int returnval = 0; +	struct dvb_frontend_event kevent; +	int ok = 0; + +	result->name = fehandle->name; +	result->type = fehandle->type; + +	switch(querytype) { +	case DVBFE_INFO_QUERYTYPE_IMMEDIATE: +		if (querymask & DVBFE_INFO_LOCKSTATUS) { +			if (!ioctl(fehandle->fd, FE_READ_STATUS, &kevent.status)) { +				returnval |= DVBFE_INFO_LOCKSTATUS; +			} +		} +		if (querymask & DVBFE_INFO_FEPARAMS) { +			if (!ioctl(fehandle->fd, FE_GET_FRONTEND, &kevent.parameters)) { +				returnval |= DVBFE_INFO_FEPARAMS; +			} +		} +		break; + +	case DVBFE_INFO_QUERYTYPE_LOCKCHANGE: +		{ +			struct pollfd pollfd; +			pollfd.fd = fehandle->fd; +			pollfd.events = POLLIN | POLLERR; + +			ok = 1; +			if (poll(&pollfd, 1, timeout) < 0) +				ok = 0; +			if (pollfd.revents & POLLERR) +				ok = 0; +			if (!(pollfd.revents & POLLIN)) +				ok = 0; +		} + +		if (ok && +		    ((querymask & DVBFE_INFO_LOCKSTATUS) || +		     (querymask & DVBFE_INFO_FEPARAMS))) { +			if (!ioctl(fehandle->fd, FE_GET_EVENT, &kevent)) { +				if (querymask & DVBFE_INFO_LOCKSTATUS) +					returnval |= DVBFE_INFO_LOCKSTATUS; +				if (querymask & DVBFE_INFO_FEPARAMS) +					returnval |= DVBFE_INFO_FEPARAMS; +			} +		} +		break; +	} + +	if (returnval & DVBFE_INFO_LOCKSTATUS) { +		result->signal = kevent.status & FE_HAS_SIGNAL ? 1 : 0; +		result->carrier = kevent.status & FE_HAS_CARRIER ? 1 : 0; +		result->viterbi = kevent.status & FE_HAS_VITERBI ? 1 : 0; +		result->sync = kevent.status & FE_HAS_SYNC ? 1 : 0; +		result->lock = kevent.status & FE_HAS_LOCK ? 1 : 0; +	} + +	if (returnval & DVBFE_INFO_FEPARAMS) { +		result->feparams.frequency = kevent.parameters.frequency; +		result->feparams.inversion = lookupval(kevent.parameters.inversion, 1, dvbfe_spectral_inversion_to_kapi); +		switch(fehandle->type) { +		case FE_QPSK: +			result->feparams.u.dvbs.symbol_rate = kevent.parameters.u.qpsk.symbol_rate; +			result->feparams.u.dvbs.fec_inner = +				lookupval(kevent.parameters.u.qpsk.fec_inner, 1, dvbfe_code_rate_to_kapi); +			break; + +		case FE_QAM: +			result->feparams.u.dvbc.symbol_rate = kevent.parameters.u.qam.symbol_rate; +			result->feparams.u.dvbc.fec_inner = +				lookupval(kevent.parameters.u.qam.fec_inner, 1, dvbfe_code_rate_to_kapi); +			result->feparams.u.dvbc.modulation = +				lookupval(kevent.parameters.u.qam.modulation, 1, dvbfe_dvbc_mod_to_kapi); +			break; + +		case FE_OFDM: +			result->feparams.u.dvbt.bandwidth = +				lookupval(kevent.parameters.u.ofdm.bandwidth, 1, dvbfe_dvbt_bandwidth_to_kapi); +			result->feparams.u.dvbt.code_rate_HP = +				lookupval(kevent.parameters.u.ofdm.code_rate_HP, 1, dvbfe_code_rate_to_kapi); +			result->feparams.u.dvbt.code_rate_LP = +				lookupval(kevent.parameters.u.ofdm.code_rate_LP, 1, dvbfe_code_rate_to_kapi); +			result->feparams.u.dvbt.constellation = +				lookupval(kevent.parameters.u.ofdm.constellation, 1, dvbfe_dvbt_const_to_kapi); +			result->feparams.u.dvbt.transmission_mode = +				lookupval(kevent.parameters.u.ofdm.transmission_mode, 1, dvbfe_dvbt_transmit_mode_to_kapi); +			result->feparams.u.dvbt.guard_interval = +				lookupval(kevent.parameters.u.ofdm.guard_interval, 1, dvbfe_dvbt_guard_interval_to_kapi); +			result->feparams.u.dvbt.hierarchy_information = +				lookupval(kevent.parameters.u.ofdm.hierarchy_information, 1, dvbfe_dvbt_hierarchy_to_kapi); +			break; + +		case FE_ATSC: +			result->feparams.u.atsc.modulation = +				lookupval(kevent.parameters.u.vsb.modulation, 1, dvbfe_atsc_mod_to_kapi); +			break; +		} +	} + +	if (querymask & DVBFE_INFO_BER) { +		if (!ioctl(fehandle->fd, FE_READ_BER, &result->ber)) +			returnval |= DVBFE_INFO_BER; +	} +	if (querymask & DVBFE_INFO_SIGNAL_STRENGTH) { +		if (!ioctl(fehandle->fd, FE_READ_SIGNAL_STRENGTH, &result->signal_strength)) +			returnval |= DVBFE_INFO_SIGNAL_STRENGTH; +	} +	if (querymask & DVBFE_INFO_SNR) { +		if (!ioctl(fehandle->fd, FE_READ_SNR, &result->snr)) +			returnval |= DVBFE_INFO_SNR; +	} +	if (querymask & DVBFE_INFO_UNCORRECTED_BLOCKS) { +		if (!ioctl(fehandle->fd, FE_READ_UNCORRECTED_BLOCKS, &result->ucblocks)) +			returnval |= DVBFE_INFO_UNCORRECTED_BLOCKS; +	} + +	// done +	return returnval; +} + +int dvbfe_set(struct dvbfe_handle *fehandle, +	      struct dvbfe_parameters *params, +	      int timeout) +{ +	struct dvb_frontend_parameters kparams; +	int res; +	struct timeval endtime; +	fe_status_t status; + +	kparams.frequency = params->frequency; +	kparams.inversion = lookupval(params->inversion, 0, dvbfe_spectral_inversion_to_kapi); +	switch(fehandle->type) { +	case FE_QPSK: +		kparams.u.qpsk.symbol_rate = params->u.dvbs.symbol_rate; +		kparams.u.qpsk.fec_inner = lookupval(params->u.dvbs.fec_inner, 0, dvbfe_code_rate_to_kapi); +		break; + +	case FE_QAM: +		kparams.u.qam.symbol_rate = params->u.dvbc.symbol_rate; +		kparams.u.qam.fec_inner = lookupval(params->u.dvbc.fec_inner, 0, dvbfe_code_rate_to_kapi); +		kparams.u.qam.modulation = lookupval(params->u.dvbc.modulation, 0, dvbfe_dvbc_mod_to_kapi); +		break; + +	case FE_OFDM: +		kparams.u.ofdm.bandwidth = lookupval(params->u.dvbt.bandwidth, 0, dvbfe_dvbt_bandwidth_to_kapi); +		kparams.u.ofdm.code_rate_HP = lookupval(params->u.dvbt.code_rate_HP, 0, dvbfe_code_rate_to_kapi); +		kparams.u.ofdm.code_rate_LP = lookupval(params->u.dvbt.code_rate_LP, 0, dvbfe_code_rate_to_kapi); +		kparams.u.ofdm.constellation = lookupval(params->u.dvbt.constellation, 0, dvbfe_dvbt_const_to_kapi); +		kparams.u.ofdm.transmission_mode = +			lookupval(params->u.dvbt.transmission_mode, 0, dvbfe_dvbt_transmit_mode_to_kapi); +		kparams.u.ofdm.guard_interval = +			lookupval(params->u.dvbt.guard_interval, 0, dvbfe_dvbt_guard_interval_to_kapi); +		kparams.u.ofdm.hierarchy_information = +			lookupval(params->u.dvbt.hierarchy_information, 0, dvbfe_dvbt_hierarchy_to_kapi); +                break; + +	case FE_ATSC: +		kparams.u.vsb.modulation = lookupval(params->u.atsc.modulation, 0, dvbfe_atsc_mod_to_kapi); +		break; + +	default: +		return -EINVAL; +	} + +	// set it and check for error +	res = ioctl(fehandle->fd, FE_SET_FRONTEND, &kparams); +	if (res) +		return res; + +	// 0 => return immediately +	if (timeout == 0) { +		return 0; +	} + +	/* calculate timeout */ +	if (timeout > 0) { +		gettimeofday(&endtime, NULL); +		timeout *= 1000; +		endtime.tv_sec += timeout / 1000000; +		endtime.tv_usec += timeout % 1000000; +	} + +	/* wait for a lock */ +	while(1) { +		/* has it locked? */ +		if (!ioctl(fehandle->fd, FE_READ_STATUS, &status)) { +			if (status & FE_HAS_LOCK) { +				break; +			} +		} + +		/* check for timeout */ +		if (timeout > 0) { +			struct timeval curtime; +			gettimeofday(&curtime, NULL); +			if ((curtime.tv_sec > endtime.tv_sec) || +			    ((curtime.tv_sec == endtime.tv_sec) && (curtime.tv_usec >= endtime.tv_usec))) { +				break; +			} +		} + +		/* delay for a bit */ +		usleep(100000); +	} + +	/* exit */ +	if (status & FE_HAS_LOCK) +		return 0; +	return -ETIMEDOUT; +} + +int dvbfe_get_pollfd(struct dvbfe_handle *handle) +{ +	return handle->fd; +} + +int dvbfe_set_22k_tone(struct dvbfe_handle *fehandle, enum dvbfe_sec_tone_mode tone) +{ +	int ret = 0; + +	switch (tone) { +	case DVBFE_SEC_TONE_OFF: +		ret = ioctl(fehandle->fd, FE_SET_TONE, SEC_TONE_OFF); +		break; +	case DVBFE_SEC_TONE_ON: +		ret = ioctl(fehandle->fd, FE_SET_TONE, SEC_TONE_ON); +		break; +	default: +		print(verbose, ERROR, 1, "Invalid command !"); +		break; +	} +	if (ret == -1) +		print(verbose, ERROR, 1, "IOCTL failed !"); + +	return ret; +} + +int dvbfe_set_tone_data_burst(struct dvbfe_handle *fehandle, enum dvbfe_sec_mini_cmd minicmd) +{ +	int ret = 0; + +	switch (minicmd) { +	case DVBFE_SEC_MINI_A: +		ret = ioctl(fehandle->fd, FE_DISEQC_SEND_BURST, SEC_MINI_A); +		break; +	case DVBFE_SEC_MINI_B: +		ret = ioctl(fehandle->fd, FE_DISEQC_SEND_BURST, SEC_MINI_B); +		break; +	default: +		print(verbose, ERROR, 1, "Invalid command"); +		break; +	} +	if (ret == -1) +		print(verbose, ERROR, 1, "IOCTL failed"); + +	return ret; +} + +int dvbfe_set_voltage(struct dvbfe_handle *fehandle, enum dvbfe_sec_voltage voltage) +{ +	int ret = 0; + +	switch (voltage) { +	case DVBFE_SEC_VOLTAGE_OFF: +		ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF); +		break; +	case DVBFE_SEC_VOLTAGE_13: +		ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13); +		break; +	case DVBFE_SEC_VOLTAGE_18: +		ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18); +		break; +	default: +		print(verbose, ERROR, 1, "Invalid command"); +		break; +	} +	if (ret == -1) +		print(verbose, ERROR, 1, "IOCTL failed"); + +	return ret; +} + +int dvbfe_set_high_lnb_voltage(struct dvbfe_handle *fehandle, int on) +{ +	switch (on) { +	case 0: +		ioctl(fehandle->fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 0); +		break; +	default: +		ioctl(fehandle->fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 1); +		break; +	} +	return 0; +} + +int dvbfe_do_dishnetworks_legacy_command(struct dvbfe_handle *fehandle, unsigned int cmd) +{ +	int ret = 0; + +	ret = ioctl(fehandle->fd, FE_DISHNETWORK_SEND_LEGACY_CMD, cmd); +	if (ret == -1) +		print(verbose, ERROR, 1, "IOCTL failed"); + +	return ret; +} + +int dvbfe_do_diseqc_command(struct dvbfe_handle *fehandle, uint8_t *data, uint8_t len) +{ +	int ret = 0; +	struct dvb_diseqc_master_cmd diseqc_message; + +	if (len > 6) +		return -EINVAL; + +	diseqc_message.msg_len = len; +	memcpy(diseqc_message.msg, data, len); + +	ret = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &diseqc_message); +	if (ret == -1) +		print(verbose, ERROR, 1, "IOCTL failed"); + +	return ret; +} + +int dvbfe_diseqc_read(struct dvbfe_handle *fehandle, int timeout, unsigned char *buf, unsigned int len) +{ +	struct dvb_diseqc_slave_reply reply; +	int result; + +	if (len > 4) +		len = 4; + +	reply.timeout = timeout; +	reply.msg_len = len; + +	if ((result = ioctl(fehandle->fd, FE_DISEQC_RECV_SLAVE_REPLY, reply)) != 0) +		return result; + +	if (reply.msg_len < len) +		len = reply.msg_len; +	memcpy(buf, reply.msg, len); + +	return len; +} diff --git a/lib/libdvbapi/dvbfe.h b/lib/libdvbapi/dvbfe.h new file mode 100644 index 0000000..69cb05b --- /dev/null +++ b/lib/libdvbapi/dvbfe.h @@ -0,0 +1,333 @@ +/* + * libdvbfe - a DVB frontend library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com> + * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#ifndef LIBDVBFE_H +#define LIBDVBFE_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> + +/** + * The types of frontend we support. + */ +enum dvbfe_type { +	DVBFE_TYPE_DVBS, +	DVBFE_TYPE_DVBC, +	DVBFE_TYPE_DVBT, +	DVBFE_TYPE_ATSC, +}; + +enum dvbfe_spectral_inversion { +	DVBFE_INVERSION_OFF, +	DVBFE_INVERSION_ON, +	DVBFE_INVERSION_AUTO +}; + +enum dvbfe_code_rate { +	DVBFE_FEC_NONE, +	DVBFE_FEC_1_2, +	DVBFE_FEC_2_3, +	DVBFE_FEC_3_4, +	DVBFE_FEC_4_5, +	DVBFE_FEC_5_6, +	DVBFE_FEC_6_7, +	DVBFE_FEC_7_8, +	DVBFE_FEC_8_9, +	DVBFE_FEC_AUTO +}; + +enum dvbfe_dvbt_const { +	DVBFE_DVBT_CONST_QPSK, +	DVBFE_DVBT_CONST_QAM_16, +	DVBFE_DVBT_CONST_QAM_32, +	DVBFE_DVBT_CONST_QAM_64, +	DVBFE_DVBT_CONST_QAM_128, +	DVBFE_DVBT_CONST_QAM_256, +	DVBFE_DVBT_CONST_AUTO +}; + +enum dvbfe_dvbc_mod { +	DVBFE_DVBC_MOD_QAM_16, +	DVBFE_DVBC_MOD_QAM_32, +	DVBFE_DVBC_MOD_QAM_64, +	DVBFE_DVBC_MOD_QAM_128, +	DVBFE_DVBC_MOD_QAM_256, +	DVBFE_DVBC_MOD_AUTO, +}; + +enum dvbfe_atsc_mod { +	DVBFE_ATSC_MOD_QAM_64, +	DVBFE_ATSC_MOD_QAM_256, +	DVBFE_ATSC_MOD_VSB_8, +	DVBFE_ATSC_MOD_VSB_16, +	DVBFE_ATSC_MOD_AUTO +}; + +enum dvbfe_dvbt_transmit_mode { +	DVBFE_DVBT_TRANSMISSION_MODE_2K, +	DVBFE_DVBT_TRANSMISSION_MODE_8K, +	DVBFE_DVBT_TRANSMISSION_MODE_AUTO +}; + +enum dvbfe_dvbt_bandwidth { +	DVBFE_DVBT_BANDWIDTH_8_MHZ, +	DVBFE_DVBT_BANDWIDTH_7_MHZ, +	DVBFE_DVBT_BANDWIDTH_6_MHZ, +	DVBFE_DVBT_BANDWIDTH_AUTO +}; + +enum dvbfe_dvbt_guard_interval { +	DVBFE_DVBT_GUARD_INTERVAL_1_32, +	DVBFE_DVBT_GUARD_INTERVAL_1_16, +	DVBFE_DVBT_GUARD_INTERVAL_1_8, +	DVBFE_DVBT_GUARD_INTERVAL_1_4, +	DVBFE_DVBT_GUARD_INTERVAL_AUTO +}; + +enum dvbfe_dvbt_hierarchy { +	DVBFE_DVBT_HIERARCHY_NONE, +	DVBFE_DVBT_HIERARCHY_1, +	DVBFE_DVBT_HIERARCHY_2, +	DVBFE_DVBT_HIERARCHY_4, +	DVBFE_DVBT_HIERARCHY_AUTO +}; + +/** + * Structure used to store and communicate frontend parameters. + */ +struct dvbfe_parameters { +	uint32_t frequency; +	enum dvbfe_spectral_inversion inversion; +	union { +		struct { +			uint32_t			symbol_rate; +			enum dvbfe_code_rate		fec_inner; +		} dvbs; + +		struct { +			uint32_t			symbol_rate; +			enum dvbfe_code_rate		fec_inner; +			enum dvbfe_dvbc_mod		modulation; +		} dvbc; + +		struct { +			enum dvbfe_dvbt_bandwidth	bandwidth; +			enum dvbfe_code_rate		code_rate_HP; +			enum dvbfe_code_rate		code_rate_LP; +			enum dvbfe_dvbt_const		constellation; +			enum dvbfe_dvbt_transmit_mode	transmission_mode; +			enum dvbfe_dvbt_guard_interval	guard_interval; +			enum dvbfe_dvbt_hierarchy	hierarchy_information; +		} dvbt; + +		struct { +			enum dvbfe_atsc_mod		modulation; +		} atsc; +	} u; +}; + +enum dvbfe_sec_voltage { +	DVBFE_SEC_VOLTAGE_13, +	DVBFE_SEC_VOLTAGE_18, +	DVBFE_SEC_VOLTAGE_OFF +}; + +enum dvbfe_sec_tone_mode { +	DVBFE_SEC_TONE_ON, +	DVBFE_SEC_TONE_OFF +}; + +enum dvbfe_sec_mini_cmd { +	DVBFE_SEC_MINI_A, +	DVBFE_SEC_MINI_B +}; + +/** + * Mask of values used in the dvbfe_get_info() call. + */ +enum dvbfe_info_mask { +	DVBFE_INFO_LOCKSTATUS			= 0x01, +	DVBFE_INFO_FEPARAMS			= 0x02, +	DVBFE_INFO_BER				= 0x04, +	DVBFE_INFO_SIGNAL_STRENGTH		= 0x08, +	DVBFE_INFO_SNR				= 0x10, +	DVBFE_INFO_UNCORRECTED_BLOCKS		= 0x20, +}; + +/** + * Structure containing values used by the dvbfe_get_info() call. + */ +struct dvbfe_info { +	enum dvbfe_type type;			/* always retrieved */ +	const char *name;			/* always retrieved */ +	unsigned int signal     : 1;		/* } DVBFE_INFO_LOCKSTATUS */ +	unsigned int carrier    : 1;		/* } */ +	unsigned int viterbi    : 1;		/* } */ +	unsigned int sync       : 1;		/* } */ +	unsigned int lock       : 1;		/* } */ +	struct dvbfe_parameters feparams;	/* DVBFE_INFO_FEPARAMS */ +	uint32_t ber;				/* DVBFE_INFO_BER */ +	uint16_t signal_strength;		/* DVBFE_INFO_SIGNAL_STRENGTH */ +	uint16_t snr;				/* DVBFE_INFO_SNR */ +	uint32_t ucblocks;			/* DVBFE_INFO_UNCORRECTED_BLOCKS */ +}; + +/** + * Possible types of query used in dvbfe_get_info. + * + * DVBFE_INFO_QUERYTYPE_IMMEDIATE  - interrogate frontend for most up to date values. + * DVBFE_INFO_QUERYTYPE_LOCKCHANGE - return details from queued lock status + * 				     change events, or wait for one to occur + * 				     if none are queued. + */ +enum dvbfe_info_querytype { +	DVBFE_INFO_QUERYTYPE_IMMEDIATE, +	DVBFE_INFO_QUERYTYPE_LOCKCHANGE, +}; + + +/** + * Frontend handle datatype. + */ +struct dvbfe_handle; + +/** + * Open a DVB frontend. + * + * @param adapter DVB adapter ID. + * @param frontend Frontend ID of that adapter to open. + * @param readonly If 1, frontend will be opened in readonly mode only. + * @return A handle on success, or NULL on failure. + */ +extern struct dvbfe_handle *dvbfe_open(int adapter, int frontend, int readonly); + +/** + * Close a DVB frontend. + * + * @param fehandle Handle opened with dvbfe_open(). + */ +extern void dvbfe_close(struct dvbfe_handle *handle); + +/** + * Set the frontend tuning parameters. + * + * Note: this function provides only the basic tuning operation; you might want to + * investigate dvbfe_set_sec() in sec.h for a unified device tuning operation. + * + * @param fehandle Handle opened with dvbfe_open(). + * @param params Params to set. + * @param timeout <0 => wait forever for lock. 0=>return immediately, >0=> + * number of milliseconds to wait for a lock. + * @return 0 on locked (or if timeout==0 and everything else worked), or + * nonzero on failure (including no lock). + */ +extern int dvbfe_set(struct dvbfe_handle *fehandle, +		     struct dvbfe_parameters *params, +		     int timeout); + +/** + * Retrieve information about the frontend. + * + * @param fehandle Handle opened with dvbfe_open(). + * @param querymask ORed bitmask of desired DVBFE_INFO_* values. + * @param result Where to put the retrieved results. + * @param querytype Type of query requested. + * @param timeout Timeout in ms to use if querytype==lockchange (0=>no timeout, <0=> wait forever). + * @return ORed bitmask of DVBFE_INFO_* indicating which values were read successfully. + */ +extern int dvbfe_get_info(struct dvbfe_handle *fehandle, +			  enum dvbfe_info_mask querymask, +			  struct dvbfe_info *result, +			  enum dvbfe_info_querytype querytype, +			  int timeout); + +/** + * Get a file descriptor for polling for lock status changes. + * + * @param fehandle Handle opened with dvbfe_open(). + * @return FD for polling. + */ +extern int dvbfe_get_pollfd(struct dvbfe_handle *handle); + +/** + *	Tone/Data Burst control + * 	@param fehandle Handle opened with dvbfe_open(). + *	@param tone, SEC_TONE_ON/SEC_TONE_OFF + */ +extern int dvbfe_set_22k_tone(struct dvbfe_handle *handle, enum dvbfe_sec_tone_mode tone); + +/** + *	22khz Tone control + * 	@param fehandle Handle opened with dvbfe_open(). + *	@param adapter, minicmd, SEC_MINI_A/SEC_MINI_B + */ +extern int dvbfe_set_tone_data_burst(struct dvbfe_handle *handle, enum dvbfe_sec_mini_cmd minicmd); + +/** + *	Voltage control + * 	@param fehandle Handle opened with dvbfe_open(). + *	@param polarization, SEC_VOLTAGE_13/SEC_VOLTAGE_18/SEC_VOLTAGE_OFF + */ +extern int dvbfe_set_voltage(struct dvbfe_handle *handle, enum dvbfe_sec_voltage voltage); + +/** + *	High LNB voltage control (increases voltage by 1v to compensate for long cables) + * 	@param fehandle Handle opened with dvbfe_open(). + *	@param on 1 to enable, 0 to disable. + */ +extern int dvbfe_set_high_lnb_voltage(struct dvbfe_handle *fehandle, int on); + +/** + *	Send a legacy Dish Networks command + * 	@param fehandle Handle opened with dvbfe_open(). + *	@param cmd, the command to send + */ +extern int dvbfe_do_dishnetworks_legacy_command(struct dvbfe_handle *handle, unsigned int cmd); + +/** + *	Send a DiSEqC Command + * 	@param fehandle Handle opened with dvbfe_open(). + *	@param data, a pointer to am array containing the data to be sent. + *      @param len Length of data in  bytes, max 6 bytes. + */ +extern int dvbfe_do_diseqc_command(struct dvbfe_handle *handle, uint8_t *data, uint8_t len); + +/** + * Read a DISEQC response from the frontend. + * + * @param fehandle Handle opened with dvbfe_open(). + * @param timeout Timeout for DISEQC response. + * @param buf Buffer to store response in. + * @param len Number of bytes in buffer. + * @return >= 0 on success (number of received bytes), <0 on failure. + */ +extern int dvbfe_diseqc_read(struct dvbfe_handle *fehandle, int timeout, unsigned char *buf, unsigned int len); + +#ifdef __cplusplus +} +#endif + +#endif // LIBDVBFE_H diff --git a/lib/libdvbapi/dvbnet.c b/lib/libdvbapi/dvbnet.c new file mode 100644 index 0000000..f0f08f9 --- /dev/null +++ b/lib/libdvbapi/dvbnet.c @@ -0,0 +1,104 @@ +/* + * libdvbnet - a DVB network support library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/param.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <linux/dvb/net.h> +#include <errno.h> +#include "dvbnet.h" + +int dvbnet_open(int adapter, int netdeviceid) +{ +	char filename[PATH_MAX+1]; +	int fd; + +	sprintf(filename, "/dev/dvb/adapter%i/net%i", adapter, netdeviceid); +	if ((fd = open(filename, O_RDWR)) < 0) { +		// if that failed, try a flat /dev structure +		sprintf(filename, "/dev/dvb%i.net%i", adapter, netdeviceid); +		fd = open(filename, O_RDWR); +	} + +	return fd; +} + +int dvbnet_add_interface(int fd, uint16_t pid, enum dvbnet_encap encapsulation) +{ +	struct dvb_net_if params; +	int status; + +	memset(¶ms, 0, sizeof(params)); +	params.pid = pid; + +	switch(encapsulation) { +	case DVBNET_ENCAP_MPE: +		params.feedtype = DVB_NET_FEEDTYPE_MPE; +		break; + +	case DVBNET_ENCAP_ULE: +		params.feedtype = DVB_NET_FEEDTYPE_ULE; +		break; + +	default: +		return -EINVAL; +	} + +	status = ioctl(fd, NET_ADD_IF, ¶ms); +	if (status < 0) +		return status; +	return params.if_num; +} + +int dvbnet_get_interface(int fd, int ifnum, uint16_t *pid, enum dvbnet_encap *encapsulation) +{ +	struct dvb_net_if info; +	int res; + +	memset(&info, 0, sizeof(struct dvb_net_if)); +	info.if_num = ifnum; + +	if ((res = ioctl(fd, NET_GET_IF, &info)) < 0) +		return res; + +	*pid = info.pid; +	switch(info.feedtype) { +	case DVB_NET_FEEDTYPE_MPE: +		*encapsulation = DVBNET_ENCAP_MPE; +		break; + +	case DVB_NET_FEEDTYPE_ULE: +		*encapsulation = DVBNET_ENCAP_ULE; +		break; + +	default: +		return -EINVAL; +	} +	return 0; +} + +int dvbnet_remove_interface(int fd, int ifnum) +{ +	return ioctl(fd, NET_REMOVE_IF, ifnum); +} diff --git a/lib/libdvbapi/dvbnet.h b/lib/libdvbapi/dvbnet.h new file mode 100644 index 0000000..287919f --- /dev/null +++ b/lib/libdvbapi/dvbnet.h @@ -0,0 +1,87 @@ +/* + * libdvbnet - a DVB network support library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#ifndef LIBDVBNET_H +#define LIBDVBNET_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> + +/** + * Possible encapsulations of data. + */ +enum dvbnet_encap { +	DVBNET_ENCAP_MPE, +	DVBNET_ENCAP_ULE, +}; + +/** + * The maximum allowed number of dvb network devices per adapter netdevice. + */ +#define DVBNET_MAX_INTERFACES 10 + +/** + * Open a DVB net interface. + * + * @param adapter DVB adapter ID. + * @param netdeviceid Network control interface of that adapter to open. + * @return A unix file descriptor on success, or -1 on failure. + */ +extern int dvbnet_open(int adapter, int netdeviceid); + +/** + * Create a new DVBNET interface. + * + * @param fd FD opened with libdvbnet_open(). + * @param pid PID of the stream containing the network data. + * @param encapsulation Encapsulation type of the stream (one of DVBNET_ENCAP_*). + * @return Index of new interface on success, < 0 on failure. + */ +extern int dvbnet_add_interface(int fd, uint16_t pid, enum dvbnet_encap encapsulation); + +/** + * Get details of a DVBNET interface. + * + * @param fd FD opened with libdvbnet_open(). + * @param ifnum Index of interface to retrieve. + * @param pid The PID of the interface. + * @param encapsulation The encapsulation of the interface (DVBNET_ENCAP_*). + * @return 0 on success, nonzero on failure. + */ +extern int dvbnet_get_interface(int fd, int ifnum, uint16_t *pid, enum dvbnet_encap *encapsulation); + +/** + * Remove a DVBNET interface. + * + * @param fd FD opened with libdvbnet_open(). + * @param ifnum Index of interface to remove. + * @return 0 on success, nonzero on failure. + */ +extern int dvbnet_remove_interface(int fd, int ifnum); + +#ifdef __cplusplus +} +#endif + +#endif // LIBDVBNET_H diff --git a/lib/libdvbapi/dvbvideo.c b/lib/libdvbapi/dvbvideo.c new file mode 100644 index 0000000..f1ffbe8 --- /dev/null +++ b/lib/libdvbapi/dvbvideo.c @@ -0,0 +1,46 @@ +/* + * libdvbnet - a DVB network support library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/param.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <linux/types.h> +#include <linux/dvb/video.h> +#include <errno.h> +#include "dvbvideo.h" + +int dvbvideo_open(int adapter, int videodeviceid) +{ +	char filename[PATH_MAX+1]; +	int fd; + +	sprintf(filename, "/dev/dvb/adapter%i/video%i", adapter, videodeviceid); +	if ((fd = open(filename, O_RDWR)) < 0) { +		// if that failed, try a flat /dev structure +		sprintf(filename, "/dev/dvb%i.video%i", adapter, videodeviceid); +		fd = open(filename, O_RDWR); +	} + +	return fd; +} diff --git a/lib/libdvbapi/dvbvideo.h b/lib/libdvbapi/dvbvideo.h new file mode 100644 index 0000000..cc49914 --- /dev/null +++ b/lib/libdvbapi/dvbvideo.h @@ -0,0 +1,46 @@ +/* + * libdvbnet - a DVB network support library + * + * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA + */ + +#ifndef LIBDVBVIDEO_H +#define LIBDVBVIDEO_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> + +/** + * Open a DVB video device. + * + * @param adapter DVB adapter ID. + * @param videodeviceid Id of video device of that adapter to open. + * @return A unix file descriptor on success, or -1 on failure. + */ +extern int dvbvideo_open(int adapter, int videodeviceid); + +// FIXME: this is a stub library + +#ifdef __cplusplus +} +#endif + +#endif // LIBDVBVIDEO_H | 
