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