Initial work on DVB hw tree
This commit is contained in:
parent
bc0d93dd72
commit
20e94bc17d
20 changed files with 505 additions and 97 deletions
4
Makefile
4
Makefile
|
@ -65,6 +65,7 @@ endif
|
|||
SRCS = src/main.c \
|
||||
src/idnode.c \
|
||||
src/prop.c \
|
||||
src/tvadapters.c \
|
||||
src/utils.c \
|
||||
src/wrappers.c \
|
||||
src/version.c \
|
||||
|
@ -154,7 +155,8 @@ SRCS-${CONFIG_LINUXDVB} += \
|
|||
src/dvb/dvb_fe.c \
|
||||
src/dvb/dvb_tables.c \
|
||||
src/dvb/diseqc.c \
|
||||
src/dvb/dvb_adapter.c \
|
||||
src/dvb/dvb_linux.c \
|
||||
src/dvb/dvb_hardware.c \
|
||||
src/dvb/dvb_network.c \
|
||||
src/dvb/dvb_multiplex.c \
|
||||
src/dvb/dvb_service.c \
|
||||
|
|
|
@ -541,7 +541,6 @@ capmt_thread(void *aux)
|
|||
capmt_t *capmt = aux;
|
||||
struct timespec ts;
|
||||
int d, i, bind_ok = 0;
|
||||
th_dvb_adapter_t *tda;
|
||||
|
||||
while (capmt->capmt_running) {
|
||||
for (i = 0; i < MAX_CA; i++)
|
||||
|
@ -574,6 +573,9 @@ capmt_thread(void *aux)
|
|||
if (!capmt->capmt_oscam) {
|
||||
bind_ok = capmt_create_udp_socket(&capmt->capmt_sock_ca0[0], capmt->capmt_port);
|
||||
} else {
|
||||
|
||||
#if 0
|
||||
th_dvb_adapter_t *tda;
|
||||
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) {
|
||||
if (tda->tda_rootpath) { //if rootpath is NULL then can't rely on tda_adapter_num because it is always 0
|
||||
if (tda->tda_adapter_num > MAX_CA) {
|
||||
|
@ -584,6 +586,7 @@ capmt_thread(void *aux)
|
|||
bind_ok = capmt_create_udp_socket(&capmt->capmt_sock_ca0[tda->tda_adapter_num], 9000 + tda->tda_adapter_num);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (bind_ok)
|
||||
handle_ca0(capmt);
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
void
|
||||
dvb_init(uint32_t adapter_mask, const char *rawfile)
|
||||
{
|
||||
TAILQ_INIT(&dvb_adapters);
|
||||
dvb_charset_init();
|
||||
dvb_network_init();
|
||||
dvb_adapter_init(adapter_mask, rawfile);
|
||||
dvb_linux_init();
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ TAILQ_HEAD(dvb_satconf_queue, dvb_satconf);
|
|||
LIST_HEAD(dvb_mux_list, dvb_mux);
|
||||
TAILQ_HEAD(dvb_mux_queue, dvb_mux);
|
||||
LIST_HEAD(dvb_network_list, dvb_network);
|
||||
TAILQ_HEAD(dvb_hardware_queue, dvb_hardware);
|
||||
|
||||
/**
|
||||
* Satconf
|
||||
|
@ -225,13 +226,45 @@ typedef struct dvb_table_feed {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* dvb_hardware refers to any kind of DVB hardware
|
||||
*
|
||||
* This includes
|
||||
*
|
||||
* DVB Adapters (On linux: /dev/dvb/adapterX)
|
||||
* DVB Frontends (On linux: /dev/dvb/adapterX/frontendX)
|
||||
* DVB-S LNBs
|
||||
* Diseqc equipment (Switches, motors, etc)
|
||||
*
|
||||
*/
|
||||
typedef struct dvb_hardware {
|
||||
idnode_t dh_id;
|
||||
|
||||
// Hierarcy
|
||||
struct dvb_hardware *dh_parent;
|
||||
TAILQ_ENTRY(dvb_hardware) dh_parent_link;
|
||||
struct dvb_hardware_queue dh_childs;
|
||||
|
||||
// If attached to a network, this is set
|
||||
dvb_network_t *dh_dn;
|
||||
LIST_ENTRY(th_dvb_adapter) dh_network_link;
|
||||
|
||||
// These are created on-demand whenever this particular network
|
||||
// attachment point tunes to a mux
|
||||
struct th_dvb_mux_instance_list dh_tdmis;
|
||||
th_dvb_mux_instance_t *dh_current_tdmi;
|
||||
|
||||
char *dh_name;
|
||||
|
||||
} dvb_hardware_t;
|
||||
|
||||
|
||||
/**
|
||||
* DVB Adapter (one of these per physical adapter)
|
||||
*/
|
||||
#define TDA_MUX_HASH_WIDTH 101
|
||||
|
||||
typedef struct th_dvb_adapter {
|
||||
|
||||
#if 1
|
||||
int tda_instance;
|
||||
|
||||
|
||||
|
@ -310,6 +343,7 @@ typedef struct th_dvb_adapter {
|
|||
// PIDs that needs to be requeued and processed as tables
|
||||
uint8_t tda_table_filter[8192];
|
||||
|
||||
#endif
|
||||
|
||||
} th_dvb_adapter_t;
|
||||
|
||||
|
@ -363,8 +397,7 @@ typedef struct th_dvb_table {
|
|||
|
||||
|
||||
extern struct dvb_network_list dvb_networks;
|
||||
extern struct th_dvb_adapter_queue dvb_adapters;
|
||||
//extern struct th_dvb_mux_instance_tree dvb_muxes;
|
||||
extern struct dvb_hardware_queue dvb_adapters;
|
||||
|
||||
void dvb_init(uint32_t adapter_mask, const char *rawfile);
|
||||
|
||||
|
@ -373,40 +406,9 @@ void dvb_init(uint32_t adapter_mask, const char *rawfile);
|
|||
*/
|
||||
void dvb_adapter_init(uint32_t adapter_mask, const char *rawfile);
|
||||
|
||||
void dvb_adapter_start (th_dvb_adapter_t *tda);
|
||||
void dvb_adapter_start(th_dvb_adapter_t *tda);
|
||||
|
||||
void dvb_adapter_stop (th_dvb_adapter_t *tda);
|
||||
|
||||
void dvb_adapter_set_displayname(th_dvb_adapter_t *tda, const char *s);
|
||||
|
||||
void dvb_adapter_set_auto_discovery(th_dvb_adapter_t *tda, int on);
|
||||
|
||||
void dvb_adapter_set_skip_initialscan(th_dvb_adapter_t *tda, int on);
|
||||
|
||||
void dvb_adapter_set_skip_checksubscr(th_dvb_adapter_t *tda, int on);
|
||||
|
||||
void dvb_adapter_set_qmon(th_dvb_adapter_t *tda, int on);
|
||||
|
||||
void dvb_adapter_set_idleclose(th_dvb_adapter_t *tda, int on);
|
||||
|
||||
void dvb_adapter_set_poweroff(th_dvb_adapter_t *tda, int on);
|
||||
|
||||
void dvb_adapter_set_sidtochan(th_dvb_adapter_t *tda, int on);
|
||||
|
||||
void dvb_adapter_set_nitoid(th_dvb_adapter_t *tda, int nitoid);
|
||||
|
||||
void dvb_adapter_set_diseqc_version(th_dvb_adapter_t *tda, unsigned int v);
|
||||
|
||||
void dvb_adapter_set_diseqc_repeats(th_dvb_adapter_t *tda,
|
||||
unsigned int repeats);
|
||||
|
||||
void dvb_adapter_set_disable_pmt_monitor(th_dvb_adapter_t *tda, int on);
|
||||
|
||||
void dvb_adapter_set_full_mux_rx(th_dvb_adapter_t *tda, int r);
|
||||
|
||||
void dvb_adapter_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src);
|
||||
|
||||
int dvb_adapter_destroy(th_dvb_adapter_t *tda);
|
||||
void dvb_adapter_stop(th_dvb_adapter_t *tda);
|
||||
|
||||
void dvb_adapter_notify(th_dvb_adapter_t *tda);
|
||||
|
||||
|
@ -601,5 +603,18 @@ struct th_subscription *dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t
|
|||
const char *name,
|
||||
streaming_target_t *st);
|
||||
|
||||
|
||||
/**
|
||||
* DVB Hardware
|
||||
*/
|
||||
idnode_t **dvb_hardware_get_childs(struct idnode *self);
|
||||
const char *dvb_hardware_get_title(struct idnode *self);
|
||||
|
||||
void *dvb_hardware_create(const idclass_t *class, size_t size,
|
||||
dvb_hardware_t *parent, const char *uuid,
|
||||
const char *name);
|
||||
|
||||
void dvb_linux_init(void);
|
||||
|
||||
#endif /* DVB_H_ */
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ dvb_fe_tune_tdmi(th_dvb_mux_instance_t *tdmi, const char *reason)
|
|||
free(tda->tda_tune_reason);
|
||||
tda->tda_tune_reason = strdup(reason);
|
||||
|
||||
dvb_adapter_start(tda);
|
||||
abort(); // dvb_adapter_start(tda);
|
||||
|
||||
// Make sure dvb_mux_stop() did the right thing
|
||||
assert(tda->tda_current_tdmi == NULL);
|
||||
|
|
82
src/dvb/dvb_hardware.c
Normal file
82
src/dvb/dvb_hardware.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Generic DVB hardware stuff
|
||||
* Copyright (C) 2013 Andreas Öman
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "tvheadend.h"
|
||||
#include "dvb.h"
|
||||
|
||||
|
||||
struct dvb_hardware_queue dvb_adapters;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
idnode_t **
|
||||
dvb_hardware_get_childs(struct idnode *self)
|
||||
{
|
||||
dvb_hardware_t *dh = (dvb_hardware_t *)self;
|
||||
dvb_hardware_t *c;
|
||||
int cnt = 1;
|
||||
|
||||
TAILQ_FOREACH(c, &dh->dh_childs, dh_parent_link)
|
||||
cnt++;
|
||||
|
||||
idnode_t **v = malloc(sizeof(idnode_t *) * cnt);
|
||||
cnt = 0;
|
||||
TAILQ_FOREACH(c, &dh->dh_childs, dh_parent_link)
|
||||
v[cnt++] = &c->dh_id;
|
||||
// qsort(v, cnt, sizeof(idnode_t *), svcsortcmp);
|
||||
v[cnt] = NULL;
|
||||
return v;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const char *
|
||||
dvb_hardware_get_title(struct idnode *self)
|
||||
{
|
||||
dvb_hardware_t *dh = (dvb_hardware_t *)self;
|
||||
return dh->dh_name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void *
|
||||
dvb_hardware_create(const idclass_t *class, size_t size,
|
||||
dvb_hardware_t *parent, const char *uuid,
|
||||
const char *name)
|
||||
{
|
||||
dvb_hardware_t *dh = calloc(1, size);
|
||||
idnode_insert(&dh->dh_id, uuid, class);
|
||||
|
||||
TAILQ_INIT(&dh->dh_childs);
|
||||
|
||||
if(parent == NULL) {
|
||||
TAILQ_INSERT_TAIL(&dvb_adapters, dh, dh_parent_link);
|
||||
} else {
|
||||
TAILQ_INSERT_TAIL(&parent->dh_childs, dh, dh_parent_link);
|
||||
}
|
||||
dh->dh_name = strdup(name);
|
||||
return dh;
|
||||
}
|
218
src/dvb/dvb_linux.c
Normal file
218
src/dvb/dvb_linux.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* DVB for Linux
|
||||
* Copyright (C) 2013 Andreas Öman
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "tvheadend.h"
|
||||
#include "dvb.h"
|
||||
#include "dvb_support.h"
|
||||
|
||||
|
||||
typedef struct linux_dvb_frontend {
|
||||
dvb_hardware_t ldf_dh;
|
||||
int ldf_adapterid;
|
||||
int ldf_frontend;
|
||||
|
||||
int ldf_fd; // if -1, frontend is closed
|
||||
|
||||
} linux_dvb_frontend_t;
|
||||
|
||||
|
||||
|
||||
|
||||
static const idclass_t linux_dvb_hardware_class = {
|
||||
.ic_class = "linux_dvb_hardware",
|
||||
.ic_get_childs = dvb_hardware_get_childs,
|
||||
.ic_get_title = dvb_hardware_get_title,
|
||||
.ic_properties = (const property_t[]){
|
||||
{
|
||||
"name", "Name", PT_STR,
|
||||
offsetof(dvb_hardware_t, dh_name),
|
||||
.notify = &idnode_notify_title_changed,
|
||||
}, {}},
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const idclass_t linux_dvb_adapter_class = {
|
||||
.ic_class = "linux_dvb_adapter",
|
||||
.ic_super = &linux_dvb_hardware_class,
|
||||
};
|
||||
|
||||
|
||||
static const idclass_t linux_dvb_frontend_class = {
|
||||
.ic_class = "linux_dvb_frontend",
|
||||
.ic_super = &linux_dvb_hardware_class,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const idclass_t linux_dvbc_frontend_class = {
|
||||
.ic_leaf = 1,
|
||||
.ic_class = "linux_dvbc_frontend",
|
||||
.ic_super = &linux_dvb_frontend_class,
|
||||
};
|
||||
|
||||
static const idclass_t linux_dvbt_frontend_class = {
|
||||
.ic_leaf = 1,
|
||||
.ic_class = "linux_dvbt_frontend",
|
||||
.ic_super = &linux_dvb_frontend_class,
|
||||
};
|
||||
|
||||
static const idclass_t linux_atsc_frontend_class = {
|
||||
.ic_leaf = 1,
|
||||
.ic_class = "linux_atsc_frontend",
|
||||
.ic_super = &linux_dvb_frontend_class,
|
||||
};
|
||||
|
||||
static const idclass_t linux_dvbs_frontend_class = {
|
||||
.ic_class = "linux_dvbs_frontend",
|
||||
.ic_super = &linux_dvb_frontend_class,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
linux_dvb_frontend_create(dvb_hardware_t *parent, int adapterid,
|
||||
int frontendid, const struct dvb_frontend_info *dfi)
|
||||
{
|
||||
const idclass_t *class;
|
||||
|
||||
switch(dfi->type) {
|
||||
case FE_OFDM:
|
||||
class = &linux_dvbt_frontend_class;
|
||||
break;
|
||||
case FE_QAM:
|
||||
class = &linux_dvbc_frontend_class;
|
||||
break;
|
||||
case FE_QPSK:
|
||||
class = &linux_dvbs_frontend_class;
|
||||
break;
|
||||
case FE_ATSC:
|
||||
class = &linux_atsc_frontend_class;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// dvb_hardware_t *fe =
|
||||
dvb_hardware_create(class,
|
||||
sizeof(linux_dvb_frontend_t), parent, NULL, dfi->name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
add_adapter(int aid)
|
||||
{
|
||||
int frontends;
|
||||
int demuxers;
|
||||
int dvrs;
|
||||
int i;
|
||||
char path[PATH_MAX];
|
||||
dvb_hardware_t *a = NULL;
|
||||
|
||||
for(frontends = 0; frontends < 32; frontends++) {
|
||||
snprintf(path, sizeof(path), "/dev/dvb/adapter%d/frontend%d",
|
||||
aid, frontends);
|
||||
if(access(path, R_OK | W_OK))
|
||||
break;
|
||||
}
|
||||
|
||||
if(frontends == 0)
|
||||
return; // Nothing here
|
||||
|
||||
for(demuxers = 0; demuxers < 32; demuxers++) {
|
||||
snprintf(path, sizeof(path), "/dev/dvb/adapter%d/demux%d",
|
||||
aid, demuxers);
|
||||
if(access(path, R_OK | W_OK))
|
||||
break;
|
||||
}
|
||||
|
||||
for(dvrs = 0; dvrs < 32; dvrs++) {
|
||||
snprintf(path, sizeof(path), "/dev/dvb/adapter%d/dvr%d",
|
||||
aid, dvrs);
|
||||
if(access(path, R_OK | W_OK))
|
||||
break;
|
||||
}
|
||||
|
||||
tvhlog(LOG_INFO, "DVB",
|
||||
"Linux DVB adapter %d: %d frontends, %d demuxers, %d DVRs",
|
||||
aid, frontends, demuxers, dvrs);
|
||||
|
||||
for(i = 0; i < frontends; i++) {
|
||||
|
||||
snprintf(path, sizeof(path), "/dev/dvb/adapter%d/frontend%d", aid, i);
|
||||
|
||||
int fd = tvh_open(path, O_RDWR | O_NONBLOCK, 0);
|
||||
if(fd == -1) {
|
||||
tvhlog(LOG_ALERT, "DVB",
|
||||
"Unable to open %s -- %s", path, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
struct dvb_frontend_info dfi;
|
||||
|
||||
int r = ioctl(fd, FE_GET_INFO, &dfi);
|
||||
close(fd);
|
||||
if(r) {
|
||||
tvhlog(LOG_ALERT, "DVB", "%s: Unable to query adapter", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(a == NULL) {
|
||||
char name[512];
|
||||
snprintf(name, sizeof(name), "/dev/dvb/adapter%d", aid);
|
||||
|
||||
a = dvb_hardware_create(&linux_dvb_adapter_class, sizeof(dvb_hardware_t),
|
||||
NULL, NULL, name);
|
||||
}
|
||||
linux_dvb_frontend_create(a, aid, i, &dfi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_linux_init(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0 ; i < 32; i++)
|
||||
add_adapter(i);
|
||||
}
|
||||
|
||||
|
|
@ -1233,7 +1233,7 @@ dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi,
|
|||
streaming_target_t *st)
|
||||
{
|
||||
th_subscription_t *s;
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
// th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
|
||||
s = subscription_create(INT32_MAX, name, st, SUBSCRIPTION_RAW_MPEGTS,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
@ -1244,10 +1244,11 @@ dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi,
|
|||
|
||||
dvb_mux_tune(tdmi->tdmi_mux, "Full mux subscription", 99999);
|
||||
abort();
|
||||
#if 0
|
||||
pthread_mutex_lock(&tda->tda_delivery_mutex);
|
||||
streaming_target_connect(&tda->tda_streaming_pad, &s->ths_input);
|
||||
pthread_mutex_unlock(&tda->tda_delivery_mutex);
|
||||
|
||||
#endif
|
||||
notify_reload("subscriptions");
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -429,18 +429,6 @@ dvb_polarisation_to_str_long(int pol)
|
|||
}
|
||||
|
||||
|
||||
th_dvb_adapter_t *
|
||||
dvb_adapter_find_by_identifier(const char *identifier)
|
||||
{
|
||||
th_dvb_adapter_t *tda;
|
||||
|
||||
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link)
|
||||
if(!strcmp(identifier, tda->tda_identifier))
|
||||
return tda;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
44
src/idnode.c
44
src/idnode.c
|
@ -194,11 +194,47 @@ add_params(struct idnode *self, const idclass_t *ic, htsmsg_t *p)
|
|||
static const char *
|
||||
idnode_get_title(idnode_t *in)
|
||||
{
|
||||
if(in->in_class->ic_get_title != NULL) {
|
||||
return in->in_class->ic_get_title(in);
|
||||
} else {
|
||||
return idnode_uuid_as_str(in);
|
||||
const idclass_t *ic = in->in_class;
|
||||
for(; ic != NULL; ic = ic->ic_super) {
|
||||
if(ic->ic_get_title != NULL)
|
||||
return ic->ic_get_title(in);
|
||||
}
|
||||
return idnode_uuid_as_str(in);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
idnode_t **
|
||||
idnode_get_childs(idnode_t *in)
|
||||
{
|
||||
if(in == NULL)
|
||||
return NULL;
|
||||
|
||||
const idclass_t *ic = in->in_class;
|
||||
for(; ic != NULL; ic = ic->ic_super) {
|
||||
if(ic->ic_get_childs != NULL)
|
||||
return ic->ic_get_childs(in);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
int
|
||||
idnode_is_leaf(idnode_t *in)
|
||||
{
|
||||
const idclass_t *ic = in->in_class;
|
||||
if(ic->ic_leaf)
|
||||
return 1;
|
||||
for(; ic != NULL; ic = ic->ic_super) {
|
||||
if(ic->ic_get_childs != NULL)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ typedef struct idclass {
|
|||
const struct idclass *ic_super;
|
||||
const char *ic_class;
|
||||
const char *ic_caption;
|
||||
int ic_leaf;
|
||||
struct htsmsg *(*ic_serialize)(struct idnode *self);
|
||||
struct idnode **(*ic_get_childs)(struct idnode *self);
|
||||
const char *(*ic_get_title)(struct idnode *self);
|
||||
|
@ -32,6 +33,10 @@ const char *idnode_uuid_as_str(const idnode_t *in);
|
|||
|
||||
void *idnode_find(const char *uuid, const idclass_t *class);
|
||||
|
||||
idnode_t **idnode_get_childs(idnode_t *in);
|
||||
|
||||
int idnode_is_leaf(idnode_t *in);
|
||||
|
||||
void idnode_unlink(idnode_t *in);
|
||||
|
||||
htsmsg_t *idnode_serialize(struct idnode *self);
|
||||
|
@ -45,3 +50,4 @@ void idnode_update_all_props(idnode_t *in,
|
|||
|
||||
void idnode_notify_title_changed(void *obj);
|
||||
|
||||
|
||||
|
|
40
src/tvadapters.c
Normal file
40
src/tvadapters.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* TV Adapters
|
||||
* Copyright (C) 2013 Andreas Öman
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tvheadend.h"
|
||||
#include "tvadapters.h"
|
||||
#include "dvb/dvb.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
idnode_t **
|
||||
tv_adapters_root(void)
|
||||
{
|
||||
dvb_hardware_t *dh;
|
||||
int cnt = 1;
|
||||
TAILQ_FOREACH(dh, &dvb_adapters, dh_parent_link)
|
||||
cnt++;
|
||||
|
||||
idnode_t **v = malloc(sizeof(idnode_t *) * cnt);
|
||||
cnt = 0;
|
||||
TAILQ_FOREACH(dh, &dvb_adapters, dh_parent_link)
|
||||
v[cnt++] = &dh->dh_id;
|
||||
v[cnt] = NULL;
|
||||
return v;
|
||||
}
|
5
src/tvadapters.h
Normal file
5
src/tvadapters.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "idnode.h"
|
||||
|
||||
idnode_t **tv_adapters_root(void);
|
|
@ -47,6 +47,7 @@
|
|||
#include "config2.h"
|
||||
#include "lang_codes.h"
|
||||
#include "subscriptions.h"
|
||||
#include "tvadapters.h"
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -1813,6 +1814,7 @@ extjs_service_update(htsmsg_t *in)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -1844,6 +1846,7 @@ extjs_tvadapter(http_connection_t *hc, const char *remain, void *opaque)
|
|||
http_output_content(hc, "text/x-json; charset=UTF-8");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -1928,17 +1931,14 @@ extjs_get_idnode(http_connection_t *hc, const char *remain, void *opaque,
|
|||
if(!strcmp(s, "root")) {
|
||||
v = rootfn();
|
||||
} else {
|
||||
idnode_t *n = idnode_find(s, NULL);
|
||||
v = n != NULL && n->in_class->ic_get_childs != NULL ?
|
||||
n->in_class->ic_get_childs(n) : NULL;
|
||||
v = idnode_get_childs(idnode_find(s, NULL));
|
||||
}
|
||||
|
||||
if(v != NULL) {
|
||||
int i;
|
||||
for(i = 0; v[i] != NULL; i++) {
|
||||
htsmsg_t *m = idnode_serialize(v[i]);
|
||||
if(v[i]->in_class->ic_get_childs == NULL)
|
||||
htsmsg_add_u32(m, "leaf", 1);
|
||||
htsmsg_add_u32(m, "leaf", idnode_is_leaf(v[i]));
|
||||
htsmsg_add_msg(out, NULL, m);
|
||||
}
|
||||
}
|
||||
|
@ -1995,6 +1995,15 @@ extjs_item_update(http_connection_t *hc, const char *remain, void *opaque)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
extjs_tvadapters(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
return extjs_get_idnode(hc, remain, opaque, &tv_adapters_root);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -2022,9 +2031,12 @@ extjs_start(void)
|
|||
http_path_add("/mergechannel", NULL, extjs_mergechannel, ACCESS_ADMIN);
|
||||
http_path_add("/iptv/services", NULL, extjs_iptvservices, ACCESS_ADMIN);
|
||||
http_path_add("/servicedetails", NULL, extjs_servicedetails, ACCESS_ADMIN);
|
||||
http_path_add("/tv/adapter", NULL, extjs_tvadapter, ACCESS_ADMIN);
|
||||
// http_path_add("/tv/adapter", NULL, extjs_tvadapter, ACCESS_ADMIN);
|
||||
http_path_add("/item/update", NULL, extjs_item_update, ACCESS_ADMIN);
|
||||
|
||||
http_path_add("/tvadapters",
|
||||
NULL, extjs_tvadapters, ACCESS_ADMIN);
|
||||
|
||||
#if ENABLE_LINUXDVB
|
||||
extjs_start_dvb();
|
||||
#endif
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -83,8 +83,10 @@ extjs_dvblocations(http_connection_t *hc, const char *remain, void *opaque)
|
|||
http_output_content(hc, "text/x-json; charset=UTF-8");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -102,7 +104,6 @@ json_single_record(htsmsg_t *rec, const char *root)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -249,6 +250,7 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque)
|
|||
http_output_content(hc, "text/x-json; charset=UTF-8");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
|
@ -666,18 +668,6 @@ extjs_dvb_copymux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
extjs_list_dvb_adapters(htsmsg_t *array)
|
||||
{
|
||||
th_dvb_adapter_t *tda;
|
||||
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link)
|
||||
htsmsg_add_msg(array, NULL, dvb_adapter_build_msg(tda));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -696,13 +686,13 @@ extjs_start_dvb(void)
|
|||
{
|
||||
http_path_add("/dvb/networks",
|
||||
NULL, extjs_dvbnetworks, ACCESS_WEB_INTERFACE);
|
||||
#if 0
|
||||
http_path_add("/dvb/locations",
|
||||
NULL, extjs_dvblocations, ACCESS_WEB_INTERFACE);
|
||||
|
||||
http_path_add("/dvb/adapter",
|
||||
NULL, extjs_dvbadapter, ACCESS_ADMIN);
|
||||
|
||||
#if 0
|
||||
|
||||
http_path_add("/dvb/muxes",
|
||||
NULL, extjs_dvbmuxes, ACCESS_ADMIN);
|
||||
|
|
|
@ -265,6 +265,7 @@ extjs_v4lservices(http_connection_t *hc, const char *remain, void *opaque)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -277,6 +278,7 @@ extjs_list_v4l_adapters(htsmsg_t *array)
|
|||
TAILQ_FOREACH(va, &v4l_adapters, va_global_link)
|
||||
htsmsg_add_msg(array, NULL, v4l_adapter_build_msg(va));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,7 +75,6 @@ dumpchannels(htsbuf_queue_t *hq)
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_LINUXDVB
|
||||
#if 0
|
||||
static void
|
||||
dumptransports(htsbuf_queue_t *hq, struct service_list *l, int indent)
|
||||
|
@ -120,7 +119,6 @@ dumptransports(htsbuf_queue_t *hq, struct service_list *l, int indent)
|
|||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -171,10 +169,6 @@ page_statedump(http_connection_t *hc, const char *remain, void *opaque)
|
|||
tvh_binshasum[19]);
|
||||
|
||||
dumpchannels(hq);
|
||||
|
||||
#if ENABLE_LINUXDVB
|
||||
dumpdvbadapters(hq);
|
||||
#endif
|
||||
|
||||
http_output_content(hc, "text/plain; charset=UTF-8");
|
||||
return 0;
|
||||
|
|
|
@ -33,13 +33,12 @@ tvheadend.item_editor = function(item) {
|
|||
}
|
||||
|
||||
var panel = new Ext.FormPanel({
|
||||
labelWidth: 75, // label settings here cascade unless overridden
|
||||
url:'save-form.php',
|
||||
labelWidth: 150, // label settings here cascade unless overridden
|
||||
frame:true,
|
||||
title: 'Parameters',
|
||||
bodyStyle:'padding:5px 5px 0',
|
||||
width: 350,
|
||||
defaults: {width: 230},
|
||||
width: 500,
|
||||
defaults: {width: 330},
|
||||
defaultType: 'textfield',
|
||||
items: fields,
|
||||
|
||||
|
@ -72,12 +71,12 @@ tvheadend.item_editor = function(item) {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
tvheadend.dvb_networks = function() {
|
||||
tvheadend.item_browser = function(url, title) {
|
||||
|
||||
var current = null;
|
||||
|
||||
var loader = new Ext.tree.TreeLoader({
|
||||
dataUrl: 'dvb/networks'
|
||||
dataUrl: url
|
||||
});
|
||||
|
||||
var tree = new Ext.tree.TreePanel({
|
||||
|
@ -86,7 +85,7 @@ tvheadend.dvb_networks = function() {
|
|||
border: false,
|
||||
root : new Ext.tree.AsyncTreeNode({
|
||||
id : 'root',
|
||||
text: 'DVB Networks'
|
||||
text: title
|
||||
}),
|
||||
listeners: {
|
||||
click: function(n) {
|
||||
|
@ -114,7 +113,7 @@ tvheadend.dvb_networks = function() {
|
|||
|
||||
|
||||
var panel = new Ext.Panel({
|
||||
title: 'DVB Networks',
|
||||
title: title,
|
||||
layout: 'hbox',
|
||||
flex: 1,
|
||||
padding: 5,
|
||||
|
@ -132,3 +131,12 @@ tvheadend.dvb_networks = function() {
|
|||
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
tvheadend.dvb_networks = function() {
|
||||
return tvheadend.item_browser('/dvb/networks', 'DVB Networks');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* Datastore for adapters
|
||||
*/
|
||||
/*
|
||||
tvheadend.tvAdapterStore = new Ext.data.JsonStore({
|
||||
root : 'entries',
|
||||
id : 'identifier',
|
||||
|
@ -71,10 +72,11 @@ tvheadend.tvadapters = function() {
|
|||
|
||||
return panel;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/*
|
||||
tvheadend.showTransportDetails = function(data) {
|
||||
html = '';
|
||||
|
||||
|
@ -106,3 +108,8 @@ tvheadend.showTransportDetails = function(data) {
|
|||
});
|
||||
win.show();
|
||||
}
|
||||
*/
|
||||
|
||||
tvheadend.tvadapters = function() {
|
||||
return tvheadend.item_browser('/tvadapters', 'TV Adapters');
|
||||
}
|
|
@ -33,12 +33,10 @@ size_t html_escaped_len(const char *src);
|
|||
const char* html_escape(char *dst, const char *src, size_t len);
|
||||
|
||||
#if ENABLE_LINUXDVB
|
||||
void extjs_list_dvb_adapters(htsmsg_t *array);
|
||||
void extjs_start_dvb(void);
|
||||
#endif
|
||||
|
||||
#if ENABLE_V4L
|
||||
void extjs_list_v4l_adapters(htsmsg_t *array);
|
||||
void extjs_start_v4l(void);
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue