Re: Report DVB Manager Week 8



Am Dienstag, den 15.07.2008, 18:34 +0200 schrieb Sebastian Pölsterl:
> Bastien Nocera schrieb:
> >> Last but not least, does somebody know how I can retrieve a list of DVB 
> >> devices that are installed in a computer? I tried HAL, but it seems that 
> >> it doesn't support that.
> > 
> > It would be good to add support for those devices in HAL then :)
> > 
> Turns out HAL does already exactly what I wanted.

ohh I just saw my Mail-Client send to Bastien only last time :(

But perhaps you still can get usage of this:

----

I get DVB device information via DBUS...

elektranox sun ~ % hal-device | grep dvb | grep -e info.udi 
info.udi = '/org/freedesktop/Hal/devices/pci_13d0_2103_dvb_2'
info.udi = '/org/freedesktop/Hal/devices/pci_13d0_2103_dvb_1'
info.udi = '/org/freedesktop/Hal/devices/pci_13d0_2103_dvb_0'
info.udi = '/org/freedesktop/Hal/devices/pci_13d0_2103_dvb'

I wrote a small C program, which gets a list of all available dvb
devices some time ago, which worked at least for my DVB-S and DVB-T
card. You find the sourcecode in the attachment ;)
/***************************************************************************
 * hal-scan.c: HAL Scanner for DVB cards
 * Author: Sebastian Reichel
 * License: GPLv2 or higher
 * Date: 15.04.2008
 **************************************************************************/

/* Standard Functions */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>

/* HAL */
#include <hal/libhal.h>

/* DBUS */
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>

/* LinuxTV */
#include <linux/dvb/frontend.h>

/* enum for the type */
enum dvb_type {
	DVB_S = 1,
	DVB_T = 2,
	DVB_C = 3,
	ATSC  = 4
};

/* structure containing a dvb-card */
struct dvb_device {
	char *udi;
	char *name;
	int type;
	
	char *dev_frontend;
	char *dev_demux;
	char *dev_dvr;
	
	char *etc_channels;
};

GList *dvb_devices;

/* gets the name of a card as string */
char* dvbm_dvb_card_name(char *frontend_device) {
	int dev;
	struct dvb_frontend_info info;
	static char * name;
	
	dev = open(frontend_device, O_RDONLY);
	
	if(dev < 0)
		return "";
	
	ioctl (dev, FE_GET_INFO, &info);
	close(dev);
	
	name = g_malloc(strlen(info.name)*sizeof(char));
	strcpy(name, info.name);
	
	return name;
}

/* gets the type of a card in integer format */
int dvbm_dvb_card_type(char *frontend_device) {
	int dev;
	struct dvb_frontend_info info;
	dev = open(frontend_device, O_RDONLY);
	
	if(dev < 0)
		return(0);
	
	ioctl (dev, FE_GET_INFO, &info);
	close(dev);
	
	switch(info.type) {
		case FE_QPSK:
			return DVB_S;
			break;
		case FE_OFDM:
			return DVB_T;
			break;
		case FE_QAM:
			return DVB_C;
			break;
		case FE_ATSC:
			return ATSC;
			break;
		default:
			return 0;
			break;
	}
	
}

/* adds a dvb device */
static void dvbm_hal_dev_add(LibHalContext *ctx, const char *udi) {
	struct dvb_device *new_dvb_device;
	char *dev, *parent;
	int i, found;

	// test if new device is a device with DVB features
	if(libhal_device_query_capability(ctx, udi, "dvb", NULL)) {
		parent = strdup(libhal_device_get_property_string(ctx, udi, "info.parent", NULL));
		dev = strdup(libhal_device_get_property_string(ctx, udi, "linux.device_file", NULL));
		
		// test if we know the parent already
		found = -1;
		for(i=0;i<g_list_length(dvb_devices);i++) {
			struct dvb_device *e = g_list_nth_data(dvb_devices, i);
			if(strcmp(e->udi, parent) == 0) {
				found = i;
				i = g_list_length(dvb_devices);
			}
		}
		
		// if not create it
		if(found == -1) {
			new_dvb_device = (struct dvb_device*)malloc(sizeof(struct dvb_device));
			new_dvb_device->udi = strdup(parent);
			dvb_devices = g_list_append(dvb_devices, new_dvb_device);
			printf("New DVB Card!\n");
		}
		
		if(strstr(dev, "demux") || strstr(dev, "frontend") || strstr(dev, "dvr")) {
			struct dvb_device *e = g_list_last(dvb_devices)->data;
			
			if(strstr(dev, "demux"))
				e->dev_demux = dev;
			else if(strstr(dev, "frontend")) {
				e->name = dvbm_dvb_card_name(dev);
				e->type = dvbm_dvb_card_type(dev);
				e->dev_frontend = dev;
			}
			else if(strstr(dev, "dvr"))
				e->dev_dvr = dev;
		}
	}
}

