diff --git a/Makefile b/Makefile index b79cefd8..83a314a5 100644 --- a/Makefile +++ b/Makefile @@ -171,10 +171,9 @@ SRCS-${CONFIG_LINUXDVB} += \ src/input/mpegts/linuxdvb/linuxdvb_device.c \ src/input/mpegts/linuxdvb/linuxdvb_adapter.c \ src/input/mpegts/linuxdvb/linuxdvb_frontend.c \ + src/input/mpegts/linuxdvb/linuxdvb_network.c \ + src/input/mpegts/linuxdvb/linuxdvb_mux.c \ -# src/input/mpegts/linuxdvb/linuxdvb_input.c \ -# src/input/mpegts/linuxdvb/linuxdvb_network.c \ -# src/input/mpegts/linuxdvb/linuxdvb_mux.c \ # src/input/mpegts/linuxdvb/linuxdvb_service.c \ # IPTV diff --git a/src/input/mpegts.h b/src/input/mpegts.h index e4c75388..8cbfb1f9 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -135,8 +135,8 @@ void mpegts_psi_section_reassemble /* Network */ struct mpegts_network { - idnode_t mn_id; - LIST_ENTRY(dvb_network) mn_global_link; + idnode_t mn_id; + LIST_ENTRY(mpegts_network) mn_global_link; /* * Identification @@ -242,6 +242,7 @@ struct mpegts_mux * Functions */ + void (*mm_config_save) (mpegts_mux_t *mm); int (*mm_start) (mpegts_mux_t *mm, const char *reason, int weight); void (*mm_stop) (mpegts_mux_t *mm); void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*); @@ -443,7 +444,7 @@ mpegts_network_t *mpegts_network_create0 const char *name ); #define mpegts_network_create(t, u, n)\ - (struct t*)mpegts_network_create0(calloc(1, sizeof(struct t)), t##_class, u, n) + (struct t*)mpegts_network_create0(calloc(1, sizeof(struct t)), &t##_class, u, n) void mpegts_network_schedule_initial_scan ( mpegts_network_t *mm ); diff --git a/src/input/mpegts/linuxdvb/linuxdvb.c b/src/input/mpegts/linuxdvb/linuxdvb.c index 34915a7d..fd006af1 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb.c +++ b/src/input/mpegts/linuxdvb/linuxdvb.c @@ -22,13 +22,10 @@ #include "settings.h" #include "linuxdvb_private.h" -#include -#include - void linuxdvb_init ( int adapter_mask ) { /* Initialise networks */ - //linuxdvb_network_init(); + linuxdvb_network_init(); /* Initialsie devices */ linuxdvb_device_init(adapter_mask); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_mux.c b/src/input/mpegts/linuxdvb/linuxdvb_mux.c new file mode 100644 index 00000000..90248353 --- /dev/null +++ b/src/input/mpegts/linuxdvb/linuxdvb_mux.c @@ -0,0 +1,168 @@ +/* + * Tvheadend - Linux DVB Multiplex + * + * Copyright (C) 2013 Adam Sutton + * + * 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 . + */ + +#include "tvheadend.h" +#include "input.h" +#include "linuxdvb_private.h" +#include "queue.h" +#include "settings.h" + +#include +#include +#include +#include +#include +#include + +/* + * Class definition + */ +extern const idclass_t mpegts_mux_class; +const idclass_t linuxdvb_mux_class = +{ + .ic_super = &mpegts_mux_class, + .ic_class = "linuxdvb_mux", + .ic_caption = "Linux DVB Multiplex", + .ic_properties = (const property_t[]){ + {} + } +}; + +const idclass_t linuxdvb_mux_dvbt_class = +{ + .ic_super = &linuxdvb_mux_class, + .ic_class = "linuxdvb_mux_dvbt", + .ic_caption = "Linux DVB-T Multiplex", + .ic_properties = (const property_t[]){ + {} + } +}; + +const idclass_t linuxdvb_mux_dvbc_class = +{ + .ic_super = &linuxdvb_mux_class, + .ic_class = "linuxdvb_mux_dvbc", + .ic_caption = "Linux DVB-C Multiplex", + .ic_properties = (const property_t[]){ + {} + } +}; + +const idclass_t linuxdvb_mux_dvbs_class = +{ + .ic_super = &linuxdvb_mux_class, + .ic_class = "linuxdvb_mux_dvbs", + .ic_caption = "Linux DVB-S Multiplex", + .ic_properties = (const property_t[]){ + {} + } +}; + +const idclass_t linuxdvb_mux_atsc_class = +{ + .ic_super = &linuxdvb_mux_class, + .ic_class = "linuxdvb_mux_atsc", + .ic_caption = "Linux ATSC Multiplex", + .ic_properties = (const property_t[]){ + {} + } +}; + +/* + * Mux Objects + */ + +static void +linuxdvb_mux_config_save ( mpegts_mux_t *mm ) +{ +} + +#if 0 +static int +linuxdvb_mux_start ( mpegts_mux_t *mm, const char *reason, int weight ) +{ + return SM_CODE_TUNING_FAILED; +} + +static void +linuxdvb_mux_stop ( mpegts_mux_t *mm ) +{ +} +#endif + +static void +linuxdvb_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) +{ +} + +static void +linuxdvb_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) +{ +} + + +linuxdvb_mux_t * +linuxdvb_mux_create0 + ( linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf ) +{ + //uint32_t u32; + //const char *str; + mpegts_mux_t *mm; + linuxdvb_mux_t *lm; + const idclass_t *idc; + + /* Class */ + if (ln->ln_type == FE_QPSK) + idc = &linuxdvb_mux_dvbs_class; + else if (ln->ln_type == FE_QAM) + idc = &linuxdvb_mux_dvbc_class; + else if (ln->ln_type == FE_OFDM) + idc = &linuxdvb_mux_dvbt_class; + else if (ln->ln_type == FE_ATSC) + idc = &linuxdvb_mux_atsc_class; + else { + tvhlog(LOG_ERR, "linuxdvb", "unknown FE type %d", ln->ln_type); + return NULL; + } + + /* Create */ + if (!(mm = mpegts_mux_create0(calloc(1, sizeof(linuxdvb_mux_t)), idc, uuid, + (mpegts_network_t*)ln, + MPEGTS_ONID_NONE, + MPEGTS_TSID_NONE))) + return NULL; + lm = (linuxdvb_mux_t*)mm; + + /* Callbacks */ + lm->mm_config_save = linuxdvb_mux_config_save; +#if 0 + lm->mm_start = linuxdvb_mux_start; + lm->mm_stop = linuxdvb_mux_stop; +#endif + lm->mm_open_table = linuxdvb_mux_open_table; + lm->mm_close_table = linuxdvb_mux_close_table; + + /* No config */ + if (!conf) + return lm; + + /* Config */ + + return lm; +} diff --git a/src/input/mpegts/linuxdvb/linuxdvb_network.c b/src/input/mpegts/linuxdvb/linuxdvb_network.c new file mode 100644 index 00000000..8a47d3dd --- /dev/null +++ b/src/input/mpegts/linuxdvb/linuxdvb_network.c @@ -0,0 +1,135 @@ +/* + * Tvheadend - Linux DVB Network + * + * Copyright (C) 2013 Adam Sutton + * + * 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 . + */ + +#include "tvheadend.h" +#include "input.h" +#include "linuxdvb_private.h" +#include "queue.h" +#include "settings.h" + +#include +#include +#include +#include +#include +#include + +extern const idclass_t mpegts_network_class; +const idclass_t linuxdvb_network_class = +{ + .ic_super = &mpegts_network_class, + .ic_class = "linuxdvb_network", + .ic_caption = "LinuxDVB Network", + .ic_properties = (const property_t[]){ +#if 0 + { PROPDEF2("type", "Network Type", + PT_STR, linuxdvb_network_t, ln_type, 1), + .get_str }, +#endif + {} + } +}; + +static mpegts_mux_t * +linuxdvb_network_create_mux + ( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *conf ) +{ + return NULL; +} + +static mpegts_service_t * +linuxdvb_network_create_service + ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) +{ + return NULL; +} + +static void +linuxdvb_network_config_save ( mpegts_network_t *mn ) +{ +} + +static linuxdvb_network_t * +linuxdvb_network_create0 + ( const char *uuid, htsmsg_t *conf ) +{ + uint32_t u32; + const char *str; + linuxdvb_network_t *ln; + htsmsg_t *c, *e; + htsmsg_field_t *f; + + /* Create */ + if (!(ln = mpegts_network_create(linuxdvb_network, uuid, NULL))) + return NULL; + + /* Callbacks */ + ln->mn_create_mux = linuxdvb_network_create_mux; + ln->mn_create_service = linuxdvb_network_create_service; + ln->mn_config_save = linuxdvb_network_config_save; + + /* No config */ + if (!conf) + return ln; + + /* Load configuration */ + if ((str = htsmsg_get_str(conf, "type"))) + ln->ln_type = dvb_str2type(str); + if ((str = htsmsg_get_str(conf, "name"))) + ln->mn_network_name = strdup(str); + if (!htsmsg_get_u32(conf, "nid", &u32)) + ln->mn_nid = u32; + + printf("network created %s / %s / %d\n", dvb_type2str(ln->ln_type), + ln->mn_network_name, ln->mn_nid); + + /* Load muxes */ + if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes", uuid))) { + HTSMSG_FOREACH(f, c) { + if (!(e = htsmsg_get_map_by_field(f))) continue; + if (!(e = htsmsg_get_map(e, "config"))) continue; + (void)linuxdvb_mux_create0(ln, f->hmf_name, e); + } + } + + return ln; +} + +linuxdvb_network_t* +linuxdvb_network_find_by_uuid(const char *uuid) +{ + idnode_t *in = idnode_find(uuid, &linuxdvb_network_class); + return (linuxdvb_network_t*)in; +} + +void linuxdvb_network_init ( void ) +{ + htsmsg_t *c, *e; + htsmsg_field_t *f; + + if (!(c = hts_settings_load_r(1, "input/linuxdvb/networks"))) + return; + + HTSMSG_FOREACH(f, c) { + if (!(e = htsmsg_get_map_by_field(f))) continue; + if (!(e = htsmsg_get_map(e, "config"))) continue; + (void)linuxdvb_network_create0(f->hmf_name, e); + } + htsmsg_destroy(c); +} diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 54d3c44b..e9a7595f 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -26,6 +26,8 @@ typedef struct linuxdvb_hardware linuxdvb_hardware_t; typedef struct linuxdvb_device linuxdvb_device_t; typedef struct linuxdvb_adapter linuxdvb_adapter_t; typedef struct linuxdvb_frontend linuxdvb_frontend_t; +typedef struct linuxdvb_network linuxdvb_network_t; +typedef struct linuxdvb_mux linuxdvb_mux_t; typedef LIST_HEAD(,linuxdvb_hardware) linuxdvb_hardware_list_t; @@ -135,4 +137,30 @@ linuxdvb_frontend_added const char *fe_path, const char *dmx_path, const char *dvr_path, const struct dvb_frontend_info *fe_info ); +struct linuxdvb_network +{ + mpegts_network_t; + + /* + * Network type + */ + fe_type_t ln_type; +}; + +void linuxdvb_network_init ( void ); +linuxdvb_network_t *linuxdvb_network_find_by_uuid(const char *uuid); + +struct linuxdvb_mux +{ + mpegts_mux_t; + + /* + * Tuning information + */ + dvb_mux_conf_t lm_tune_conf; +}; + +linuxdvb_mux_t *linuxdvb_mux_create0 + (linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf); + #endif /* __TVH_LINUXDVB_PRIVATE_H__ */ diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index d0fbd8b4..8be71e99 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -77,7 +77,7 @@ mpegts_network_create0 idnode_insert(&mn->mn_id, uuid, idc); mn->mn_create_mux = mpegts_network_create_mux; mn->mn_config_save = mpegts_network_config_save; - mn->mn_network_name = strdup(netname); + if (netname) mn->mn_network_name = strdup(netname); TAILQ_INIT(&mn->mn_initial_scan_pending_queue); TAILQ_INIT(&mn->mn_initial_scan_current_queue); return mn;