/* removes a dvb device */
static void dvbm_hal_dev_rem(LibHalContext *ctx, const char *udi) {
	struct dvb_device tmp_dvb_device;
	char *string;
	int i;

	for(i=0; i<g_list_length(dvb_devices); i++) {
		struct dvb_device *e = g_list_nth_data(dvb_devices, i);
		if(strcmp(e->udi, udi) == 0) {
			printf("Removed DVB Device: %s\n", e->name);
			dvb_devices = g_list_remove(dvb_devices, e);
		}
	}
}

/* converts the interger type to human readable string type */
static char* dvbm_dvb_type_to_string(int i) {
	switch(i) {
		case 1:
			return "DVB-S";
		case 2:
			return "DVB-T";
		case 3:
			return "DVB-C";
		case 4:
			return "ATSC";
		default:
			return "ERROR";
	}
}

/* gives informations about all dvb devices */
static void dvbm_hal_dev_info() {
	int i;
	
	for(i=0; i<g_list_length(dvb_devices); i++) {
		struct dvb_device *e = g_list_nth_data(dvb_devices, i);
		printf("Device: %s\n", e->name);
		printf(" UDI: %s\n", e->udi);
		printf(" Type: %s\n", dvbm_dvb_type_to_string(e->type));
		printf(" Demux Device: %s\n", e->dev_demux);
		printf(" Frontend Device: %s\n", e->dev_frontend);
		printf(" Record Device: %s\n", e->dev_dvr);
	}
}


int main(int argc, char **argv) {
	LibHalContext *ctx;
	DBusConnection *dbus_connection;
	DBusError error;
	GMainLoop *loop;
	int numbers;
	char **udis;
	int i;

	// initalize dvb_devices
	dvb_devices = NULL;

	// create new hal binding
	ctx = libhal_ctx_new();
	if(ctx == NULL)
		g_warning("Could not create HAL context");

	// initialize error structure
	dbus_error_init(&error);

	// connect to the DBUS
	dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
	if (dbus_error_is_set(&error))
		g_warning("Could not connect to system bus %s\n", error.message);

	// configure DBUS
	dbus_connection_setup_with_g_main (dbus_connection, NULL);
	dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);

	// say HAL to use the DBUS connection
	libhal_ctx_set_dbus_connection(ctx, dbus_connection);

	// Callbacks for HAL events
	libhal_ctx_set_device_added(ctx, dvbm_hal_dev_add);
	libhal_ctx_set_device_removed(ctx, dvbm_hal_dev_rem);
	
	// initialize the connection and listen to HAL
	if(!libhal_ctx_init(ctx, &error)) {
		g_warning("libhal_ctx_init failed: %s", error.message);
		dbus_error_free(&error);
		libhal_ctx_free(ctx);
		return 1;
	}

	// Search for devices with dvb capability
	udis = libhal_find_device_by_capability(ctx, "dvb", &numbers, &error);

	// add devices
	for(i=0; i<numbers; i++)
		dvbm_hal_dev_add(ctx, udis[i]);

	// information about plugged cards
	dvbm_hal_dev_info();

	// start loop, which waits for new events
	loop = g_main_new(FALSE);
	g_main_run(loop);

	// frees the HAL things
	libhal_ctx_free(ctx);

	return 0;
}

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]